B2G/QA/Automation/Style Guide

< B2G‎ | QA‎ | Automation
Revision as of 20:52, 3 November 2015 by Npark (talk | contribs) (→‎Tests - Style: provide link)

The goal of this style guide is to provide rules to write ui-automation code that is clear and effective. It is a fork of this webqa page.

It is also recommended to review Geo's draft of automation best practices, which gives a theoretical overview of writing automation tests.

General Concepts

How-Tos

Python Script Style Guide

Logic

Handling shadow DOM

TBD - njpark

Switching frames and system frame

TBD - mwargers

Handling browser instances

TBD - mwargers

Returning the page object after completing an action

TBD - njpark

   When writing methods that is doing some action on the device, for instance opening an app or opening a subpage, make sure that the resulting action is finished and return the object of the resulting action, e.g. the app or the subpage (PageRegion)


Use of Libraries

Limited use of conditionals

  • Methods should not contain logic that depends on properties of the page. The logic and expectations should be within the test, and adding this to the page object could guard your tests against genuine failures.
# Good
def click_login(self)
    self.selenium.find_element(*self._login_locator).click()

# Bad
def click_login(self)
    if not self.is_user_logged_in:
        self.selenium.find_element(*self._login_locator).click()
    else:
        pass

Locators

TBD - jlorenzo

  • Locator variables should be prefixed with _ to show that it is private.
  • Variables should be descriptive of the area and not clash with any properties.
  • Should have a suffix of _locator.
  • Accessing locators should be done through a property or method as this keeps the locator as read-only.
@property
def search_term(self):
    return self.selenium.find_element(*self._search_box_locator).value
  • We should use locators in the following order of preference (there will be exceptions):
    • ID
    • Name
    • Class name
    • CSS selector
    • XPath
  • CSS locators should use whitespace for readability when using direct descendants.
# Good
_my_locator = "css=#content > p > a"
    
# Bad
_my_locator = "css=#content>p>a"
  • Use Python tuples to define locators:
# Good
_my_locator = (By.ID, "content")

PageRegions

TBD - jlorenzo

  • How to deal with stale root_elements

In some circumstances, for example where a header/navigation is common across the website, we will use a page region. The page region is a child class of the base Page object, which is inherited by all page objects. This means that the navigation can be reached from any page object and herein lies the DRY!

A brief example:

class BasePage(Page):

    @property
    def header(self):
        return BasePage.HeaderRegion(self.testsetup)
    
    class HeaderRegion(Page):

        _login_link = (By.ID, "home")

        @def click_login(self):
            self.selenium.find_element(*self._login_link).click()

Referring to this page region with a property makes it very readable and concise from within the test. Clicking login during a test would be performed like this:

my_page.header.click_login()

Another example where this might be used is on a search results page, the page region being the search results element.

Assertions

TBD - jlorenzo

  • Tests should handle the asserts -- not the page objects.
  • Tests should use Python's native assert statement.
  • When doing equivalency assertions, put the expected value first, followed by the actual value, for example:
# Good
a = some_function()
assert 'expected result' == a

# Bad
a = some_function()
assert a == 'expected result'

How to use GaiaHeader and GaiaBinaryControl

TBD - jlorenzo

Submitting and Reviewing Patches

Submission

To make sure that we can review your patch as quickly and efficiently as possibly we would like patches to have a single test in them and the necessary changes to the page objects. This also limits the chances of merge conflicts later.
Please refer to this page for gaia patch submission steps.

Review

First of all, make sure above mentioned guidelines are not violated, and check for the following:

Look for transitions that are not waited on

TBD - jlorenzo

Check for change/removal of methods

In order to make sure that the change is cascaded, `git grep` is your friend. TBD - jlorenzo

Are the locators correct? Could they be improved?

TBD - jlorenzo

Are the locators/methods used that were added?

TBD - mwargers A linter would also help to enforce it, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1186388

Are workarounds explained in the code file?

TBD - jlorenzo