Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/testcentricity/testcentricity_web
TestCentricity™ For Web core POM test automation framework gem
https://github.com/testcentricity/testcentricity_web
automation cucumber page-object-model ruby-gem selenium test-automation web webdriver
Last synced: about 1 month ago
JSON representation
TestCentricity™ For Web core POM test automation framework gem
- Host: GitHub
- URL: https://github.com/testcentricity/testcentricity_web
- Owner: TestCentricity
- License: bsd-3-clause
- Created: 2022-04-18T23:06:15.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-11-04T23:15:01.000Z (2 months ago)
- Last Synced: 2024-11-15T22:19:11.965Z (about 2 months ago)
- Topics: automation, cucumber, page-object-model, ruby-gem, selenium, test-automation, web, webdriver
- Language: Ruby
- Homepage: https://rubygems.org/gems/testcentricity_web
- Size: 27.5 MB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# TestCentricity™ For Web
[![Gem Version](https://badge.fury.io/rb/testcentricity_web.svg)](https://badge.fury.io/rb/testcentricity_web)
[![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause)
![Gem Downloads](https://img.shields.io/gem/dt/testcentricity_web)
![Maintained](https://img.shields.io/badge/maintenance-actively--developed-brightgreen.svg)
[![Docs](https://img.shields.io/badge/docs-rubydoc-blue.svg)](http://www.rubydoc.info/gems/testcentricity_web)The TestCentricity™ For Web core framework for desktop and mobile web browser-based app testing implements a Page Object Model
DSL for use with Cucumber (version 7.x or greater) or RSpec, and Selenium-Webdriver. It also facilitates the configuration
of the appropriate Selenium-Webdriver capabilities required to establish connections with one or more local or cloud hosted
desktop or mobile web browsers.The TestCentricity™ For Web gem supports connecting to, and running automated tests against the following target web browsers:
* locally hosted desktop browsers (Chrome, Edge, Firefox, or Safari)
* locally hosted "headless" Chrome, Firefox, or Edge browsers
* remote desktop and emulated mobile web browsers hosted on Selenium Grid 4 and Dockerized Selenium Grid 4 environments
* mobile Safari browsers on iOS device simulators or physical iOS devices (using Appium 2.x and XCode on macOS)
* mobile Chrome or Android browsers on Android Studio virtual device emulators (using Appium and Android Studio)
* cloud hosted desktop (Firefox, Chrome, Safari, IE, or Edge) or mobile (iOS Mobile Safari or Android Chrome) web browsers using the following service:
* [Browserstack](https://www.browserstack.com/list-of-browsers-and-platforms?product=automate)
* [Sauce Labs](https://saucelabs.com/platform/cross-browser-testing)
* [TestingBot](https://testingbot.com/features)
* [LambdaTest](https://www.lambdatest.com/selenium-automation)
* web portals utilizing JavaScript front end application frameworks like Ember, React, Angular, and GWT
* web pages containing HTML5 Video and Audio objects
* locally hosted emulated iOS Mobile Safari, Android, Windows Phone, or Blackberry mobile browsers (running within a local instance of Chrome)## What's New
A complete history of bug fixes and new features can be found in the {file:CHANGELOG.md CHANGELOG} file.
The RubyDocs for this gem can be found [here](https://www.rubydoc.info/gems/testcentricity_web).
An example project that demonstrates the implementation of a page object model framework using TestCentricity™ For Web and
Cucumber can be found [here](https://github.com/TestCentricity/tc_multi_webdriver_sample).### Which gem should I use?
* The [TestCentricity For **Web** gem](https://rubygems.org/gems/testcentricity_web) supports testing of web interfaces via desktop and mobile web browsers
* The [TestCentricity For **Mobile** gem](https://rubygems.org/gems/testcentricity_mobile) supports testing of native iOS and Android mobile apps
* The [TestCentricity For **Apps** gem](https://rubygems.org/gems/testcentricity_apps) supports testing of MacOS desktop apps and native iOS and Android mobile apps| Tested platforms | TestCentricity For Web | TestCentricity For Mobile | TestCentricity For Apps |
|---------------------------------------------|:-:|:-:|:-:|
| Desktop/mobile web browsers only | Yes | No | No |
| Native mobile iOS and/or Android apps only | No | Yes | Yes |
| MacOS desktop apps | No | No | Yes |## Installation
TestCentricity For Web version 4.4 and above requires Ruby version 3.0.0 or later. To install the TestCentricity For Web gem,
add this line to your automation project's `Gemfile`:gem 'testcentricity_web'
And then execute:
$ bundle
Or install it yourself using:
$ gem install testcentricity_web
## Setup
### Using CucumberIf you are using Cucumber, you need to require the following in your `env.rb` file:
```ruby
require 'capybara/cucumber'
require 'testcentricity_web'
```### Using RSpec
If you are using RSpec instead, you need to require the following in your `spec_helper.rb` file:
```ruby
require 'capybara/rspec'
require 'testcentricity_web'
```---
## PageObjectsThe **Page Object Model** is a test automation pattern that aims to create an abstraction of your web app's User Interface
that can be used in tests. A **Page Object** represents a single page in your AUT (Application Under Test). **Page Objects**
encapsulate the implementation details of a web page and expose an API that supports interaction with, and validation of
the UI elements on the page.**Page Objects** makes it easier to maintain automated tests because changes to page UI elements are updated in only one
location - in the **Page Object** class definition. By adopting a **Page Object Model**, Cucumber Feature files and step
definitions are no longer required to hold specific information about a page's UI objects, thus minimizing maintenance
requirements. If any element on, or property of a page changes (URL path, text field attributes, button captions, etc.),
maintenance is performed in the `PageObject` class definition only, typically with no need to update the affected feature
files, scenarios, or step definitions.### Defining a PageObject
Your `PageObject` class definitions should be contained within individual `.rb` files in the `features/support/pages` folder
of your test automation project. You define new `PageObjects` as shown below:
```ruby
class LoginPage < TestCentricity::PageObject
endclass HomePage < TestCentricity::PageObject
endclass RegistrationPage < TestCentricity::PageObject
endclass UserAccountPage < TestCentricity::PageObject
end
```### Adding Traits to a PageObject
Web pages typically have names and URLs associated with them. Web pages also typically have a unique object or attribute
that, when present, indicates that the page's contents have fully loaded.The `page_name` trait is registered with the `PageManager` object, which includes a `find_page` method that takes a page
name as a parameter and returns an instance of the associated `PageObject`. If you intend to use the `PageManager`, you
must define a `page_name` trait for each `PageObject` to be registered. Refer to [**section 7 (Instantiating Your PageObjects)**](#instantiating-your-pageobjects).The `page_name` trait is usually a `String` value that represents the name of the page that will be matched by the `PageManager.findpage`
method. `page_name` traits are case and white-space sensitive. For pages that may be referenced with multiple names, the
`page_name` trait may also be an `Array` of `String` values representing those page names.A `page_locator` trait is defined if a page has a unique object or attribute that exists once the page's contents have fully
loaded. The `page_locator` trait is a CSS or Xpath expression that uniquely identifies the object or attribute. The
`verify_page_exists` method waits for the `page_locator` trait to exist.An optional `page_url` trait should be defined if a page can be directly loaded using a URL. If you set Capybara's `app_host`,
or specify a base URL when calling the `WebDriverConnect.initialize_web_driver` method, then your `page_url` trait can be the
relative URL slug that will be appended to the base URL specified in `app_host`. Specifying a `page_url` trait is optional,
as not all web pages can be directly loaded via a URL.You define your page's **Traits** as shown below:
```ruby
class LoginPage < TestCentricity::PageObject
trait(:page_name) { 'Login' }
trait(:page_url) { '/sign_in' }
trait(:page_locator) { 'body.login-body' }
endclass HomePage < TestCentricity::PageObject
# this page may be referred to as 'Home' or 'Dashboard' page so page_name trait is an Array of Strings
trait(:page_name) { ['Home', 'Dashboard'] }
trait(:page_url) { '/dashboard' }
trait(:page_locator) { 'body.dashboard' }
endclass RegistrationPage < TestCentricity::PageObject
trait(:page_name) { 'Registration' }
trait(:page_url) { '/register' }
trait(:page_locator) { 'body.registration' }
endclass UserAccountPage < TestCentricity::PageObject
trait(:page_name) { 'User Account' }
trait(:page_url) { "/user_account/#{User.current.id}" }
trait(:page_locator) { 'body.useraccount' }
end
```### Adding UI Elements to a PageObject
Web pages are made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists, buttons, etc.
**UI Elements** are added to your `PageObject` class definition as shown below:
```ruby
class LoginPage < TestCentricity::PageObject
trait(:page_name) { 'Login' }
trait(:page_url) { '/sign_in' }
trait(:page_locator) { 'body.login-body' }# Login page UI elements
textfield :user_id_field, 'input#userName'
textfield :password_field, 'input#password'
button :login_button, 'button#login'
checkbox :remember_checkbox, 'input#rememberUser'
label :error_message_label, 'div#statusBar.login-error'
endclass RegistrationPage < TestCentricity::PageObject
trait(:page_name) { 'Registration' }
trait(:page_url) { '/register' }
trait(:page_locator) { 'body.registration' }# Registration page UI elements
textfields first_name_field: 'input#firstName',
last_name_field: 'input#lastName',
email_field: 'input#email',
phone_number_field: 'input#phone',
address_field: 'input#streetAddress',
city_field: 'input#city',
post_code_field: 'input#postalCode',
password_field: 'input#password',
pword_confirm_field: 'input#passwordConfirmation'
selectlists title_select: 'select#title',
gender_select: 'select#gender',
state_select: 'select#stateProvince'
checkbox :email_opt_in_check, 'input#marketingEmailsOptIn'
button :sign_up_button, 'button#registrationSignUp'
end
```### Adding Methods to a PageObject
It is good practice for your Cucumber step definitions to call high level methods in your your `PageObject` instead of
directly accessing and interacting with a page object's UI elements. You can add high level methods to your `PageObject`
class definition for interacting with the UI to hide implementation details, as shown below:
```ruby
class LoginPage < TestCentricity::PageObject
trait(:page_name) { 'Login' }
trait(:page_url) { '/sign_in' }
trait(:page_locator) { 'body.login-body' }# Login page UI elements
textfield :user_id_field, 'input#userName'
textfield :password_field, 'input#password'
button :login_button, 'button#login'
checkbox :remember_checkbox, 'input#rememberUser'
label :error_message_label, 'div#statusBar.login-error'
link :forgot_password_link, 'a.forgotPassword'# log in to web app
def login(user_id, password)
user_id_field.set(user_id)
password_field.set(password)
login_button.click
end# set the state of the Remember Me checkbox
def remember_me(state)
remember_checkbox.set_checkbox_state(state)
end# verify Login page default UI state
def verify_page_ui
ui = {
self => { title: 'Login' },
login_button => {
visible: true,
caption: 'LOGIN'
},
user_id_field => {
visible: true,
enabled: true,
value: '',
placeholder: 'User name'
},
password_field => {
visible: true,
enabled: true,
value: '',
placeholder: 'Password'
},
remember_checkbox => {
exists: true,
enabled: true,
checked: false
},
forgot_password_link => {
visible: true,
caption: 'Forgot your password?'
},
error_message_label => { visible: false }
}
verify_ui_states(ui)
end
endclass RegistrationPage < TestCentricity::PageObject
trait(:page_name) { 'Registration' }
trait(:page_url) { '/register' }
trait(:page_locator) { 'body.registration' }# Registration page UI elements
textfields first_name_field: 'input#firstName',
last_name_field: 'input#lastName',
email_field: 'input#email',
phone_number_field: 'input#phone',
address_field: 'input#streetAddress',
city_field: 'input#city',
post_code_field: 'input#postalCode',
password_field: 'input#password',
pword_confirm_field: 'input#passwordConfirmation'
selectlists title_select: 'select#title',
gender_select: 'select#gender',
state_select: 'select#stateProvince'
checkbox :email_opt_in_check, 'input#marketingEmailsOptIn'
buttons sign_up_button: 'button#registrationSignUp',
cancel_button: 'button#registrationCancel'# populate Registration page fields with profile data
def enter_profile_data(profile)
fields = { title_select => profile.title,
first_name_field => profile.first_name,
last_name_field => profile.last_name,
gender_select => profile.gender,
phone_number_field => profile.phone,
email_field => profile.email,
address_field => profile.address,
city_field => profile.city,
state_select => profile.state,
post_code_field => profile.postal_code,
password_field => profile.password,
pword_confirm_field => profile.confirm_password,
email_opt_in_check => profile.email_opt_in
}
populate_data_fields(fields)
sign_up_button.click
end
end
```Once your `PageObjects` have been instantiated, you can call your methods as shown below:
```ruby
login_page.remember_me(true)
login_page.login(user_id = 'snicklefritz', password = 'Pa55w0rd')
```---
## PageSectionsA `PageSection` is a collection of **UI Elements** that may appear in multiple locations on a page, or on multiple pages
in a web app. It is a collection of **UI Elements** that represent a conceptual area of functionality, like a navigation
bar, a search capability, a menu, or a pop-up panel. **UI Elements** and functional behavior are confined to the scope of
a `PageSection` object.Below is an example of a header navigation bar feature that is common to multiple pages -
![Navigation Header](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/NavBar1.png "Navigation Header")
-
![Navigation Header](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/NavBar2.png "Navigation Header")
Below is an example of a popup Shopping Bag panel associated with a header navigation bar -
![Shopping Bag Popup](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/ShoppingBagPopUp.png "Shopping Bag Popup")
A `PageSection` may contain other `PageSection` objects.
### Defining a PageSection
Your `PageSection` class definitions should be contained within individual `.rb` files in the `features/support/sections`
folder of your test automation project. You define new `PageSection` as shown below:
```ruby
class BagViewPopup < TestCentricity::PageSection
end
```### Adding Traits to a PageSection
A `PageSection` typically has a root node object that encapsulates a collection of `UIElements`. The `section_locator` trait
specifies the CSS or Xpath expression that uniquely identifies that root node object.You define your section's **Traits** as shown below:
```ruby
class BagViewPopup < TestCentricity::PageSection
trait(:section_locator) { 'aside.ac-gn-bagview' }
trait(:section_name) { 'Shopping Bag Popup' }
end
```### Adding UI Elements to a PageSection
`PageSections` are typically made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists,
buttons, etc. **UI Elements** are added to your `PageSection` class definition as shown below:
```ruby
class BagViewPopup < TestCentricity::PageSection
trait(:section_locator) { 'aside.ac-gn-bagview' }
trait(:section_name) { 'Shopping Bag Popup' }# Shopping Bag Popup UI elements
label :bag_message, 'p[class*="ac-gn-bagview-message"]'
lists bag_items_list: 'ul[class*="ac-gn-bagview-bag"]',
bag_nav_list: 'ul.ac-gn-bagview-nav-list '
button :checkout_button, 'a[class*="ac-gn-bagview-button-checkout"]'
end
```### Adding Methods to a PageSection
You can add high level methods to your `PageSection` class definition, as shown below:
```ruby
class BagViewPopup < TestCentricity::PageSection
trait(:section_locator) { 'aside.ac-gn-bagview' }
trait(:section_name) { 'Shopping Bag Popup' }# Shopping Bag Popup UI elements
label :bag_message, 'p[class*="ac-gn-bagview-message"]'
lists bag_items_list: 'ul[class*="ac-gn-bagview-bag"]',
bag_nav_list: 'ul.ac-gn-bagview-nav-list '
button :checkout_button, 'a[class*="ac-gn-bagview-button-checkout"]'def item_count
bag_items_list.visible? ? bag_items_list.item_count : 0
enddef perform_action(action)
case action.gsub(/\s+/, '_').downcase.to_sym
when :check_out
checkout_button.click
when :view_bag
bag_nav_list.choose_item(1)
when :saved_items
bag_nav_list.choose_item(2)
when :orders
bag_nav_list.choose_item(3)
when :account
bag_nav_list.choose_item(4)
when :sign_in, :sign_out
bag_nav_list.choose_item(5)
else
raise "#{action} is not a valid selector"
end
end
end
```### Adding PageSections to your PageObject
You add a `PageSection` to its associated `PageObject` as shown below:
```ruby
class HomePage < TestCentricity::PageObject
trait(:page_name) { 'Home' }
trait(:page_url) { '/dashboard' }
trait(:page_locator) { 'body.dashboard' }# Home page Section Objects
section :search_form, SearchForm
end
```
Once your `PageObject` has been instantiated, you can call its `PageSection` methods as shown below:
```ruby
home_page.search_form.search_for('ocarina')
```---
## UIElements`PageObjects` and `PageSections` are typically made up of UI elements like text fields, check boxes, select lists (combo
boxes), radio buttons, tables, ordered and unordered lists, buttons, images, HTML5 video or audio player objects, etc.
UI elements are declared and instantiated within the class definition of the `PageObject` or `PageSection` in which they
are contained. With TestCentricity For Web, all UI elements are based on the `UIElement` class.### Declaring and Instantiating UIElements
Single `UIElement` declarations have the following format:
elementType :elementName, locator* The `elementName` is the unique name that you will use to refer to the UI element and is specified as a `Symbol`.
* The `locator` is the CSS or XPath attribute that uniquely and unambiguously identifies the `UIElement`.Multiple `UIElement` declarations for a collection of elements of the same type can be performed by passing a hash table
containing the names and locators of each individual element.### Example UIElement Declarations
Supported `UIElement` elementTypes and their declarations have the following format:
*Single element declarations:*
```ruby
class SamplePage < TestCentricity::PageObjectbutton :button_name, locator
textfield :field_name, locator
checkbox :checkbox_name, locator
radio :radio_button_name, locator
label :label_name, locator
link :link_name, locator
selectlist :select_name, locator
list :list_name, locator
table :table_name, locator
range :range_name, locator
image :image_name, locator
video :video_name, locator
audio :audio_name, locator
filefield :filefield_name, locatorend
```
*Multiple element declarations:*
```ruby
class SamplePage < TestCentricity::PageObjectbuttons button_1_name: locator,
button_2_name: locator,
button_X_name: locator
textfields field_1_name: locator,
field_2_name: locator,
field_X_name: locator
checkboxes check_1_name: locator,
check_2_name: locator,
check_X_name: locator
radios radio_1_name: locator,
radio_X_name: locator
labels label_1_name: locator,
label_X_name: locator
links link_1_name: locator,
link_X_name: locator
selectlists selectlist_1_name: locator,
selectlist_X_name: locator
lists list_1_name: locator,
list_X_name: locator
tables table_1_name: locator,
table_X_name: locator
ranges range_1_name: locator,
range_X_name: locator
images image_1_name: locator,
image_X_name: locator
videos video_1_name: locator,
video_X_name: locator
audios audio_1_name: locator,
audio_X_name: locator
filefields filefield_1_name: locator,
filefield_X_name: locatorend
```Refer to the Class List documentation for the `PageObject` and `PageSection` classes for details on the class methods used
for declaring and instantiating `UIElements`. Examples of UI element declarations can be found in the [**section 4.3 (Adding UI Elements to your PageObject)**](#adding-ui-elements-to-a-pageobject)
and [**section 5.3 (Adding UI Elements to your PageSection)**](#adding-ui-elements-to-a-pagesection) sections above.### UIElement Inherited Methods
With TestCentricity, all UI elements are based on the `UIElement` class, and inherit the following methods:
**Action methods:**
element.click
element.double_click
element.right_click
element.click_at(x, y)
element.hover
element.hover_at(x, y)
element.scroll_to(position)
element.drag_by(right_offset, down_offset)
element.drag_and_drop(target, right_offset, down_offset)**Object state methods:**
element.exists?
element.visible?
element.hidden?
element.enabled?
element.disabled?
element.displayed?
element.obscured?
element.focused?
element.required?
element.content_editable?
element.crossorigin
element.get_value
element.count
element.style
element.title
element.width
element.height
element.x
element.y
element.get_attribute(attrib)
element.get_native_attribute(attrib)**Waiting methods:**
element.wait_until_exists(seconds)
element.wait_until_gone(seconds)
element.wait_until_visible(seconds)
element.wait_until_hidden(seconds)
element.wait_until_enabled(seconds)
element.wait_until_value_is(value, seconds)
element.wait_until_value_changes(seconds)
element.wait_while_busy(seconds)**WAI-ARIA Object Accessibility (A11y) methods:**
element.role
element.tabindex
element.aria_disabled?
element.aria_hidden?
element.aria_expanded?
element.aria_required?
element.aria_invalid?
element.aria_checked?
element.aria_readonly?
element.aria_haspopup?
element.aria_selected?
element.aria_pressed?
element.aria_label
element.aria_labelledby
element.aria_describedby
element.aria_live
element.aria_sort
element.aria_rowcount
element.aria_colcount
element.aria_valuemax
element.aria_valuemin
element.aria_valuenow
element.aria_valuetext
element.aria_orientation
element.aria_roledescription
element.aria_autocomplete
element.aria_controls
element.aria_modal?
element.aria_keyshortcuts
element.aria_multiline?
element.aria_multiselectable?
element.aria_busy?### Populating a PageObject or PageSection With Data
A typical automated test may be required to perform the entry of test data by interacting with various `UIElements` on your
`PageObject` or `PageSection`. This data entry can be performed using the various object action methods (listed above) for
each `UIElement` that needs to be interacted with.The `PageObject.populate_data_fields` and `PageSection.populate_data_fields` methods support the entry of test data into a
collection of `UIElements`. The `populate_data_fields` method accepts a hash containing key/hash pairs of `UIElements` and
their associated data to be entered. Data values must be in the form of a `String` for `textfield`, `selectlist`, and `filefield`
controls. For `checkbox` and `radio` controls, data must either be a `Boolean` or a `String` that evaluates to a `Boolean`
value (Yes, No, 1, 0, true, false). For `range` controls, data must be an `Integer`. For `input(type='color')` color picker
controls, which are specified as a `textfield`, data must be in the form of a hex color `String`. For `section` objects,
data values must be a `String`, and the `section` object must have a `set` method defined.The `populate_data_fields` method verifies that data attributes associated with each `UIElement` is not `nil` or `empty`
before attempting to enter data into the `UIElement`.The optional `wait_time` parameter is used to specify the time (in seconds) to wait for each `UIElement` to become viable
for data entry (the `UIElement` must be visible and enabled) before entering the associated data value. This option is useful
in situations where entering data, or setting the state of a `UIElement` might cause other `UIElements` to become visible
or active. Specifying a wait_time value ensures that the subsequent `UIElements` will be ready to be interacted with as
states are changed. If the wait time is `nil`, then the wait time will be 5 seconds.
```ruby
def enter_data(user_data)
fields = {
first_name_field => user_data.first_name,
last_name_field => user_data.last_name,
email_field => user_data.email,
country_code_select => user_data.country_code,
phone_number_field => user_data.phone_number,
time_zone_select => user_data.time_zone,
language_select => user_data.language
}
populate_data_fields(fields, wait_time = 2)
end
```### Verifying UIElements on a PageObject or PageSection
A typical automated test executes one or more interactions with the user interface, and then performs a validation to verify
whether the expected state of the UI has been achieved. This verification can be performed using the various object state
methods (listed above) for each `UIElement` that requires verification. Depending on the complexity and number of `UIElements`
to be verified, the code required to verify the presence of `UIElements` and their correct states can become cumbersome.The `PageObject.verify_ui_states` and `PageSection.verify_ui_states` methods support the verification of multiple properties
of multiple UI elements on a `PageObject` or `PageSection`. The `verify_ui_states` method accepts a hash containing key/hash
pairs of UI elements and their properties or attributes to be verified.
```ruby
ui = {
object1 => { property: state },
object2 => { property: state, property: state },
object3 => { property: state }
}
verify_ui_states(ui)
```
The `verify_ui_states` method queues up any exceptions that occur while verifying each object's properties until all `UIElements`
and their properties have been checked, and then posts any exceptions encountered upon completion. Posted exceptions include
a screenshot with a red dashed highlight around the UI element that did not match the expected results.The `verify_ui_states` method supports the following property/state pairs:
**All Objects:**
:exists Boolean
:enabled Boolean
:disabled Boolean
:visible Boolean
:hidden Boolean
:displayed Boolean
:obscured Boolean
:width Integer
:height Integer
:x Integer
:y Integer
:class String
:value or :caption String
:attribute Hash
:style String
:tabindex Integer
:required Boolean
:crossorigin String**Pages:**
:secure Boolean
:title String**Text Fields:**
:readonly Boolean
:placeholder String
:maxlength Integer
:min Integer
:max Integer
:step IntegerText Field Constraint Validation
:validation_message String
:badInput Boolean
:customError Boolean
:patternMismatch Boolean
:rangeOverflow Boolean
:rangeUnderflow Boolean
:stepMismatch Boolean
:tooLong Boolean
:tooShort Boolean
:typeMismatch Boolean
:valid Boolean
:valueMissing Boolean**Checkboxes:**
:checked Boolean
:indeterminate Boolean**Radio Buttons:**
:selected Boolean
**Links:**
:href String
**Images**
:loaded Boolean
:broken Boolean
:src String
:alt String**Lists**
:items Array of Strings
:itemcount Integer
:item Hash
:selected String**Select Lists** (ComboBoxes):
:items or :options Array of Strings
:itemcount or :optioncount Integer
:selected String
:groupcount Integer
:group_headings Array of Strings**Tables**
:rowcount Integer
:columncount Integer
:columnheaders Array of String
:cell Hash
:row Hash
:column Hash**Audio/Video Media Objects**
:autoplay Boolean
:ended Boolean
:controls Boolean
:loop Boolean
:muted Boolean
:default_muted Boolean
:paused Boolean
:seeking Boolean
:src String
:current_time Float
:default_playback_rate Float
:duration Float
:playback_rate Float
:ready_state Integer
:volume Float
:preload String
:poster String
:track_count Integer
:active_track Integer
:active_track_data Hash
:all_tracks_data Array of Hash
:track_data Hash
:active_track_source String
:track_source String#### ARIA Accessibility Property/State Pairs
The `verify_ui_states` method supports the following ARIA accessibility property/state pairs:
:aria_label String
:aria_disabled Boolean
:aria_labelledby String
:aria_describedby String
:aria_live Boolean
:aria_selected Boolean
:aria_hidden Boolean
:aria_expanded Boolean
:aria_required Boolean
:aria_invalid Boolean
:aria_checked Boolean
:aria_readonly Boolean
:aria_pressed Boolean
:aria_busy Boolean
:aria_haspopup Boolean
:aria_sort String
:aria_rowcount String
:aria_colcount String
:aria_valuemax String
:aria_valuemin String
:aria_valuenow String
:aria_valuetext String
:aria_orientation String
:aria_keyshortcuts String
:aria_roledescription String
:aria_autocomplete String
:aria_controls String
:aria_modal String
:aria_multiline Boolean
:aria_multiselectable Boolean
:content_editable Boolean
:role String#### Comparison States
The `verify_ui_states` method supports comparison states using property/comparison state pairs:
```ruby
object => { property: { comparison_state: value } }
```
Comparison States::lt or :less_than Integer or String
:lt_eq or :less_than_or_equal Integer or String
:gt or :greater_than Integer or String
:gt_eq or :greater_than_or_equal Integer or String
:starts_with String
:ends_with String
:contains String
:not_contains or :does_not_contain Integer or String
:not_equal Integer, String, or BooleanThe example below depicts a `verify_changes_saved` method that uses the `verify_ui_states` method to verify that all expected
values appear in the associated text fields after entering data and performing a save operation.
```ruby
def verify_changes_saved
# verify saved user data is correctly displayed
ui = {
first_name_field => {
visible: true,
aria_invalid: false,
value: User.current.first_name
},
last_name_field => {
visible: true,
aria_invalid: false,
value: User.current.last_name
},
email_field => {
visible: true,
aria_invalid: false,
value: User.current.email
},
phone_number_field => {
visible: true,
aria_invalid: false,
value: User.current.phone_number
},
time_zone_select => {
visible: true,
aria_invalid: false,
value: User.current.time_zone
},
language_select => {
visible: true,
aria_invalid: false,
value: User.current.language
},
avatar_container => { visible: true },
avatar_image => {
visible: true,
broken: false,
src: { ends_with: User.current.avatar_file_name },
alt: "#{User.current.first_name} #{User.current.last_name}",
style: { contains: 'border-radius: 50%;'}
},
error_message_label => { visible: false }
}
verify_ui_states(ui)# verify avatar src url does not contain /null/ institution id
verify_ui_states(avatar_image => { src: { does_not_contain: "/null/" } })
end
```#### I18n Translation Validation
The `verify_ui_states` method also supports I18n string translations using property/I18n key name pairs:
```ruby
object => { property: { translate_key: 'name of key in I18n compatible .yml file' } }
```
**I18n Translation Keys:**:translate String
:translate_upcase String
:translate_downcase String
:translate_capitalize String
:translate_titlecase StringThe example below depicts the usage of the `verify_ui_states` method to verify that the captions for a popup Shopping Bag
panel are correctly translated.![Localized UI](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/LocalizedUI.png "Localized UI")
```ruby
class BagViewPopup < TestCentricity::PageSection
trait(:section_locator) { 'aside.ac-gn-bagview' }
trait(:section_name) { 'Shopping Bag Popup' }# Shopping Bag Popup UI elements
label :bag_message, 'p[class*="ac-gn-bagview-message"]'
lists bag_items_list: 'ul[class*="ac-gn-bagview-bag"]',
bag_nav_list: 'ul.ac-gn-bagview-nav-list '
button :checkout_button, 'a[class*="ac-gn-bagview-button-checkout"]'def verify_empty_bag_ui
nav_items = %w[
BagViewPopup.bag
BagViewPopup.saved_items
BagViewPopup.orders
BagViewPopup.account
BagViewPopup.sign_in
]
ui = {
bag_message => {
visible: true,
caption: { translate: 'BagViewPopup.bag_is_empty' }
},
bag_nav_list => {
visible: true,
itemcount: 5,
items: { translate: nav_items }
},
bag_items_list => { visible: false },
checkout_button => { visible: false }
}
verify_ui_states(ui)
end
end
```
I18n `.yml` files contain key/value pairs representing the name of a translated string (key) and the string value. For the
popup Shopping Bag panel example above, the translated strings for English, Spanish, and French are represented in below:**English** - `en.yml`
```yaml
en:
BagViewPopup:
bag_is_empty: 'Your Bag is empty.'
bag: 'Bag'
saved_items: 'Saved Items'
orders: 'Orders'
account: 'Account'
sign_in: 'Sign in'
sign_out: 'Sign out'
```
**Spanish** - `es.yml`
```yaml
es:
BagViewPopup:
bag_is_empty: 'Tu bolsa está vacía.'
bag: 'Bolsa'
saved_items: 'Artículos guardados'
orders: 'Pedidos'
account: 'Cuenta'
sign_in: 'Iniciar sesión'
sign_out: 'Cerrar sesión'
```
**French** - `fr.yml`
```yaml
fr:
BagViewPopup:
bag_is_empty: 'Votre sac est vide.'
bag: 'Sac'
saved_items: 'Articles enregistrés'
orders: 'Commandes'
account: 'Compte'
sign_in: 'Ouvrir une session'
sign_out: 'Fermer la session'
```Each supported language/locale combination has a corresponding `.yml` file. I18n `.yml` file naming convention uses
[ISO-639 language codes](https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1252447) and
[ISO-3166 country codes](https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1250799). For example:| Language (Country) | File name |
|-----------------------|-----------|
| English | en.yml |
| English (Canada) | en-CA.yml |
| French (Canada) | fr-CA.yml |
| French | fr.yml |
| Spanish | es.yml |
| German | de.yml |
| Portuguese (Brazil) | pt-BR.yml |
| Portuguese (Portugal) | pt-PT.yml |Baseline translation strings are stored in `.yml` files in the `config/locales/` folder.
📁 my_automation_project/
├── 📁 config/
│ ├── 📁 locales/
│ │ ├── 📄 en.yml
│ │ ├── 📄 en-AU.yml
│ │ ├── 📄 es.yml
│ │ ├── 📄 de.yml
│ │ ├── 📄 fr.yml
│ │ ├── 📄 fr-CA.yml
│ │ ├── 📄 pt-BR.yml
│ │ └── 📄 pt-PT.yml
│ ├── 📁 test_data/
│ └── 📄 cucumber.yml
├── 📁 downloads/
├── 📁 features/
├── 📄 Gemfile
└── 📄 README.md### Working With Custom UIElements
Many responsive and touch-enabled web based user interfaces are implemented using front-end JavaScript libraries for building
user interfaces based on multiple composite UI components. Popular JS libraries include React, Angular, and Ember.js. These
stylized and adorned controls can present a challenge when attempting to interact with them using Capybara and Selenium based
automated tests.#### Radio and Checkbox UIElements
Sometimes, radio buttons and checkboxes implemented using JS component libraries cannot be interacted with due to other UI
elements being overlaid on top of them, causing the base `input(type='radio')` or `input(type='checkbox')` element to not
receive click actions.In the screenshot below of an airline flight search and booking page, the **Round-trip**, **One-way**, and **Multi-city**
radio buttons are overlaid with `div` elements that also acts as proxies for their associated `input(type='radio')` elements,
and that intercept the `click` actions that would normally be handled by the `input(type='radio')` elements.![Custom Radio buttons](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomRadios.png "Custom Radio buttons")
The checkbox controls on the airline flight search and booking page are also overlaid with `div` elements that intercept
the `click` actions that would normally be handled by the `input(type='checkbox')` elements.![Custom Checkbox controls](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomCheckbox.png "Custom Checkbox controls")
The `Radio.define_custom_elements` and `CheckBox.define_custom_elements` methods provide a way to specify the `input`,
`proxy`, and/or `label` elements associated with the `input(type='radio')` and `input(type='checkbox')` elements. The
`define_custom_elements` method should be called from an `initialize` method for the `PageObject` or `PageSection` where
the `radio` or `checkbox` elements are instantiated.The code snippet below demonstrates the use of the `Radio.define_custom_elements` and `CheckBox.define_custom_elements`
methods to define the multiple UI elements that comprise each radio button and checkbox.
```ruby
class FlightBookingPage < TestCentricity::PageObject
trait(:page_name) { 'Flight Booking Home' }
trait(:page_locator) { 'div[class*="bookerContainer"]' }# Flight Booking page UI elements
radios roundtrip_radio: 'div[role="radiogroup"] > div.ftRadio:nth-of-type(1)',
one_way_radio: 'div[role="radiogroup"] > div.ftRadio:nth-of-type(2)',
multi_city_radio: 'div[role="radiogroup"] > div.ftRadio:nth-of-type(3)'
checkboxes use_miles_check: 'div#divAwardReservation',
flex_dates_check: 'div#divLowFareCalendar > div.left',
near_from_check: 'div#divIncludeNearbyDepartureAirports',
near_to_check: 'div#divIncludeNearbyArrivalAirports'def initialize
# define the custom element components for the Round Trip, One Way, and Multi-City radio buttons
radio_spec = {
input: 'input[type="radio"]',
label: 'label.normal'
}
roundtrip_radio.define_custom_elements(radio_spec)
one_way_radio.define_custom_elements(radio_spec)
multi_city_radio.define_custom_elements(radio_spec)# define the custom element components for the checkboxes
check_spec = {
input: 'input[type="checkbox"]',
label: 'label.normal'
}
use_miles_check.define_custom_elements(check_spec)
flex_dates_check.define_custom_elements(check_spec)
near_from_check.define_custom_elements(check_spec)
near_to_check.define_custom_elements(check_spec)
end
end
```
#### List UIElementsThe basic HTML `list` element is typically composed of the parent `ul` or `ol` object, and one or more `li` elements
representing the items in the list. However, list controls implemented using JS component libraries can be composed of
multiple elements representing the components of a list implementation.In the screenshots below, an inspection of the **Menu Groups** horizontal scrolling list on a **Restaurant Detail** page
reveals that it is a `div` element that contains multiple `button` elements with `data-testid` attributes of `menu-group`
that represent the list items that can be selected.![Custom List](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomList.png "Custom List")
The `List.define_list_elements` method provides a means of specifying the elements that make up the key components of a
`list` control. The method accepts a hash of element designators (key) and a CSS or Xpath expression (value) that expression
that uniquely identifies the element. Valid element designators are `:list_item`and `:selected_item`.The `RestaurantPage` page object's `initialize` method in the code snippet below demonstrates the use of the `List.define_list_elements`
method to define the common components that make up the **Menu Groups** horizontal scrolling list.
```ruby
class RestaurantPage < TestCentricity::PageObject
trait(:page_name) { 'Restaurant Detail' }
trait(:page_locator) { 'div.restaurant-menus-container' }# Restaurant Detail page UI elements
list :menu_groups_list, 'div[class*="menus-and-groups-selector__SliderItems"]'def initialize
super
# define the custom list element components for the Menu Groupslists
list_spec = { list_item: 'button[data-testid="menu-group"]' }
menu_groups_list.define_list_elements(list_spec)
end
end
```#### SelectList UIElements
The basic HTML `select` element is typically composed of the parent `select` object, and one or more `option` elements
representing the selectable items in the drop-down list. However, `select` type controls implemented using JS component
libraries (React.js, Chosen, GWT, etc.) can be composed of multiple elements representing the various components of a
drop-down style `selectlist` implementation.![Custom SelectList](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomSelectList1.png "Custom SelectList")
In the screenshots below, an inspection of the **Football Teams** selector reveals that it is a `div` element that contains
a `textfield` element (outlined in purple) for inputting a selection by typing, a `ul` element (outlined in blue) that
contains the drop-down list, and multiple `li` elements with the `active-result` snippet in their `class` names (outlined
in orange) that represent the list items or options that can be selected. The currently selected item or option can be
identified by an `li` with the `result-selected` snippet in its `class` name. Group headings and items in the drop-down
list are represented by `li` elements with a `class` name of `group-result` (outlined in green).![Custom SelectList](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomSelectList.jpg "Custom SelectList")
The `SelectList.define_list_elements` method provides a means of specifying the various elements that make up the key
components of a `selectlist` control. The method accepts a hash of element designators (key) and a CSS or Xpath expression
(value) that uniquely identifies the element. Valid element designators are `:list_item`, `:options_list`, `:list_trigger`,
`:selected_item`, `:text_field`, `:group_heading`, and `:group_item`.The `CustomControlsPage` page object's `initialize` method in the code snippet below demonstrates the use of the
`SelectList.define_list_elements` method to define the common components that make up the **Teams** drop-down style selector.
```ruby
class CustomControlsPage < TestCentricity::PageObject
trait(:page_name) { 'Custom Controls' }
trait(:page_locator) { 'div.custom-controls-page-body' }# Custom Controls page UI elements
selectlists country_select: 'div#country_chosen',
team_select: 'div#team_chosen'def initialize
super
# define the custom list element components for the Team Chosen selectlists
list_spec = {
selected_item: 'li[class*="result-selected"]',
list_item: 'li[class*="active-result"]',
text_field: 'input.chosen-search-input',
options_list: 'ul.chosen-results',
group_item: 'li.group-result',
group_heading: 'li.group-result'
}
country_select.define_list_elements(list_spec)
team_select.define_list_elements(list_spec)
end
end
```#### Table UIElements
The basic HTML `table` element is typically composed of the parent `table` object, a body (`tbody`) containing one or
more rows (`tr`), with each row containing one or more columns (`td`). Tables can also include an optional header (`thead`)
with a header row (`tr`) containing one or more header columns (`th`).However, custom tables can be implemented using elements other than the standard table components described above. In the
screenshot below, an inspection of the table reveals that it is comprised of `div` elements representing the table, body,
rows, columns, header, header row, and header columns.![Custom Table](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomTable.png "Custom Table")
The `Table.define_table_elements` method provides a means of specifying the various elements that make up the key
components of a `table`. The method accepts a hash of element designators (key) and a CSS or Xpath expression (value)
that uniquely identifies the element. Valid element designators are `:table_header`, `:header_row`, `:header_column`,
`:table_body`, `:table_row`, and `:table_column`.The `CustomControlsPage` page object's `initialize` method in the code snippet below demonstrates the use of the
`Table.define_table_elements` method to define the components that make up the responsive `table`.
```ruby
class CustomControlsPage < TestCentricity::PageObject
trait(:page_name) { 'Custom Controls' }
trait(:page_locator) { 'div.custom-controls-page-body' }# Custom Controls page UI elements
table :custom_table, 'div#resp-table'def initialize
super
# define the custom element components for the table
table_spec = {
table_header: 'div.resp-table-header',
header_row: 'div.resp-table-row',
header_column: 'div.table-header-cell',
table_body: 'div.resp-table-body',
table_row: 'div.resp-table-row',
table_column: 'div.table-body-cell'
}
custom_table.define_table_elements(table_spec)
end
end
```---
## Instantiating Your PageObjectsBefore you can call the methods in your `PageObjects` and `PageSections`, you must instantiate the `PageObjects` of your
web application, as well as create instance variables which can be used when calling a `PageObject`'s methods from your
step definitions. There are several ways to instantiate your `PageObjects`.One common implementation is shown below:
```ruby
module WorldPages
def login_page
@login_page ||= LoginPage.new
enddef home_page
@home_page ||= HomePage.new
enddef registration_page
@registration_page ||= RegistrationPage.new
enddef search_results_page
@search_results_page ||= SearchResultsPage.new
end
endWorld(WorldPages)
```
The `WorldPages` module above can be defined in your `env.rb` file, or you can define it in a separate `world_pages.rb`
file in the `features/support` folder.While this approach is effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly
becomes cumbersome to manage if your web application has dozens of `PageObjects` that need to be instantiated and managed.### Using the PageManager
The `PageManager` class provides methods for supporting the instantiation and management of `PageObjects`. In the code
example below, the `page_objects` method contains a hash table of your `PageObject` instances and their associated
`PageObject` classes to be instantiated by `PageManager`:
```ruby
module WorldPages
def page_objects
{
login_page: LoginPage,
home_page: HomePage,
registration_page: RegistrationPage,
search_results_page: SearchResultsPage,
products_grid_page: ProductsCollectionPage,
product_detail_page: ProductDetailPage,
shopping_basket_page: ShoppingBasketPage,
payment_method_page: PaymentMethodPage,
confirm_purchase_page: PurchaseConfirmationPage,
my_account_page: MyAccountPage,
my_order_history_page: MyOrderHistoryPage,
my_ship_to_addresses_page: MyShipToAddressesPage,
terms_conditions_page: TermsConditionsPage,
privacy_policy_page: PrivacyPolicyPage,
faqs_page: FAQsPage,
contact_us_page: ContactUsPage
}
end
endWorld(WorldPages)
```
The `WorldPages` module above should be defined in the `world_pages.rb` file in the `features/support` folder.Include the code below in your `env.rb` file to ensure that your `PageObjects` are instantiated before your Cucumber
scenarios are executed:
```ruby
include WorldPages
WorldPages.instantiate_page_objects
```
**NOTE:** If you intend to use the `PageManager`, you must define a `page_name` trait for each of the `PageObjects` to
be registered.### Leveraging the PageManager in Your Cucumber Tests
Many Cucumber based automated tests suites include scenarios that verify that web pages are correctly loaded, displayed,
or can be navigated to by clicking associated links. One such Cucumber navigation scenario is displayed below:
```gherkin
Scenario Outline: Verify Home page navigation links
Given I am on the Home page
When I click the navigation link
Then I expect the page to be correctly displayedExamples:
|page name |
|Registration |
|My Account |
|Terms & Conditions |
|Privacy Policy |
|FAQs |
|Contact Us |
```
In the above example, the step definitions associated with the 3 steps might be implemented using a `page_dispatcher`
method using a `case` statement to parse the `page` parameter as in the example below:
```ruby
Given(/^I am on the (.*) page$/) do |page_name|
target_page = page_dispatcher(page_name)
target_page.load_page
endWhen(/^I click the (.*) navigation link$/) do |link_name|
target_page = page_dispatcher(link_name)
target_page.navigate_to
endThen(/^I expect the (.*) page to be correctly displayed$/) do |page_name|
target_page = page_dispatcher(page_name)
target_page.verify_page_exists
target_page.verify_page_ui
end# this method takes a page name as a parameter and returns an instance of the associated Page Object
def page_dispatcher(page_name)
page = case page_name
when 'Registration'
registration_page
when 'My Account'
my_account_page
when 'Terms & Conditions'
terms_conditions_page
when 'Privacy Policy'
privacy_policy_page
when 'Contact Us'
contact_us_page
when 'FAQs'
faqs_page
end
raise "No page object defined for page named '#{page_name}'" unless page
page
end
````While this approach may be effective for small web applications with only a few pages (and hence few `PageObjects`), it
quickly becomes cumbersome to manage if your web application has dozens of `PageObjects` that need to be managed.The `PageManager` class provides a `find_page` method that replaces the cumbersome and difficult to maintain `case`
statement used in the above example. The `PageManager.current_page` method allows you to set or get an instance of the
currently active Page Object.To use these `PageManager` methods, include the step definitions and code below in a `page_steps.rb` or `generic_steps.rb`
file in the `features/step_definitions` folder:
```ruby
include TestCentricityGiven(/^I am on the (.*) page$/) do |page_name|
target_page = PageManager.find_page(page_name)
target_page.load_page
endWhen(/^I click the (.*) navigation link$/) do |page_name|
target_page = PageManager.find_page(page_name)
target_page.navigate_to
endThen(/^I expect to see the (.*) page$/) do |page_name|
target_page = PageManager.find_page(page_name)
target_page.verify_page_exists
endThen(/^I expect the (.*) page to be correctly displayed$/) do |page_name|
target_page = PageManager.find_page(page_name)
target_page.verify_page_exists
target_page.verify_page_ui
end
```---
## Connecting to Web BrowsersSince its inception, TestCentricity has provided support for establishing a single connection to a target desktop or mobile
web browser by instantiating a WebDriver object. **Environment Variables** are used to specify the local, grid, or remote
cloud hosted target web browser, and the various WebDriver capability parameters required to configure the driver object.
The appropriate **Environment Variables** are typically specified in the command line at runtime through the use of profiles
set in a `cucumber.yml` file (Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below).However, for those use cases requiring the instantiation of multiple WebDriver objects within a test case or test scenario,
**Environment Variables** are a less effective means of specifying multiple driver capabilities. And even in those use cases
where only a single WebDriver object is required, there are a growing number of optional Selenium and Appium capabilities
that are being offered by cloud hosted browser service providers (like BrowserStack, Sauce Labs, TestingBot, or LambdaTest)
that **Environment Variables** may not effectively address.Beginning with TestCentricity version 4.4.0, the `TestCentricity::WebDriverConnect.initialize_web_driver` method accepts
an optional `options` hash for specifying desired capabilities (using the W3C protocol), driver type, driver name, endpoint
URL, device type, and desktop web browser window size information. TestCentricity also now supports the instantiation of
multiple WebDriver objects to establish connections with, and coordinate test execution between multiple desktop and/or
mobile web browser instances.Some use cases for the verification of real-time multiple user interactions across multiple concurrent browsers or devices are:
- Chat, Messaging, or Social Media apps/web portals used by one or more users interacting in real time (posts, reposts, likes)
- Ride Hailing/Sharing Services with separate Rider and Driver experience apps/web portals
- Food Delivery Services with a Customer app for finding restaurants and ordering food, a Restaurant app for fulfilling
the food order and coordinating delivery, and a Driver app for ensuring delivery of the order to the customer
- Learning Management/Student Engagement platforms that allow teachers to monitor student engagement and progress on assigned
activities and support for remote real-time collaboration between students and teachersIf the optional `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
then **Environment Variables** must be used to specify the target local or remote web browser, and the various webdriver
capability parameters required to establish a connection with a single target web browser.### Specifying Options and Capabilities in the `options` Hash
For those test scenarios requiring the instantiation of multiple WebDriver objects, or where cumbersome **Environment
Variables** are less than ideal, call the `TestCentricity::WebDriverConnect.initialize_web_driver` method with an `options`
hash that specifies the WebDriver desired capabilities and the driver type, as depicted in the example below:
```ruby
options = {
capabilities: { browserName: :firefox },
driver: :webdriver
}
WebDriverConnect.initialize_web_driver(options)
```
Additional options that can be specified in an `options` hash include the following:| Option | Purpose |
|-----------------|--------------------------------------------------------------------------------------------|
| `browser_size:` | optional desktop web browser window size (width and height) |
| `driver_name:` | optional driver name |
| `endpoint:` | optional endpoint URL for remote grid or cloud hosted browser service providers |
| `device_type:` | only used for locally or cloud hosted mobile device browser - set to `:phone` or `:tablet` |Details on specifying desired capabilities, driver type, endpoint URL, and default driver names are provided in each of the
browser hosting sections below.#### Specifying the Driver Type
The `driver:` type is a required entry in the `options` hash when instantiating a WebDriver object using the `initialize_web_driver`
method. Valid `driver:` type values are listed in the table below:| `driver:` | **Driver Type** |
|-----------------|--------------------------------------------------------------------------------------------|
| `:webdriver` | locally hosted desktop or emulated mobile browser |
| `:grid` | Selenium Grid 4 hosted browser |
| `:appium` | locally hosted native iOS/Android mobile browser using device simulator or physical device |
| `:browserstack` | remote browser hosted on BrowserStack |
| `:saucelabs` | remote browser hosted on Sauce Labs |
| `:testingbot` | remote browser hosted on TestingBot |
| `:lambdatest` | remote browser hosted on LambdaTest |
| `:custom` | remote browser hosted on unsupported cloud based browser hosting services |#### Specifying a Driver Name
An optional user defined `driver_name:` can be specified in the `options` hash when instantiating a WebDriver object using
the `TestCentricity::WebDriverConnect.initialize_web_driver` method. If a driver name is not specified, the `initialize_web_driver`
method will assign a default driver name comprised of the specified driver type (`driver:`) and the `browserName:` specified
in the `capabilities:` hash. Details on default driver names are provided in each of the browser hosting sections below.For those test scenarios requiring the instantiation of multiple WebDriver objects, each driver object should be assigned a
unique driver name, which is used when switching between driver contexts. For instance, when performing end-to-end testing
of a Food Delivery Service which consists of separate web portals for the Customer Experience (find, order, and pay for food),
the Restaurant Experience (menu management, order fulfillment, and order delivery dispatch), and the Delivery Driver Experience
(customer location and tracking), 3 driver objects must be instantiated.Assigning meaningful unique driver names for the 3 driver objects (`:customer_portal`, `:merchant_portal`, `:delivery_portal`)
in the `options` hash when calling `TestCentricity::WebDriverConnect.initialize_web_driver` method reduces confusion when
switching between the driver objects using the `TestCentricity:WebDriverConnect.activate_driver(driver_name)` method, which
expects a driver name, specified as a `Symbol`.### Setting Desktop Browser Window Size
#### Using `:browser_size` in the `options` Hash
The size (width and height) of a desktop browser window can be specified in the `options` hash for browsers that are hosted
locally, in a Selenium Grid, or by a cloud hosted browser service provider. You cannot set the size of a mobile device web
browser, which is determined by the mobile device's screen size.To set the size of a desktop browser window in the `options` hash, you specify a `:browser_size` with the desired width and
height in pixels as shown below:
```ruby
options = {
browser_size: [1100, 900],
capabilities: { browserName: :edge },
driver: :webdriver
}
WebDriverConnect.initialize_web_driver(options)
```
To maximize a desktop browser window, you specify a `:browser_size` of 'max' as shown below:
```ruby
options = {
browser_size: 'max',
capabilities: { browserName: :chrome },
driver: :webdriver
}
WebDriverConnect.initialize_web_driver(options)
```
If a `:browser_size` is not specified, then the default size of a desktop browser window will be set to the size specified
in the `BROWSER_SIZE` Environment Variable (if it has been specified) or to a default width and height of 1650 by 1000 pixels.#### Using the `BROWSER_SIZE` Environment Variable
To set the size of a desktop browser window without using an `options` hash, you set the `BROWSER_SIZE` Environment Variable
to the desired width and height in pixels as shown below:BROWSER_SIZE=1600,1000
To maximize a desktop browser window, you set the `BROWSER_SIZE` Environment Variable to 'max' as shown below:
BROWSER_SIZE=max
If the `BROWSER_SIZE` Environment Variable is not specified, then the default size of a desktop browser window will be set
to a width and height of 1650 by 1000 pixels.### Locally Hosted Desktop Web Browsers
For locally hosted desktop web browsers running on macOS, Windows, or Linux platforms, the browser type and driver type
must be specified when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method. The table below contains
the values that can be used to specify the locally hosted desktop web browser to be instantiated when calling the
`initialize_web_driver` method:| `browserName:` or `WEB_BROWSER` | **Desktop Platform** |
|---------------------------------|-----------------------------------------------------|
| `chrome` | macOS, Windows, or Linux |
| `chrome_headless` | macOS, Windows, or Linux (headless - no visible UI) |
| `firefox` | macOS, Windows, or Linux |
| `firefox_headless` | macOS, Windows, or Linux (headless - no visible UI) |
| `edge` | macOS or Windows |
| `edge_headless` | macOS or Windows (headless - no visible UI) |
| `safari` | macOS only |#### Local Desktop Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method, then
the following Environment Variables must be set as described in the table below:| **Environment Variable** | **Description** |
|--------------------------|-------------------------------------------------------------------|
| `WEB_BROWSER` | Must be set to one of the values from the table above |
| `DRIVER` | Must be set to `webdriver` |
| `BROWSER_SIZE` | [Optional] Set to _'width in pixels, heigh in pixels'_ or _'max'_ |Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
#### Local Desktop Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:webdriver`
- `browserName:` in the `capabilities:` hash must be set to one of the values from the table above```ruby
options = {
capabilities: { browserName: value_from_table_above },
driver: :webdriver
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:local_` - e.g. `:local_chrome` or `:local_edge_headless`.Below is an example of an `options` hash for specifying a connection to a locally hosted Firefox desktop web browser. The
`options` hash includes options for specifying the driver name and setting the browser window size.
```ruby
options = {
driver: :webdriver,
driver_name: :customer_context,
browser_size: [1400, 1100],
capabilities: { browserName: :firefox }
}
WebDriverConnect.initialize_web_driver(options)
```#### Testing File Downloads With Desktop Browsers
File download functionality can be tested with locally hosted instances of Chrome, Edge, or Firefox desktop browsers. Your
automation project must set the `DOWNLOADS` Environment Variable to `true`, which will result in a `/downloads` folder being
created, which will be used as the destination for files that are downloaded by your automated tests. The `/downloads` folder
will be at the same level as the `/config` and `/features` folders, as depicted below:📁 my_automation_project/
├── 📁 config/
├── 📁 downloads/
├── 📁 features/
├── 📄 Gemfile
└── 📄 README.mdWhen running tests in multiple concurrent threads using the `parallel_tests` gem, a new folder will be created within the
`/downloads` folder for each test thread. This is to ensure that files downloaded in each test thread are isolated from tests
running in other parallel threads. An example of the`/downloads` folder structure for 4 parallel threads is depicted below:📁 my_automation_project/
├── 📁 config/
├── 📁 downloads/
│ ├── 📁 1/
│ ├── 📁 2/
│ ├── 📁 3/
│ └── 📁 4/
├── 📁 features/
├── 📄 Gemfile
└── 📄 README.mdWhen testing file downloads using a local instance of Firefox, you will need to specify the MIME types of the various file
types that your tests will be downloading. This is accomplished by setting the `MIME_TYPES` Environment Variable to a
comma-delimited string containing the list of MIME types to be accepted. The `MIME_TYPES` Environment Variable should be
set before initializing the Firefox web driver. This list of file types is required as it will prevent Firefox from displaying
the File Download modal dialog, which will halt your automated tests. An example of a list of MIME types is depicted below:
```ruby
# set list of all supported MIME types for testing file downloads with Firefox
mime_types = [
'application/pdf',
'image/png',
'image/jpeg',
'image/gif',
'text/csv',
'text/plain'
]
ENV['MIME_TYPES'] = mime_types.join(',')
```A detailed list of file MIME types can be found [here](https://www.freeformatter.com/mime-types-list.html).
### Locally Hosted Emulated Mobile Web Browsers
You can run your tests against mobile device browsers that are emulated within a locally hosted instance of a Chrome desktop
browser on macOS or Windows. The specified mobile browser's user agent, CSS screen dimensions, and default screen orientation
will be automatically set within the local Chrome browser instance. You may also specify the emulated device's screen orientation.> ⚠️ For best results when testing against mobile web browsers, you should run your tests against iOS and Android simulators
or physical devices, either hosted locally or via a remotely cloud hosted service.For locally hosted emulated mobile web browsers, the `WEB_BROWSER` Environment Variable must be set to one of the values
from the table below:| `browserName:` or `WEB_BROWSER` | **CSS Screen Dimensions** | **Default Orientation** | **OS Version** |
|---------------------------------|---------------------------|-------------------------|----------------------|
| `iphone_11` | 414 x 896 | portrait | iOS 15.5 |
| `iphone_11_pro` | 375 x 812 | portrait | iOS 15.5 |
| `iphone_11_pro_max` | 414 x 896 | portrait | iOS 15.5 |
| `iphone_12_mini` | 375 x 812 | portrait | iOS 15.5 |
| `iphone_12` | 390 x 844 | portrait | iOS 15.5 |
| `iphone_12_pro` | 390 x 844 | portrait | iOS 15.5 |
| `iphone_12_pro_max` | 428 x 926 | portrait | iOS 15.5 |
| `iphone_13_mini` | 375 x 812 | portrait | iOS 15.5 |
| `iphone_13` | 390 x 844 | portrait | iOS 15.5 |
| `iphone_13_pro` | 390 x 844 | portrait | iOS 15.5 |
| `iphone_13_pro_max` | 428 x 926 | portrait | iOS 15.5 |
| `iphone_se` | 375 x 667 | portrait | iOS 15.5 |
| `iphone_14` | 390 x 844 | portrait | iOS 16.2 |
| `iphone_14_plus` | 428 x 926 | portrait | iOS 16.2 |
| `iphone_14_pro` | 393 x 852 | portrait | iOS 16.2 |
| `iphone_14_pro_max` | 430 x 932 | portrait | iOS 16.2 |
| `ipad` | 1080 x 810 | landscape | iOS 15.5 |
| `ipad_mini` | 1133 x 744 | landscape | iOS 15.5 |
| `ipad_air` | 1180 x 820 | landscape | iOS 15.5 |
| `ipad_pro_11` | 1194 x 834 | landscape | iOS 15.5 |
| `ipad_pro_12_9` | 1366 x 1024 | landscape | iOS 15.5 |
| `pixel_5` | 393 x 851 | portrait | Android 12 |
| `pixel_6` | 412 x 915 | portrait | Android 12 |
| `pixel_xl` | 412 x 732 | portrait | Android 12 |
| `nexus_10` | 1280 x 800 | landscape | Android 12 |
| `pixel_c` | 1280 x 900 | landscape | Android 12 |
| `kindle_fire` | 1024 x 600 | landscape | |
| `kindle_firehd7` | 800 x 480 | landscape | Fire OS 3 |
| `kindle_firehd8` | 1280 x 800 | landscape | Fire OS 5 |
| `kindle_firehd10` | 1920 x 1200 | landscape | Fire OS 5 |
| `surface` | 1366 x 768 | landscape | |
| `blackberry_playbook` | 1024 x 600 | landscape | BlackBerry Tablet OS |
| `windows_phone7` | 320 x 480 | portrait | Windows Phone OS 7.5 |
| `windows_phone8` | 320 x 480 | portrait | Windows Phone OS 8.0 |
| `lumia_950_xl` | 360 x 640 | portrait | Windows Phone OS 10 |
| `blackberry_z10` | 384 x 640 | portrait | BlackBerry 10 OS |
| `blackberry_z30` | 360 x 640 | portrait | BlackBerry 10 OS |
| `blackberry_leap` | 360 x 640 | portrait | BlackBerry 10 OS |
| `blackberry_passport` | 504 x 504 | square | BlackBerry 10 OS |#### Local Emulated Mobile Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
then the following Environment Variables must be set as described in the table below:| **Environment Variable** | **Description** |
|--------------------------|-------------------------------------------------------|
| `WEB_BROWSER` | Must be set to one of the values from the table above |
| `DRIVER` | Must be set to `webdriver` |
| `ORIENTATION` | [Optional] Set to `portrait` or `landscape` |Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
#### Local Emulated Mobile Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:webdriver`
- `browserName:` in the `capabilities:` hash must be set to one of the values from the table above```ruby
options = {
capabilities: { browserName: value_from_table_above },
driver: :webdriver
}
WebDriverConnect.initialize_web_driver(options)
```
To change the emulated device's screen orientation from the default setting, set the optional `orientation:` to either
`:portrait` or `:landscape` in the `capabilities:` hash as shown in the example below:
```ruby
options = {
capabilities: {
browserName: :ipad_pro_12_9,
orientation: :portrait
},
driver: :webdriver
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:local_` - e.g. `:local_ipad_pro_12_9` or `:local_pixel_6`.Below is an example of an `options` hash for specifying a connection to a locally hosted emulated mobile Safari web browser
running on an iPhone. The`options` hash includes options for specifying the driver name and setting the browser orientation
to landscape mode.
```ruby
options = {
driver: :webdriver,
driver_name: :user1,
capabilities: {
browserName: :iphone_13_pro_max,
orientation: :landscape
}
}
WebDriverConnect.initialize_web_driver(options)
```#### User Defined Emulated Mobile Browser Profiles
User defined mobile browser profiles can be specified in a `device.yml` file for testing locally hosted emulated mobile
web browsers running in an instance of the Chrome desktop browser. The user specified browser profiles must be located
at `config/data/devices/devices.yml` as depicted below:📁 my_automation_project/
├── 📁 config/
│ ├── 📁 data/
│ │ └── 📁 devices/
│ │ └── 📄devices.yml
│ ├── 📁 locales/
│ ├── 📁 test_data/
│ └── 📄 cucumber.yml
├── 📁 downloads/
├── 📁 features/
├── 📄 Gemfile
└── 📄 README.mdThe format for a new mobile browser profile is:
```yaml
:my_device_profile:
:name: "My New Device Name"
:os: (ios, android, kindle, or blackberry)
:type: (phone or tablet)
:css_width: css width in pixels
:css_height: css height in pixels
:default_orientation: (portrait or landscape)
:user_agent: "user agent string"
```To specify a user defined emulated mobile browser, set `browserName:` or the `WEB_BROWSER` Environment Variable to the
device's profile name.### Selenium Grid Hosted Desktop and Emulated Mobile Web Browsers
For remotely hosted desktop web browsers running on a Selenium 4 Grid, the browser type and driver type must be specified
when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method. The table below contains the values that
can be used to specify the grid hosted desktop web browser to be instantiated when calling the`initialize_web_driver` method:| `browserName:` or `WEB_BROWSER` |
|---------------------------------|
| `chrome` |
| `chrome_headless` |
| `firefox` |
| `firefox_headless` |
| `edge` |
| `edge_headless` |#### Grid Browsers using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
then the following Environment Variables must be set as described in the table below:| **Environment Variable** | **Description** |
|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
| `WEB_BROWSER` | Must be set to one of the values from the table above, or any of the emulated mobile web browsers described above in section 8.4. |
| `DRIVER` | Must be set to `grid` |
| `REMOTE_ENDPOINT` | [Optional] Set to the URL of the Grid hub. Set to `http://localhost:4444/wd/hub` if not specified |
| `BROWSER_SIZE` | [Optional] Set to _'width in pixels, heigh in pixels'_ or _'max'_ |Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
#### Grid Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:grid`
- `browserName:` in the `capabilities:` hash must be set to one of the values from the table above```ruby
options = {
capabilities: { browserName: value_from_table_above },
driver: :grid,
endpoint: 'http://localhost:4444/wd/hub'
}
WebDriverConnect.initialize_web_driver(options)
```
>ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:remote_` - e.g. `:remote_chrome` or `:remote_edge_headless`.
>
> ℹ️ If an `endpoint:` is not specified in the `options`hash, then the default remote endpoint URL of `http://localhost:4444/wd/hub`
will be used.Below is an example of an `options` hash for specifying a connection to a grid hosted Chrome desktop web browser. The
`options` hash includes options for specifying the driver name and setting the browser window size.
```ruby
options = {
driver: :grid,
driver_name: :admin_user,
browser_size: [1400, 1100],
capabilities: { browserName: :chrome }
}
WebDriverConnect.initialize_web_driver(options)
```### Locally Hosted Mobile Browsers on Simulators or Physical Devices
Refer to [this page](https://appium.io/docs/en/2.2/guides/caps/) for information regarding specifying Appium capabilities.
⚠️ If you are running locally hosted mobile web tests on iOS or Android simulators or devices using version 1.x of the Appium
server, the `APPIUM_SERVER_VERSION` environment variable must be set to `1` in order to ensure that the correct Appium server
endpoint is used.#### Mobile Safari Browser on iOS Simulators or iOS Physical Devices
You can run your mobile web tests against the mobile Safari browser on iOS device simulators or physically connected iOS
devices using Appium and XCode on macOS. You must install Appium, XCode, and the iOS version-specific device simulators
for XCode. Information about Appium setup and configuration requirements with the XCUITest driver for testing on physically
connected iOS devices can be found on [this page](https://github.com/appium/appium-xcuitest-driver/blob/master/docs/real-device-config.md). Refer to [this page](https://appium.github.io/appium-xcuitest-driver/5.12/capabilities/) for information regarding specifying
Appium capabilities that are specific to the XCUITest driver.The Appium server must be running prior to invoking Cucumber to run your features/scenarios. Refer to [**section 8.6.3 (Starting and Stopping Appium Server)**](#starting-and-stopping-appium-server) below.
##### Local Mobile Safari Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
the following **Environment Variables** must be set as described in the table below.| **Environment Variable** | **Description** |
|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `DRIVER` | Must be set to `appium` |
| `AUTOMATION_ENGINE` | Must be set to `xcuitest` |
| `APP_PLATFORM_NAME` | Must be set to `iOS` |
| `APP_BROWSER` | Must be set to `Safari` |
| `APP_VERSION` | Must be set to which ever iOS version you wish to run within the XCode Simulator |
| `APP_DEVICE` | Set to iOS device name supported by the iOS Simulator (`iPhone 13 Pro Max`, `iPad Pro (12.9-inch) (5th generation)`, etc.) or name of physically connected iOS device |
| `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
| `UDID` | UDID of physically connected iOS device (not used for simulators) |
| `TEAM_ID` | unique 10-character Apple developer team identifier string (not used for simulators) |
| `TEAM_NAME` | String representing a signing certificate (not used for simulators) |
| `APP_ALLOW_POPUPS` | [Optional] Allow javascript to open new windows in Safari. Set to `true` or `false` |
| `APP_IGNORE_FRAUD_WARNING` | [Optional] Prevent Safari from showing a fraudulent website warning. Set to `true` or `false` |
| `APP_NO_RESET` | [Optional] Don't reset app state after each test. Set to `true` or `false` |
| `APP_FULL_RESET` | [Optional] Perform a complete reset. Set to `true` or `false` |
| `APP_INITIAL_URL` | [Optional] Initial URL, default is a local welcome page. e.g. `http://www.apple.com` |
| `WDA_LOCAL_PORT` | [Optional] Used to forward traffic from Mac host to real iOS devices over USB. Default value is same as port number used by WDA on device. |
| `ORIENTATION` | [Optional] Set to `portrait` or `landscape` (only for iOS simulators) |
| `NEW_COMMAND_TIMEOUT` | [Optional] Time (in Seconds) that Appium will wait for a new command from the client |
| `SHOW_SIM_KEYBOARD` | [Optional] Show the simulator keyboard during text entry. Set to `true` or `false` |
| `SHUTDOWN_OTHER_SIMS` | [Optional] Close any other running simulators. Set to `true` or `false`. See note below. |The `SHUTDOWN_OTHER_SIMS` environment variable can only be set if you are running Appium Server with the `--relaxed-security`
or `--allow-insecure=shutdown_other_sims` arguments passed when starting it from the command line, or when running the server
from the Appium Server GUI app. A security violation error will occur without relaxed security enabled.Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
##### Local Mobile Safari Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:appium`
- `device_type:` must be set to `:tablet` or `:phone`
- `browserName:` must be set to 'Safari' in the `capabilities:` hash
- `platformName:` must be set to 'ios' in the `capabilities:` hash
- `'appium:automationName':` must be set to 'xcuitest' in the `capabilities:` hash
- `'appium:platformVersion':` must be set to the version of iOS on the simulator or physical device
- `'appium:deviceName':` must be set to the name of the iOS simulator or physical device```ruby
options = {
driver: :appium,
device_type: phone_or_tablet,
capabilities: {
platformName: 'ios',
browserName: 'Safari',
'appium:automationName': 'xcuitest',
'appium:platformVersion': ios_version,
'appium:deviceName': device_or_simulator_name
},
endpoint: 'http://localhost:4723'
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`appium_safari`.
>
> ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL of `http://localhost:4723`
will be used.Below is an example of an `options` hash for specifying a connection to a locally hosted mobile Safari web browser running
on an iPad simulator. The `options` hash includes options for specifying the driver name and setting the simulated device
orientation to portrait mode.
```ruby
options = {
driver: :appium,
device_type: :tablet,
driver_name: :student_ipad,
capabilities: {
platformName: 'ios',
browserName: 'Safari',
'appium:platformVersion': '15.4',
'appium:deviceName': 'iPad Pro (12.9-inch) (5th generation)',
'appium:automationName': 'xcuitest',
'appium:orientation': 'PORTRAIT'
}
}
WebDriverConnect.initialize_web_driver(options)
```#### Mobile Chrome or Android Browsers on Android Studio Virtual Device Emulators
You can run your mobile web tests against the mobile Chrome or Android browser on emulated Android devices using Appium and
Android Studio on macOS. You must install Android Studio, the desired Android version-specific virtual device emulators, and
Appium. Refer to [this page](https://appium.io/docs/en/2.2/quickstart/uiauto2-driver/) for information on configuring Appium to work with the Android SDK. Refer to [this page](https://github.com/appium/appium-uiautomator2-driver)
for information regarding specifying Appium capabilities that are specific to the UiAutomator2 driver.The Appium server must be running prior to invoking Cucumber to run your features/scenarios. Refer to [**section 8.6.3 (Starting and Stopping Appium Server)**](#starting-and-stopping-appium-server) below.
##### Local Mobile Android Browsers using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
the following **Environment Variables** must be set as described in the table below.| **Environment Variable** | **Description** |
|---------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| `DRIVER` | Must be set to `appium` |
| `AUTOMATION_ENGINE` | Must be set to `UiAutomator2` |
| `APP_PLATFORM_NAME` | Must be set to `Android` |
| `APP_BROWSER` | Must be set to `Chrome` or `Browser` |
| `APP_VERSION` | Must be set to which ever Android OS version you wish to run with the Android Virtual Device |
| `APP_DEVICE` | Set to Android Virtual Device ID (`Pixel_2_XL_API_26`, `Nexus_6_API_23`, etc.) found in Advanced Settings of AVD Configuration |
| `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
| `ORIENTATION` | [Optional] Set to `portrait` or `landscape` |
| `APP_INITIAL_URL` | [Optional] Initial URL, default is a local welcome page. e.g. `http://www.apple.com` |
| `APP_NO_RESET` | [Optional] Don't reset app state after each test. Set to `true` or `false` |
| `APP_FULL_RESET` | [Optional] Perform a complete reset. Set to `true` or `false` |
| `NEW_COMMAND_TIMEOUT` | [Optional] Time (in Seconds) that Appium will wait for a new command from the client |
| `CHROMEDRIVER_EXECUTABLE` | [Optional] Absolute local path to ChromeDriver executable |Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
##### Local Mobile Android Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:appium`
- `device_type:` must be set to `:tablet` or `:phone`
- `browserName:` must be set to 'Chrome' in the `capabilities:` hash
- `platformName:` must be set to 'Android' in the `capabilities:` hash
- `'appium:automationName':` must be set to 'UiAutomator2' in the `capabilities:` hash
- `'appium:platformVersion':` must be set to the version of Android on the simulator or physical device
- `'appium:deviceName':` must be set to the Android Virtual Device ID```ruby
options = {
driver: :appium,
device_type: phone_or_tablet,
capabilities: {
platformName: 'Android',
browserName: 'Chrome',
'appium:automationName': 'UiAutomator2',
'appium:platformVersion': android_version,
'appium:deviceName': simulator_name,
'appium:avd': simulator_name
},
endpoint: 'http://localhost:4723'
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`appium_chrome`.
>
> ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL of `http://localhost:4723`
will be used.Below is an example of an `options` hash for specifying a connection to a locally hosted mobile Chrome web browser running
on an Android phone simulator. The `options` hash includes options for specifying the driver name, setting the simulated
device orientation to landscape mode, and specifying the path to the ChromeDriver executable.
```ruby
options = {
driver: :appium,
device_type: :phone,
driver_name: :student_phone,
capabilities: {
platformName: 'Android',
browserName: 'Chrome',
'appium:platformVersion': '12.0',
'appium:deviceName': 'Pixel_5_API_31',
'appium:avd': 'Pixel_5_API_31',
'appium:automationName': 'UiAutomator2',
'appium:orientation': 'LANDSCAPE',
'appium:chromedriverExecutable': '/Users/Shared/config/webdrivers/chromedriver'
}
}
WebDriverConnect.initialize_web_driver(options)
```#### Starting and Stopping Appium Server
##### Using Appium Server with Cucumber
The Appium server must be running prior to invoking Cucumber to run your features/scenarios on locally hosted mobile simulators
or physical devices. To programmatically control the starting and stopping of Appium server with the execution of your automated
tests, place the code shown below in your `hooks.rb` file.
```ruby
BeforeAll do
# start Appium Server if APPIUM_SERVER = 'run' and target browser is a mobile simulator or device
if ENV['APPIUM_SERVER'] == 'run' && Environ.driver == :appium
$server = TestCentricity::AppiumServer.new
$server.start
end
endAfterAll do
# terminate all driver instances
WebDriverConnect.close_all_drivers
# terminate Appium Server if APPIUM_SERVER = 'run' and target browser is a mobile simulator or device
$server.stop if ENV['APPIUM_SERVER'] == 'run' && Environ.driver == :appium && $server.running?
end
```
The `APPIUM_SERVER` environment variable must be set to `run` in order to programmatically start and stop the Appium server.
This can be set by adding the following to your `cucumber.yml` file and including `-p run_appium` in your command line when
starting your Cucumber test suite(s):run_appium: APPIUM_SERVER=run
If you are running locally hosted mobile web tests on iOS or Android simulators or devices using version 1.x of the Appium
server, the `APPIUM_SERVER_VERSION` environment variable must be set to `1` in order to ensure that the correct Appium server
endpoint is used. This can be set by adding the following to your `cucumber.yml` file and including `-p appium_1x` in your
command line when starting your Cucumber test suite(s):appium_1x: APPIUM_SERVER_VERSION=1
Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
##### Using Appium Server with RSpec
The Appium server must be running prior to executing test specs on locally hosted mobile simulators or physical device. To
control the starting and stopping of the Appium server with the execution of your specs, place the code shown below in the
body of an example group:
```ruby
before(:context) do
# start Appium server before all of the examples in this group
$server = TestCentricity::AppiumServer.new
$server.start
endafter(:context) do
# terminate Appium Server after all of the examples in this group
$server.stop if Environ.driver == :appium && $server.running?
end
```
If you are running locally hosted mobile web tests on iOS or Android simulators or devices using version 1.x of the Appium
server, the `APPIUM_SERVER_VERSION` environment variable must be set to `1` in order to ensure that the correct Appium server
endpoint is used.### Remote Cloud Hosted Desktop and Mobile Web Browsers
You can run your automated tests against remote cloud hosted desktop and mobile web browsers using the BrowserStack, SauceLabs,
TestingBot, or LambdaTest services. If your tests are running against a web site hosted on your local computer (`localhost`),
or on a staging server inside your LAN, you must set the `TUNNELING` Environment Variable to `true`.If the BrowserStack Local instance is running (`TUNNELING` Environment Variable is `true`), call the`TestCentricity::WebDriverConnect.close_tunnel`
method upon completion of your test suite to stop the Local instance. Place the code shown below in your `env.rb` or
`hooks.rb` file:
```ruby
# code to stop BrowserStack Local instance after end of test (if tunneling is enabled)
at_exit do
TestCentricity::WebDriverConnect.close_tunnel if Environ.tunneling
end
```
#### Remote Desktop Browsers on the BrowserStack ServiceFor remotely hosted desktop web browsers on the BrowserStack service, refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/docs/automate/capabilities)
for information regarding the options and capabilities available for the various supported desktop operating systems and
web browsers. Select the **Legacy** Integration method tab and the **W3C Protocol** tab on the capabilities page.##### BrowserStack Desktop Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
the following **Environment Variables** must be set as described in the table below.| **Environment Variable** | **Description** |
|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `DRIVER` | Must be set to `browserstack` |
| `BS_USERNAME` | Must be set to your BrowserStack account user name |
| `BS_AUTHKEY` | Must be set to your BrowserStack account access key |
| `BS_OS` | Must be set to `OS X` or `Windows` |
| `BS_OS_VERSION` | Refer to `os_version` capability in chart |
| `BS_BROWSER` | Refer to `browserName` capability in chart |
| `BS_VERSION` | [Optional] Refer to `browser_version` capability in chart. If not specified, latest stable version of browser will be used. |
| `TUNNELING` | [Optional] Must be `true` if you are testing against internal/local servers (`true` or `false`). If `true`, the BrowserStack Local instance will be automatically started. |
| `RESOLUTION` | [Optional] Refer to supported screen `resolution` capability in chart |
| `RECORD_VIDEO` | [Optional] Enable screen video recording during test execution (`true` or `false`) |
| `TIME_ZONE` | [Optional] Specify custom time zone. Refer to `browserstack.timezone` capability in chart |
| `IP_GEOLOCATION` | [Optional] Specify IP Geolocation. Refer to [IP Geolocation](https://www.browserstack.com/ip-geolocation) to select a country code. |
| `ALLOW_POPUPS` | [Optional] Allow popups (`true` or `false`) - for Safari, IE, and Edge browsers only |
| `ALLOW_COOKIES` | [Optional] Allow all cookies (`true` or `false`) - for Safari browsers only |
| `SCREENSHOTS` | [Optional] Generate screenshots for debugging (`true` or `false`) |
| `NETWORK_LOGS` | [Optional] Capture network logs (`true` or `false`) |##### BrowserStack Desktop Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:browserstack`
- `browserName:` in the `capabilities:` hash must be set to name from capability in chart
- `browserVersion:` in the `capabilities:` hash must be set to browser version from capability in chart```ruby
options = {
driver: :browserstack,
capabilities: {
browserName: browser_name_from_chart,
browserVersion: browser_version_from_chart,
'bstack:options': {
userName: bs_account_user_name,
accessKey: bs_account_access_key,
os: os_name_from_chart,
osVersion: os_version_from_chart
}
}
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:browserstack_` - e.g. `:browserstack_chrome` or `:browserstack_safari`.
>
> ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
>
> `https://#{ENV['BS_USERNAME']}:#{ENV['BS_AUTHKEY']}@hub-cloud.browserstack.com/wd/hub`This default endpoint requires that the `BS_USERNAME` Environment Variable is set to your BrowserStack account user name and
the `BS_AUTHKEY` Environment Variable is set to your BrowserStack access key.Below is an example of an `options` hash for specifying a connection to the latest version of an Edge desktop web browser
running on macOS Sonoma hosted on BrowserStack. The `options` hash includes options for specifying the driver name, setting
the browser window size, and capabilities for setting screen resolution, geoLocation, time zone, Selenium version, and various
test configuration options.
```ruby
options = {
driver: :browserstack,
driver_name: :admin_user,
browser_size: [1400, 1100],
capabilities: {
browserName: 'Edge',
browserVersion: 'latest',
'bstack:options': {
userName: ENV['BS_USERNAME'],
accessKey: ENV['BS_AUTHKEY'],
projectName: 'ALP AP',
buildName: "Test Build #{ENV['BUILD_NUM']}",
sessionName: 'AU Regression Suite',
os: 'OS X',
osVersion: 'Sonoma',
resolution: '3840x2160',
local: 'false',
seleniumVersion: '4.15.0',
networkLogs: 'true',
geoLocation: 'AU',
timezone: 'Perth'
}
}
}
WebDriverConnect.initialize_web_driver(options)
```#### Remote Mobile Browsers on the BrowserStack Service
For remotely hosted mobile web browsers on the BrowserStack service, refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/docs/automate/capabilities)
for information regarding the options and capabilities available for the various supported mobile operating systems, devices,
and web browsers. Select the **Legacy** Integration method tab and the **W3C Protocol** tab on the capabilities page.##### BrowserStack Mobile Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
the following **Environment Variables** must be set as described in the table below.| **Environment Variable** | **Description** |
|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `DRIVER` | Must be set to `browserstack` |
| `BS_USERNAME` | Must be set to your BrowserStack account user name |
| `BS_AUTHKEY` | Must be set to your BrowserStack account access key |
| `BS_OS` | Must be set to `ios` or `android` |
| `BS_OS_VERSION` | Refer to `osVersion` capability in chart |
| `BS_BROWSER` | Must be set to `Safari` (for iOS) or `Chrome` (for Android) |
| `BS_DEVICE` | Refer to `deviceName` capability in chart |
| `BS_REAL_MOBILE` | Set to `true` if running against a real device |
| `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
| `TUNNELING` | [Optional] Must be `true` if you are testing against internal/local servers (`true` or `false`). If `true`, the BrowserStack Local instance will be automatically started. |
| `ORIENTATION` | [Optional] Set to `portrait` or `landscape` |
| `RECORD_VIDEO` | [Optional] Enable screen video recording during test execution (`true` or `false`) |
| `TIME_ZONE` | [Optional] Specify custom time zone. Refer to `browserstack.timezone` capability in chart |
| `IP_GEOLOCATION` | [Optional] Specify IP Geolocation. Refer to [IP Geolocation](https://www.browserstack.com/ip-geolocation) to select a country code. |
| `SCREENSHOTS` | [Optional] Generate screenshots for debugging (`true` or `false`) |
| `NETWORK_LOGS` | [Optional] Capture network logs (`true` or `false`) |
| `APPIUM_LOGS` | [Optional] Generate Appium logs (`true` or `false`) |##### BrowserStack Mobile Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:browserstack`
- `device_type:` must be set to `:tablet` or `:phone`
- `browserName:` in the `capabilities:` hash must be set to name from capability in chart```ruby
options = {
driver: :browserstack,
device_type: phone_or_tablet,
capabilities: {
browserName: browser_name_from_chart,
'bstack:options': {
userName: bs_account_user_name,
accessKey: bs_account_access_key,
osVersion: os_version_from_chart,
deviceName: device_name_from_chart
}
}
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:browserstack_` - e.g. `:browserstack_chrome` or `:browserstack_safari`.
>
> ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
>
> `https://#{ENV['BS_USERNAME']}:#{ENV['BS_AUTHKEY']}@hub-cloud.browserstack.com/wd/hub`This default endpoint requires that the `BS_USERNAME` Environment Variable is set to your BrowserStack account user name and
the `BS_AUTHKEY` Environment Variable is set to your BrowserStack access key.Below is an example of an `options` hash for specifying a connection to a mobile Samsung web browser running on an Android
tablet hosted on BrowserStack. The `options` hash includes options for specifying the driver name, and capabilities for setting
geoLocation, time zone, Appium version, and various test configuration options.
```ruby
options = {
driver: :browserstack,
driver_name: :admin_tablet,
capabilities: {
browserName: 'samsung',
device_type: :tablet,
'bstack:options': {
userName: ENV['BS_USERNAME'],
accessKey: ENV['BS_AUTHKEY'],
projectName: 'ALP AP',
buildName: "Test Build #{ENV['BUILD_NUM']}",
sessionName: 'AU Regression Suite',
os: 'android',
osVersion: '13.0',
deviceName: 'Samsung Galaxy Tab S9',
deviceOrientation: 'portrait',
appiumVersion: '1.22.0',
realMobile: 'true',
local: 'false',
networkLogs: 'true',
geoLocation: 'AU',
timezone: 'Perth'
}
}
}
WebDriverConnect.initialize_web_driver(options)
```#### Remote Desktop Browsers on the Sauce Labs Service
For remotely hosted desktop web browsers on the Sauce Labs service, refer to the [Platform Configurator page](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/)
for information regarding the options and capabilities available for the various supported desktop operating systems and
web browsers. Use the **Selenium 4** selection in the Config Script section of the Configurator page.##### Sauce Labs Desktop Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
the following **Environment Variables** must be set as described in the table below.| **Environment Variable** | **Description** |
|--------------------------|----------------------------------------------------------------------------------------------------------------------------|
| `DRIVER` | Must be set to `saucelabs` |
| `SL_USERNAME` | Must be set to your Sauce Labs account user name or email address |
| `SL_AUTHKEY` | Must be set to your Sauce Labs account access key |
| `SL_DATA_CENTER` | Must be set to your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`) |
| `SL_OS` | Refer to `platformName` capability in the Config Script section of the Platform Configurator page |
| `SL_BROWSER` | Must be set to `chrome`, `firefox`, `safari`, `internetExplorer`, or `MicrosoftEdge` |
| `SL_VERSION` | Refer to `browserVersion` capability in the Config Script section of the Platform Configurator page |
| `RESOLUTION` | [Optional] Refer to supported `screenResolution` capability in the Config Script section of the Platform Configurator page |
| `BROWSER_SIZE` | [Optional] Specify width, height of browser window |
| `RECORD_VIDEO` | [Optional] Enable screen video recording during test execution (`true` or `false`) |##### Sauce Labs Desktop Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:saucelabs`
- `browserName:` in the `capabilities:` hash must be set to name from capability in chart
- `browser_version:` in the `capabilities:` hash must be set to browser version from capability in chart```ruby
options = {
driver: :saucelabs,
capabilities: {
browserName: browser_name_from_chart,
browser_version: browser_version_from_chart,
platform_name: platform_name_from_chart,
'sauce:options': {
username: sl_account_user_name,
access_key: bs_account_access_key
}
}
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:saucelabs_` - e.g. `:saucelabs_chrome` or `:saucelabs_safari`.
>
> ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
>
> `https://#{ENV['SL_USERNAME']}:#{ENV['SL_AUTHKEY']}@ondemand.#{ENV['SL_DATA_CENTER']}.saucelabs.com:443/wd/hub`This default endpoint requires that the `SL_USERNAME` Environment Variable is set to your Sauce Labs account user name, the
`SL_AUTHKEY` Environment Variable is set to your Sauce Labs access key, and the `SL_DATA_CENTER` Environment Variable is
set to your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`).Below is an example of an `options` hash for specifying a connection to the latest version of an Edge desktop web browser
running on macOS Ventura hosted on Sauce Labs. The `options` hash includes options for specifying the driver name, setting
the browser window size, and capabilities for setting screen resolution, time zone, and various test configuration options.
```ruby
options = {
driver: :saucelabs,
driver_name: :admin_user,
browser_size: [1400, 1100],
capabilities: {
browserName: 'MicrosoftEdge',
browser_version: 'latest',
platform_name: 'macOS 13',
'sauce:options': {
username: ENV['SL_USERNAME'],
access_key: ENV['SL_AUTHKEY'],
name: 'ALP AP',
build: "Test Build #{ENV['BUILD_NUM']}",
screenResolution: '2048x1536',
timeZone: 'Perth',
maxDuration: 2400,
idleTimeout: 60
}
}
}
WebDriverConnect.initialize_web_driver(options)
```#### Remote Mobile Browsers on the Sauce Labs Service
For remotely hosted mobile web browsers on the Sauce Labs service, refer to the [Platform Configurator page](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/)
for information regarding the options and capabilities available for the various supported mobile operating systems, devices,
and web browsers.##### Sauce Labs Mobile Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
the following **Environment Variables** must be set as described in the table below.| **Environment Variable** | **Description** |
|--------------------------|-----------------------------------------------------------------------------------------------------------------|
| `DRIVER` | Must be set to `saucelabs` |
| `AUTOMATION_ENGINE` | Must be set to `XCUITest` or `UiAutomator2` |
| `SL_PLATFORM` | Must be set to `iOS` or `Android` |
| `SL_BROWSER` | Must be set to `Safari` or `Chrome` |
| `SL_VERSION` | Refer to `platformVersion` capability in the Config Script section of the Platform Configurator page |
| `SL_DEVICE` | Refer to `deviceName` capability in chart |
| `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
| `SL_USERNAME` | Must be set to your Sauce Labs account user name or email address |
| `SL_AUTHKEY` | Must be set to your Sauce Labs account access key |
| `SL_DATA_CENTER` | Must be set to your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`) |
| `ORIENTATION` | [Optional] Set to `PORTRAIT` or `LANDSCAPE` |##### Sauce Labs Mobile Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:saucelabs`
- `device_type:` must be set to `:tablet` or `:phone`
- `browserName:` in the `capabilities:` hash must be set to `browserName` from capability in chart
- `platform_name:` in the `capabilities:` hash must be set to `platform_name` from capability in chart
- `'appium:automationName':` must be set to `automationName` from capability in chart
- `'appium:platformVersion':` must be set to `platformVersion` from capability in chart
- `'appium:deviceName':` must be set to `deviceName` from capability in chart```ruby
options = {
driver: :saucelabs,
device_type: phone_or_tablet,
capabilities: {
browserName: browser_name_from_chart,
platform_name: platform_name_from_chart,
'appium:automationName': automationName_from_chart,
'appium:platformVersion': os_version_from_chart,
'appium:deviceName': device_name_from_chart,
'sauce:options': {
userName: bs_account_user_name,
accessKey: bs_account_access_key
}
}
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:saucelabs_` - e.g. `:saucelabs_chrome` or `:saucelabs_safari`.
>
> ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
>
> `https://#{ENV['SL_USERNAME']}:#{ENV['SL_AUTHKEY']}@ondemand.#{ENV['SL_DATA_CENTER']}.saucelabs.com:443/wd/hub`This default endpoint requires that the `SL_USERNAME` Environment Variable is set to your Sauce Labs account user name, the
`SL_AUTHKEY` Environment Variable is set to your Sauce Labs access key, and the `SL_DATA_CENTER` Environment Variable is
set to your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`).Below is an example of an `options` hash for specifying a connection to a mobile Safari web browser running on an iPad
tablet hosted on Sauce Labs. The `options` hash includes options for specifying the driver name, and capabilities for setting
device orientation, Appium version, and various test configuration options.
```ruby
options = {
driver: :saucelabs,
device_type: :tablet,
driver_name: :admin_tablet,
capabilities: {
browserName: 'Safari',
platform_name: 'iOS',
'appium:automationName': 'XCUITest',
'appium:platformVersion': '15.4',
'appium:deviceName': 'iPad Pro (12.9 inch) (5th generation) Simulator',
'sauce:options': {
username: ENV['SL_USERNAME'],
access_key: ENV['SL_AUTHKEY'],
name: 'ALP AP',
build: "Test Build #{ENV['BUILD_NUM']}",
deviceOrientation: 'PORTRAIT',
appiumVersion: '1.22.3'
}
}
}
WebDriverConnect.initialize_web_driver(options)
```#### Remote Desktop Browsers on the TestingBot Service
For remotely hosted desktop web browsers on the TestingBot service, refer to the [TestingBot List of Available Browsers page](https://testingbot.com/support/getting-started/browsers.html)
and the [TestingBot Automated Test Options page](https://testingbot.com/support/other/test-options) for information regarding the options and capabilities available for
the various supported desktop operating systems and web browsers.##### TestingBot Desktop Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
the following **Environment Variables** must be set as described in the table below.| **Environment Variable** | **Description** |
|--------------------------|--------------------------------------------------------------------------------------------------------------------|
| `DRIVER` | Must be set to `testingbot` |
| `TB_USERNAME` | Must be set to your TestingBot account user name |
| `TB_AUTHKEY` | Must be set to your TestingBot account access key |
| `TB_OS` | Refer to `platform` capability in chart |
| `TB_BROWSER` | Refer to `browserName` capability in chart |
| `TB_VERSION` | Refer to `version` capability in chart |
| `TUNNELING` | [Optional] Must be `true` if you are testing against internal/local servers (`true` or `false`) |
| `RESOLUTION` | [Optional] Refer to [Change Screen Resolution](https://testingbot.com/support/other/test-options#screenresolution) |
| `BROWSER_SIZE` | [Optional] Specify width, height of browser window |##### TestingBot Desktop Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:testingbot`
- `browserName:` in the `capabilities:` hash must be set to name from capability in chart
- `browser_version:` in the `capabilities:` hash must be set to browser version from capability in chart
- `platform_name:` in the `capabilities:` hash must be set to platform name from capability in chart```ruby
options = {
driver: :testingbot,
capabilities: {
browserName: browser_name_from_chart,
browser_version: browser_version_from_chart,
platform_name: platform_name_from_chart
}
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:testingbot_` - e.g. `:testingbot_chrome` or `:testingbot_microsoftedge`.
>
> ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
>
> `https://#{ENV['TB_USERNAME']}:#{ENV['TB_AUTHKEY']}@hub.testingbot.com/wd/hub`This default endpoint requires that the `TB_USERNAME` Environment Variable is set to your TestingBot account user name and
the `TB_AUTHKEY` Environment Variable is set to your TestingBot access key.Below is an example of an `options` hash for specifying a connection to the latest version of an Edge desktop web browser
running on macOS Sonoma hosted on TestingBot. The `options` hash includes options for specifying the driver name, setting
the browser window size, and capabilities for setting screen resolution, time zone, and various test configuration options.
```ruby
options = {
driver: :testingbot,
driver_name: :admin_user,
browser_size: [1400, 1100],
capabilities: {
browserName: 'microsoftedge',
browser_version: 'latest',
platform_name: 'SONOMA',
'tb:options': {
name: 'ALP AP',
build: "Test Build #{ENV['BUILD_NUM']}",
timeZone: 'Australia/Adelaide',
'testingbot.geoCountryCode': 'AU',
'screen-resolution': '2048x1536',
'selenium-version': '4.14.1'
}
}
}
WebDriverConnect.initialize_web_driver(options)
```#### Remote Mobile Browsers on the TestingBot Service
For remotely hosted mobile web browsers on the TestingBot service, refer to the [TestingBot List of Available Browsers page](https://testingbot.com/support/getting-started/browsers.html)
and the [TestingBot Automated Test Options page](https://testingbot.com/support/other/test-options) for information regarding the options and capabilities available for
the various supported mobile operating systems, devices, and web browsers.##### TestingBot Mobile Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
the following **Environment Variables** must be set as described in the table below.| **Environment Variable** | **Description** |
|--------------------------|-------------------------------------------------------------------------------------------------|
| `DRIVER` | Must be set to `testingbot` |
| `TB_USERNAME` | Must be set to your TestingBot account user name |
| `TB_AUTHKEY` | Must be set to your TestingBot account access key |
| `TB_PLATFORM` | Must be set to `iOS` or `ANDROID` |
| `TB_OS` | Must be set to `iOS` or `ANDROID` |
| `TB_BROWSER` | Must be set to `safari` (for iOS) or `chrome` (for Android) |
| `TB_VERSION` | Refer to `version` capability in chart |
| `TB_DEVICE` | Refer to `deviceName` capability in chart |
| `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
| `TUNNELING` | [Optional] Must be `true` if you are testing against internal/local servers (`true` or `false`) |
| `ORIENTATION` | [Optional] Set to `portrait` or `landscape` |##### TestingBot Mobile Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:testingbot`
- `device_type:` must be set to `:tablet` or `:phone`
- `browserName:` in the `capabilities:` hash must be set to `browserName` from capability in chart
- `platform_name:` in the `capabilities:` hash must be set to `platform_name` from capability in chart```ruby
options = {
driver: :testingbot,
device_type: phone_or_tablet,
capabilities: {
browserName: browser_name_from_chart,
platform_name: platform_name_from_chart,
browserVersion: os_version_from_chart,
'tb:options': {
deviceName: device_name_from_chart
}
}
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:testingbot_` - e.g. `:testingbot_chrome` or `:testingbot_safari`.
>
> ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
>
> `https://#{ENV['TB_USERNAME']}:#{ENV['TB_AUTHKEY']}@hub.testingbot.com/wd/hub`This default endpoint requires that the `TB_USERNAME` Environment Variable is set to your TestingBot account user name and
the `TB_AUTHKEY` Environment Variable is set to your TestingBot access key.Below is an example of an `options` hash for specifying a connection to a mobile Safari web browser running on an iPad
tablet hosted on TestingBot. The `options` hash includes options for specifying the driver name, and capabilities for setting
device orientation, Appium version, and various test configuration options.
```ruby
options = {
driver: :testingbot,
device_type: :tablet,
driver_name: :admin_tablet,
capabilities: {
browserName: 'safari',
browserVersion: '15.4',
platformName: 'iOS',
'tb:options': {
deviceName: 'iPad Pro (12.9-inch) (5th generation)',
name: 'ALP AP',
build: "Test Build #{ENV['BUILD_NUM']}",
orientation: 'LANDSCAPE'
}
}
}
WebDriverConnect.initialize_web_driver(options)
```#### Remote Desktop Browsers on the LambdaTest Service
For remotely hosted desktop web browsers on the LambdaTest service, refer to the Selenium 4 Configuration Wizard on the
[Selenium Desired Capabilities Generator](https://www.lambdatest.com/capabilities-generator/) for information regarding the options and capabilities available for the
various supported desktop operating systems and web browsers.##### LambdaTest Desktop Browser using Environment Variables
If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
the following **Environment Variables** must be set as described in the table below.| **Environment Variable** | **Description** |
|--------------------------|------------------------------------------------------------------------------------------|
| `DRIVER` | Must be set to `lambdatest` |
| `LT_USERNAME` | Must be set to your LambdaTest account user name or email address |
| `LT_AUTHKEY` | Must be set to your LambdaTest account access key |
| `LT_OS` | Refer to `platformName` capability in the sample script of the Wizard |
| `LT_BROWSER` | Refer to `browserName` capability in the sample script of the Wizard |
| `LT_VERSION` | Refer to `browserVersion` capability in chart |
| `RESOLUTION` | [Optional] Refer to supported `resolution` capability in the sample script of the Wizard |
| `BROWSER_SIZE` | [Optional] Specify width, height of browser window |
| `RECORD_VIDEO` | [Optional] Enable screen video recording during test execution (`true` or `false`) |
| `ALLOW_POPUPS` | [Optional] Allow popups (`true` or `false`) - for Safari, IE, and Edge browsers only |
| `ALLOW_COOKIES` | [Optional] Allow all cookies (`true` or `false`) - for Safari browsers only |
| `CONSOLE_LOGS` | [Optional] Used to capture browser console logs. |##### LambdaTest Desktop Browser in the `options` Hash
When using the `options` hash, the following options and capabilities must be specified:
- `driver:` must be set to `:lambdatest`
- `browserName:` in the `capabilities:` hash must be set to name from capability in chart
- `browserVersion:` in the `capabilities:` hash must be set to browser version from capability in chart```ruby
options = {
driver: :lambdatest,
capabilities: {
browserName: browser_name_from_chart,
browserVersion: browser_version_from_chart,
'LT:Options': {
username: lt_account_user_name,
accessKey: lt_account_access_key,
platformName: platformName_from_chart
}
}
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:lambdatest_` - e.g. `:lambdatest_chrome` or `:lambdatest_safari`.
>
ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
>
> `https://#{ENV['LT_USERNAME']}:#{ENV['LT_AUTHKEY']}@hub.lambdatest.com/wd/hub`This default endpoint requires that the `LT_USERNAME` Environment Variable is set to your LambdaTest account user name and
the `LT_AUTHKEY` Environment Variable is set to your LambdaTest access key.Below is an example of an `options` hash for specifying a connection to the latest version of an Edge desktop web browser
running on macOS Sonoma hosted on LambdaTest. The `options` hash includes options for specifying the driver name, setting
the browser window size, and capabilities for setting screen resolution, geoLocation, time zone, Selenium version, and various
test configuration options.
```ruby
options = {
driver: :lambdatest,
driver_name: :admin_user,
browser_size: [1400, 1100],
capabilities: {
browserName: 'MicrosoftEdge',
browserVersion: '119.0',
'LT:Options': {
platformName: 'macOS Sonoma',
username: ENV['LT_USERNAME'],
accessKey: ENV['LT_AUTHKEY'],
project: 'ALP AP',
build: "Test Build #{ENV['BUILD_NUM']}",
resolution: '2560x1440',
selenium_version: '4.13.0',
networkLogs: 'true',
geoLocation: 'AU',
timezone: 'Adelaide',
console: 'info',
network: true
}
}
}
WebDriverConnect.initialize_web_driver(options)
```#### Remote Browsers on Unsupported Cloud Hosting Services
Limited support is provided for executing automated tests against remotely hosted desktop and mobile web browsers on currently
unsupported cloud hosting services. You must call the `TestCentricity::WebDriverConnect.initialize_web_driver` method with
an `options` hash - Environment Variables cannot be used to specify a user-defined custom WebDriver instance.The following options and capabilities must be specified:
- `driver:` must be set to `:custom`
- `endpoint:` must be set to the endpoint URL configuration specified by the hosting service
- `browserName:` in the `capabilities:` hash must be set to name from capability specified by the hosting serviceAll other required capabilities specified by the hosting service configuration documentation should be included in the
`capabilities:` hash.
```ruby
options = {
driver: :custom,
endpoint: endpoint_url,
capabilities: { browserName: browser_name_from_chart }
}
WebDriverConnect.initialize_web_driver(options)
```
> ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
`:custom_` - e.g. `:custom_chrome` or `:custom_safari`.Prior to calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method, you must set `Environ.platform` to
either `:desktop` or `:mobile`, and `Environ.device` to either `:web` or `:device` dependent on whether the target browser
is a desktop browser or a mobile browser running on a mobile device or simulator.Below is an example for specifying a connection to a Firefox desktop web browser on an unsupported hosting service:
```ruby
# specify desktop platform
Environ.platform = :desktop
Environ.device = :web
# instantiate a cloud hosted desktop web browser on an unsupported hosting service
options = {
driver: :custom,
driver_name: :user_defined,
browser_size: [1400, 1100],
endpoint: endpoint_url,
capabilities: {
browserName: 'Firefox',
browser_version: browser_version_from_chart
# other capabilities go here
}
}
WebDriverConnect.initialize_web_driver(options)
```
Below is an example for specifying a connection to a mobile Safari web browser running on an iPad on an unsupported hosting
service:
```ruby
# specify mobile platform, device type, and device name
Environ.platform = :mobile
Environ.device = :device
Environ.device_name = device_name_from_chart
# instantiate a cloud hosted mobile browser on a device on an unsupported hosting service
options = {
driver: :custom,
driver_name: :user_defined,
device_type: :tablet,
endpoint: endpoint_url,
capabilities: {
browserName: 'Safari',
# other capabilities go here
}
}
WebDriverConnect.initialize_web_driver(options)
```### Closing Browser and Driver Instances
#### Closing Instances Using Cucumber
To close all browser and driver instances upon completion of your automated Cucumber features, place the code shown below
in your `hooks.rb` file:
```ruby
AfterAll do
# terminate all driver instances
WebDriverConnect.close_all_drivers
end
```#### Closing Instances Using RSpec
To close all browser and driver instances upon completion of an automated spec, place the code shown below in the body
of an example group:
```ruby
after(:each) do
# terminate all driver instances
WebDriverConnect.close_all_drivers
end
```### Using Browser Specific Profiles in `cucumber.yml`
While you can set **Environment Variables** in the command line when invoking Cucumber, a preferred method of specifying and
managing target web browsers is to create browser specific **Profiles** that set the appropriate **Environment Variables**
for each target browser in your `cucumber.yml` file.Below is a list of Cucumber **Profiles** for supported locally and remotely hosted desktop and mobile web browsers (put
these in in your`cucumber.yml` file). Before you can use the BrowserStack, SauceLabs, TestingBot or LambdaTest services,
you will need to replace the *INSERT USER NAME HERE* and *INSERT PASSWORD HERE* placeholder text with your user account
and authorization code for the cloud service(s) that you intend to connect with.> ⚠️ Cloud service credentials should not be stored as text in your `cucumber.yml` file where it can be exposed by anyone
with access to your version control system.<% desktop = "--tags @desktop --require features BROWSER_TILE=true BROWSER_SIZE=1500,1000" %>
<% tablet = "--tags @desktop --require features BROWSER_TILE=true" %>
<% mobile = "--tags @mobile --require features BROWSER_TILE=true" %>#==============
# profiles for locally hosted desktop web browsers
#==============firefox: WEB_BROWSER=firefox <%= desktop %>
chrome: WEB_BROWSER=chrome <%= desktop %>
edge: WEB_BROWSER=edge <%= desktop %>
safari: WEB_BROWSER=safari <%= desktop %>firefox_headless: WEB_BROWSER=firefox_headless <%= desktop %>
chrome_headless: WEB_BROWSER=chrome_headless <%= desktop %>
edge_headless: WEB_BROWSER=edge_headless <%= desktop %>#==============
# profiles for locally hosted mobile web browsers (emulated locally in Chrome browser)
#==============iphone_11: WEB_BROWSER=iphone_11 <%= mobile %>
iphone_11_pro: WEB_BROWSER=iphone_11_pro <%= mobile %>
iphone_11_pro_max: WEB_BROWSER=iphone_11_pro_max <%= mobile %>
iphone_12_mini: WEB_BROWSER=iphone_12_mini <%= mobile %>
iphone_12: WEB_BROWSER=iphone_12 <%= mobile %>
iphone_12_pro: WEB_BROWSER=iphone_12_pro <%= mobile %>
iphone_12_pro_max: WEB_BROWSER=iphone_12_pro_max <%= mobile %>
iphone_13_mini: WEB_BROWSER=iphone_13_mini <%= mobile %>
iphone_13: WEB_BROWSER=iphone_13 <%= mobile %>
iphone_13_pro: WEB_BROWSER=iphone_13_pro <%= mobile %>
iphone_13_pro_max: WEB_BROWSER=iphone_13_pro_max <%= mobile %>
iphone_se: WEB_BROWSER=iphone_se <%= mobile %>
iphone_14: WEB_BROWSER=iphone_14 <%= mobile %>
iphone_14_plus: WEB_BROWSER=iphone_14_plus <%= mobile %>
iphone_14_pro: WEB_BROWSER=iphone_14_pro <%= mobile %>
iphone_14_pro_max: WEB_BROWSER=iphone_14_pro_max <%= mobile %>
ipad: WEB_BROWSER=ipad <%= tablet %>
ipad_mini: WEB_BROWSER=ipad_mini <%= tablet %>
ipad_air: WEB_BROWSER=ipad_air <%= tablet %>
ipad_pro_11: WEB_BROWSER=ipad_pro_11 <%= tablet %>
ipad_pro_12_9: WEB_BROWSER=ipad_pro_12_9 <%= tablet %>
pixel_5: WEB_BROWSER=pixel_5 <%= mobile %>
pixel_6: WEB_BROWSER=pixel_6 <%= mobile %>
pixel_xl: WEB_BROWSER=pixel_xl <%= mobile %>
windows_phone7: WEB_BROWSER=windows_phone7 <%= mobile %>
windows_phone8: WEB_BROWSER=windows_phone8 <%= mobile %>
lumia_950_xl: WEB_BROWSER=lumia_950_xl <%= mobile %>
blackberry_z10: WEB_BROWSER=blackberry_z10 <%= mobile %>
blackberry_z30: WEB_BROWSER=blackberry_z30 <%= mobile %>
blackberry_leap: WEB_BROWSER=blackberry_leap <%= mobile %>
blackberry_passport: WEB_BROWSER=blackberry_passport <%= mobile %>
pixel_c: WEB_BROWSER=pixel_c <%= tablet %>
nexus_10: WEB_BROWSER=nexus_10 <%= tablet %>
kindle_fire: WEB_BROWSER=kindle_fire <%= tablet %>
kindle_firehd7: WEB_BROWSER=kindle_firehd7 <%= tablet %>
kindle_firehd8: WEB_BROWSER=kindle_firehd8 <%= tablet %>
kindle_firehd10: WEB_BROWSER=kindle_firehd10 <%= tablet %>
surface: WEB_BROWSER=surface <%= tablet %>
blackberry_playbook: WEB_BROWSER=blackberry_playbook <%= tablet %>#==============
# profiles for mobile device screen orientation
#==============portrait: ORIENTATION=portrait
landscape: ORIENTATION=landscape#==============
# profile to start Appium Server prior to running mobile browser tests on iOS or Android simulators or physical devices
#==============run_appium: APPIUM_SERVER=run
appium_1x: APPIUM_SERVER_VERSION=1#==============
# profiles for mobile Safari web browsers hosted within XCode iOS simulator
# NOTE: Requires installation of XCode, iOS version specific target simulators, and Appium
#==============appium_ios: DRIVER=appium AUTOMATION_ENGINE=XCUITest APP_PLATFORM_NAME="ios" APP_BROWSER="Safari" NEW_COMMAND_TIMEOUT=30 SHOW_SIM_KEYBOARD=false
app_ios_15: --profile appium_ios APP_VERSION="15.4"
ipad_pro_12_15_sim: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (12.9-inch) (5th generation)"
ipad_air_15_sim: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad Air (5th generation)" <%= desktop %>
ipad_15_sim: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad (9th generation)"#==============
# profiles for mobile Safari web browsers running on physically connected iOS devices
# NOTE: Requires installation of XCode and Appium
#==============my_ios_15_iphone: --profile app_ios_15 DEVICE_TYPE=phone APP_DEVICE="My Test iPhoneX" UDID="INSERT YOUR DEVICE UDID"
my_ios_15_ipad: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="My Test iPad Pro" UDID="INSERT YOUR DEVICE UDID"#==============
# profiles for Android mobile web browsers hosted within Android Studio Android Virtual Device emulators
# NOTE: Requires installation of Android Studio, Android version specific virtual device simulators, and Appium
#==============appium_android: DRIVER=appium APP_PLATFORM_NAME="Android" <%= mobile %>
app_android_12: --profile appium_android APP_BROWSER="Chrome" APP_VERSION="12.0"
pixel_c_api31_sim: --profile app_android_12 DEVICE_TYPE=tablet APP_DEVICE="Pixel_C_API_31"#==============
# profiles for remotely hosted web browsers on the BrowserStack service
# WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with
# access to your version control system
#==============browserstack: DRIVER=browserstack BS_USERNAME="" BS_AUTHKEY=""
bs_desktop: --profile browserstack <%= desktop %> RESOLUTION="1920x1080"
bs_mobile: --profile browserstack <%= mobile %># BrowserStack macOS desktop browser profiles
bs_macos_sonoma: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="Sonoma"
bs_chrome_sonoma: --profile bs_macos_sonoma BS_BROWSER="Chrome" BS_VERSION="latest"
bs_edge_sonoma: --profile bs_macos_sonoma BS_BROWSER="Edge" BS_VERSION="latest"
bs_safari_sonoma: --profile bs_macos_sonoma BS_BROWSER="Safari" BS_VERSION="latest"# BrowserStack Windows desktop browser profiles
bs_win11: --profile bs_desktop BS_OS="Windows" BS_OS_VERSION="11"
bs_chrome_win11: --profile bs_win11 BS_BROWSER="Chrome" BS_VERSION="latest"
bs_edge_win11: --profile bs_win11 BS_BROWSER="Edge" BS_VERSION="latest"
bs_win10: --profile bs_desktop BS_OS="Windows" BS_OS_VERSION="10"
bs_ie_win10: --profile bs_win10 BS_BROWSER="IE" BS_VERSION="11.0"# BrowserStack iOS mobile browser profiles
bs_ipad: --profile bs_mobile BS_OS=ios BS_BROWSER=Safari DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
bs_ipad_pro_12: --profile bs_ipad BS_DEVICE="iPad Pro 12.9 2018" BS_OS_VERSION="15"# BrowserStack Android mobile browser profiles
bs_android: --profile bs_mobile BS_OS=android BS_BROWSER=Chrome DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
bs_android_tablet: --profile bs_android BS_DEVICE="Samsung Galaxy Tab S7" BS_OS_VERSION="10.0"#==============
# profiles for remotely hosted web browsers on the SauceLabs service
# WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with
# access to your version control system
#==============saucelabs: DRIVER=saucelabs SL_USERNAME="" SL_AUTHKEY="" SL_DATA_CENTER="
sl_mobile: --profile saucelabs <%= mobile %># SauceLabs macOS desktop browser profiles
sl_macos_ventura: --profile sl_desktop SL_OS="macOS 13" RESOLUTION="1920x1440"
sl_chrome_ventura: --profile sl_macos_ventura SL_BROWSER="chrome" SL_VERSION="latest"
sl_edge_ventura: --profile sl_macos_ventura SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
sl_firefox_ventura: --profile sl_macos_ventura SL_BROWSER="Firefox" SL_VERSION="latest"# SauceLabs Windows desktop browser profiles
sl_windows: --profile sl_desktop RESOLUTION="1920x1200"
sl_edge_win11: --profile sl_windows SL_OS="Windows 11" SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
sl_ie_win10: --profile sl_windows SL_OS="Windows 10" SL_BROWSER="internet explorer" SL_VERSION="11"# SauceLabs iOS mobile browser profiles
sl_ipad: --profile sl_mobile DEVICE_TYPE=tablet SL_PLATFORM=iOS SL_BROWSER=Safari
sl_ipad_pro_12: --profile sl_ipad SL_DEVICE="iPad Pro (12.9 inch) (5th generation) Simulator" SL_VERSION="15.0"#==============
# profiles for remotely hosted web browsers on the TestingBot service
# WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with
# access to your version control system
#==============testingbot: DRIVER=testingbot TB_USERNAME="" TB_AUTHKEY=""
tb_desktop: --profile testingbot <%= desktop %> RESOLUTION="1920x1200"# TestingBot macOS desktop browser profiles
tb_macos_sonoma: --profile tb_desktop TB_OS="SONOMA"
tb_chrome_sonoma: --profile tb_macos_sonoma TB_BROWSER="chrome" TB_VERSION="latest"
tb_edge_sonoma: --profile tb_macos_sonoma TB_BROWSER="microsoftedge" TB_VERSION="latest"# TestingBot Windows desktop browser profiles
tb_win11: --profile tb_desktop TB_OS="WIN11"
tb_edge_win11: --profile tb_win11 TB_BROWSER="microsoftedge" TB_VERSION="latest"
tb_win10: --profile tb_desktop TB_OS="WIN10"
tb_ie_win10: --profile tb_win10 TB_BROWSER="internet explorer" TB_VERSION="11"#==============
# profiles for remotely hosted web browsers on the LambdaTest service
# WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with
# access to your version control system
#==============lambdatest: DRIVER=lambdatest LT_USERNAME= LT_AUTHKEY=
lt_desktop: --profile lambdatest <%= desktop %> RESOLUTION="2560x1440"# LambdaTest macOS desktop browser profiles
lt_macos_monterey: --profile lt_desktop LT_OS="MacOS Monterey"
lt_chrome_monterey: --profile lt_macos_monterey LT_BROWSER="Chrome" LT_VERSION="98.0"
lt_edge_monterey: --profile lt_macos_monterey LT_BROWSER="MicrosoftEdge" LT_VERSION="97.0"# LambdaTest Windows desktop browser profiles
lt_win11: --profile lt_desktop LT_OS="Windows 11"
lt_edge_win11: --profile lt_win11 LT_BROWSER="MicrosoftEdge" LT_VERSION="98.0"
lt_win10: --profile lt_desktop LT_OS="Windows 10"
lt_i0_win11: --profile lt_win10 LT_BROWSER="Internet Explorer" LT_VERSION="11.0"To specify a locally hosted target browser using a profile at runtime, you use the flag `--profile` or `-p` followed by the
profile name when invoking Cucumber in the command line. For instance, the following command invokes Cucumber and specifies
that a local instance of Firefox will be used as the target web browser:
cucumber -p firefoxThe following command specifies that Cucumber will run tests against an instance of Chrome hosted within a Dockerized Selenium
Grid 4 environment:
cucumber -p chrome -p gridThe following command specifies that Cucumber will run tests against a local instance of Chrome, which will be used to emulate
an iPad Pro in landscape orientation:
cucumber -p ipad_pro -p landscapeThe following command specifies that Cucumber will run tests against an iPad Pro (12.9-inch) (5th generation) with iOS version
15.4 in an XCode Simulator in landscape orientation:
cucumber -p ipad_pro_12_15_sim -p landscape
⚠️ Appium must be running prior to executing this commandYou can ensure that Appium Server is running by including `-p run_appium` in your command line:
cucumber -p ipad_pro_12_15_sim -p landscape -p run_appium
If you are running locally hosted mobile web tests using version 1.x of Appium server, you must include `-p appium_1x` in
your command line:cucumber -p ipad_pro_12_15_sim -p landscape -p run_appium -p appium_1x
The following command specifies that Cucumber will run tests against a remotely hosted Safari web browser running on a macOS
Sonoma virtual machine on the BrowserStack service:cucumber -p bs_safari_sonoma
---
## Recommended Project Organization and StructureBelow is an example of the project structure of a typical Cucumber based test automation framework with a Page Object Model
architecture. `PageObject` class definitions should be stored in the `/features/support/pages` folder, organized in functional
area sub-folders as needed. Likewise, `PageSection` class definitions should be stored in the `/features/support/sections` folder.📁 my_automation_project/
├── 📁 config/
│ ├── 📁 locales/
│ ├── 📁 test_data/
│ └── 📄 cucumber.yml
├── 📁 downloads/
├── 📁 features/
│ ├── 📁 step_definitions/
│ └── 📁 support/
│ ├── 📁 pages/
│ ├── 📁 sections/
│ ├── 📄 env.rb
│ ├── 📄 hooks.rb
│ └── 📄 world_pages.rb
├── 📄 Gemfile
└── 📄 README.md---
## Web Test Automation Framework Implementation![TestCentricity For Web Framework Overview](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/tc_overview.jpg "TestCentricity For Web Framework Overview")
---
## Copyright and LicenseTestCentricity™ Framework is Copyright (c) 2014-2024, Tony Mrozinski.
All rights reserved.Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
conditions are met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the distribution.3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.