Manual:Coding conventions/Selenium-Ruby

Since I pair with people from different teams and I work on the mediawiki-selenium gem I tend to see a lot of Ruby, Selenium, Cucumber and page-object code. I have noticed some code that I like and some code that I do not like.

To move the code towards what I like, I have been working on this page. I plan to implement the changes myself, if nobody does it before I have the time to do it. I do not have a timeline for that.

I would really appreciate if you would read the page (it should take you 5 minutes or so) and let me know if you agree or disagree with my thoughts, if I missed something, if something needs to be explained, if the page should have more text and less code or vice versa...

You can let me know in the page discussion section, at QA mailing list, at #wikimedia-qa freenode IRC channel (I am zeljkof there). Also, feel free to update the page.

This page describes coding conventions used by Cucumber test files in MediaWiki codebase. For the list of repositories that contain the files see links section of mediawiki-selenium readme file. There are three types of files, Cucumber features files, Cucumber step definition files and page object files.

Cucumber feature files
For example file see any file in  folder of qa-browsertests repository. Feature files usually contain features and scenarios.

Required tags
Every feature or scenario in a feature file should have a site and browser specific tag.
 * Site specific tag is for example  or  . The tag specifies where the feature or scenario should run. This convention is currently used in most places.
 * Browser specific tag is for example  or  . The tag specifies which browser should be used to run the feature or scenario. This convention is currently not used. At the moment we tag features or scenarios if they are known to fail with specific browser, for example.

Optional tags
Some features or scenarios can have an optional tag.
 * If the feature or scenario requires the user to log in, it should have  tag. This convention is currently used in most places.


 * If the feature or scenario runs fine on a clean wiki, it should be tagged . This convention is currently not used. At the moment we tag features or scenarios that are known to fail on a clean wiki with.
 * If the feature or scenario requires custom browser configuration, it should be tagged . This convention is currently not used. At the moment we tag features or scenarios that need custom browser configuration with   tag in UniversalLanguageSelector repository and with   tag in MobileFrontend repository.

Cucumber step definition files
For example file see any file in   folder of qa-browsertests repository. Step definition files usually contain,   and   steps.

Simplicity
In general, code in step definition files should be as simple as possible. Ideally, just one or two lines per step. All complicated code should be moved to page objects. This convention is currently used in most places.

Example:

Grouped By Type
Steps should be grouped by type. and  steps should be grouped in one group,   steps should be grouped separately.

Example:

This convention is currently not used. At the moment we do not combine  and   steps in one group.

Alphabetically Sorted
Inside a group, steps should be sorted alphabetically by step name. That moves steps with similar name close to each other. Steps with similar name usually have similar functionality, making them good candidates for merging. This convention is currently used in most places.

Example:

Page object files
For example file see any file in   folder of qa-browsertests repository. Step definition files usually contain page URL, page elements and methods. All complicated functionality should be moved to methods.

URL
Page URL is optional. It is used in step definitions when a  or   step needs to go directly to a page, or when a   step needs to check page URL.

Example:

Page elements
Simple page elements should be defined using page-object Ruby gem API.

Example:

Elements that are complicated to find should pass blocks finding the elements to the page-object API.

Example:

Methods
If a page has complicated functionality, a method in page object is usually the best place for it.

Example: