root
+ config
+ data DataMagic folder for test data
+ lib
+ constants Constants
+ page_object Customizations for page object
+ pages Page-object classes
+ components Components used in multiple pages (e.g. banners, tables, etc.)
+ steps Preconditions and/or multi-action test steps
+ resources Test resource files
+ results Test results
+ spec Test scenario implementations
+ xss_vulnerabilities Test suite
+ spec_helper.rb Rspec configuration
- Homebrew and Bundler are required.
config/datafolder is where different environments have their test data stored. Defaults can be changed on-demand.- Run the following step that installs the necessary dependencies:
bundle installCurrently, the following environment variables are in use:
-
ENV_URLdefaults tolocalhost:3000. Any valid url (IP:PORT) can be passed to set the monolith target environment. -
CONFIGdefaults todefault. Available options aredefault,staging&production. This option controls which test data.ymlfile would be used by the test run. -
BROWSERdefaults tochrome. Available options arechrome,firefox&safari. For example:BROWSER=safariorBROWSER=firefox. To use Safari, please read and follow steps from: Watir Safari Guides. Headless mode is supported in Chrome & Firefox. You can turn on headless locally by passing the following:
BROWSER=chrome_headlessorBROWSER=firefox_headless. -
CI_BROWSERis boolean, used as a mandatory option for CI builds. Available options areCHROME&FIREFOX. -
WINDOW_SIZE-> defaults to maximize browser window. Available for Chrome and Firefox. Safari has a known bug where resizing the browser window does not work as expected. You should specify a resolution to resize the browser window to a given width and height. For example:WINDOW_SIZE=1280*740orWINDOW_SIZE=1280x740.
List available tasks and their descriptions:
rake --tasks- Execute subscriptions tests on staging:
bundle exec rake staging:task_nameAdd environment variable BROWSER to existing rake tasks:
BROWSER=firefox bundle exec rake staging:task_name- Executes desired spec on localhost:
bundle exec rspec ./spec/path_to_spec/your_spec.rb- Executes desired spec on staging:
ENV_URL=https://app.....dev/ CONFIG=staging bundle exec rspec ./spec/path_to_spec/your_spec.rb- Executes desired spec on production:
ENV_URL=https://app.....com/ CONFIG=production bundle exec rspec ./spec/path_to_spec/your_spec.rbUse the --tag (or -t) option to run examples that match a specified tag.
The tag can be a simple name or a name:value pair.
You would specify --tag and the tag name (without the :) as a runtime parameter, like so:
bundle exec rspec --tag smokeAlternatively, you can ignore tags with a ~ prepended to the tag name:
bundle exec rspec --tag ~smokeTo run just the smoke tag and negate the local:false tag, you would do the following:
bundle exec rspec --tag smoke --tag ~local:falseTo run smoke tag and negate the local:false and chrome:false tags, you would do the following:
bundle exec rspec --tag smoke --tag ~local:false --tag ~chrome:falseEach individual test has TestRail ID as tag (symbol after test's name, which contains digits enclosed in
quotes: tms:'12345')
- Execute desired test on localhost:
bundle exec rspec --tag tms:12345- Executes desired test on staging:
ENV_URL=https://app.....dev/ CONFIG=staging bundle exec rspec --tag tms:12345In order to execute shared examples you specify the path to the spec file, not to the shared examples file in
the rspec command (as usual).
bundle exec rspec ./spec/path_to_spec/your_spec.rbIn order to execute only one test from a shared examples group you have two options:
- Specify the name of the example with the
--exampleoption:
bundle exec rspec ./spec/path_to_spec/your_spec.rb --example name_of_the_scenarioNote: if you use interpolation in the scenario name substitute the interpolated variable with the proper string.
- Specify the TestRail ID with the
--tagoption:
bundle exec rspec ./spec/path_to_spec/your_spec.rb --tag tms:12345ENV_URL=https://app.....dev/ CONFIG=staging bundle exec parallel_rspec ./spec/path_to_spec/your_spec.rbMake the first environment be 1:
ENV_URL=https://app.....dev/ CONFIG=staging bundle exec parallel_rspec --first-is-1 ./spec/path_to_spec/your_spec.rbSpecify how many processes to use, default: available CPUs:
ENV_URL=https://app.....dev/ CONFIG=staging bundle exec parallel_rspec -n 2 ./spec/path_to_spec/your_spec.rbFor more info, please visit: Parallel gem documentation
The test results will be recorded in the results directory.
To generate the report from existing Allure results you can use the following command:
allure generate results/allure-results --clean -o allure-reportOpen it in your default system browser, run:
allure open allure-reportFor more info, please visit: Allure Framework official documentation
Usage of watir-scroll
Slice and dice tests with tags
You can define helper methods in a module and include it in your example
groups using the config.include configuration option.
File named xyz_steps.rb could be added to ./lib/steps/ with:
module XYZSteps
def help
:available
end
endAt spec_helper.rb update RSpec.configure do |config| with:
config.include XYZSteps
The RSpec docs for helper methods can be found at Define helper methods in a module
Defining element collections using the page objects gem
Plural form of element using page-object gem
Watir, Page-objects: how to get all elements that have the same identifier
Looping through a collection of divs in Watir
Watir can find and return an:
Element - The first (single) matching element or
Element Collection - All matching elements.
There are two element type methods, for each supported element, that correlate to the return type:
Singular - This version returns the element.
Plural - This version returns the element collection.
For example, the div method, which is singular, will tell Watir to find the first div element on the page:
browser.div
The pluralization of div is divs, which will return all div elements on the page:
browser.divs
Note that the pluralized version is generally the singular version with an ‘s’ added to the end. However, following English conventions, there will be some element types that have ‘es’ added to the end or have the ending ‘y’ replaced by ‘ies’.
Source: Book: Watirways
Interacting with elements on the page (xyz_page):
xyz_element.present?
xyz_element.exists?
xyz_element.selected?
xyz_element.enabled?
xyz_element.text # If element has text.
xyz_element.attribute('attribute')Interacting with browser on the page (xyz_page):
@browser.refresh
@browser.url
@browser.title
@browser.textInteracting with elements in the spec (xyz_spec):
on(XyzPage).xyz_element.present?
on(XyzPage).xyz_element.exists?
on(XyzPage).xyz_element.selected?
on(XyzPage).xyz_element.enabled?
on(XyzPage).xyz_element.textInteracting with current page in the spec (xyz_spec):
@current_page.url
@current_page.title
@current_page.text
@current_page.refresh
@current_page.text.include? 'text' # Return true if the specified text appears on the page# start new driver session
@browser = Watir::Browser.new :firefox
@browser = Watir::Browser.new :chrome
@browser = Watir::Browser.new :ie
# goto url
@browser.goto "https://labs.com"
# refresh
@browser.refresh
# close
@browser.quit# enter value
@browser.text_field(:id => "text").set "watir-webdriver"
# get value
@browser.text_field(:id => "text").value
# clear
@browser.text_field(:id => "text").clear# is enabled?
@browser.button(:id => "btn").enabled?
# button's text
@browser.button(:id => "btn").text
# click
@browser.button(:id => "btn").click# check
@browser.checkbox(:id => "btn").set
@browser.checkbox(:id => "btn").set(true)
# uncheck
@browser.checkbox(:id => "btn").clear
@browser.checkbox(:id => "btn").set(false)
# is checked?
@browser.checkbox(:id => "btn").set?# select from list text
@browser.select_list(:id => "list").select "var"
# select using value
@browser.select_list(:id => "list").select_value "var2"
# value is selected?
@browser.select_list(:id => "list").selected?("var2")
# get value
puts @browser.select_list(:id => "list").value
# get all items
@browser.select_list(:id => "list").options.each do |i|
puts "#{i.text}"
end# select value
@browser.radio(:id => "radio").set
# is var selected?
@browser.radio(:id => "radio").set?# is image loaded?
@browser.image(:src => "img.gif").loaded?
# height
@browser.image(:src => "img.gif").height
# width
@browser.image(:src => "img.gif").width
# click
@browser.image(:src => "img.gif").click
# click 1st image
@browser.images[0].click# get text
@browser.div(:class => "body").text
# get text of 2nd div when it appears
@browser.divs[1].when_present.text# row 1, col 1
@browser.table(:id => "table")[0][0].text
# row 1, col 2 (alternate)
@browser.table(:id => "table").tr { 0 }.cell { 1 }.text
# row 2 - entire text
puts @browser.table(:id => "table")[1].text
# click row #4
puts @browser.table(:id => "table")[3].click
# get column count
@browser.table(:id => "table").row.cells.length
# row count
@browser.table(:id => "table").row_count
@browser.table(:id => "table").rows.length# [exists?]
@browser.text_field(:id => "text").exists?
# [enabled?]
@browser.select_list(:id => "list").enabled?
# [present?]
@browser.element(:id => "e").present?
# [tag_name]
@browser.element(:id => "e").tag_name
# [screenshot]
@browser.screenshot.save "c:\\page.png"
# [to_subtype] # returns button
@browser.element(:id => "btn").to_subtype
# [index] click 2nd image on page
@browser.image(:index => 1).click
# [loops]
# get names of all text-fields
@browser.text_fields.each do |i|
puts i.name
end
# get name of first text-field
puts @browser.text_fields[0].name
# get name of second text-field
puts @browser.text_fields[1].name# [wait_until_present]
@browser.button(:id => "btn").when_until_present
# [when_present]
@browser.button(:id => "btn").when_present.click
@browser.button(:id => "btn").when_present(10).click
# [wait_while_present]
@browser.button(:value => "submit").click
@browser.button(:value => "submit").wait_while_present
# [implicit wait] 5 seconds
# good to have, but i don't recommend its global use
@browser.driver.manage.timeouts.implicit_wait = 5Whenever there are tests that are absolutely the same but have to be executed from different places (e.g. tests related to same functionality for costs and sales) we can take advantage of RSpec’s shared examples functionality (documentation can be found here).
When you create shared examples, you can put them in the spec/shared_examples folder. The files have to be with .rb
extension and should NOT have _spec in the end of their name. A file should look like this:
shared_examples 'meaningful name of the shared examples group' do |parameters_if_needed|
before do
you_can_put_hooks_if_needed
end
it 'scenario one' do
scenario_code
end
it 'scenario_two' do
scenario_code
end
endThen, in the spec file you can include the examples with the include_examples method:
describe "Some tests" do
some_code
include_examples 'name_of_the_shared_examples_group'
endWe would like to keep adding TestRail IDs in all executed tests. With that in mind, when creating shared examples, it would be good to always have at least one parameter - tms. A shared example file will then look like this:
shared_examples 'name of examples' do |tms|
it "name of test", tms: tms do
test_code
end
endWhen using the shared example you then pass on the parameter as follows:
include_examples 'name of examples', '23336'When the shared examples group contains multiple tests, you can make a tmses parameter and when calling the examples to put an array of tms numbers as an argument:
shared_examples 'shared examples group' do |tmses|
it "test one", tms: tmses[0] do
test_code
end
it "test two", tms: tmses[1] do
test_code
end
endThe invocation will then look like this:
include_examples 'shared examples group', %w(12345 12346 12347)In order to execute shared examples you specify the path to the spec file, not to the shared examples file in the rspec command (as usual).
bundle exec rspec ./spec/path_to_spec/your_spec.rbIn order to execute only one test from a shared examples group you have two options.
- Specify the name of the example with the
--exampleoption
bundle exec rspec ./spec/path_to_spec/your_spec.rb --example name_of_the_scenarioNote: if you use interpolation in the scenario name substitute the interpolated variable with the proper string.
- Specify the TestRail ID with the
--tagoption
bundle exec rspec ./spec/path_to_spec/your_spec.rb --tag tms:12345