testcentricity_web 4.1.2.1 → 4.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -2
- data/Gemfile.lock +1 -1
- data/README.md +471 -250
- data/lib/testcentricity_web/appium_server.rb +2 -2
- data/lib/testcentricity_web/version.rb +1 -1
- data/lib/testcentricity_web/web_core/webdriver_helper.rb +78 -120
- data/lib/testcentricity_web/web_elements/select_list.rb +10 -7
- metadata +2 -2
    
        data/README.md
    CHANGED
    
    | @@ -3,14 +3,12 @@ | |
| 3 3 | 
             
            [](https://badge.fury.io/rb/testcentricity_web)  [](http://opensource.org/licenses/BSD-3-Clause)
         | 
| 4 4 |  | 
| 5 5 |  | 
| 6 | 
            -
            The TestCentricity™ Web core generic framework for desktop and mobile web browser-based app testing implements a Page Object  | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
            **An example project that demonstrates the implementation of a page object model framework using Cucumber and TestCentricity™ can be found [here](https://github.com/TestCentricity/tc_web_sample).**
         | 
| 6 | 
            +
            The TestCentricity™ Web core generic framework for desktop and mobile web browser-based app testing implements a Page Object Model DSL
         | 
| 7 | 
            +
            for use with Cucumber, Capybara (version 3.x), and Selenium-Webdriver (version 4.x). It also facilitates the configuration of the appropriate
         | 
| 8 | 
            +
            Selenium-Webdriver capabilities required to establish a connection with a local or cloud hosted desktop or mobile web browser.
         | 
| 10 9 |  | 
| 11 10 | 
             
            The TestCentricity™ Web gem supports running automated tests against the following web test targets:
         | 
| 12 | 
            -
            * locally hosted desktop browsers ( | 
| 13 | 
            -
            * locally hosted emulated iOS Mobile Safari, Android, Windows Phone, or Blackberry mobile browsers (running within a local instance of Chrome)
         | 
| 11 | 
            +
            * locally hosted desktop browsers (Chrome, Edge, Firefox, Safari, or IE)
         | 
| 14 12 | 
             
            * locally hosted "headless" Chrome, Firefox, or Edge browsers
         | 
| 15 13 | 
             
            * remote desktop and emulated mobile web browsers hosted on Selenium Grid 4 and Dockerized Selenium Grid 4 environments
         | 
| 16 14 | 
             
            * mobile Safari browsers on iOS device simulators or physical iOS devices (using Appium and XCode on OS X)
         | 
| @@ -22,16 +20,20 @@ The TestCentricity™ Web gem supports running automated tests against the follo | |
| 22 20 | 
             
              * [LambdaTest](https://www.lambdatest.com/selenium-automation)
         | 
| 23 21 | 
             
            * web portals utilizing JavaScript front end application frameworks like Ember, React, Angular, and GWT
         | 
| 24 22 | 
             
            * web pages containing HTML5 Video and Audio objects
         | 
| 23 | 
            +
            * locally hosted emulated iOS Mobile Safari, Android, Windows Phone, or Blackberry mobile browsers (running within a local instance of Chrome)
         | 
| 25 24 |  | 
| 26 25 |  | 
| 27 26 | 
             
            ## What's New
         | 
| 28 27 |  | 
| 29 28 | 
             
            A complete history of bug fixes and new features can be found in the {file:CHANGELOG.md CHANGELOG} file.
         | 
| 30 29 |  | 
| 30 | 
            +
            An example project that demonstrates the implementation of a page object model framework using Cucumber and TestCentricity™
         | 
| 31 | 
            +
            can be found [here](https://github.com/TestCentricity/tc_web_sample).
         | 
| 32 | 
            +
             | 
| 31 33 |  | 
| 32 34 | 
             
            ## Installation
         | 
| 33 35 |  | 
| 34 | 
            -
            TestCentricity requires Ruby 2.7 or later. To install the TestCentricity gem, add this line to your automation project's Gemfile:
         | 
| 36 | 
            +
            TestCentricity version 4.1 and above requires Ruby 2.7 or later. To install the TestCentricity gem, add this line to your automation project's Gemfile:
         | 
| 35 37 |  | 
| 36 38 | 
             
                gem 'testcentricity_web'
         | 
| 37 39 |  | 
| @@ -47,7 +49,7 @@ Or install it yourself as: | |
| 47 49 | 
             
            ## Setup
         | 
| 48 50 | 
             
            ### Using Cucumber
         | 
| 49 51 |  | 
| 50 | 
            -
            If you are using Cucumber, you need to require the following in your  | 
| 52 | 
            +
            If you are using Cucumber, you need to require the following in your `env.rb` file:
         | 
| 51 53 |  | 
| 52 54 | 
             
                require 'capybara/cucumber'
         | 
| 53 55 | 
             
                require 'testcentricity_web'
         | 
| @@ -55,7 +57,7 @@ If you are using Cucumber, you need to require the following in your *env.rb* fi | |
| 55 57 |  | 
| 56 58 | 
             
            ### Using RSpec
         | 
| 57 59 |  | 
| 58 | 
            -
            If you are using RSpec instead, you need to require the following in your  | 
| 60 | 
            +
            If you are using RSpec instead, you need to require the following in your `env.rb` file:
         | 
| 59 61 |  | 
| 60 62 | 
             
                require 'capybara'
         | 
| 61 63 | 
             
                require 'capybara/rspec'
         | 
| @@ -65,7 +67,7 @@ If you are using RSpec instead, you need to require the following in your *env.r | |
| 65 67 | 
             
            ### Using Appium
         | 
| 66 68 |  | 
| 67 69 | 
             
            If you will be running your tests on mobile Safari browsers on simulated iOS devices using Appium and XCode Simulators, you need to require
         | 
| 68 | 
            -
            the following in your  | 
| 70 | 
            +
            the following in your `env.rb` file:
         | 
| 69 71 |  | 
| 70 72 | 
             
                require 'appium_capybara'
         | 
| 71 73 |  | 
| @@ -78,7 +80,7 @@ And then execute: | |
| 78 80 | 
             
                $ bundle
         | 
| 79 81 |  | 
| 80 82 |  | 
| 81 | 
            -
            ##  | 
| 83 | 
            +
            ## PageObjects
         | 
| 82 84 |  | 
| 83 85 | 
             
            The **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
         | 
| 84 86 | 
             
            in tests. A **Page Object** is an object that represents a single page in your AUT (Application Under Test). **Page Objects** encapsulate the
         | 
| @@ -87,14 +89,14 @@ implementation details of a web page and expose an API that supports interaction | |
| 87 89 | 
             
            **Page Objects** makes it easier to maintain automated tests because changes to page UI elements are updated in only one location - in the
         | 
| 88 90 | 
             
            **Page Object** class definition. By adopting a **Page Object Model**, Cucumber Feature files and step definitions are no longer required to
         | 
| 89 91 | 
             
            hold specific information about a page's UI objects, thus minimizing maintenance requirements. If any element on, or property of a page changes
         | 
| 90 | 
            -
            (URL path, text field attributes, button captions, etc.), maintenance is performed in the  | 
| 92 | 
            +
            (URL path, text field attributes, button captions, etc.), maintenance is performed in the `PageObject` class definition only, typically with
         | 
| 91 93 | 
             
            no need to update the affected feature file, scenarios, or step definitions.
         | 
| 92 94 |  | 
| 93 95 |  | 
| 94 | 
            -
            ### Defining a  | 
| 96 | 
            +
            ### Defining a PageObject
         | 
| 95 97 |  | 
| 96 | 
            -
            Your  | 
| 97 | 
            -
            test automation project. You define new  | 
| 98 | 
            +
            Your `PageObject` class definitions should be contained within individual `.rb` files in the `features/support/pages` folder of your
         | 
| 99 | 
            +
            test automation project. You define new `PageObjects` as shown below:
         | 
| 98 100 |  | 
| 99 101 | 
             
                class LoginPage < TestCentricity::PageObject
         | 
| 100 102 | 
             
                end
         | 
| @@ -108,14 +110,14 @@ test automation project. You define new **Page Objects** as shown below: | |
| 108 110 | 
             
                end
         | 
| 109 111 |  | 
| 110 112 |  | 
| 111 | 
            -
            ### Adding Traits to your  | 
| 113 | 
            +
            ### Adding Traits to your PageObject
         | 
| 112 114 |  | 
| 113 115 | 
             
            Web pages typically have names and URLs associated with them. Web pages also typically have a unique object or attribute that, when present,
         | 
| 114 116 | 
             
            indicates that the page's contents have fully loaded.
         | 
| 115 117 |  | 
| 116 | 
            -
            The `page_name` trait is registered with the  | 
| 117 | 
            -
            parameter and returns an instance of the associated  | 
| 118 | 
            -
            trait for each  | 
| 118 | 
            +
            The `page_name` trait is registered with the `PageManager` object, which includes a `find_page` method that takes a page name as a
         | 
| 119 | 
            +
            parameter and returns an instance of the associated `Page Object`. If you intend to use the `PageManager`, you must define a `page_name`
         | 
| 120 | 
            +
            trait for each `PageObject` to be registered.
         | 
| 119 121 |  | 
| 120 122 | 
             
            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.
         | 
| 121 123 | 
             
            `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
         | 
| @@ -133,36 +135,36 @@ for the `page_locator` trait to exist. | |
| 133 135 | 
             
            You define your page's **Traits** as shown below:
         | 
| 134 136 |  | 
| 135 137 | 
             
                class LoginPage < TestCentricity::PageObject
         | 
| 136 | 
            -
                  trait(:page_name) | 
| 137 | 
            -
                  trait(:page_url) | 
| 138 | 
            -
                  trait(:page_locator) | 
| 138 | 
            +
                  trait(:page_name)    { 'Login' }
         | 
| 139 | 
            +
                  trait(:page_url)     { '/sign_in' }
         | 
| 140 | 
            +
                  trait(:page_locator) { 'body.login-body' }
         | 
| 139 141 | 
             
                end
         | 
| 140 142 |  | 
| 141 143 |  | 
| 142 144 | 
             
                class HomePage < TestCentricity::PageObject
         | 
| 143 145 | 
             
                  # this page may be referred to as 'Home' or 'Dashboard' page so page_name trait is an Array of Strings
         | 
| 144 | 
            -
                  trait(:page_name) | 
| 145 | 
            -
                  trait(:page_url) | 
| 146 | 
            -
                  trait(:page_locator) | 
| 146 | 
            +
                  trait(:page_name)    { ['Home', 'Dashboard'] }
         | 
| 147 | 
            +
                  trait(:page_url)     { '/dashboard' }
         | 
| 148 | 
            +
                  trait(:page_locator) { 'body.dashboard' }
         | 
| 147 149 | 
             
                end
         | 
| 148 150 |  | 
| 149 151 |  | 
| 150 152 | 
             
                class RegistrationPage < TestCentricity::PageObject
         | 
| 151 | 
            -
                  trait(:page_name) | 
| 152 | 
            -
                  trait(:page_url) | 
| 153 | 
            -
                  trait(:page_locator) | 
| 153 | 
            +
                  trait(:page_name)    { 'Registration' }
         | 
| 154 | 
            +
                  trait(:page_url)     { '/register' }
         | 
| 155 | 
            +
                  trait(:page_locator) { 'body.registration' }
         | 
| 154 156 | 
             
                end
         | 
| 155 157 |  | 
| 156 158 |  | 
| 157 | 
            -
            ### Adding UI Elements to your  | 
| 159 | 
            +
            ### Adding UI Elements to your PageObject
         | 
| 158 160 |  | 
| 159 161 | 
             
            Web pages are made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists, buttons, etc.
         | 
| 160 | 
            -
            **UI Elements** are added to your  | 
| 162 | 
            +
            **UI Elements** are added to your `PageObject` class definition as shown below:
         | 
| 161 163 |  | 
| 162 164 | 
             
                class LoginPage < TestCentricity::PageObject
         | 
| 163 | 
            -
                  trait(:page_name) | 
| 164 | 
            -
                  trait(:page_url) | 
| 165 | 
            -
                  trait(:page_locator) | 
| 165 | 
            +
                  trait(:page_name)    { 'Login' }
         | 
| 166 | 
            +
                  trait(:page_url)     { '/sign_in' }
         | 
| 167 | 
            +
                  trait(:page_locator) { 'body.login-body' }
         | 
| 166 168 |  | 
| 167 169 | 
             
                  # Login page UI elements
         | 
| 168 170 | 
             
                  textfield :user_id_field,       'input#userName'
         | 
| @@ -174,9 +176,9 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes, | |
| 174 176 |  | 
| 175 177 |  | 
| 176 178 | 
             
                class RegistrationPage < TestCentricity::PageObject
         | 
| 177 | 
            -
                  trait(:page_name) | 
| 178 | 
            -
                  trait(:page_url) | 
| 179 | 
            -
                  trait(:page_locator) | 
| 179 | 
            +
                  trait(:page_name)    { 'Registration' }
         | 
| 180 | 
            +
                  trait(:page_url)     { '/register' }
         | 
| 181 | 
            +
                  trait(:page_locator) { 'body.registration' }
         | 
| 180 182 |  | 
| 181 183 | 
             
                  # Registration page UI elements
         | 
| 182 184 | 
             
                  textfields  first_name_field:    'input#firstName',
         | 
| @@ -196,16 +198,16 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes, | |
| 196 198 | 
             
                end
         | 
| 197 199 |  | 
| 198 200 |  | 
| 199 | 
            -
            ### Adding Methods to your  | 
| 201 | 
            +
            ### Adding Methods to your PageObject
         | 
| 200 202 |  | 
| 201 | 
            -
            It is good practice for your Cucumber step definitions to call high level methods in your your  | 
| 202 | 
            -
            and interacting with a page object's UI elements. You can add high level methods to your  | 
| 203 | 
            +
            It is good practice for your Cucumber step definitions to call high level methods in your your `PageObject` instead of directly accessing
         | 
| 204 | 
            +
            and interacting with a page object's UI elements. You can add high level methods to your `PageObject` class definition for interacting with
         | 
| 203 205 | 
             
            the UI to hide implementation details, as shown below:
         | 
| 204 206 |  | 
| 205 207 | 
             
                class LoginPage < TestCentricity::PageObject
         | 
| 206 | 
            -
                  trait(:page_name) | 
| 207 | 
            -
                  trait(:page_url) | 
| 208 | 
            -
                  trait(:page_locator) | 
| 208 | 
            +
                  trait(:page_name)    { 'Login' }
         | 
| 209 | 
            +
                  trait(:page_url)     { '/sign_in' }
         | 
| 210 | 
            +
                  trait(:page_locator) { 'body.login-body' }
         | 
| 209 211 |  | 
| 210 212 | 
             
                  # Login page UI elements
         | 
| 211 213 | 
             
                  textfield :user_id_field,        'input#userName'
         | 
| @@ -232,9 +234,9 @@ the UI to hide implementation details, as shown below: | |
| 232 234 | 
             
                    ui = {
         | 
| 233 235 | 
             
                        self                 => { title: 'Login' },
         | 
| 234 236 | 
             
                        login_button         => { visible: true, caption: 'LOGIN' },
         | 
| 235 | 
            -
                        user_id_field        => { visible: true, enabled: true },
         | 
| 237 | 
            +
                        user_id_field        => { visible: true, enabled: true, value: '', placeholder: 'User name' },
         | 
| 236 238 | 
             
                        password_field       => { visible: true, enabled: true, value: '', placeholder: 'Password' },
         | 
| 237 | 
            -
                        remember_checkbox    => { : | 
| 239 | 
            +
                        remember_checkbox    => { exists: true, enabled: true, checked: false },
         | 
| 238 240 | 
             
                        forgot_password_link => { visible: true, caption: 'Forgot your password?' },
         | 
| 239 241 | 
             
                        error_message_label  => { visible: false }
         | 
| 240 242 | 
             
                        }
         | 
| @@ -244,9 +246,9 @@ the UI to hide implementation details, as shown below: | |
| 244 246 |  | 
| 245 247 |  | 
| 246 248 | 
             
                class RegistrationPage < TestCentricity::PageObject
         | 
| 247 | 
            -
                  trait(:page_name) | 
| 248 | 
            -
                  trait(:page_url) | 
| 249 | 
            -
                  trait(:page_locator) | 
| 249 | 
            +
                  trait(:page_name)    { 'Registration' }
         | 
| 250 | 
            +
                  trait(:page_url)     { '/register' }
         | 
| 251 | 
            +
                  trait(:page_locator) { 'body.registration' }
         | 
| 250 252 |  | 
| 251 253 | 
             
                  # Registration page UI elements
         | 
| 252 254 | 
             
                  textfields  first_name_field:    'input#firstName',
         | 
| @@ -278,7 +280,8 @@ the UI to hide implementation details, as shown below: | |
| 278 280 | 
             
                               state_select        => profile.state,
         | 
| 279 281 | 
             
                               post_code_field     => profile.postal_code,
         | 
| 280 282 | 
             
                               password_field      => profile.password,
         | 
| 281 | 
            -
                               pword_confirm_field => profile.confirm_password
         | 
| 283 | 
            +
                               pword_confirm_field => profile.confirm_password,
         | 
| 284 | 
            +
                               email_opt_in_check  => profile.email_opt_in
         | 
| 282 285 | 
             
                      }
         | 
| 283 286 | 
             
                    populate_data_fields(fields)
         | 
| 284 287 | 
             
                    sign_up_button.click
         | 
| @@ -287,18 +290,18 @@ the UI to hide implementation details, as shown below: | |
| 287 290 |  | 
| 288 291 |  | 
| 289 292 |  | 
| 290 | 
            -
            Once your  | 
| 293 | 
            +
            Once your `PageObjects` have been instantiated, you can call your methods as shown below:
         | 
| 291 294 |  | 
| 292 295 | 
             
                login_page.remember_me(true)
         | 
| 293 296 | 
             
                login_page.login('snicklefritz', 'Pa55w0rd')
         | 
| 294 297 |  | 
| 295 298 |  | 
| 296 299 |  | 
| 297 | 
            -
            ##  | 
| 300 | 
            +
            ## PageSections
         | 
| 298 301 |  | 
| 299 | 
            -
            A  | 
| 302 | 
            +
            A `PageSection` is a collection of **UI Elements** that may appear in multiple locations on a page, or on multiple pages in a web
         | 
| 300 303 | 
             
            app. It is a collection of **UI Elements** that represent a conceptual area of functionality, like a navigation bar, a search capability,
         | 
| 301 | 
            -
            or a menu. **UI Elements** and functional behavior are confined to the scope of a  | 
| 304 | 
            +
            or a menu. **UI Elements** and functional behavior are confined to the scope of a `PageSection` object.
         | 
| 302 305 |  | 
| 303 306 | 
             
            <img src="https://i.imgur.com/BTgi59R.jpg" alt="Navigation Header" title="Navigation Header">
         | 
| 304 307 |  | 
| @@ -307,39 +310,39 @@ or a menu. **UI Elements** and functional behavior are confined to the scope of | |
| 307 310 | 
             
            <img src="https://i.imgur.com/Yqgw4sP.jpg" alt="User Profile Popup" title="User Profile Popup">
         | 
| 308 311 |  | 
| 309 312 |  | 
| 310 | 
            -
            A  | 
| 313 | 
            +
            A `PageSection` may contain other `PageSection` objects.
         | 
| 311 314 |  | 
| 312 315 |  | 
| 313 | 
            -
            ### Defining a PageSection | 
| 316 | 
            +
            ### Defining a PageSection
         | 
| 314 317 |  | 
| 315 | 
            -
            Your  | 
| 316 | 
            -
            your test automation project. You define new  | 
| 318 | 
            +
            Your `PageSection` class definitions should be contained within individual `.rb` files in the `features/support/sections` folder of
         | 
| 319 | 
            +
            your test automation project. You define new `PageSection` as shown below:
         | 
| 317 320 |  | 
| 318 321 | 
             
                class SearchForm < TestCentricity::PageSection
         | 
| 319 322 | 
             
                end
         | 
| 320 323 |  | 
| 321 324 |  | 
| 322 | 
            -
            ### Adding Traits to a PageSection | 
| 325 | 
            +
            ### Adding Traits to a PageSection
         | 
| 323 326 |  | 
| 324 | 
            -
            A  | 
| 327 | 
            +
            A `PageSection` typically has a root node object that encapsulates a collection of `UIElements`. The `section_locator` trait
         | 
| 325 328 | 
             
            specifies the CSS or Xpath expression that uniquely identifies that root node object.
         | 
| 326 329 |  | 
| 327 | 
            -
            You define your  | 
| 330 | 
            +
            You define your section's **Traits** as shown below:
         | 
| 328 331 |  | 
| 329 332 | 
             
                class SearchForm < TestCentricity::PageSection
         | 
| 330 | 
            -
                  trait(:section_locator) | 
| 331 | 
            -
                  trait(:section_name) | 
| 333 | 
            +
                  trait(:section_locator) { 'form#gnav-search' }
         | 
| 334 | 
            +
                  trait(:section_name)    { 'Search widget' }
         | 
| 332 335 | 
             
                end
         | 
| 333 336 |  | 
| 334 337 |  | 
| 335 | 
            -
            ### Adding UI Elements to your PageSection | 
| 338 | 
            +
            ### Adding UI Elements to your PageSection
         | 
| 336 339 |  | 
| 337 | 
            -
             | 
| 338 | 
            -
            **UI Elements** are added to your  | 
| 340 | 
            +
            `PageSections` are typically made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists, buttons, etc.
         | 
| 341 | 
            +
            **UI Elements** are added to your `PageSection` class definition as shown below:
         | 
| 339 342 |  | 
| 340 343 | 
             
                class SearchForm < TestCentricity::PageSection
         | 
| 341 | 
            -
                  trait(:section_locator) | 
| 342 | 
            -
                  trait(:section_name) | 
| 344 | 
            +
                  trait(:section_locator) { 'form#gnav-search' }
         | 
| 345 | 
            +
                  trait(:section_name)    { 'Search widget' }
         | 
| 343 346 |  | 
| 344 347 | 
             
                  # Search Form UI elements
         | 
| 345 348 | 
             
                  textfield :search_field,  'input#search-query'
         | 
| @@ -347,13 +350,13 @@ Page sections are typically made up of UI elements like text fields, check boxes | |
| 347 350 | 
             
                end
         | 
| 348 351 |  | 
| 349 352 |  | 
| 350 | 
            -
            ### Adding Methods to your PageSection | 
| 353 | 
            +
            ### Adding Methods to your PageSection
         | 
| 351 354 |  | 
| 352 | 
            -
            You can add high level methods to your  | 
| 355 | 
            +
            You can add high level methods to your `PageSection` class definition, as shown below:
         | 
| 353 356 |  | 
| 354 357 | 
             
                class SearchForm < TestCentricity::PageSection
         | 
| 355 | 
            -
                  trait(:section_locator) | 
| 356 | 
            -
                  trait(:section_name) | 
| 358 | 
            +
                  trait(:section_locator) { 'form#gnav-search' }
         | 
| 359 | 
            +
                  trait(:section_name)    { 'Search widget' }
         | 
| 357 360 |  | 
| 358 361 | 
             
                  # Search Form UI elements
         | 
| 359 362 | 
             
                  textfield :search_field,  'input#search-query'
         | 
| @@ -366,48 +369,48 @@ You can add high level methods to your **PageSection** class definition, as show | |
| 366 369 | 
             
                end
         | 
| 367 370 |  | 
| 368 371 |  | 
| 369 | 
            -
            ### Adding  | 
| 372 | 
            +
            ### Adding PageSections to your PageObject
         | 
| 370 373 |  | 
| 371 | 
            -
            You add a  | 
| 374 | 
            +
            You add a `PageSection` to its associated `PageObject` as shown below:
         | 
| 372 375 |  | 
| 373 376 | 
             
                class HomePage < TestCentricity::PageObject
         | 
| 374 | 
            -
                  trait(:page_name) | 
| 375 | 
            -
                  trait(:page_url) | 
| 376 | 
            -
                  trait(:page_locator) | 
| 377 | 
            +
                  trait(:page_name)     { 'Home' }
         | 
| 378 | 
            +
                  trait(:page_url)      { '/dashboard' }
         | 
| 379 | 
            +
                  trait(:page_locator)  { 'body.dashboard' }
         | 
| 377 380 |  | 
| 378 381 | 
             
                  # Home page Section Objects
         | 
| 379 382 | 
             
                  section :search_form, SearchForm
         | 
| 380 383 | 
             
                end
         | 
| 381 384 |  | 
| 382 | 
            -
            Once your  | 
| 385 | 
            +
            Once your `PageObject` has been instantiated, you can call its `PageSection` methods as shown below:
         | 
| 383 386 |  | 
| 384 387 | 
             
                home_page.search_form.search_for('ocarina')
         | 
| 385 388 |  | 
| 386 389 |  | 
| 387 390 |  | 
| 388 | 
            -
            ##  | 
| 391 | 
            +
            ## UIElements
         | 
| 389 392 |  | 
| 390 | 
            -
             | 
| 391 | 
            -
            tables, lists, buttons, images, HTML5 video objects, HTML5 audio objects, etc. **UI Elements** are declared | 
| 392 | 
            -
            definition of the  | 
| 393 | 
            -
            the  | 
| 393 | 
            +
            `PageObjects` and `PageSections` are typically made up of **UI Element** like text fields, check boxes, select lists (combo boxes),
         | 
| 394 | 
            +
            radio buttons, tables, ordered and unordered lists, buttons, images, HTML5 video objects, HTML5 audio objects, etc. **UI Elements** are declared
         | 
| 395 | 
            +
            and instantiated within the class definition of the `PageObject` or `PageSection` in which they are contained. With TestCentricity Web,
         | 
| 396 | 
            +
            all UI elements are based on the `UIElement` class.
         | 
| 394 397 |  | 
| 395 398 |  | 
| 396 | 
            -
            ### Declaring and Instantiating  | 
| 399 | 
            +
            ### Declaring and Instantiating UIElements
         | 
| 397 400 |  | 
| 398 | 
            -
            Single  | 
| 401 | 
            +
            Single `UIElement` declarations have the following format:
         | 
| 399 402 |  | 
| 400 403 | 
             
                elementType :element Name, locator
         | 
| 401 404 |  | 
| 402 | 
            -
            * The `element name` is the unique name that you will use to refer to the UI element and is specified as a  | 
| 403 | 
            -
            * The `locator` is the CSS or XPath attribute that uniquely and unambiguously identifies the  | 
| 405 | 
            +
            * The `element name` is the unique name that you will use to refer to the UI element and is specified as a `Symbol`.
         | 
| 406 | 
            +
            * The `locator` is the CSS or XPath attribute that uniquely and unambiguously identifies the `UIElement`.
         | 
| 404 407 |  | 
| 405 | 
            -
            Multiple  | 
| 408 | 
            +
            Multiple `UIElement` declarations for a collection of elements of the same type can be performed by passing a hash table containing the
         | 
| 406 409 | 
             
            names and locators of each individual element.
         | 
| 407 410 |  | 
| 408 | 
            -
            ### Example  | 
| 411 | 
            +
            ### Example UIElement Declarations
         | 
| 409 412 |  | 
| 410 | 
            -
            Supported  | 
| 413 | 
            +
            Supported `UIElement` elementTypes and their declarations have the following format:
         | 
| 411 414 |  | 
| 412 415 | 
             
            *Single element declarations:*
         | 
| 413 416 |  | 
| @@ -469,14 +472,14 @@ Supported **UI Element** elementTypes and their declarations have the following | |
| 469 472 | 
             
                end
         | 
| 470 473 |  | 
| 471 474 |  | 
| 472 | 
            -
            Refer to the Class List documentation for the  | 
| 473 | 
            -
            and instantiating  | 
| 475 | 
            +
            Refer to the Class List documentation for the `PageObject` and `PageSection` classes for details on the class methods used for declaring
         | 
| 476 | 
            +
            and instantiating `UIElements`. Examples of UI element declarations can be found in the ***Adding UI Elements to your Page Object*** and
         | 
| 474 477 | 
             
            ***Adding UI Elements to your PageSection Object*** sections above.
         | 
| 475 478 |  | 
| 476 479 |  | 
| 477 480 | 
             
            ### UIElement Inherited Methods
         | 
| 478 481 |  | 
| 479 | 
            -
            With TestCentricity, all UI elements are based on the  | 
| 482 | 
            +
            With TestCentricity, all UI elements are based on the `UIElement` class, and inherit the following methods:
         | 
| 480 483 |  | 
| 481 484 | 
             
            **Action methods:**
         | 
| 482 485 |  | 
| @@ -600,7 +603,7 @@ for each `UIElement` that requires verification. Depending on the complexity and | |
| 600 603 | 
             
            verify the presence of `UIElements` and their correct states can become cumbersome.
         | 
| 601 604 |  | 
| 602 605 | 
             
            The `PageObject.verify_ui_states` and `PageSection.verify_ui_states` methods support the verification of multiple properties of multiple
         | 
| 603 | 
            -
            UI elements on a  | 
| 606 | 
            +
            UI elements on a `PageObject` or `PageSection`. The `verify_ui_states` method accepts a hash containing key/hash pairs of UI
         | 
| 604 607 | 
             
            elements and their properties or attributes to be verified.
         | 
| 605 608 |  | 
| 606 609 | 
             
                 ui = {
         | 
| @@ -631,6 +634,8 @@ The `verify_ui_states` method supports the following property/state pairs: | |
| 631 634 | 
             
                :class             String
         | 
| 632 635 | 
             
                :value or :caption String
         | 
| 633 636 | 
             
                :attribute         Hash
         | 
| 637 | 
            +
                :style             String
         | 
| 638 | 
            +
                :tabindex          Integer
         | 
| 634 639 |  | 
| 635 640 | 
             
            **Text Fields:**
         | 
| 636 641 |  | 
| @@ -643,12 +648,17 @@ The `verify_ui_states` method supports the following property/state pairs: | |
| 643 648 |  | 
| 644 649 | 
             
            **Checkboxes:**
         | 
| 645 650 |  | 
| 646 | 
            -
                :checked | 
| 651 | 
            +
                :checked       Boolean
         | 
| 652 | 
            +
                :indeterminate Boolean
         | 
| 647 653 |  | 
| 648 654 | 
             
            **Radio Buttons:**
         | 
| 649 655 |  | 
| 650 656 | 
             
                :selected Boolean
         | 
| 651 657 |  | 
| 658 | 
            +
            **Links:**
         | 
| 659 | 
            +
             | 
| 660 | 
            +
                :href String
         | 
| 661 | 
            +
             | 
| 652 662 | 
             
            **Images**
         | 
| 653 663 |  | 
| 654 664 | 
             
                :loaded Boolean
         | 
| @@ -668,6 +678,8 @@ The `verify_ui_states` method supports the following property/state pairs: | |
| 668 678 | 
             
                :items or :options         Array of Strings
         | 
| 669 679 | 
             
                :itemcount or :optioncount Integer
         | 
| 670 680 | 
             
                :selected                  String
         | 
| 681 | 
            +
                :groupcount                Integer
         | 
| 682 | 
            +
                :group_headings            Array of Strings
         | 
| 671 683 |  | 
| 672 684 | 
             
            **Tables**
         | 
| 673 685 |  | 
| @@ -699,9 +711,9 @@ The `verify_ui_states` method supports the following property/state pairs: | |
| 699 711 | 
             
                :preload               String
         | 
| 700 712 | 
             
                :poster                String
         | 
| 701 713 |  | 
| 702 | 
            -
             | 
| 714 | 
            +
            #### ARIA accessibility property/state pairs
         | 
| 703 715 |  | 
| 704 | 
            -
             | 
| 716 | 
            +
            The `verify_ui_states` method supports the following ARIA accessibility property/state pairs:
         | 
| 705 717 |  | 
| 706 718 | 
             
                :aria_label           String
         | 
| 707 719 | 
             
                :aria_disabled        Boolean
         | 
| @@ -733,12 +745,15 @@ The `verify_ui_states` method supports the following ARIA accessibility property | |
| 733 745 | 
             
                :aria_multiline       Boolean
         | 
| 734 746 | 
             
                :aria_multiselectable Boolean
         | 
| 735 747 | 
             
                :content_editable     Boolean
         | 
| 748 | 
            +
                :role                 String
         | 
| 749 | 
            +
             | 
| 750 | 
            +
            #### Comparison States
         | 
| 736 751 |  | 
| 737 752 | 
             
            The `verify_ui_states` method supports comparison states using property/comparison state pairs:
         | 
| 738 753 |  | 
| 739 754 | 
             
                object => { property: { comparison_state: value } }
         | 
| 740 755 |  | 
| 741 | 
            -
             | 
| 756 | 
            +
            Comparison States:
         | 
| 742 757 |  | 
| 743 758 | 
             
                :lt or :less_than                  Integer or String
         | 
| 744 759 | 
             
                :lt_eq or :less_than_or_equal      Integer or String
         | 
| @@ -773,19 +788,19 @@ values appear in the associated text fields after entering data and performing a | |
| 773 788 | 
             
                end
         | 
| 774 789 |  | 
| 775 790 |  | 
| 776 | 
            -
             | 
| 791 | 
            +
            #### I18n Translation Validation
         | 
| 777 792 |  | 
| 778 793 | 
             
            The `verify_ui_states` method also supports I18n string translations using property/I18n key name pairs:
         | 
| 779 794 |  | 
| 780 | 
            -
                object => { property: { translate_key:  | 
| 795 | 
            +
                object => { property: { translate_key: 'name of key in I18n compatible .yml file' } }
         | 
| 781 796 |  | 
| 782 797 | 
             
            **I18n Translation Keys:**
         | 
| 783 798 |  | 
| 784 | 
            -
                :translate            String | 
| 785 | 
            -
                :translate_upcase     String | 
| 786 | 
            -
                :translate_downcase   String | 
| 787 | 
            -
                :translate_capitalize String | 
| 788 | 
            -
                translate_titlecase | 
| 799 | 
            +
                :translate            String
         | 
| 800 | 
            +
                :translate_upcase     String
         | 
| 801 | 
            +
                :translate_downcase   String
         | 
| 802 | 
            +
                :translate_capitalize String
         | 
| 803 | 
            +
                :translate_titlecase  String
         | 
| 789 804 |  | 
| 790 805 | 
             
            The example below depicts the usage of the `verify_ui_states` method to verify that the captions for menu items are correctly
         | 
| 791 806 | 
             
            translated.
         | 
| @@ -804,27 +819,166 @@ translated. | |
| 804 819 | 
             
                  verify_ui_states(ui)
         | 
| 805 820 | 
             
                end
         | 
| 806 821 |  | 
| 807 | 
            -
             | 
| 808 | 
            -
             | 
| 822 | 
            +
            Each supported language/locale combination has a corresponding `.yml` file. I18n `.yml` file naming convention uses
         | 
| 823 | 
            +
            [ISO-639 language codes and ISO-3166 country codes](https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html). For example:
         | 
| 809 824 |  | 
| 810 | 
            -
                 | 
| 811 | 
            -
             | 
| 812 | 
            -
             | 
| 813 | 
            -
             | 
| 814 | 
            -
             | 
| 815 | 
            -
             | 
| 816 | 
            -
             | 
| 817 | 
            -
             | 
| 825 | 
            +
            | Language (Country)    | File name |
         | 
| 826 | 
            +
            |-----------------------|-----------|
         | 
| 827 | 
            +
            | English               | en.yml    |
         | 
| 828 | 
            +
            | English (Canada)      | en-CA.yml |
         | 
| 829 | 
            +
            | French (Canada)       | fr-CA.yml |
         | 
| 830 | 
            +
            | French                | fr.yml    |
         | 
| 831 | 
            +
            | Spanish               | es.yml    |
         | 
| 832 | 
            +
            | German                | de.yml    |
         | 
| 833 | 
            +
            | Portuguese (Brazil)   | pt-BR.yml |
         | 
| 834 | 
            +
            | Portuguese (Portugal) | pt-PT.yml |
         | 
| 818 835 |  | 
| 819 836 | 
             
            I18n `.yml` files contain key/value pairs representing the name of a translated string (key) and the string value.
         | 
| 820 837 |  | 
| 838 | 
            +
            Baseline translation strings are stored in `.yml` files in the `config/locales/` folder.
         | 
| 839 | 
            +
             | 
| 840 | 
            +
                my_automation_project
         | 
| 841 | 
            +
                    ├── config
         | 
| 842 | 
            +
                    │   ├── locales
         | 
| 843 | 
            +
                    │   │   ├── en.yml
         | 
| 844 | 
            +
                    │   │   ├── es.yml
         | 
| 845 | 
            +
                    │   │   ├── fr.yml
         | 
| 846 | 
            +
                    │   │   ├── fr-CA.yml
         | 
| 847 | 
            +
                    │   │   └── en-AU.yml
         | 
| 848 | 
            +
                    │   ├── test_data
         | 
| 849 | 
            +
                    │   └── cucumber.yml
         | 
| 850 | 
            +
                    ├── downloads
         | 
| 851 | 
            +
                    ├── features
         | 
| 852 | 
            +
                    ├── Gemfile
         | 
| 853 | 
            +
                    └── README.md
         | 
| 854 | 
            +
             | 
| 855 | 
            +
             | 
| 856 | 
            +
            ### Working with custom UIElements
         | 
| 857 | 
            +
             | 
| 858 | 
            +
            Many responsive and touch-enabled web based user interfaces are implemented using front-end JavaScript libraries for building user
         | 
| 859 | 
            +
            interfaces based on UI components. Popular JS libraries include React, Angular, and Ember.js. These stylized and adorned controls can
         | 
| 860 | 
            +
            present a challenge when attempting to interact with them using Capybara and Selenium based automated tests.
         | 
| 861 | 
            +
             | 
| 862 | 
            +
            #### Radio and Checkbox UIElements
         | 
| 863 | 
            +
             | 
| 864 | 
            +
            Sometimes, radio buttons and checkboxes implemented using JS component libraries cannot be interacted with due to other UI elements
         | 
| 865 | 
            +
            being overlaid on top of them and the base `input(type='radio')` or `input(type='checkbox')` element not being visible.
         | 
| 866 | 
            +
             | 
| 867 | 
            +
            In the screenshots below of an airline flight search and booking page, the **Roundtrip** and **One-way** radio buttons are adorned with
         | 
| 868 | 
            +
            `label` elements that also acts as proxies for their associated `input(type='radio')` elements, and they intercept the `click` actions
         | 
| 869 | 
            +
            that would normally be handled by the `input(type='radio')` elements.
         | 
| 821 870 |  | 
| 871 | 
            +
            <img src="https://i.imgur.com/7bW5u4c.jpg" alt="Roundtrip Radio button Input" title="Roundtrip Radio button Input">
         | 
| 822 872 |  | 
| 823 | 
            -
            ## Instantiating your Page Objects
         | 
| 824 873 |  | 
| 825 | 
            -
             | 
| 826 | 
            -
             | 
| 827 | 
            -
             | 
| 874 | 
            +
            This screenshot shows the `label` element that is overlaid above the **Roundtrip** `input(type='radio')` element.
         | 
| 875 | 
            +
             | 
| 876 | 
            +
            <img src="https://i.imgur.com/2stWiyR.jpg" alt="Roundtrip Radio button Label" title="Roundtrip Radio button Label">
         | 
| 877 | 
            +
             | 
| 878 | 
            +
             | 
| 879 | 
            +
            The checkbox controls in this web UI are also adorned with `label` elements that act as proxies for their associated `input(type='checkbox')`
         | 
| 880 | 
            +
            elements.
         | 
| 881 | 
            +
             | 
| 882 | 
            +
            <img src="https://i.imgur.com/JcOANqZ.jpg" alt="One-way Radio button Label" title="One-way Radio button Label">
         | 
| 883 | 
            +
             | 
| 884 | 
            +
             | 
| 885 | 
            +
            The `Radio.define_custom_elements` and `CheckBox.define_custom_elements` methods provide a way to specify the `proxy` and/or `label`
         | 
| 886 | 
            +
            elements associated with the `input(type='radio')` or `input(type='checkbox')` elements. The `define_custom_elements` method
         | 
| 887 | 
            +
            should be called from an `initialize` method for the `PageObject` or `PageSection` where the `radio` or `checkbox` element is instantiated.
         | 
| 888 | 
            +
            The code snippet below demonstrates the use of the `Radio.define_custom_elements` and `CheckBox.define_custom_elements` methods to
         | 
| 889 | 
            +
            resolve the testability issues posed by the adorned **Roundtrip** and **One-way** radio buttons and the **Flexible dates** checkbox.
         | 
| 890 | 
            +
             | 
| 891 | 
            +
                class FlightBookingPage < TestCentricity::PageObject
         | 
| 892 | 
            +
                  trait(:page_name)    { 'Flight Booking Home' }
         | 
| 893 | 
            +
                  trait(:page_locator) { "div[class*='bookerContainer']" }
         | 
| 894 | 
            +
                  
         | 
| 895 | 
            +
                  # Flight Booking page UI elements
         | 
| 896 | 
            +
                  radios   roundtrip_radio: 'input#roundtrip',
         | 
| 897 | 
            +
                           one_way_radio:   'input#oneway'
         | 
| 898 | 
            +
                  checkbox :flexible_check, 'input#flexibleDates'
         | 
| 899 | 
            +
                  
         | 
| 900 | 
            +
                  def initialize
         | 
| 901 | 
            +
                    # define the custom element components for the Round Trip radio button
         | 
| 902 | 
            +
                    radio_spec = { proxy: "label[for='roundtrip']" }
         | 
| 903 | 
            +
                    roundtrip_radio.define_custom_elements(radio_spec)
         | 
| 904 | 
            +
                    # define the custom element components for the One Way radio button
         | 
| 905 | 
            +
                    radio_spec = { proxy: "label[for='oneway']" }
         | 
| 906 | 
            +
                    one_way_radio.define_custom_elements(radio_spec)
         | 
| 907 | 
            +
                    # define the custom element components for the Flexible Date checkbox
         | 
| 908 | 
            +
                    check_spec = { proxy: 'label#flexDatesLabel' }
         | 
| 909 | 
            +
                    flexible_check.define_custom_elements(check_spec)
         | 
| 910 | 
            +
                  end
         | 
| 911 | 
            +
                end
         | 
| 912 | 
            +
             | 
| 913 | 
            +
             | 
| 914 | 
            +
            #### SelectList UIElements
         | 
| 915 | 
            +
             | 
| 916 | 
            +
            The basic HTML `select` element is typically composed of the parent `select` object, and one or more `option` elements representing
         | 
| 917 | 
            +
            the selectable items in the drop-down list. However, `select` type controls implemented using JS component libraries can be composed
         | 
| 918 | 
            +
            of multiple elements representing the various components of a drop-down style `selectlist` implementation.
         | 
| 919 | 
            +
             | 
| 920 | 
            +
            In the screenshots below of an airline flight search and booking page, there are no `select` or `option` elements associated with the
         | 
| 921 | 
            +
            **Month**, **Day**, and **Cabin Type** drop-down style selectors. An inspection of the **Month** selector reveals that it is a `div`
         | 
| 922 | 
            +
            element that contains a `button` element (outlined in red) for triggering the drop-down list, a `ul` element (outlined in green) that
         | 
| 923 | 
            +
            contains the drop-down list, and multiple `li` elements (outlined in blue) that represent the list items or options that can be
         | 
| 924 | 
            +
            selected. The currently selected item or option can be identified by either the `listBoxOptionSelected` snippet in its `class` name or
         | 
| 925 | 
            +
            the `aria-selected` attribute (outlined in orange).
         | 
| 926 | 
            +
             | 
| 927 | 
            +
            Further examination of the **Day** and **Cabin Type** drop-down style selectors reveal that their composition is identical to the
         | 
| 928 | 
            +
            **Month** selector.
         | 
| 929 | 
            +
             | 
| 930 | 
            +
            <img src="https://i.imgur.com/LYAC2lh.jpg" alt="Custom SelectList" title="Custom SelectList">
         | 
| 931 | 
            +
             | 
| 932 | 
            +
             | 
| 933 | 
            +
            The `SelectList.define_list_elements` method provides a means of specifying the various elements that make up the key components of
         | 
| 934 | 
            +
            a `selectlist` control. The method accepts a hash of element designators (key) and a CSS or Xpath expression (value) that expression
         | 
| 935 | 
            +
            that uniquely identifies the element. Valid element designators are `list_item:`, `options_list:`, `list_trigger:`, `selected_item:`,
         | 
| 936 | 
            +
            `text_field:`, `group_heading:`, and `group_item:`.
         | 
| 937 | 
            +
             | 
| 938 | 
            +
            The code snippet below demonstrates the use of the `SelectList.define_list_elements` method to define the common components that make
         | 
| 939 | 
            +
            up the **Month**, **Day**, and **Cabin Type** drop-down style selectors. Note the use of the ARIA `role` and `aria-selected` attributes
         | 
| 940 | 
            +
            as element locators.
         | 
| 941 | 
            +
             | 
| 942 | 
            +
                class FlightBookingPage < TestCentricity::PageObject
         | 
| 943 | 
            +
                  trait(:page_name)    { 'Flight Booking Home' }
         | 
| 944 | 
            +
                  trait(:page_locator) { "div[class*='bookerContainer']" }
         | 
| 945 | 
            +
                  
         | 
| 946 | 
            +
                  # Flight Booking page UI elements
         | 
| 947 | 
            +
                  selectlists month_select:      "div[class*='expandFlexMonth']",
         | 
| 948 | 
            +
                              duration_select:   "div[class*='expandFlexDay']",
         | 
| 949 | 
            +
                              cabin_type_select: "div[class*='bookFlightForm__optionField'] > div[class*='app-components-ListBox']"
         | 
| 950 | 
            +
             | 
| 951 | 
            +
                  def initialize
         | 
| 952 | 
            +
                    # define the custom list element components for the Month, Duration, and Cabin Type selectlist objects
         | 
| 953 | 
            +
                    list_spec = {
         | 
| 954 | 
            +
                      selected_item: "li[aria-selected=true]",
         | 
| 955 | 
            +
                      options_list:  "ul[role='listbox']",
         | 
| 956 | 
            +
                      list_item:     "li[role='option']",
         | 
| 957 | 
            +
                      list_trigger:  "button[role='combobox']"
         | 
| 958 | 
            +
                    }
         | 
| 959 | 
            +
                    month_select.define_list_elements(list_spec)
         | 
| 960 | 
            +
                    duration_select.define_list_elements(list_spec)
         | 
| 961 | 
            +
                    cabin_type_select.define_list_elements(list_spec)
         | 
| 962 | 
            +
                  end
         | 
| 963 | 
            +
                end
         | 
| 964 | 
            +
             | 
| 965 | 
            +
             | 
| 966 | 
            +
            #### List UIElements
         | 
| 967 | 
            +
             | 
| 968 | 
            +
            The basic HTML list is typically composed of the parent `ul` object, and one or more `li` elements representing the items
         | 
| 969 | 
            +
            in the list. However, list controls implemented using JS component libraries can be composed of multiple elements representing the
         | 
| 970 | 
            +
            components of a list implementation.
         | 
| 971 | 
            +
             | 
| 972 | 
            +
            The `List.define_list_elements` method provides a means of specifying the elements that make up the key components of a `list` control.
         | 
| 973 | 
            +
            The method accepts a hash of element designators (key) and a CSS or Xpath expression (value) that expression that uniquely identifies
         | 
| 974 | 
            +
            the element. Valid element designators are `list_item:`and `selected_item:`.
         | 
| 975 | 
            +
             | 
| 976 | 
            +
             | 
| 977 | 
            +
            ## Instantiating your PageObjects
         | 
| 978 | 
            +
             | 
| 979 | 
            +
            Before you can call the methods in your `PageObjects` and `PageSections`, you must instantiate the `PageObjects` of your web
         | 
| 980 | 
            +
            application, as well as create instance variables which can be used when calling a `PageObject`'s methods from your step definitions.
         | 
| 981 | 
            +
            There are several ways to instantiate your `PageObjects`.
         | 
| 828 982 |  | 
| 829 983 | 
             
            One common implementation is shown below:
         | 
| 830 984 |  | 
| @@ -851,14 +1005,14 @@ One common implementation is shown below: | |
| 851 1005 | 
             
            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
         | 
| 852 1006 | 
             
            `features/support` folder.
         | 
| 853 1007 |  | 
| 854 | 
            -
            While this approach is effective for small web applications with only a few pages (and hence few  | 
| 855 | 
            -
            cumbersome to manage if your web application has dozens of  | 
| 1008 | 
            +
            While this approach is effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly becomes
         | 
| 1009 | 
            +
            cumbersome to manage if your web application has dozens of `PageObjects` that need to be instantiated and managed.
         | 
| 856 1010 |  | 
| 857 1011 | 
             
            ### Using the PageManager
         | 
| 858 1012 |  | 
| 859 | 
            -
            The  | 
| 860 | 
            -
            the `page_objects` method contains a hash table of your  | 
| 861 | 
            -
             | 
| 1013 | 
            +
            The `PageManager` class provides methods for supporting the instantiation and management of `PageObjects`. In the code example below,
         | 
| 1014 | 
            +
            the `page_objects` method contains a hash table of your `PageObject` instances and their associated `PageObject` class names to be 
         | 
| 1015 | 
            +
            instantiated by `PageManager`:
         | 
| 862 1016 |  | 
| 863 1017 | 
             
                module WorldPages
         | 
| 864 1018 | 
             
                  def page_objects
         | 
| @@ -888,13 +1042,13 @@ to be instantiated by **PageManager**: | |
| 888 1042 |  | 
| 889 1043 | 
             
            The `WorldPages` module above should be defined in the `world_pages.rb` file in the `features/support` folder.
         | 
| 890 1044 |  | 
| 891 | 
            -
            Include the code below in your `env.rb` file to ensure that your  | 
| 1045 | 
            +
            Include the code below in your `env.rb` file to ensure that your `PageObjects` are instantiated before your Cucumber scenarios are
         | 
| 892 1046 | 
             
            executed:
         | 
| 893 1047 |  | 
| 894 1048 | 
             
                include WorldPages
         | 
| 895 1049 | 
             
                WorldPages.instantiate_page_objects
         | 
| 896 1050 |  | 
| 897 | 
            -
            **NOTE:** If you intend to use the  | 
| 1051 | 
            +
            **NOTE:** If you intend to use the `PageManager`, you must define a `page_name` trait for each of the `PageObjects` to be registered.
         | 
| 898 1052 |  | 
| 899 1053 |  | 
| 900 1054 | 
             
            ### Leveraging the PageManager in your Cucumber tests
         | 
| @@ -956,14 +1110,13 @@ In the above example, the step definitions associated with the 3 steps might be | |
| 956 1110 | 
             
                  end
         | 
| 957 1111 |  | 
| 958 1112 |  | 
| 1113 | 
            +
            While this approach may be effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly becomes
         | 
| 1114 | 
            +
            cumbersome to manage if your web application has dozens of `PageObjects` that need to be managed.
         | 
| 959 1115 |  | 
| 960 | 
            -
             | 
| 961 | 
            -
             | 
| 962 | 
            -
             | 
| 963 | 
            -
            The **PageManager** class provides a `find_page` method that replaces the cumbersome and difficult to maintain `case` statement used in the
         | 
| 964 | 
            -
            above example. The **PageManager** `current_page` method allows you to set or get an instance of the currently active Page Object.
         | 
| 1116 | 
            +
            The `PageManager` class provides a `find_page` method that replaces the cumbersome and difficult to maintain `case` statement used in the
         | 
| 1117 | 
            +
            above example. The `PageManager.current_page` method allows you to set or get an instance of the currently active Page Object.
         | 
| 965 1118 |  | 
| 966 | 
            -
            To use these  | 
| 1119 | 
            +
            To use these `PageManager` methods, include the step definitions and code below in a `page_steps.rb` or `generic_steps.rb` file in the
         | 
| 967 1120 | 
             
            `features/step_definitions` folder:
         | 
| 968 1121 |  | 
| 969 1122 | 
             
                include TestCentricity
         | 
| @@ -1017,7 +1170,7 @@ values from the table below: | |
| 1017 1170 | 
             
            | `safari`           | OS X only                                      |
         | 
| 1018 1171 | 
             
            | `ie`               | Windows only (IE version 10.x or greater only) |
         | 
| 1019 1172 |  | 
| 1020 | 
            -
            Refer to **section 8. | 
| 1173 | 
            +
            Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
         | 
| 1021 1174 |  | 
| 1022 1175 |  | 
| 1023 1176 | 
             
            #### Setting desktop browser window size
         | 
| @@ -1033,16 +1186,13 @@ To maximize a desktop browser window, you set the `BROWSER_SIZE` Environment Var | |
| 1033 1186 |  | 
| 1034 1187 | 
             
            #### Testing file downloads with desktop browsers
         | 
| 1035 1188 |  | 
| 1036 | 
            -
            File download functionality can be tested with locally hosted instances of Chrome or Firefox desktop browsers. Your automation project must include
         | 
| 1189 | 
            +
            File download functionality can be tested with locally hosted instances of Chrome, Edge, or Firefox desktop browsers. Your automation project must include
         | 
| 1037 1190 | 
             
            a `/downloads` folder at the same level as the `/config` and `/features` folders, as depicted below:
         | 
| 1038 1191 |  | 
| 1039 1192 | 
             
                my_automation_project
         | 
| 1040 1193 | 
             
                    ├── config
         | 
| 1041 | 
            -
                    │   └── test_data
         | 
| 1042 1194 | 
             
                    ├── downloads
         | 
| 1043 1195 | 
             
                    ├── features
         | 
| 1044 | 
            -
                    │   ├── step_definitions
         | 
| 1045 | 
            -
                    │   └── support
         | 
| 1046 1196 | 
             
                    ├── Gemfile
         | 
| 1047 1197 | 
             
                    └── README.md
         | 
| 1048 1198 |  | 
| @@ -1053,15 +1203,12 @@ test thread. This is to ensure that files downloaded in each test thread are iso | |
| 1053 1203 |  | 
| 1054 1204 | 
             
                my_automation_project
         | 
| 1055 1205 | 
             
                    ├── config
         | 
| 1056 | 
            -
                    │   └── test_data
         | 
| 1057 1206 | 
             
                    ├── downloads
         | 
| 1058 1207 | 
             
                    │   ├── 1
         | 
| 1059 1208 | 
             
                    │   ├── 2
         | 
| 1060 1209 | 
             
                    │   ├── 3
         | 
| 1061 1210 | 
             
                    │   └── 4
         | 
| 1062 1211 | 
             
                    ├── features
         | 
| 1063 | 
            -
                    │   ├── step_definitions
         | 
| 1064 | 
            -
                    │   └── support
         | 
| 1065 1212 | 
             
                    ├── Gemfile
         | 
| 1066 1213 | 
             
                    └── README.md
         | 
| 1067 1214 |  | 
| @@ -1138,7 +1285,7 @@ To change the emulated device's screen orientation from the default setting, set | |
| 1138 1285 | 
             
            To use a local instance of the Chrome desktop browser to host the emulated mobile web browser, you must set the `HOST_BROWSER` Environment Variable
         | 
| 1139 1286 | 
             
            to `chrome`.
         | 
| 1140 1287 |  | 
| 1141 | 
            -
            Refer to **section 8. | 
| 1288 | 
            +
            Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
         | 
| 1142 1289 |  | 
| 1143 1290 |  | 
| 1144 1291 | 
             
            #### User defined mobile device profiles
         | 
| @@ -1156,8 +1303,6 @@ of the Chrome desktop browser. The user specified device profiles must be locate | |
| 1156 1303 | 
             
                    │   └── cucumber.yml
         | 
| 1157 1304 | 
             
                    ├── downloads
         | 
| 1158 1305 | 
             
                    ├── features
         | 
| 1159 | 
            -
                    │   ├── step_definitions
         | 
| 1160 | 
            -
                    │   └── support
         | 
| 1161 1306 | 
             
                    ├── Gemfile
         | 
| 1162 1307 | 
             
                    └── README.md
         | 
| 1163 1308 |  | 
| @@ -1183,10 +1328,12 @@ For remote desktop and emulated mobile web browsers running on Selenium Grid 4 o | |
| 1183 1328 | 
             
            | `SELENIUM`               | Must be set to `remote`                                                                                                                                                       |
         | 
| 1184 1329 | 
             
            | `REMOTE_ENDPOINT`        | Must be set to the URL of the Grid hub, which is usually `http://localhost:4444/wd/hub`                                                                                       |
         | 
| 1185 1330 |  | 
| 1186 | 
            -
            Refer to **section 8. | 
| 1331 | 
            +
            Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
         | 
| 1187 1332 |  | 
| 1188 1333 |  | 
| 1189 | 
            -
            ### Mobile  | 
| 1334 | 
            +
            ### Mobile browsers on Simulators or Physical Devices
         | 
| 1335 | 
            +
             | 
| 1336 | 
            +
            #### Mobile Safari browser on iOS Simulators or iOS Physical Devices
         | 
| 1190 1337 |  | 
| 1191 1338 | 
             
            You can run your mobile web tests against the mobile Safari browser on simulated iOS devices or physically connected iOS devices using Appium and XCode on
         | 
| 1192 1339 | 
             
            OS X. You must install Appium, XCode, and the iOS version-specific device simulators for XCode. You must also ensure that the `appium_capybara` gem is
         | 
| @@ -1197,34 +1344,38 @@ The Appium server must be running prior to invoking Cucumber to run your feature | |
| 1197 1344 |  | 
| 1198 1345 | 
             
            Once your test environment is properly configured, the following **Environment Variables** must be set as described in the table below.
         | 
| 1199 1346 |  | 
| 1200 | 
            -
            | **Environment Variable**   | **Description** | 
| 1201 | 
            -
             | 
| 1202 | 
            -
            | `WEB_BROWSER`              | Must be set to `appium` | 
| 1203 | 
            -
            | `APP_PLATFORM_NAME`        | Must be set to `iOS` | 
| 1204 | 
            -
            | `APP_BROWSER`              | Must be set to `Safari` | 
| 1205 | 
            -
            | `APP_VERSION`              | Must be set to ` | 
| 1206 | 
            -
            | `APP_DEVICE`               | Set to iOS device name supported by the iOS Simulator (`iPhone  | 
| 1207 | 
            -
            | `DEVICE_TYPE`              | Must be set to `phone` or `tablet` | 
| 1208 | 
            -
            | `APP_UDID`                 | UDID of physically connected iOS device (not used for simulators) | 
| 1209 | 
            -
            | `TEAM_ID`                  | unique 10-character Apple developer team identifier string (not used for simulators) | 
| 1210 | 
            -
            | `TEAM_NAME`                | String representing a signing certificate (not used for simulators) | 
| 1211 | 
            -
            | `APP_ALLOW_POPUPS`         | [Optional] Allow javascript to open new windows in Safari. Set to `true` or `false` | 
| 1212 | 
            -
            | `APP_IGNORE_FRAUD_WARNING` | [Optional] Prevent Safari from showing a fraudulent website warning. Set to `true` or `false` | 
| 1213 | 
            -
            | `APP_NO_RESET`             | [Optional] Don't reset app state after each test. Set to `true` or `false` | 
| 1214 | 
            -
            | `APP_FULL_RESET`           | [Optional] Perform a complete reset. Set to `true` or `false` | 
| 1215 | 
            -
            | `APP_INITIAL_URL`          | [Optional] Initial URL, default is a local welcome page.  e.g.  `http://www.apple.com` | 
| 1216 | 
            -
            | `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. | 
| 1217 | 
            -
            | `LOCALE`                   | [Optional] Locale to set for the simulator.  e.g.  `fr_CA` | 
| 1218 | 
            -
            | `LANGUAGE`                 | [Optional] Language to set for the simulator.  e.g.  `fr` | 
| 1219 | 
            -
            | `ORIENTATION`              | [Optional] Set to `portrait` or `landscape` (only for iOS simulators) | 
| 1220 | 
            -
            | `NEW_COMMAND_TIMEOUT`      | [Optional] Time (in Seconds) that Appium will wait for a new command from the client | 
| 1221 | 
            -
            | `SHOW_SIM_KEYBOARD`        | [Optional] Show the simulator keyboard during text entry. Set to `true` or `false` | 
| 1222 | 
            -
            | `SHUTDOWN_OTHER_SIMS`      | [Optional] Close any other running simulators. Set to `true` or `false | 
| 1223 | 
            -
             | 
| 1224 | 
            -
             | 
| 1225 | 
            -
             | 
| 1226 | 
            -
             | 
| 1227 | 
            -
             | 
| 1347 | 
            +
            | **Environment Variable**   | **Description**                                                                                                                                                       |
         | 
| 1348 | 
            +
            |----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
         | 
| 1349 | 
            +
            | `WEB_BROWSER`              | Must be set to `appium`                                                                                                                                               |
         | 
| 1350 | 
            +
            | `APP_PLATFORM_NAME`        | Must be set to `iOS`                                                                                                                                                  |
         | 
| 1351 | 
            +
            | `APP_BROWSER`              | Must be set to `Safari`                                                                                                                                               |
         | 
| 1352 | 
            +
            | `APP_VERSION`              | Must be set to `15.4`, `14.5`, or which ever iOS version you wish to run within the XCode Simulator                                                                   |
         | 
| 1353 | 
            +
            | `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 |
         | 
| 1354 | 
            +
            | `DEVICE_TYPE`              | Must be set to `phone` or `tablet`                                                                                                                                    |
         | 
| 1355 | 
            +
            | `APP_UDID`                 | UDID of physically connected iOS device (not used for simulators)                                                                                                     |
         | 
| 1356 | 
            +
            | `TEAM_ID`                  | unique 10-character Apple developer team identifier string (not used for simulators)                                                                                  |
         | 
| 1357 | 
            +
            | `TEAM_NAME`                | String representing a signing certificate (not used for simulators)                                                                                                   |
         | 
| 1358 | 
            +
            | `APP_ALLOW_POPUPS`         | [Optional] Allow javascript to open new windows in Safari. Set to `true` or `false`                                                                                   |
         | 
| 1359 | 
            +
            | `APP_IGNORE_FRAUD_WARNING` | [Optional] Prevent Safari from showing a fraudulent website warning. Set to `true` or `false`                                                                         |
         | 
| 1360 | 
            +
            | `APP_NO_RESET`             | [Optional] Don't reset app state after each test. Set to `true` or `false`                                                                                            |
         | 
| 1361 | 
            +
            | `APP_FULL_RESET`           | [Optional] Perform a complete reset. Set to `true` or `false`                                                                                                         |
         | 
| 1362 | 
            +
            | `APP_INITIAL_URL`          | [Optional] Initial URL, default is a local welcome page.  e.g.  `http://www.apple.com`                                                                                |
         | 
| 1363 | 
            +
            | `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.                            |
         | 
| 1364 | 
            +
            | `LOCALE`                   | [Optional] Locale to set for the simulator.  e.g.  `fr_CA`                                                                                                            |
         | 
| 1365 | 
            +
            | `LANGUAGE`                 | [Optional] Language to set for the simulator.  e.g.  `fr`                                                                                                             |
         | 
| 1366 | 
            +
            | `ORIENTATION`              | [Optional] Set to `portrait` or `landscape` (only for iOS simulators)                                                                                                 |
         | 
| 1367 | 
            +
            | `NEW_COMMAND_TIMEOUT`      | [Optional] Time (in Seconds) that Appium will wait for a new command from the client                                                                                  |
         | 
| 1368 | 
            +
            | `SHOW_SIM_KEYBOARD`        | [Optional] Show the simulator keyboard during text entry. Set to `true` or `false`                                                                                    |
         | 
| 1369 | 
            +
            | `SHUTDOWN_OTHER_SIMS`      | [Optional] Close any other running simulators. Set to `true` or `false`. See note below.                                                                              |
         | 
| 1370 | 
            +
             | 
| 1371 | 
            +
            The `SHUTDOWN_OTHER_SIMS` environment variable can only be set if you are running Appium Server with the `--relaxed-security` or
         | 
| 1372 | 
            +
            `--allow-insecure=shutdown_other_sims` arguments passed when starting it from the command line, or when running the server from the
         | 
| 1373 | 
            +
            Appium Server GUI app. A security violation error will occur without relaxed security enabled. 
         | 
| 1374 | 
            +
             | 
| 1375 | 
            +
            Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
         | 
| 1376 | 
            +
             | 
| 1377 | 
            +
             | 
| 1378 | 
            +
            #### Mobile Chrome or Android browsers on Android Studio Virtual Device emulators
         | 
| 1228 1379 |  | 
| 1229 1380 | 
             
            You can run your mobile web tests against the mobile Chrome or Android browser on emulated Android devices using Appium and Android Studio on OS X. You
         | 
| 1230 1381 | 
             
            must install Android Studio, the desired Android version-specific virtual device emulators, and Appium. Refer to [this page](http://appium.io/docs/en/drivers/android-uiautomator2/index.html)
         | 
| @@ -1241,7 +1392,7 @@ Once your test environment is properly configured, the following **Environment V | |
| 1241 1392 | 
             
            | `WEB_BROWSER`             | Must be set to `appium`                                                                                                        |
         | 
| 1242 1393 | 
             
            | `APP_PLATFORM_NAME`       | Must be set to `Android`                                                                                                       |
         | 
| 1243 1394 | 
             
            | `APP_BROWSER`             | Must be set to `Chrome` or `Browser`                                                                                           |
         | 
| 1244 | 
            -
            | `APP_VERSION`             | Must be set to ` | 
| 1395 | 
            +
            | `APP_VERSION`             | Must be set to `12.0`, or which ever Android OS version you wish to run with the Android Virtual Device                        |
         | 
| 1245 1396 | 
             
            | `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 |
         | 
| 1246 1397 | 
             
            | `DEVICE_TYPE`             | Must be set to `phone` or `tablet`                                                                                             |
         | 
| 1247 1398 | 
             
            | `ORIENTATION`             | [Optional] Set to `portrait` or `landscape`                                                                                    |
         | 
| @@ -1253,16 +1404,54 @@ Once your test environment is properly configured, the following **Environment V | |
| 1253 1404 | 
             
            | `NEW_COMMAND_TIMEOUT`     | [Optional] Time (in Seconds) that Appium will wait for a new command from the client                                           |
         | 
| 1254 1405 | 
             
            | `CHROMEDRIVER_EXECUTABLE` | [Optional] Absolute local path to webdriver executable                                                                         |
         | 
| 1255 1406 |  | 
| 1256 | 
            -
            Refer to **section 8. | 
| 1407 | 
            +
            Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
         | 
| 1408 | 
            +
             | 
| 1409 | 
            +
             | 
| 1410 | 
            +
            #### Starting and stopping Appium Server
         | 
| 1411 | 
            +
             | 
| 1412 | 
            +
            The Appium server must be running prior to invoking Cucumber to run your features/scenarios on mobile simulators or physical
         | 
| 1413 | 
            +
            device. To programmatically control the starting and stopping of Appium server with the execution of your automated tests, place
         | 
| 1414 | 
            +
            the code shown below in your `hooks.rb` file.
         | 
| 1415 | 
            +
             | 
| 1416 | 
            +
                BeforeAll do
         | 
| 1417 | 
            +
                  # start Appium Server if APPIUM_SERVER = 'run' and target browser is a mobile simulator or device
         | 
| 1418 | 
            +
                  if ENV['APPIUM_SERVER'] == 'run' && Environ.driver == :appium
         | 
| 1419 | 
            +
                    $server = TestCentricity::AppiumServer.new
         | 
| 1420 | 
            +
                    $server.start
         | 
| 1421 | 
            +
                  end
         | 
| 1422 | 
            +
                end
         | 
| 1423 | 
            +
             | 
| 1424 | 
            +
                AfterAll do
         | 
| 1425 | 
            +
                  # terminate Appium Server if APPIUM_SERVER = 'run' and target browser is a mobile simulator or device
         | 
| 1426 | 
            +
                  $server.stop if ENV['APPIUM_SERVER'] == 'run' && Environ.driver == :appium && $server.running?
         | 
| 1427 | 
            +
                  # close driver
         | 
| 1428 | 
            +
                  Capybara.page.driver.quit
         | 
| 1429 | 
            +
                  Capybara.reset_sessions!
         | 
| 1430 | 
            +
                  Environ.session_state = :quit
         | 
| 1431 | 
            +
                end
         | 
| 1432 | 
            +
             | 
| 1433 | 
            +
             | 
| 1434 | 
            +
            The `APPIUM_SERVER` environment variable must be set to `run` in order to programmatically start and stop Appium server. This can be
         | 
| 1435 | 
            +
            set by adding the following to your `cucumber.yml` file and including `-p run_appium` in your command line when starting your Cucumber
         | 
| 1436 | 
            +
            test suite(s):
         | 
| 1437 | 
            +
             | 
| 1438 | 
            +
                run_appium: APPIUM_SERVER=run
         | 
| 1439 | 
            +
             | 
| 1257 1440 |  | 
| 1441 | 
            +
            Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
         | 
| 1258 1442 |  | 
| 1259 | 
            -
            ### Remotely hosted desktop and mobile web browsers
         | 
| 1260 1443 |  | 
| 1261 | 
            -
             | 
| 1444 | 
            +
            ### Remote cloud hosted desktop and mobile web browsers
         | 
| 1445 | 
            +
             | 
| 1446 | 
            +
            You can run your automated tests against remote cloud hosted desktop and mobile web browsers using the BrowserStack, SauceLabs, TestingBot, or
         | 
| 1262 1447 | 
             
            LambdaTest services. If your tests are running against a web site hosted on your local computer (`localhost`), or on a staging server inside
         | 
| 1263 1448 | 
             
            your LAN, you must set the `TUNNELING` Environment Variable to `true`.
         | 
| 1264 1449 |  | 
| 1265 | 
            -
             | 
| 1450 | 
            +
            Due to lack of support for Selenium 4.x and the W3C browser capabilities protocol, support for CrossBrowserTesting and Gridlastic cloud hosted
         | 
| 1451 | 
            +
            Selenium grid services was removed as of version 4.1 of this gem. If your testing requires access to either of those services, or support for
         | 
| 1452 | 
            +
            Selenium version 3.x, you should use earlier versions of this gem.
         | 
| 1453 | 
            +
             | 
| 1454 | 
            +
            Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
         | 
| 1266 1455 |  | 
| 1267 1456 |  | 
| 1268 1457 | 
             
            #### Remote desktop browsers on the BrowserStack service
         | 
| @@ -1271,24 +1460,24 @@ For remotely hosted desktop web browsers on the BrowserStack service, the follow | |
| 1271 1460 | 
             
            the table below. Refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/automate/capabilities?tag=selenium-4)
         | 
| 1272 1461 | 
             
            for information regarding the specific capabilities.
         | 
| 1273 1462 |  | 
| 1274 | 
            -
            | **Environment Variable** | **Description** | 
| 1275 | 
            -
             | 
| 1276 | 
            -
            | `WEB_BROWSER`            | Must be set to `browserstack` | 
| 1277 | 
            -
            | `BS_USERNAME`            | Must be set to your BrowserStack account user name | 
| 1278 | 
            -
            | `BS_AUTHKEY`             | Must be set to your BrowserStack account access key | 
| 1279 | 
            -
            | `BS_OS`                  | Must be set to `OS X` or `Windows` | 
| 1280 | 
            -
            | `BS_OS_VERSION`          | Refer to `os_version` capability in chart | 
| 1281 | 
            -
            | `BS_BROWSER`             | Refer to ` | 
| 1282 | 
            -
            | `BS_VERSION`             | [Optional] Refer to `browser_version` capability in chart. If not specified, latest stable version of browser will be used. | 
| 1283 | 
            -
            | `TUNNELING`              | Must be `true` if you are testing against internal/local servers (`true` or `false`). If `true`, the BrowserStack Local instance will be automatically started. |
         | 
| 1284 | 
            -
            | `RESOLUTION`             | [Optional] Refer to supported screen `resolution` capability in chart | 
| 1285 | 
            -
            | `RECORD_VIDEO`           | [Optional] Enable screen video recording during test execution (`true` or `false`) | 
| 1286 | 
            -
            | `TIME_ZONE`              | [Optional] Specify custom time zone. Refer to `browserstack.timezone` capability in chart | 
| 1287 | 
            -
            | `IP_GEOLOCATION`         | [Optional] Specify IP Geolocation. Refer to [IP Geolocation](https://www.browserstack.com/ip-geolocation) to select a country code. | 
| 1288 | 
            -
            | `ALLOW_POPUPS`           | [Optional] Allow popups (`true` or `false`) - for Safari, IE, and Edge browsers only | 
| 1289 | 
            -
            | `ALLOW_COOKIES`          | [Optional] Allow all cookies (`true` or `false`) - for Safari browsers only | 
| 1290 | 
            -
            | `SCREENSHOTS`            | [Optional] Generate screenshots for debugging (`true` or `false`) | 
| 1291 | 
            -
            | `NETWORK_LOGS`           | [Optional] Capture network logs (`true` or `false`) | 
| 1463 | 
            +
            | **Environment Variable** | **Description**                                                                                                                                                            |
         | 
| 1464 | 
            +
            |--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
         | 
| 1465 | 
            +
            | `WEB_BROWSER`            | Must be set to `browserstack`                                                                                                                                              |
         | 
| 1466 | 
            +
            | `BS_USERNAME`            | Must be set to your BrowserStack account user name                                                                                                                         |
         | 
| 1467 | 
            +
            | `BS_AUTHKEY`             | Must be set to your BrowserStack account access key                                                                                                                        |
         | 
| 1468 | 
            +
            | `BS_OS`                  | Must be set to `OS X` or `Windows`                                                                                                                                         |
         | 
| 1469 | 
            +
            | `BS_OS_VERSION`          | Refer to `os_version` capability in chart                                                                                                                                  |
         | 
| 1470 | 
            +
            | `BS_BROWSER`             | Refer to `browserName` capability in chart                                                                                                                                 |
         | 
| 1471 | 
            +
            | `BS_VERSION`             | [Optional] Refer to `browser_version` capability in chart. If not specified, latest stable version of browser will be used.                                                |
         | 
| 1472 | 
            +
            | `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. |
         | 
| 1473 | 
            +
            | `RESOLUTION`             | [Optional] Refer to supported screen `resolution` capability in chart                                                                                                      |
         | 
| 1474 | 
            +
            | `RECORD_VIDEO`           | [Optional] Enable screen video recording during test execution (`true` or `false`)                                                                                         |
         | 
| 1475 | 
            +
            | `TIME_ZONE`              | [Optional] Specify custom time zone. Refer to `browserstack.timezone` capability in chart                                                                                  |
         | 
| 1476 | 
            +
            | `IP_GEOLOCATION`         | [Optional] Specify IP Geolocation. Refer to [IP Geolocation](https://www.browserstack.com/ip-geolocation) to select a country code.                                        |
         | 
| 1477 | 
            +
            | `ALLOW_POPUPS`           | [Optional] Allow popups (`true` or `false`) - for Safari, IE, and Edge browsers only                                                                                       |
         | 
| 1478 | 
            +
            | `ALLOW_COOKIES`          | [Optional] Allow all cookies (`true` or `false`) - for Safari browsers only                                                                                                |
         | 
| 1479 | 
            +
            | `SCREENSHOTS`            | [Optional] Generate screenshots for debugging (`true` or `false`)                                                                                                          |
         | 
| 1480 | 
            +
            | `NETWORK_LOGS`           | [Optional] Capture network logs (`true` or `false`)                                                                                                                        |
         | 
| 1292 1481 |  | 
| 1293 1482 | 
             
            If the BrowserStack Local instance is running (`TUNNELING` Environment Variable is `true`), call the`TestCentricity::WebDriverConnect.close_tunnel` method
         | 
| 1294 1483 | 
             
            upon completion of your test suite to stop the Local instance. Place the code shown below in your `env.rb` or `hooks.rb` file.
         | 
| @@ -1305,43 +1494,43 @@ For remotely hosted mobile web browsers on the BrowserStack service, the followi | |
| 1305 1494 | 
             
            the table below. Refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/automate/capabilities?tag=selenium-4)
         | 
| 1306 1495 | 
             
            for information regarding the specific capabilities.
         | 
| 1307 1496 |  | 
| 1308 | 
            -
            | **Environment Variable** | **Description** | 
| 1309 | 
            -
             | 
| 1310 | 
            -
            | `WEB_BROWSER`            | Must be set to `browserstack` | 
| 1311 | 
            -
            | `BS_USERNAME`            | Must be set to your BrowserStack account user name | 
| 1312 | 
            -
            | `BS_AUTHKEY`             | Must be set to your BrowserStack account access key | 
| 1313 | 
            -
            | `BS_OS`                  | Must be set to `ios` or `android` | 
| 1314 | 
            -
            | `BS_BROWSER`             | Must be set to `Safari` (for iOS) or `Chrome` (for Android) | 
| 1315 | 
            -
            | `BS_DEVICE`              | Refer to ` | 
| 1316 | 
            -
            | `BS_REAL_MOBILE`         | Set to `true` if running against a real device | 
| 1317 | 
            -
            | `DEVICE_TYPE`            | Must be set to `phone` or `tablet` | 
| 1318 | 
            -
            | `TUNNELING`              | Must be `true` if you are testing against internal/local servers (`true` or `false`). If `true`, the BrowserStack Local instance will be automatically started. |
         | 
| 1319 | 
            -
            | `ORIENTATION`            | [Optional] Set to `portrait` or `landscape` | 
| 1320 | 
            -
            | `RECORD_VIDEO`           | [Optional] Enable screen video recording during test execution (`true` or `false`) | 
| 1321 | 
            -
            | `TIME_ZONE`              | [Optional] Specify custom time zone. Refer to `browserstack.timezone` capability in chart | 
| 1322 | 
            -
            | `IP_GEOLOCATION`         | [Optional] Specify IP Geolocation. Refer to [IP Geolocation](https://www.browserstack.com/ip-geolocation) to select a country code. | 
| 1323 | 
            -
            | `SCREENSHOTS`            | [Optional] Generate screenshots for debugging (`true` or `false`) | 
| 1324 | 
            -
            | `NETWORK_LOGS`           | [Optional] Capture network logs (`true` or `false`) | 
| 1325 | 
            -
            | `APPIUM_LOGS`            | [Optional] Generate Appium logs (`true` or `false`) | 
| 1497 | 
            +
            | **Environment Variable** | **Description**                                                                                                                                                            |
         | 
| 1498 | 
            +
            |--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
         | 
| 1499 | 
            +
            | `WEB_BROWSER`            | Must be set to `browserstack`                                                                                                                                              |
         | 
| 1500 | 
            +
            | `BS_USERNAME`            | Must be set to your BrowserStack account user name                                                                                                                         |
         | 
| 1501 | 
            +
            | `BS_AUTHKEY`             | Must be set to your BrowserStack account access key                                                                                                                        |
         | 
| 1502 | 
            +
            | `BS_OS`                  | Must be set to `ios` or `android`                                                                                                                                          |
         | 
| 1503 | 
            +
            | `BS_BROWSER`             | Must be set to `Safari` (for iOS) or `Chrome` (for Android)                                                                                                                |
         | 
| 1504 | 
            +
            | `BS_DEVICE`              | Refer to `deviceName` capability in chart                                                                                                                                  |
         | 
| 1505 | 
            +
            | `BS_REAL_MOBILE`         | Set to `true` if running against a real device                                                                                                                             |
         | 
| 1506 | 
            +
            | `DEVICE_TYPE`            | Must be set to `phone` or `tablet`                                                                                                                                         |
         | 
| 1507 | 
            +
            | `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. |
         | 
| 1508 | 
            +
            | `ORIENTATION`            | [Optional] Set to `portrait` or `landscape`                                                                                                                                |
         | 
| 1509 | 
            +
            | `RECORD_VIDEO`           | [Optional] Enable screen video recording during test execution (`true` or `false`)                                                                                         |
         | 
| 1510 | 
            +
            | `TIME_ZONE`              | [Optional] Specify custom time zone. Refer to `browserstack.timezone` capability in chart                                                                                  |
         | 
| 1511 | 
            +
            | `IP_GEOLOCATION`         | [Optional] Specify IP Geolocation. Refer to [IP Geolocation](https://www.browserstack.com/ip-geolocation) to select a country code.                                        |
         | 
| 1512 | 
            +
            | `SCREENSHOTS`            | [Optional] Generate screenshots for debugging (`true` or `false`)                                                                                                          |
         | 
| 1513 | 
            +
            | `NETWORK_LOGS`           | [Optional] Capture network logs (`true` or `false`)                                                                                                                        |
         | 
| 1514 | 
            +
            | `APPIUM_LOGS`            | [Optional] Generate Appium logs (`true` or `false`)                                                                                                                        |
         | 
| 1326 1515 |  | 
| 1327 1516 | 
             
            #### Remote desktop browsers on the Sauce Labs service
         | 
| 1328 1517 |  | 
| 1329 | 
            -
            For remotely hosted desktop web browsers on the Sauce Labs service, the following **Environment Variables** must be set as described in
         | 
| 1330 | 
            -
             | 
| 1331 | 
            -
            information regarding the specific capabilities.
         | 
| 1332 | 
            -
             | 
| 1333 | 
            -
            | **Environment Variable** | **Description** | 
| 1334 | 
            -
             | 
| 1335 | 
            -
            | `WEB_BROWSER`            | Must be set to `saucelabs` | 
| 1336 | 
            -
            | `SL_USERNAME`            | Must be set to your Sauce Labs account user name or email address | 
| 1337 | 
            -
            | `SL_AUTHKEY`             | Must be set to your Sauce Labs account access key | 
| 1338 | 
            -
            | `DATA_CENTER`            | Must be set to your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`) | 
| 1339 | 
            -
            | `SL_OS`                  | Refer to ` | 
| 1340 | 
            -
            | `SL_BROWSER`             | Must be set to `chrome`, `firefox`, `safari`, `internet explorer`, or ` | 
| 1341 | 
            -
            | `SL_VERSION`             | Refer to ` | 
| 1342 | 
            -
            | `RESOLUTION`             | [Optional] Refer to supported `screenResolution` capability in the  | 
| 1343 | 
            -
            | `BROWSER_SIZE `          | [Optional] Specify width, height of browser window | 
| 1344 | 
            -
            | `RECORD_VIDEO`           | [Optional] Enable screen video recording during test execution (`true` or `false`) | 
| 1518 | 
            +
            For remotely hosted desktop web browsers on the Sauce Labs service, the following **Environment Variables** must be set as described in the
         | 
| 1519 | 
            +
            table below. Use the Selenium 4 selection on the [Platform Configurator page](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/)
         | 
| 1520 | 
            +
            to obtain information regarding the specific capabilities.
         | 
| 1521 | 
            +
             | 
| 1522 | 
            +
            | **Environment Variable** | **Description**                                                                                                            |
         | 
| 1523 | 
            +
            |--------------------------|----------------------------------------------------------------------------------------------------------------------------|
         | 
| 1524 | 
            +
            | `WEB_BROWSER`            | Must be set to `saucelabs`                                                                                                 |
         | 
| 1525 | 
            +
            | `SL_USERNAME`            | Must be set to your Sauce Labs account user name or email address                                                          |
         | 
| 1526 | 
            +
            | `SL_AUTHKEY`             | Must be set to your Sauce Labs account access key                                                                          |
         | 
| 1527 | 
            +
            | `DATA_CENTER`            | Must be set to your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`)            |
         | 
| 1528 | 
            +
            | `SL_OS`                  | Refer to `platformName` capability in the Config Script section of the Platform Configurator page                          |
         | 
| 1529 | 
            +
            | `SL_BROWSER`             | Must be set to `chrome`, `firefox`, `safari`, `internet explorer`, or `MicrosoftEdge`                                      |
         | 
| 1530 | 
            +
            | `SL_VERSION`             | Refer to `browserVersion` capability in the Config Script section of the Platform Configurator page                        |
         | 
| 1531 | 
            +
            | `RESOLUTION`             | [Optional] Refer to supported `screenResolution` capability in the Config Script section of the Platform Configurator page |
         | 
| 1532 | 
            +
            | `BROWSER_SIZE `          | [Optional] Specify width, height of browser window                                                                         |
         | 
| 1533 | 
            +
            | `RECORD_VIDEO`           | [Optional] Enable screen video recording during test execution (`true` or `false`)                                         |
         | 
| 1345 1534 |  | 
| 1346 1535 | 
             
            #### Remote desktop browsers on the TestingBot service
         | 
| 1347 1536 |  | 
| @@ -1357,24 +1546,24 @@ regarding the specific capabilities. | |
| 1357 1546 | 
             
            | `TB_OS`                  | Refer to `platform` capability in chart                                                                           |
         | 
| 1358 1547 | 
             
            | `TB_BROWSER`             | Refer to `browserName` capability in chart                                                                        |
         | 
| 1359 1548 | 
             
            | `TB_VERSION`             | Refer to `version` capability in chart                                                                            |
         | 
| 1360 | 
            -
            | `TUNNELING`              | Must be `true` if you are testing against internal/local servers (`true` or `false`) | 
| 1549 | 
            +
            | `TUNNELING`              | [Optional] Must be `true` if you are testing against internal/local servers (`true` or `false`)                   |
         | 
| 1361 1550 | 
             
            | `RESOLUTION`             | [Optional] Possible values: `800x600`, `1024x768`, `1280x960`, `1280x1024`, `1600x1200`, `1920x1200`, `2560x1440` |
         | 
| 1362 1551 | 
             
            | `BROWSER_SIZE`           | [Optional] Specify width, height of browser window                                                                |
         | 
| 1363 1552 |  | 
| 1364 1553 | 
             
            #### Remote desktop browsers on the LambdaTest service
         | 
| 1365 1554 |  | 
| 1366 1555 | 
             
            For remotely hosted desktop web browsers on the LambdaTest service, the following **Environment Variables** must be set as described in the table
         | 
| 1367 | 
            -
            below. Use the Configuration Wizard on the [Selenium Desired Capabilities Generator](https://www.lambdatest.com/capabilities-generator/) | 
| 1368 | 
            -
            information regarding the specific capabilities.
         | 
| 1556 | 
            +
            below. Use the Selenium 4 Configuration Wizard on the [Selenium Desired Capabilities Generator](https://www.lambdatest.com/capabilities-generator/)
         | 
| 1557 | 
            +
            to obtain information regarding the specific capabilities.
         | 
| 1369 1558 |  | 
| 1370 1559 | 
             
            | **Environment Variable** | **Description**                                                                          |
         | 
| 1371 1560 | 
             
            |--------------------------|------------------------------------------------------------------------------------------|
         | 
| 1372 1561 | 
             
            | `WEB_BROWSER`            | Must be set to `lambdatest`                                                              |
         | 
| 1373 1562 | 
             
            | `LT_USERNAME`            | Must be set to your LambdaTest account user name or email address                        |
         | 
| 1374 1563 | 
             
            | `LT_AUTHKEY`             | Must be set to your LambdaTest account access key                                        |
         | 
| 1375 | 
            -
            | `LT_OS`                  | Refer to ` | 
| 1564 | 
            +
            | `LT_OS`                  | Refer to `platformName` capability in the sample script of the Wizard                    |
         | 
| 1376 1565 | 
             
            | `LT_BROWSER`             | Refer to `browserName` capability in the sample script of the Wizard                     |
         | 
| 1377 | 
            -
            | `LT_VERSION`             | Refer to ` | 
| 1566 | 
            +
            | `LT_VERSION`             | Refer to `browserVersion` capability in chart                                            |
         | 
| 1378 1567 | 
             
            | `RESOLUTION`             | [Optional] Refer to supported `resolution` capability in the sample script of the Wizard |
         | 
| 1379 1568 | 
             
            | `BROWSER_SIZE`           | [Optional] Specify width, height of browser window                                       |
         | 
| 1380 1569 | 
             
            | `RECORD_VIDEO`           | [Optional] Enable screen video recording during test execution (`true` or `false`)       |
         | 
| @@ -1480,17 +1669,25 @@ that you intend to connect with. | |
| 1480 1669 |  | 
| 1481 1670 | 
             
                portrait:  ORIENTATION=portrait
         | 
| 1482 1671 | 
             
                landscape: ORIENTATION=landscape
         | 
| 1672 | 
            +
             | 
| 1483 1673 |  | 
| 1674 | 
            +
                #==============
         | 
| 1675 | 
            +
                # profile to start Appium Server prior to running mobile browser tests on iOS or Android simulators or physical devices
         | 
| 1676 | 
            +
                #==============
         | 
| 1484 1677 |  | 
| 1678 | 
            +
                run_appium: APPIUM_SERVER=run
         | 
| 1679 | 
            +
             | 
| 1680 | 
            +
             | 
| 1485 1681 | 
             
                #==============
         | 
| 1486 1682 | 
             
                # profiles for mobile Safari web browsers hosted within XCode iOS simulator
         | 
| 1487 1683 | 
             
                # NOTE: Requires installation of XCode, iOS version specific target simulators, Appium, and the appium_capybara gem
         | 
| 1488 1684 | 
             
                #==============
         | 
| 1489 1685 |  | 
| 1490 | 
            -
                appium_ios: WEB_BROWSER=appium AUTOMATION_ENGINE=XCUITest APP_PLATFORM_NAME="ios" APP_BROWSER="Safari" NEW_COMMAND_TIMEOUT=30  | 
| 1491 | 
            -
                app_ios_15: --profile appium_ios APP_VERSION="15. | 
| 1492 | 
            -
                 | 
| 1493 | 
            -
                ipad_air_15_sim: | 
| 1686 | 
            +
                appium_ios: WEB_BROWSER=appium AUTOMATION_ENGINE=XCUITest APP_PLATFORM_NAME="ios" APP_BROWSER="Safari" NEW_COMMAND_TIMEOUT=30 SHOW_SIM_KEYBOARD=false
         | 
| 1687 | 
            +
                app_ios_15: --profile appium_ios APP_VERSION="15.4"
         | 
| 1688 | 
            +
                ipad_pro_12_15_sim: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (12.9-inch) (5th generation)"
         | 
| 1689 | 
            +
                ipad_air_15_sim:    --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad Air (5th generation)" <%= desktop %>
         | 
| 1690 | 
            +
                ipad_15_sim:        --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad (9th generation)"
         | 
| 1494 1691 |  | 
| 1495 1692 |  | 
| 1496 1693 | 
             
                #==============
         | 
| @@ -1608,38 +1805,62 @@ To specify a locally hosted target browser using a profile at runtime, you use t | |
| 1608 1805 | 
             
            invoking Cucumber in the command line. For instance, the following command invokes Cucumber and specifies that a local instance of Firefox
         | 
| 1609 1806 | 
             
            will be used as the target web browser:
         | 
| 1610 1807 |  | 
| 1611 | 
            -
                 | 
| 1808 | 
            +
                cucumber -p firefox
         | 
| 1612 1809 |  | 
| 1613 1810 |  | 
| 1614 | 
            -
            The following command specifies that Cucumber will run tests against an instance of Chrome hosted within a Dockerized Selenium Grid  | 
| 1811 | 
            +
            The following command specifies that Cucumber will run tests against an instance of Chrome hosted within a Dockerized Selenium Grid 4
         | 
| 1812 | 
            +
            environment:
         | 
| 1615 1813 |  | 
| 1616 | 
            -
                 | 
| 1814 | 
            +
                cucumber -p chrome -p grid
         | 
| 1617 1815 |  | 
| 1618 1816 |  | 
| 1619 1817 | 
             
            The following command specifies that Cucumber will run tests against a local instance of Chrome, which will be used to emulate an iPad Pro
         | 
| 1620 1818 | 
             
            in landscape orientation:
         | 
| 1621 1819 |  | 
| 1622 | 
            -
                 | 
| 1820 | 
            +
                cucumber -p ipad_pro -p landscape
         | 
| 1623 1821 |  | 
| 1624 1822 |  | 
| 1625 | 
            -
            The following command specifies that Cucumber will run tests against an iPad Pro with iOS version  | 
| 1626 | 
            -
            in landscape orientation:
         | 
| 1823 | 
            +
            The following command specifies that Cucumber will run tests against an iPad Pro (12.9-inch) (5th generation) with iOS version 15.2 in an
         | 
| 1824 | 
            +
            XCode Simulator in landscape orientation:
         | 
| 1627 1825 |  | 
| 1628 | 
            -
                 | 
| 1826 | 
            +
                cucumber -p ipad_pro_12_15_sim -p landscape
         | 
| 1629 1827 |  | 
| 1630 1828 | 
             
                NOTE:  Appium must be running prior to executing this command
         | 
| 1631 1829 |  | 
| 1830 | 
            +
            You can ensure that Appium Server is running by including `-p run_appium` in your command line:
         | 
| 1831 | 
            +
             | 
| 1832 | 
            +
                cucumber -p ipad_pro_12_15_sim -p landscape -p run_appium
         | 
| 1833 | 
            +
             | 
| 1632 1834 |  | 
| 1633 | 
            -
            The following command specifies that Cucumber will run tests against a remotely hosted Safari web browser running on  | 
| 1835 | 
            +
            The following command specifies that Cucumber will run tests against a remotely hosted Safari web browser running on a macOS Monterey
         | 
| 1634 1836 | 
             
            virtual machine on the BrowserStack service:
         | 
| 1635 1837 |  | 
| 1636 | 
            -
                cucumber -p  | 
| 1637 | 
            -
             | 
| 1838 | 
            +
                cucumber -p bs_safari_monterey
         | 
| 1839 | 
            +
             | 
| 1840 | 
            +
             | 
| 1638 1841 |  | 
| 1639 | 
            -
             | 
| 1640 | 
            -
            landscape orientation running on the BrowserStack service:
         | 
| 1842 | 
            +
            ## Recommended Project Organization and Structure
         | 
| 1641 1843 |  | 
| 1642 | 
            -
             | 
| 1844 | 
            +
            Below is an example of the project structure of a typical Cucumber based test automation framework with a Page Object Model
         | 
| 1845 | 
            +
            architecture. `PageObject` class definitions should be stored in the `/features/support/pages` folder, organized in functional
         | 
| 1846 | 
            +
            area sub-folders as needed. Likewise, `PageSection` class definitions should be stored in the `/features/support/sections` folder.
         | 
| 1847 | 
            +
             | 
| 1848 | 
            +
                my_automation_project
         | 
| 1849 | 
            +
                    ├── config
         | 
| 1850 | 
            +
                    │   ├── locales
         | 
| 1851 | 
            +
                    │   ├── test_data
         | 
| 1852 | 
            +
                    │   └── cucumber.yml
         | 
| 1853 | 
            +
                    ├── downloads
         | 
| 1854 | 
            +
                    ├── features
         | 
| 1855 | 
            +
                    │   ├── step_definitions
         | 
| 1856 | 
            +
                    │   └── support
         | 
| 1857 | 
            +
                    │   │   ├── pages
         | 
| 1858 | 
            +
                    │   │   ├── sections
         | 
| 1859 | 
            +
                    │   │   ├── env.rb
         | 
| 1860 | 
            +
                    │   │   ├── hooks.rb
         | 
| 1861 | 
            +
                    │   │   └── world_pages.rb
         | 
| 1862 | 
            +
                    ├── Gemfile
         | 
| 1863 | 
            +
                    └── README.md
         | 
| 1643 1864 |  | 
| 1644 1865 |  | 
| 1645 1866 |  |