testcentricity_web 4.3.0 → 4.4.0

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -11
  3. data/LICENSE.md +1 -1
  4. data/README.md +1931 -801
  5. data/lib/devices/devices.yml +144 -216
  6. data/lib/testcentricity_web/browser_helper.rb +33 -4
  7. data/lib/testcentricity_web/data_objects/environment.rb +96 -15
  8. data/lib/testcentricity_web/exception_queue_helper.rb +5 -6
  9. data/lib/testcentricity_web/version.rb +1 -1
  10. data/lib/testcentricity_web/web_core/page_object.rb +53 -49
  11. data/lib/testcentricity_web/web_core/page_objects_helper.rb +20 -11
  12. data/lib/testcentricity_web/web_core/page_section.rb +31 -34
  13. data/lib/testcentricity_web/web_core/webdriver_helper.rb +416 -288
  14. data/lib/testcentricity_web/web_elements/audio.rb +6 -4
  15. data/lib/testcentricity_web/web_elements/button.rb +7 -4
  16. data/lib/testcentricity_web/web_elements/checkbox.rb +149 -147
  17. data/lib/testcentricity_web/web_elements/file_field.rb +38 -36
  18. data/lib/testcentricity_web/web_elements/image.rb +75 -70
  19. data/lib/testcentricity_web/web_elements/label.rb +6 -4
  20. data/lib/testcentricity_web/web_elements/link.rb +15 -13
  21. data/lib/testcentricity_web/web_elements/list.rb +171 -169
  22. data/lib/testcentricity_web/web_elements/media.rb +384 -379
  23. data/lib/testcentricity_web/web_elements/radio.rb +135 -133
  24. data/lib/testcentricity_web/web_elements/range.rb +16 -29
  25. data/lib/testcentricity_web/web_elements/select_list.rb +247 -245
  26. data/lib/testcentricity_web/web_elements/table.rb +575 -573
  27. data/lib/testcentricity_web/web_elements/textfield.rb +143 -139
  28. data/lib/testcentricity_web/web_elements/ui_element.rb +1171 -0
  29. data/lib/testcentricity_web/web_elements/video.rb +39 -37
  30. data/lib/testcentricity_web/world_extensions.rb +37 -4
  31. data/lib/testcentricity_web.rb +4 -23
  32. metadata +27 -79
  33. data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +0 -1148
data/README.md CHANGED
@@ -1,22 +1,26 @@
1
1
  # TestCentricity™ Web
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/testcentricity_web.svg)](https://badge.fury.io/rb/testcentricity_web) [![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause)
4
- ![Gem Downloads](https://img.shields.io/gem/dt/testcentricity_web) ![Maintained](https://img.shields.io/maintenance/yes/2022)
3
+ [![Gem Version](https://badge.fury.io/rb/testcentricity_web.svg)](https://badge.fury.io/rb/testcentricity_web)
4
+ [![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause)
5
+ ![Gem Downloads](https://img.shields.io/gem/dt/testcentricity_web)
6
+ ![Maintained](https://img.shields.io/maintenance/yes/2023)
7
+ [![Docs](https://img.shields.io/badge/docs-rubydoc-blue.svg)](http://www.rubydoc.info/gems/testcentricity_web)
5
8
 
6
9
 
7
- The TestCentricity™ Web core framework for desktop and mobile web browser-based app testing implements a Page Object Model DSL for use
8
- with Cucumber (version 7.x or greater), Capybara (version 3.37), and Selenium-Webdriver (version 4.3). It also facilitates the configuration of the appropriate
9
- Selenium-Webdriver capabilities required to establish a connection with a local or cloud hosted desktop or mobile web browser.
10
+ The TestCentricity™ Web core framework for desktop and mobile web browser-based app testing implements a Page Object Model
11
+ DSL for use with Cucumber (version 7.x or greater) or RSpec, and Selenium-Webdriver (version 4.14). It also facilitates the
12
+ configuration of the appropriate Selenium-Webdriver capabilities required to establish connections with one or more local
13
+ or cloud hosted desktop or mobile web browsers.
10
14
 
11
- The TestCentricity™ Web gem supports running automated tests against the following web test targets:
12
- * locally hosted desktop browsers (Chrome, Edge, Firefox, Safari, or IE)
15
+ The TestCentricity™ Web gem supports connecting to, and running automated tests against the following target web browsers:
16
+ * locally hosted desktop browsers (Chrome, Edge, Firefox, or Safari)
13
17
  * locally hosted "headless" Chrome, Firefox, or Edge browsers
14
18
  * remote desktop and emulated mobile web browsers hosted on Selenium Grid 4 and Dockerized Selenium Grid 4 environments
15
19
  * mobile Safari browsers on iOS device simulators or physical iOS devices (using Appium and XCode on macOS)
16
- * mobile Chrome or Android browsers on Android Studio virtual device emulators (using Appium and Android Studio on macOS)
17
- * cloud hosted desktop (Firefox, Chrome, Safari, IE, or Edge) or mobile (iOS Mobile Safari or Android) web browsers using the following service:
20
+ * mobile Chrome or Android browsers on Android Studio virtual device emulators (using Appium and Android Studio)
21
+ * cloud hosted desktop (Firefox, Chrome, Safari, IE, or Edge) or mobile (iOS Mobile Safari or Android Chrome) web browsers using the following service:
18
22
  * [Browserstack](https://www.browserstack.com/list-of-browsers-and-platforms?product=automate)
19
- * [Sauce Labs](https://saucelabs.com/open-source#automated-testing-platform)
23
+ * [Sauce Labs](https://saucelabs.com/platform/cross-browser-testing)
20
24
  * [TestingBot](https://testingbot.com/features)
21
25
  * [LambdaTest](https://www.lambdatest.com/selenium-automation)
22
26
  * web portals utilizing JavaScript front end application frameworks like Ember, React, Angular, and GWT
@@ -36,8 +40,8 @@ can be found [here](https://github.com/TestCentricity/tc_web_sample).
36
40
 
37
41
  ## Installation
38
42
 
39
- TestCentricity Web version 4.1 and above requires Ruby 2.7.5 or later. To install the TestCentricity Web gem, add this line to your
40
- automation project's Gemfile:
43
+ TestCentricity Web version 4.4 and above requires Ruby version 3.0.0 or later. To install the TestCentricity Web gem, add
44
+ this line to your automation project's `Gemfile`:
41
45
 
42
46
  gem 'testcentricity_web'
43
47
 
@@ -45,7 +49,7 @@ And then execute:
45
49
 
46
50
  $ bundle
47
51
 
48
- Or install it yourself as:
52
+ Or install it yourself using:
49
53
 
50
54
  $ gem install testcentricity_web
51
55
 
@@ -63,44 +67,30 @@ If you are using Cucumber, you need to require the following in your `env.rb` fi
63
67
 
64
68
  If you are using RSpec instead, you need to require the following in your `spec_helper.rb` file:
65
69
 
66
- require 'capybara'
67
70
  require 'capybara/rspec'
68
71
  require 'testcentricity_web'
69
72
 
70
73
 
71
- ### Using Appium
72
-
73
- If you will be running your tests on mobile Safari browsers on simulated iOS devices using Appium and XCode Simulators, you need to require
74
- the following in your `env.rb` and/or `spec_helper.rb` file:
75
-
76
- require 'appium_capybara'
77
-
78
- You also need to add this line to your automation project's Gemfile:
79
-
80
- gem 'appium_capybara'
81
-
82
- And then execute:
83
-
84
- $ bundle
85
-
86
-
74
+ ---
87
75
  ## PageObjects
88
76
 
89
- 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
90
- in tests. A **Page Object** is an object that represents a single page in your AUT (Application Under Test). **Page Objects** encapsulate the
91
- implementation details of a web page and expose an API that supports interaction with, and validation of the UI elements on the page.
77
+ The **Page Object Model** is a test automation pattern that aims to create an abstraction of your web app's User Interface
78
+ that can be used in tests. A **Page Object** represents a single page in your AUT (Application Under Test). **Page Objects**
79
+ encapsulate the implementation details of a web page and expose an API that supports interaction with, and validation of
80
+ the UI elements on the page.
92
81
 
93
- **Page Objects** makes it easier to maintain automated tests because changes to page UI elements are updated in only one location - in the
94
- **Page Object** class definition. By adopting a **Page Object Model**, Cucumber Feature files and step definitions are no longer required to
95
- hold specific information about a page's UI objects, thus minimizing maintenance requirements. If any element on, or property of a page changes
96
- (URL path, text field attributes, button captions, etc.), maintenance is performed in the `PageObject` class definition only, typically with
97
- no need to update the affected feature file, scenarios, or step definitions.
82
+ **Page Objects** makes it easier to maintain automated tests because changes to page UI elements are updated in only one
83
+ location - in the **Page Object** class definition. By adopting a **Page Object Model**, Cucumber Feature files and step
84
+ definitions are no longer required to hold specific information about a page's UI objects, thus minimizing maintenance
85
+ requirements. If any element on, or property of a page changes (URL path, text field attributes, button captions, etc.),
86
+ maintenance is performed in the `PageObject` class definition only, typically with no need to update the affected feature
87
+ files, scenarios, or step definitions.
98
88
 
99
89
 
100
90
  ### Defining a PageObject
101
91
 
102
- Your `PageObject` class definitions should be contained within individual `.rb` files in the `features/support/pages` folder of your
103
- test automation project. You define new `PageObjects` as shown below:
92
+ Your `PageObject` class definitions should be contained within individual `.rb` files in the `features/support/pages` folder
93
+ of your test automation project. You define new `PageObjects` as shown below:
104
94
 
105
95
  class LoginPage < TestCentricity::PageObject
106
96
  end
@@ -114,27 +104,32 @@ test automation project. You define new `PageObjects` as shown below:
114
104
  end
115
105
 
116
106
 
117
- ### Adding Traits to your PageObject
107
+ class UserAccountPage < TestCentricity::PageObject
108
+ end
109
+
118
110
 
119
- Web pages typically have names and URLs associated with them. Web pages also typically have a unique object or attribute that, when present,
120
- indicates that the page's contents have fully loaded.
111
+ ### Adding Traits to a PageObject
121
112
 
122
- The `page_name` trait is registered with the `PageManager` object, which includes a `find_page` method that takes a page name as a
123
- parameter and returns an instance of the associated `PageObject`. If you intend to use the `PageManager`, you must define a `page_name`
124
- trait for each `PageObject` to be registered.
113
+ Web pages typically have names and URLs associated with them. Web pages also typically have a unique object or attribute
114
+ that, when present, indicates that the page's contents have fully loaded.
125
115
 
126
- 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.
127
- `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
128
- an `Array` of `String` values representing those page names.
116
+ The `page_name` trait is registered with the `PageManager` object, which includes a `find_page` method that takes a page
117
+ name as a parameter and returns an instance of the associated `PageObject`. If you intend to use the `PageManager`, you
118
+ must define a `page_name` trait for each `PageObject` to be registered. Refer to [**section 7 (Instantiating Your PageObjects)**](#instantiating-your-pageobjects).
129
119
 
130
- A `page_locator` trait is defined if a page has a unique object or attribute that exists once the page's contents have fully loaded. The
131
- `page_locator` trait is a CSS or Xpath expression that uniquely identifies the object or attribute. The `verify_page_exists` method waits
132
- for the `page_locator` trait to exist.
133
120
 
134
- A `page_url` trait should be defined if a page can be directly loaded using a URL. If you set Capybara's `app_host`, or specify a base URL
135
- when calling the `WebDriverConnect.initialize_web_driver` method, then your `page_url` trait can be the relative URL slug that will
136
- be appended to the base URL specified in `app_host`. Specifying a `page_url` trait is optional, as not all web pages can be directly loaded
137
- via a URL.
121
+ The `page_name` trait is usually a `String` value that represents the name of the page that will be matched by the `PageManager.findpage`
122
+ method. `page_name` traits are case and white-space sensitive. For pages that may be referenced with multiple names, the
123
+ `page_name` trait may also be an `Array` of `String` values representing those page names.
124
+
125
+ A `page_locator` trait is defined if a page has a unique object or attribute that exists once the page's contents have fully
126
+ loaded. The `page_locator` trait is a CSS or Xpath expression that uniquely identifies the object or attribute. The
127
+ `verify_page_exists` method waits for the `page_locator` trait to exist.
128
+
129
+ An optional `page_url` trait should be defined if a page can be directly loaded using a URL. If you set Capybara's `app_host`,
130
+ or specify a base URL when calling the `WebDriverConnect.initialize_web_driver` method, then your `page_url` trait can be the
131
+ relative URL slug that will be appended to the base URL specified in `app_host`. Specifying a `page_url` trait is optional,
132
+ as not all web pages can be directly loaded via a URL.
138
133
 
139
134
  You define your page's **Traits** as shown below:
140
135
 
@@ -160,7 +155,14 @@ You define your page's **Traits** as shown below:
160
155
  end
161
156
 
162
157
 
163
- ### Adding UI Elements to your PageObject
158
+ class UserAccountPage < TestCentricity::PageObject
159
+ trait(:page_name) { 'User Account' }
160
+ trait(:page_url) { "/user_account/#{User.current.id}" }
161
+ trait(:page_locator) { 'body.useraccount' }
162
+ end
163
+
164
+
165
+ ### Adding UI Elements to a PageObject
164
166
 
165
167
  Web pages are made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists, buttons, etc.
166
168
  **UI Elements** are added to your `PageObject` class definition as shown below:
@@ -169,7 +171,7 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes,
169
171
  trait(:page_name) { 'Login' }
170
172
  trait(:page_url) { '/sign_in' }
171
173
  trait(:page_locator) { 'body.login-body' }
172
-
174
+
173
175
  # Login page UI elements
174
176
  textfield :user_id_field, 'input#userName'
175
177
  textfield :password_field, 'input#password'
@@ -177,13 +179,13 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes,
177
179
  checkbox :remember_checkbox, 'input#rememberUser'
178
180
  label :error_message_label, 'div#statusBar.login-error'
179
181
  end
180
-
182
+
181
183
 
182
184
  class RegistrationPage < TestCentricity::PageObject
183
185
  trait(:page_name) { 'Registration' }
184
186
  trait(:page_url) { '/register' }
185
187
  trait(:page_locator) { 'body.registration' }
186
-
188
+
187
189
  # Registration page UI elements
188
190
  textfields first_name_field: 'input#firstName',
189
191
  last_name_field: 'input#lastName',
@@ -202,17 +204,17 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes,
202
204
  end
203
205
 
204
206
 
205
- ### Adding Methods to your PageObject
207
+ ### Adding Methods to a PageObject
206
208
 
207
- It is good practice for your Cucumber step definitions to call high level methods in your your `PageObject` instead of directly accessing
208
- and interacting with a page object's UI elements. You can add high level methods to your `PageObject` class definition for interacting with
209
- the UI to hide implementation details, as shown below:
209
+ It is good practice for your Cucumber step definitions to call high level methods in your your `PageObject` instead of
210
+ directly accessing and interacting with a page object's UI elements. You can add high level methods to your `PageObject`
211
+ class definition for interacting with the UI to hide implementation details, as shown below:
210
212
 
211
213
  class LoginPage < TestCentricity::PageObject
212
214
  trait(:page_name) { 'Login' }
213
215
  trait(:page_url) { '/sign_in' }
214
216
  trait(:page_locator) { 'body.login-body' }
215
-
217
+
216
218
  # Login page UI elements
217
219
  textfield :user_id_field, 'input#userName'
218
220
  textfield :password_field, 'input#password'
@@ -220,7 +222,7 @@ the UI to hide implementation details, as shown below:
220
222
  checkbox :remember_checkbox, 'input#rememberUser'
221
223
  label :error_message_label, 'div#statusBar.login-error'
222
224
  link :forgot_password_link, 'a.forgotPassword'
223
-
225
+
224
226
  # log in to web app
225
227
  def login(user_id, password)
226
228
  user_id_field.set(user_id)
@@ -236,24 +238,44 @@ the UI to hide implementation details, as shown below:
236
238
  # verify Login page default UI state
237
239
  def verify_page_ui
238
240
  ui = {
239
- self => { title: 'Login' },
240
- login_button => { visible: true, caption: 'LOGIN' },
241
- user_id_field => { visible: true, enabled: true, value: '', placeholder: 'User name' },
242
- password_field => { visible: true, enabled: true, value: '', placeholder: 'Password' },
243
- remember_checkbox => { exists: true, enabled: true, checked: false },
244
- forgot_password_link => { visible: true, caption: 'Forgot your password?' },
245
- error_message_label => { visible: false }
241
+ self => { title: 'Login' },
242
+ login_button => {
243
+ visible: true,
244
+ caption: 'LOGIN'
245
+ },
246
+ user_id_field => {
247
+ visible: true,
248
+ enabled: true,
249
+ value: '',
250
+ placeholder: 'User name'
251
+ },
252
+ password_field => {
253
+ visible: true,
254
+ enabled: true,
255
+ value: '',
256
+ placeholder: 'Password'
257
+ },
258
+ remember_checkbox => {
259
+ exists: true,
260
+ enabled: true,
261
+ checked: false
262
+ },
263
+ forgot_password_link => {
264
+ visible: true,
265
+ caption: 'Forgot your password?'
266
+ },
267
+ error_message_label => { visible: false }
246
268
  }
247
269
  verify_ui_states(ui)
248
270
  end
249
271
  end
250
-
272
+
251
273
 
252
274
  class RegistrationPage < TestCentricity::PageObject
253
275
  trait(:page_name) { 'Registration' }
254
276
  trait(:page_url) { '/register' }
255
277
  trait(:page_locator) { 'body.registration' }
256
-
278
+
257
279
  # Registration page UI elements
258
280
  textfields first_name_field: 'input#firstName',
259
281
  last_name_field: 'input#lastName',
@@ -270,7 +292,7 @@ the UI to hide implementation details, as shown below:
270
292
  checkbox :email_opt_in_check, 'input#marketingEmailsOptIn'
271
293
  buttons sign_up_button: 'button#registrationSignUp',
272
294
  cancel_button: 'button#registrationCancel'
273
-
295
+
274
296
  # populate Registration page fields with profile data
275
297
  def enter_profile_data(profile)
276
298
  fields = { title_select => profile.title,
@@ -297,32 +319,38 @@ the UI to hide implementation details, as shown below:
297
319
  Once your `PageObjects` have been instantiated, you can call your methods as shown below:
298
320
 
299
321
  login_page.remember_me(true)
300
- login_page.login('snicklefritz', 'Pa55w0rd')
301
-
322
+ login_page.login(user_id = 'snicklefritz', password = 'Pa55w0rd')
302
323
 
303
324
 
325
+ ---
304
326
  ## PageSections
305
327
 
306
- A `PageSection` is a collection of **UI Elements** that may appear in multiple locations on a page, or on multiple pages in a web
307
- app. It is a collection of **UI Elements** that represent a conceptual area of functionality, like a navigation bar, a search capability,
308
- or a menu. **UI Elements** and functional behavior are confined to the scope of a `PageSection` object.
328
+ A `PageSection` is a collection of **UI Elements** that may appear in multiple locations on a page, or on multiple pages
329
+ in a web app. It is a collection of **UI Elements** that represent a conceptual area of functionality, like a navigation
330
+ bar, a search capability, a menu, or a pop-up panel. **UI Elements** and functional behavior are confined to the scope of
331
+ a `PageSection` object.
332
+
333
+ Below is an example of a header navigation bar feature that is common to multiple pages -
334
+
335
+ ![Navigation Header](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/NavBar1.png "Navigation Header")
309
336
 
310
- <img src="https://i.imgur.com/BTgi59R.jpg" alt="Navigation Header" title="Navigation Header">
337
+ -
311
338
 
312
- <img src="https://i.imgur.com/dkxloE5.jpg" alt="Navigation Header" title="Navigation Header">
339
+ ![Navigation Header](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/NavBar2.png "Navigation Header")
313
340
 
314
- <img src="https://i.imgur.com/Yqgw4sP.jpg" alt="User Profile Popup" title="User Profile Popup">
341
+ Below is an example of a popup Shopping Bag panel associated with a header navigation bar -
315
342
 
343
+ ![Shopping Bag Popup](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/ShoppingBagPopUp.png "Shopping Bag Popup")
316
344
 
317
345
  A `PageSection` may contain other `PageSection` objects.
318
346
 
319
347
 
320
348
  ### Defining a PageSection
321
349
 
322
- Your `PageSection` class definitions should be contained within individual `.rb` files in the `features/support/sections` folder of
323
- your test automation project. You define new `PageSection` as shown below:
350
+ Your `PageSection` class definitions should be contained within individual `.rb` files in the `features/support/sections`
351
+ folder of your test automation project. You define new `PageSection` as shown below:
324
352
 
325
- class SearchForm < TestCentricity::PageSection
353
+ class BagViewPopup < TestCentricity::PageSection
326
354
  end
327
355
 
328
356
 
@@ -333,42 +361,64 @@ specifies the CSS or Xpath expression that uniquely identifies that root node ob
333
361
 
334
362
  You define your section's **Traits** as shown below:
335
363
 
336
- class SearchForm < TestCentricity::PageSection
337
- trait(:section_locator) { 'form#gnav-search' }
338
- trait(:section_name) { 'Search widget' }
364
+ class BagViewPopup < TestCentricity::PageSection
365
+ trait(:section_locator) { 'aside.ac-gn-bagview' }
366
+ trait(:section_name) { 'Shopping Bag Popup' }
339
367
  end
340
368
 
341
369
 
342
- ### Adding UI Elements to your PageSection
370
+ ### Adding UI Elements to a PageSection
343
371
 
344
- `PageSections` are typically made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists, buttons, etc.
345
- **UI Elements** are added to your `PageSection` class definition as shown below:
372
+ `PageSections` are typically made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists,
373
+ buttons, etc. **UI Elements** are added to your `PageSection` class definition as shown below:
346
374
 
347
- class SearchForm < TestCentricity::PageSection
348
- trait(:section_locator) { 'form#gnav-search' }
349
- trait(:section_name) { 'Search widget' }
350
-
351
- # Search Form UI elements
352
- textfield :search_field, 'input#search-query'
353
- button :search_button, 'button[type=submit]'
375
+ class BagViewPopup < TestCentricity::PageSection
376
+ trait(:section_locator) { 'aside.ac-gn-bagview' }
377
+ trait(:section_name) { 'Shopping Bag Popup' }
378
+
379
+ # Shopping Bag Popup UI elements
380
+ label :bag_message, 'p[class*="ac-gn-bagview-message"]'
381
+ lists bag_items_list: 'ul[class*="ac-gn-bagview-bag"]',
382
+ bag_nav_list: 'ul.ac-gn-bagview-nav-list '
383
+ button :checkout_button, 'a[class*="ac-gn-bagview-button-checkout"]'
354
384
  end
355
385
 
356
386
 
357
- ### Adding Methods to your PageSection
387
+ ### Adding Methods to a PageSection
358
388
 
359
389
  You can add high level methods to your `PageSection` class definition, as shown below:
360
390
 
361
- class SearchForm < TestCentricity::PageSection
362
- trait(:section_locator) { 'form#gnav-search' }
363
- trait(:section_name) { 'Search widget' }
364
-
365
- # Search Form UI elements
366
- textfield :search_field, 'input#search-query'
367
- button :search_button, 'button[type=submit]'
368
-
369
- def search_for(value)
370
- search_field.set(value)
371
- search_button.click
391
+ class BagViewPopup < TestCentricity::PageSection
392
+ trait(:section_locator) { 'aside.ac-gn-bagview' }
393
+ trait(:section_name) { 'Shopping Bag Popup' }
394
+
395
+ # Shopping Bag Popup UI elements
396
+ label :bag_message, 'p[class*="ac-gn-bagview-message"]'
397
+ lists bag_items_list: 'ul[class*="ac-gn-bagview-bag"]',
398
+ bag_nav_list: 'ul.ac-gn-bagview-nav-list '
399
+ button :checkout_button, 'a[class*="ac-gn-bagview-button-checkout"]'
400
+
401
+ def item_count
402
+ bag_items_list.visible? ? bag_items_list.item_count : 0
403
+ end
404
+
405
+ def perform_action(action)
406
+ case action.gsub(/\s+/, '_').downcase.to_sym
407
+ when :check_out
408
+ checkout_button.click
409
+ when :view_bag
410
+ bag_nav_list.choose_item(1)
411
+ when :saved_items
412
+ bag_nav_list.choose_item(2)
413
+ when :orders
414
+ bag_nav_list.choose_item(3)
415
+ when :account
416
+ bag_nav_list.choose_item(4)
417
+ when :sign_in, :sign_out
418
+ bag_nav_list.choose_item(5)
419
+ else
420
+ raise "#{action} is not a valid selector"
421
+ end
372
422
  end
373
423
  end
374
424
 
@@ -378,10 +428,10 @@ You can add high level methods to your `PageSection` class definition, as shown
378
428
  You add a `PageSection` to its associated `PageObject` as shown below:
379
429
 
380
430
  class HomePage < TestCentricity::PageObject
381
- trait(:page_name) { 'Home' }
382
- trait(:page_url) { '/dashboard' }
383
- trait(:page_locator) { 'body.dashboard' }
384
-
431
+ trait(:page_name) { 'Home' }
432
+ trait(:page_url) { '/dashboard' }
433
+ trait(:page_locator) { 'body.dashboard' }
434
+
385
435
  # Home page Section Objects
386
436
  section :search_form, SearchForm
387
437
  end
@@ -391,12 +441,13 @@ Once your `PageObject` has been instantiated, you can call its `PageSection` met
391
441
  home_page.search_form.search_for('ocarina')
392
442
 
393
443
 
444
+ ---
394
445
  ## UIElements
395
446
 
396
- `PageObjects` and `PageSections` are typically made up of **UI Element** like text fields, check boxes, select lists (combo boxes),
397
- radio buttons, tables, ordered and unordered lists, buttons, images, HTML5 video objects, HTML5 audio objects, etc. **UI Elements** are declared
398
- and instantiated within the class definition of the `PageObject` or `PageSection` in which they are contained. With TestCentricity Web,
399
- all UI elements are based on the `UIElement` class.
447
+ `PageObjects` and `PageSections` are typically made up of UI elements like text fields, check boxes, select lists (combo
448
+ boxes), radio buttons, tables, ordered and unordered lists, buttons, images, HTML5 video or audio player objects, etc.
449
+ UI elements are declared and instantiated within the class definition of the `PageObject` or `PageSection` in which they
450
+ are contained. With TestCentricity Web, all UI elements are based on the `UIElement` class.
400
451
 
401
452
 
402
453
  ### Declaring and Instantiating UIElements
@@ -408,8 +459,8 @@ Single `UIElement` declarations have the following format:
408
459
  * The `elementName` is the unique name that you will use to refer to the UI element and is specified as a `Symbol`.
409
460
  * The `locator` is the CSS or XPath attribute that uniquely and unambiguously identifies the `UIElement`.
410
461
 
411
- Multiple `UIElement` declarations for a collection of elements of the same type can be performed by passing a hash table containing the
412
- names and locators of each individual element.
462
+ Multiple `UIElement` declarations for a collection of elements of the same type can be performed by passing a hash table
463
+ containing the names and locators of each individual element.
413
464
 
414
465
  ### Example UIElement Declarations
415
466
 
@@ -419,64 +470,65 @@ Supported `UIElement` elementTypes and their declarations have the following for
419
470
 
420
471
  class SamplePage < TestCentricity::PageObject
421
472
 
422
- button :button_name, locator
423
- textfield :field_name, locator
424
- checkbox :checkbox_name, locator
425
- radio :radio_button_name, locator
426
- label :label_name, locator
427
- link :link_name, locator
428
- selectlist :select_name, locator
429
- list :list_name, locator
430
- table :table_name, locator
431
- range :range_name, locator
432
- image :image_name, locator
433
- video :video_name, locator
434
- audio :audio_name, locator
435
- filefield :filefield_name, locator
436
-
473
+ button :button_name, locator
474
+ textfield :field_name, locator
475
+ checkbox :checkbox_name, locator
476
+ radio :radio_button_name, locator
477
+ label :label_name, locator
478
+ link :link_name, locator
479
+ selectlist :select_name, locator
480
+ list :list_name, locator
481
+ table :table_name, locator
482
+ range :range_name, locator
483
+ image :image_name, locator
484
+ video :video_name, locator
485
+ audio :audio_name, locator
486
+ filefield :filefield_name, locator
487
+
437
488
  end
438
489
 
439
490
  *Multiple element declarations:*
440
491
 
441
492
  class SamplePage < TestCentricity::PageObject
442
-
443
- buttons button_1_name: locator,
444
- button_2_name: locator,
445
- button_X_name: locator
446
- textfields field_1_name: locator,
447
- field_2_name: locator,
448
- field_X_name: locator
449
- checkboxes check_1_name: locator,
450
- check_2_name: locator,
451
- check_X_name: locator
452
- radios radio_1_name: locator,
453
- radio_X_name: locator
454
- labels label_1_name: locator,
455
- label_X_name: locator
456
- links link_1_name: locator,
457
- link_X_name: locator
458
- selectlists selectlist_1_name: locator,
459
- selectlist_X_name: locator
460
- lists list_1_name: locator,
461
- list_X_name: locator
462
- tables table_1_name: locator,
463
- table_X_name: locator
464
- ranges range_1_name: locator,
465
- range_X_name: locator
466
- images image_1_name: locator,
467
- image_X_name: locator
468
- videos video_1_name: locator,
469
- video_X_name: locator
470
- audios audio_1_name: locator,
471
- audio_X_name: locator
472
- filefields filefield_1_name: locator,
473
- filefield_X_name: locator
493
+
494
+ buttons button_1_name: locator,
495
+ button_2_name: locator,
496
+ button_X_name: locator
497
+ textfields field_1_name: locator,
498
+ field_2_name: locator,
499
+ field_X_name: locator
500
+ checkboxes check_1_name: locator,
501
+ check_2_name: locator,
502
+ check_X_name: locator
503
+ radios radio_1_name: locator,
504
+ radio_X_name: locator
505
+ labels label_1_name: locator,
506
+ label_X_name: locator
507
+ links link_1_name: locator,
508
+ link_X_name: locator
509
+ selectlists selectlist_1_name: locator,
510
+ selectlist_X_name: locator
511
+ lists list_1_name: locator,
512
+ list_X_name: locator
513
+ tables table_1_name: locator,
514
+ table_X_name: locator
515
+ ranges range_1_name: locator,
516
+ range_X_name: locator
517
+ images image_1_name: locator,
518
+ image_X_name: locator
519
+ videos video_1_name: locator,
520
+ video_X_name: locator
521
+ audios audio_1_name: locator,
522
+ audio_X_name: locator
523
+ filefields filefield_1_name: locator,
524
+ filefield_X_name: locator
474
525
 
475
526
  end
476
527
 
477
528
 
478
- Refer to the Class List documentation for the `PageObject` and `PageSection` classes for details on the class methods used for declaring
479
- and instantiating `UIElements`. Examples of UI element declarations can be found in the ***Adding UI Elements to your PageObject*** and
529
+ Refer to the Class List documentation for the `PageObject` and `PageSection` classes for details on the class methods used
530
+ for declaring and instantiating `UIElements`. Examples of UI element declarations can be found in the ***Adding UI Elements
531
+ to your PageObject*** and
480
532
  ***Adding UI Elements to your PageSection*** sections above.
481
533
 
482
534
 
@@ -519,7 +571,6 @@ With TestCentricity, all UI elements are based on the `UIElement` class, and inh
519
571
  element.y
520
572
  element.get_attribute(attrib)
521
573
  element.get_native_attribute(attrib)
522
- element.inspect
523
574
 
524
575
  **Waiting methods:**
525
576
 
@@ -568,26 +619,28 @@ With TestCentricity, all UI elements are based on the `UIElement` class, and inh
568
619
  element.aria_busy?
569
620
 
570
621
 
571
- ### Populating your PageObject or PageSection with data
622
+ ### Populating a PageObject or PageSection With Data
572
623
 
573
- A typical automated test may be required to perform the entry of test data by interacting with various `UIElements` on your `PageObject` or
574
- `PageSection`. This data entry can be performed using the various object action methods (listed above) for each `UIElement` that needs to be
575
- interacted with.
624
+ A typical automated test may be required to perform the entry of test data by interacting with various `UIElements` on your
625
+ `PageObject` or `PageSection`. This data entry can be performed using the various object action methods (listed above) for
626
+ each `UIElement` that needs to be interacted with.
576
627
 
577
- The `PageObject.populate_data_fields` and `PageSection.populate_data_fields` methods support the entry of test data into a collection of
578
- `UIElements`. The `populate_data_fields` method accepts a hash containing key/hash pairs of `UIElements` and their associated data to be
579
- entered. Data values must be in the form of a `String` for `textfield`, `selectlist`, and `filefield` controls. For `checkbox` and `radio`
580
- controls, data must either be a `Boolean` or a `String` that evaluates to a `Boolean` value (Yes, No, 1, 0, true, false). For `range` controls,
581
- data must be an `Integer`. For `input(type='color')` color picker controls, which are specified as a `textfield`, data must be in the form
582
- of a hex color `String`. For `section` objects, data values must be a `String`, and the `section` object must have a `set` method defined.
628
+ The `PageObject.populate_data_fields` and `PageSection.populate_data_fields` methods support the entry of test data into a
629
+ collection of `UIElements`. The `populate_data_fields` method accepts a hash containing key/hash pairs of `UIElements` and
630
+ their associated data to be entered. Data values must be in the form of a `String` for `textfield`, `selectlist`, and `filefield`
631
+ controls. For `checkbox` and `radio` controls, data must either be a `Boolean` or a `String` that evaluates to a `Boolean`
632
+ value (Yes, No, 1, 0, true, false). For `range` controls, data must be an `Integer`. For `input(type='color')` color picker
633
+ controls, which are specified as a `textfield`, data must be in the form of a hex color `String`. For `section` objects,
634
+ data values must be a `String`, and the `section` object must have a `set` method defined.
583
635
 
584
- The `populate_data_fields` method verifies that data attributes associated with each `UIElement` is not `nil` or `empty` before attempting to
585
- enter data into the `UIElement`.
636
+ The `populate_data_fields` method verifies that data attributes associated with each `UIElement` is not `nil` or `empty`
637
+ before attempting to enter data into the `UIElement`.
586
638
 
587
- The optional `wait_time` parameter is used to specify the time (in seconds) to wait for each `UIElement` to become viable for data entry
588
- (the `UIElement` must be visible and enabled) before entering the associated data value. This option is useful in situations where entering data,
589
- or setting the state of a `UIElement` might cause other `UIElements` to become visible or active. Specifying a wait_time value ensures that the
590
- subsequent `UIElements` will be ready to be interacted with as states are changed. If the wait time is `nil`, then the wait time will be 5 seconds.
639
+ The optional `wait_time` parameter is used to specify the time (in seconds) to wait for each `UIElement` to become viable
640
+ for data entry (the `UIElement` must be visible and enabled) before entering the associated data value. This option is useful
641
+ in situations where entering data, or setting the state of a `UIElement` might cause other `UIElements` to become visible
642
+ or active. Specifying a wait_time value ensures that the subsequent `UIElements` will be ready to be interacted with as
643
+ states are changed. If the wait time is `nil`, then the wait time will be 5 seconds.
591
644
 
592
645
  def enter_data(user_data)
593
646
  fields = {
@@ -603,16 +656,16 @@ subsequent `UIElements` will be ready to be interacted with as states are change
603
656
  end
604
657
 
605
658
 
606
- ### Verifying UIElements on your PageObject or PageSection
659
+ ### Verifying UIElements on a PageObject or PageSection
607
660
 
608
- A typical automated test executes one or more interactions with the user interface, and then performs a validation to verify whether
609
- the expected state of the UI has been achieved. This verification can be performed using the various object state methods (listed above)
610
- for each `UIElement` that requires verification. Depending on the complexity and number of `UIElements` to be verified, the code required to
611
- verify the presence of `UIElements` and their correct states can become cumbersome.
661
+ A typical automated test executes one or more interactions with the user interface, and then performs a validation to verify
662
+ whether the expected state of the UI has been achieved. This verification can be performed using the various object state
663
+ methods (listed above) for each `UIElement` that requires verification. Depending on the complexity and number of `UIElements`
664
+ to be verified, the code required to verify the presence of `UIElements` and their correct states can become cumbersome.
612
665
 
613
- The `PageObject.verify_ui_states` and `PageSection.verify_ui_states` methods support the verification of multiple properties of multiple
614
- UI elements on a `PageObject` or `PageSection`. The `verify_ui_states` method accepts a hash containing key/hash pairs of UI
615
- elements and their properties or attributes to be verified.
666
+ The `PageObject.verify_ui_states` and `PageSection.verify_ui_states` methods support the verification of multiple properties
667
+ of multiple UI elements on a `PageObject` or `PageSection`. The `verify_ui_states` method accepts a hash containing key/hash
668
+ pairs of UI elements and their properties or attributes to be verified.
616
669
 
617
670
  ui = {
618
671
  object1 => { property: state },
@@ -621,9 +674,9 @@ elements and their properties or attributes to be verified.
621
674
  }
622
675
  verify_ui_states(ui)
623
676
 
624
- The `verify_ui_states` method queues up any exceptions that occur while verifying each object's properties until all `UIElements` and their
625
- properties have been checked, and then posts any exceptions encountered upon completion. Posted exceptions include a screenshot with a red
626
- dashed highlight around the UI element that did not match the expected results.
677
+ The `verify_ui_states` method queues up any exceptions that occur while verifying each object's properties until all `UIElements`
678
+ and their properties have been checked, and then posts any exceptions encountered upon completion. Posted exceptions include
679
+ a screenshot with a red dashed highlight around the UI element that did not match the expected results.
627
680
 
628
681
  The `verify_ui_states` method supports the following property/state pairs:
629
682
 
@@ -662,7 +715,7 @@ The `verify_ui_states` method supports the following property/state pairs:
662
715
  :max Integer
663
716
  :step Integer
664
717
 
665
- Text Field Constraint validation
718
+ Text Field Constraint Validation
666
719
 
667
720
  :validation_message String
668
721
  :badInput Boolean
@@ -748,7 +801,7 @@ The `verify_ui_states` method supports the following property/state pairs:
748
801
  :active_track_source String
749
802
  :track_source String
750
803
 
751
- #### ARIA accessibility property/state pairs
804
+ #### ARIA Accessibility Property/State Pairs
752
805
 
753
806
  The `verify_ui_states` method supports the following ARIA accessibility property/state pairs:
754
807
 
@@ -809,14 +862,44 @@ values appear in the associated text fields after entering data and performing a
809
862
  def verify_changes_saved
810
863
  # verify saved user data is correctly displayed
811
864
  ui = {
812
- first_name_field => { visible: true, aria_invalid: false, value: User.current.first_name },
813
- last_name_field => { visible: true, aria_invalid: false, value: User.current.last_name },
814
- email_field => { visible: true, aria_invalid: false, value: User.current.email },
815
- phone_number_field => { visible: true, aria_invalid: false, value: User.current.phone_number },
816
- time_zone_select => { visible: true, aria_invalid: false, value: User.current.time_zone },
817
- language_select => { visible: true, aria_invalid: false, value: User.current.language },
818
- avatar_container => { visible: true },
819
- avatar_image => { visible: true, broken: false, src: { contains: User.current.avatar_file_name } },
865
+ first_name_field => {
866
+ visible: true,
867
+ aria_invalid: false,
868
+ value: User.current.first_name
869
+ },
870
+ last_name_field => {
871
+ visible: true,
872
+ aria_invalid: false,
873
+ value: User.current.last_name
874
+ },
875
+ email_field => {
876
+ visible: true,
877
+ aria_invalid: false,
878
+ value: User.current.email
879
+ },
880
+ phone_number_field => {
881
+ visible: true,
882
+ aria_invalid: false,
883
+ value: User.current.phone_number
884
+ },
885
+ time_zone_select => {
886
+ visible: true,
887
+ aria_invalid: false,
888
+ value: User.current.time_zone
889
+ },
890
+ language_select => {
891
+ visible: true,
892
+ aria_invalid: false,
893
+ value: User.current.language
894
+ },
895
+ avatar_container => { visible: true },
896
+ avatar_image => {
897
+ visible: true,
898
+ broken: false,
899
+ src: { ends_with: User.current.avatar_file_name },
900
+ alt: "#{User.current.first_name} #{User.current.last_name}",
901
+ style: { contains: 'border-radius: 50%;'}
902
+ },
820
903
  error_message_label => { visible: false }
821
904
  }
822
905
  verify_ui_states(ui)
@@ -840,25 +923,89 @@ The `verify_ui_states` method also supports I18n string translations using prope
840
923
  :translate_capitalize String
841
924
  :translate_titlecase String
842
925
 
843
- The example below depicts the usage of the `verify_ui_states` method to verify that the captions for menu items are correctly
844
- translated.
845
-
846
- def verify_menu
847
- ui = {
848
- account_settings_item => { visible: true, caption: { translate: 'Header.settings.account' } },
849
- help_item => { visible: true, caption: { translate: 'Header.settings.help' } },
850
- feedback_item => { visible: true, caption: { translate: 'Header.settings.feedback' } },
851
- legal_item => { visible: true, caption: { translate: 'Header.settings.legal' } },
852
- institution_item => { visible: true, caption: { translate: 'Header.settings.institution' } },
853
- configurations_item => { visible: true, caption: { translate: 'Header.settings.configurations' } },
854
- contact_us_item => { visible: true, caption: { translate: 'Header.settings.contact' } },
855
- downloads_item => { visible: true, caption: { translate: 'Header.settings.downloads' } }
856
- }
857
- verify_ui_states(ui)
926
+ The example below depicts the usage of the `verify_ui_states` method to verify that the captions for a popup Shopping Bag
927
+ panel are correctly translated.
928
+
929
+ ![Localized UI](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/LocalizedUI.png "Localized UI")
930
+
931
+ class BagViewPopup < TestCentricity::PageSection
932
+ trait(:section_locator) { 'aside.ac-gn-bagview' }
933
+ trait(:section_name) { 'Shopping Bag Popup' }
934
+
935
+ # Shopping Bag Popup UI elements
936
+ label :bag_message, 'p[class*="ac-gn-bagview-message"]'
937
+ lists bag_items_list: 'ul[class*="ac-gn-bagview-bag"]',
938
+ bag_nav_list: 'ul.ac-gn-bagview-nav-list '
939
+ button :checkout_button, 'a[class*="ac-gn-bagview-button-checkout"]'
940
+
941
+ def verify_empty_bag_ui
942
+ nav_items = %w[
943
+ BagViewPopup.bag
944
+ BagViewPopup.saved_items
945
+ BagViewPopup.orders
946
+ BagViewPopup.account
947
+ BagViewPopup.sign_in
948
+ ]
949
+ ui = {
950
+ bag_message => {
951
+ visible: true,
952
+ caption: { translate: 'BagViewPopup.bag_is_empty' }
953
+ },
954
+ bag_nav_list => {
955
+ visible: true,
956
+ itemcount: 5,
957
+ items: { translate: nav_items }
958
+ },
959
+ bag_items_list => { visible: false },
960
+ checkout_button => { visible: false }
961
+ }
962
+ verify_ui_states(ui)
963
+ end
858
964
  end
859
965
 
966
+ I18n `.yml` files contain key/value pairs representing the name of a translated string (key) and the string value. For the
967
+ popup Shopping Bag panel example above, the translated strings for English, Spanish, and French are represented in below:
968
+
969
+ **English** - `en.yml`
970
+
971
+ en:
972
+ BagViewPopup:
973
+ bag_is_empty: 'Your Bag is empty.'
974
+ bag: 'Bag'
975
+ saved_items: 'Saved Items'
976
+ orders: 'Orders'
977
+ account: 'Account'
978
+ sign_in: 'Sign in'
979
+ sign_out: 'Sign out'
980
+
981
+ **Spanish** - `es.yml`
982
+
983
+ es:
984
+ BagViewPopup:
985
+ bag_is_empty: 'Tu bolsa está vacía.'
986
+ bag: 'Bolsa'
987
+ saved_items: 'Artículos guardados'
988
+ orders: 'Pedidos'
989
+ account: 'Cuenta'
990
+ sign_in: 'Iniciar sesión'
991
+ sign_out: 'Cerrar sesión'
992
+
993
+ **French** - `fr.yml`
994
+
995
+ fr:
996
+ BagViewPopup:
997
+ bag_is_empty: 'Votre sac est vide.'
998
+ bag: 'Sac'
999
+ saved_items: 'Articles enregistrés'
1000
+ orders: 'Commandes'
1001
+ account: 'Compte'
1002
+ sign_in: 'Ouvrir une session'
1003
+ sign_out: 'Fermer la session'
1004
+
1005
+
860
1006
  Each supported language/locale combination has a corresponding `.yml` file. I18n `.yml` file naming convention uses
861
- [ISO-639 language codes and ISO-3166 country codes](https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html). For example:
1007
+ [ISO-639 language codes](https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1252447) and
1008
+ [ISO-3166 country codes](https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1250799). For example:
862
1009
 
863
1010
  | Language (Country) | File name |
864
1011
  |-----------------------|-----------|
@@ -871,151 +1018,231 @@ Each supported language/locale combination has a corresponding `.yml` file. I18n
871
1018
  | Portuguese (Brazil) | pt-BR.yml |
872
1019
  | Portuguese (Portugal) | pt-PT.yml |
873
1020
 
874
- I18n `.yml` files contain key/value pairs representing the name of a translated string (key) and the string value.
875
-
876
1021
  Baseline translation strings are stored in `.yml` files in the `config/locales/` folder.
877
1022
 
878
- my_automation_project
879
- ├── config
880
- │ ├── locales
881
- │ │ ├── en.yml
882
- │ │ ├── es.yml
883
- │ │ ├── fr.yml
884
- │ │ ├── fr-CA.yml
885
- │ │ └── en-AU.yml
886
- │ ├── test_data
887
- └── cucumber.yml
888
- ├── downloads
889
- ├── features
890
- ├── Gemfile
891
- └── README.md
892
-
893
-
894
- ### Working with custom UIElements
895
-
896
- Many responsive and touch-enabled web based user interfaces are implemented using front-end JavaScript libraries for building user
897
- interfaces based on UI components. Popular JS libraries include React, Angular, and Ember.js. These stylized and adorned controls can
898
- present a challenge when attempting to interact with them using Capybara and Selenium based automated tests.
1023
+ 📁 my_automation_project/
1024
+ ├── 📁 config/
1025
+ │ ├── 📁 locales/
1026
+ │ │ ├── 📄 en.yml
1027
+ │ │ ├── 📄 en-AU.yml
1028
+ │ │ ├── 📄 es.yml
1029
+ │ │ ├── 📄 de.yml
1030
+ │ │ ├── 📄 fr.yml
1031
+ ├── 📄 fr-CA.yml
1032
+ │ ├── 📄 pt-BR.yml
1033
+ │ │ └── 📄 pt-PT.yml
1034
+ ├── 📁 test_data/
1035
+ │ └── 📄 cucumber.yml
1036
+ ├── 📁 downloads/
1037
+ ├── 📁 features/
1038
+ ├── 📄 Gemfile
1039
+ └── 📄 README.md
1040
+
1041
+
1042
+ ### Working With Custom UIElements
1043
+
1044
+ Many responsive and touch-enabled web based user interfaces are implemented using front-end JavaScript libraries for building
1045
+ user interfaces based on multiple composite UI components. Popular JS libraries include React, Angular, and Ember.js. These
1046
+ stylized and adorned controls can present a challenge when attempting to interact with them using Capybara and Selenium based
1047
+ automated tests.
899
1048
 
900
1049
  #### Radio and Checkbox UIElements
901
1050
 
902
- Sometimes, radio buttons and checkboxes implemented using JS component libraries cannot be interacted with due to other UI elements
903
- being overlaid on top of them and the base `input(type='radio')` or `input(type='checkbox')` element not being visible.
904
-
905
- In the screenshots below of an airline flight search and booking page, the **Roundtrip** and **One-way** radio buttons are adorned by
906
- `label` elements that also acts as proxies for their associated `input(type='radio')` elements, and they intercept the `click` actions
907
- that would normally be handled by the `input(type='radio')` elements.
908
-
909
- <img src="https://i.imgur.com/7bW5u4c.jpg" alt="Roundtrip Radio button Input" title="Roundtrip Radio button Input">
1051
+ Sometimes, radio buttons and checkboxes implemented using JS component libraries cannot be interacted with due to other UI
1052
+ elements being overlaid on top of them, causing the base `input(type='radio')` or `input(type='checkbox')` element to not
1053
+ receive click actions.
910
1054
 
1055
+ In the screenshot below of an airline flight search and booking page, the **Round-trip**, **One-way**, and **Multi-city**
1056
+ radio buttons are overlaid with `div` elements that also acts as proxies for their associated `input(type='radio')` elements,
1057
+ and that intercept the `click` actions that would normally be handled by the `input(type='radio')` elements.
911
1058
 
912
- This screenshot shows the `label` element that is overlaid above the **Roundtrip** `input(type='radio')` element.
1059
+ ![Custom Radio buttons](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomRadios.png "Custom Radio buttons")
913
1060
 
914
- <img src="https://i.imgur.com/2stWiyR.jpg" alt="Roundtrip Radio button Label" title="Roundtrip Radio button Label">
1061
+ The checkbox controls on the airline flight search and booking page are also overlaid with `div` elements that intercept
1062
+ the `click` actions that would normally be handled by the `input(type='checkbox')` elements.
915
1063
 
1064
+ ![Custom Checkbox controls](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomCheckbox.png "Custom Checkbox controls")
916
1065
 
917
- The checkbox controls in this web UI are also adorned with `label` elements that act as proxies for their associated `input(type='checkbox')`
918
- elements.
919
1066
 
920
- <img src="https://i.imgur.com/JcOANqZ.jpg" alt="One-way Radio button Label" title="One-way Radio button Label">
1067
+ The `Radio.define_custom_elements` and `CheckBox.define_custom_elements` methods provide a way to specify the `input`,
1068
+ `proxy`, and/or `label` elements associated with the `input(type='radio')` and `input(type='checkbox')` elements. The
1069
+ `define_custom_elements` method should be called from an `initialize` method for the `PageObject` or `PageSection` where
1070
+ the `radio` or `checkbox` elements are instantiated.
921
1071
 
922
-
923
- The `Radio.define_custom_elements` and `CheckBox.define_custom_elements` methods provide a way to specify the `input`, `proxy`
924
- and/or `label` elements associated with the `input(type='radio')` or `input(type='checkbox')` elements. The `define_custom_elements`
925
- method should be called from an `initialize` method for the `PageObject` or `PageSection` where the `radio` or `checkbox` element is
926
- instantiated. The code snippet below demonstrates the use of the `Radio.define_custom_elements` and `CheckBox.define_custom_elements`
927
- methods to resolve the testability issues posed by the adorned **Roundtrip** and **One-way** radio buttons and the **Flexible dates**
928
- checkbox.
1072
+ The code snippet below demonstrates the use of the `Radio.define_custom_elements` and `CheckBox.define_custom_elements`
1073
+ methods to define the multiple UI elements that comprise each radio button and checkbox.
929
1074
 
930
1075
  class FlightBookingPage < TestCentricity::PageObject
931
1076
  trait(:page_name) { 'Flight Booking Home' }
932
- trait(:page_locator) { "div[class*='bookerContainer']" }
933
-
1077
+ trait(:page_locator) { 'div[class*="bookerContainer"]' }
1078
+
934
1079
  # Flight Booking page UI elements
935
- radios roundtrip_radio: "label[for='roundtrip']",
936
- one_way_radio: "label[for='oneway']"
937
- checkbox :flexible_check, 'input#flexibleDates'
938
-
1080
+ radios roundtrip_radio: 'div[role="radiogroup"] > div.ftRadio:nth-of-type(1)',
1081
+ one_way_radio: 'div[role="radiogroup"] > div.ftRadio:nth-of-type(2)',
1082
+ multi_city_radio: 'div[role="radiogroup"] > div.ftRadio:nth-of-type(3)'
1083
+ checkboxes use_miles_check: 'div#divAwardReservation',
1084
+ flex_dates_check: 'div#divLowFareCalendar > div.left',
1085
+ near_from_check: 'div#divIncludeNearbyDepartureAirports',
1086
+ near_to_check: 'div#divIncludeNearbyArrivalAirports'
1087
+
939
1088
  def initialize
940
- # define the custom element components for the Round Trip and One Way radio buttons
941
- radio_spec = { input: "input[type='radio']" }
1089
+ # define the custom element components for the Round Trip, One Way, and Multi-City radio buttons
1090
+ radio_spec = {
1091
+ input: 'input[type="radio"]',
1092
+ label: 'label.normal'
1093
+ }
942
1094
  roundtrip_radio.define_custom_elements(radio_spec)
943
1095
  one_way_radio.define_custom_elements(radio_spec)
944
- # define the custom element components for the Flexible Date checkbox
945
- check_spec = { proxy: 'label#flexDatesLabel' }
946
- flexible_check.define_custom_elements(check_spec)
1096
+ multi_city_radio.define_custom_elements(radio_spec)
1097
+
1098
+ # define the custom element components for the checkboxes
1099
+ check_spec = {
1100
+ input: 'input[type="checkbox"]',
1101
+ label: 'label.normal'
1102
+ }
1103
+ use_miles_check.define_custom_elements(check_spec)
1104
+ flex_dates_check.define_custom_elements(check_spec)
1105
+ near_from_check.define_custom_elements(check_spec)
1106
+ near_to_check.define_custom_elements(check_spec)
1107
+ end
1108
+ end
1109
+
1110
+ #### List UIElements
1111
+
1112
+ The basic HTML `list` element is typically composed of the parent `ul` or `ol` object, and one or more `li` elements
1113
+ representing the items in the list. However, list controls implemented using JS component libraries can be composed of
1114
+ multiple elements representing the components of a list implementation.
1115
+
1116
+ In the screenshots below, an inspection of the **Menu Groups** horizontal scrolling list on a **Restaurant Detail** page
1117
+ reveals that it is a `div` element that contains multiple `button` elements with `data-testid` attributes of `menu-group`
1118
+ that represent the list items that can be selected.
1119
+
1120
+ ![Custom List](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomList.png "Custom List")
1121
+
1122
+ The `List.define_list_elements` method provides a means of specifying the elements that make up the key components of a
1123
+ `list` control. The method accepts a hash of element designators (key) and a CSS or Xpath expression (value) that expression
1124
+ that uniquely identifies the element. Valid element designators are `:list_item`and `:selected_item`.
1125
+
1126
+ The `RestaurantPage` page object's `initialize` method in the code snippet below demonstrates the use of the `List.define_list_elements`
1127
+ method to define the common components that make up the **Menu Groups** horizontal scrolling list.
1128
+
1129
+ class RestaurantPage < TestCentricity::PageObject
1130
+ trait(:page_name) { 'Restaurant Detail' }
1131
+ trait(:page_locator) { 'div.restaurant-menus-container' }
1132
+
1133
+ # Restaurant Detail page UI elements
1134
+ list :menu_groups_list, 'div[class*="menus-and-groups-selector__SliderItems"]'
1135
+
1136
+ def initialize
1137
+ super
1138
+ # define the custom list element components for the Menu Groupslists
1139
+ list_spec = { list_item: 'button[data-testid="menu-group"]' }
1140
+ menu_groups_list.define_list_elements(list_spec)
947
1141
  end
948
1142
  end
949
1143
 
950
1144
 
951
1145
  #### SelectList UIElements
952
1146
 
953
- The basic HTML `select` element is typically composed of the parent `select` object, and one or more `option` elements representing
954
- the selectable items in the drop-down list. However, `select` type controls implemented using JS component libraries can be composed
955
- of multiple elements representing the various components of a drop-down style `selectlist` implementation.
1147
+ The basic HTML `select` element is typically composed of the parent `select` object, and one or more `option` elements
1148
+ representing the selectable items in the drop-down list. However, `select` type controls implemented using JS component
1149
+ libraries (React.js, Chosen, GWT, etc.) can be composed of multiple elements representing the various components of a
1150
+ drop-down style `selectlist` implementation.
956
1151
 
957
- In the screenshots below of an airline flight search and booking page, there are no `select` or `option` elements associated with the
958
- **Month**, **Day**, and **Cabin Type** drop-down style selectors. An inspection of the **Month** selector reveals that it is a `div`
959
- element that contains a `button` element (outlined in red) for triggering the drop-down list, a `ul` element (outlined in green) that
960
- contains the drop-down list, and multiple `li` elements (outlined in blue) that represent the list items or options that can be
961
- selected. The currently selected item or option can be identified by either the `listBoxOptionSelected` snippet in its `class` name or
962
- the `aria-selected` attribute (outlined in orange).
1152
+ ![Custom SelectList](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomSelectList1.png "Custom SelectList")
963
1153
 
964
- Further examination of the **Day** and **Cabin Type** drop-down style selectors reveal that their composition is identical to the
965
- **Month** selector.
966
1154
 
967
- <img src="https://i.imgur.com/LYAC2lh.jpg" alt="Custom SelectList" title="Custom SelectList">
1155
+ In the screenshots below, an inspection of the **Football Teams** selector reveals that it is a `div` element that contains
1156
+ a `textfield` element (outlined in purple) for inputting a selection by typing, a `ul` element (outlined in blue) that
1157
+ contains the drop-down list, and multiple `li` elements with the `active-result` snippet in their `class` names (outlined
1158
+ in orange) that represent the list items or options that can be selected. The currently selected item or option can be
1159
+ identified by an `li` with the `result-selected` snippet in its `class` name. Group headings and items in the drop-down
1160
+ list are represented by `li` elements with a `class` name of `group-result` (outlined in green).
968
1161
 
1162
+ ![Custom SelectList](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomSelectList.jpg "Custom SelectList")
969
1163
 
970
- The `SelectList.define_list_elements` method provides a means of specifying the various elements that make up the key components of
971
- a `selectlist` control. The method accepts a hash of element designators (key) and a CSS or Xpath expression (value) that expression
972
- that uniquely identifies the element. Valid element designators are `list_item:`, `options_list:`, `list_trigger:`, `selected_item:`,
973
- `text_field:`, `group_heading:`, and `group_item:`.
1164
+ The `SelectList.define_list_elements` method provides a means of specifying the various elements that make up the key
1165
+ components of a `selectlist` control. The method accepts a hash of element designators (key) and a CSS or Xpath expression
1166
+ (value) that uniquely identifies the element. Valid element designators are `:list_item`, `:options_list`, `:list_trigger`,
1167
+ `:selected_item`, `:text_field`, `:group_heading`, and `:group_item`.
974
1168
 
975
- The code snippet below demonstrates the use of the `SelectList.define_list_elements` method to define the common components that make
976
- up the **Month**, **Day**, and **Cabin Type** drop-down style selectors. Note the use of the ARIA `role` and `aria-selected` attributes
977
- as element locators.
1169
+ The `CustomControlsPage` page object's `initialize` method in the code snippet below demonstrates the use of the
1170
+ `SelectList.define_list_elements` method to define the common components that make up the **Teams** drop-down style selector.
978
1171
 
979
- class FlightBookingPage < TestCentricity::PageObject
980
- trait(:page_name) { 'Flight Booking Home' }
981
- trait(:page_locator) { "div[class*='bookerContainer']" }
982
-
983
- # Flight Booking page UI elements
984
- selectlists month_select: "div[class*='expandFlexMonth']",
985
- duration_select: "div[class*='expandFlexDay']",
986
- cabin_type_select: "div[class*='bookFlightForm__optionField'] > div[class*='app-components-ListBox']"
1172
+ class CustomControlsPage < TestCentricity::PageObject
1173
+ trait(:page_name) { 'Custom Controls' }
1174
+ trait(:page_locator) { 'div.custom-controls-page-body' }
1175
+
1176
+ # Custom Controls page UI elements
1177
+ selectlists country_select: 'div#country_chosen',
1178
+ team_select: 'div#team_chosen'
987
1179
 
988
1180
  def initialize
989
- # define the custom list element components for the Month, Duration, and Cabin Type selectlist objects
1181
+ super
1182
+ # define the custom list element components for the Team Chosen selectlists
990
1183
  list_spec = {
991
- selected_item: "li[aria-selected=true]",
992
- options_list: "ul[role='listbox']",
993
- list_item: "li[role='option']",
994
- list_trigger: "button[role='combobox']"
1184
+ selected_item: 'li[class*="result-selected"]',
1185
+ list_item: 'li[class*="active-result"]',
1186
+ text_field: 'input.chosen-search-input',
1187
+ options_list: 'ul.chosen-results',
1188
+ group_item: 'li.group-result',
1189
+ group_heading: 'li.group-result'
995
1190
  }
996
- month_select.define_list_elements(list_spec)
997
- duration_select.define_list_elements(list_spec)
998
- cabin_type_select.define_list_elements(list_spec)
1191
+ country_select.define_list_elements(list_spec)
1192
+ team_select.define_list_elements(list_spec)
999
1193
  end
1000
1194
  end
1001
1195
 
1002
1196
 
1003
- #### List UIElements
1197
+ #### Table UIElements
1198
+
1199
+ The basic HTML `table` element is typically composed of the parent `table` object, a body (`tbody`) containing one or
1200
+ more rows (`tr`), with each row containing one or more columns (`td`). Tables can also include an optional header (`thead`)
1201
+ with a header row (`tr`) containing one or more header columns (`th`).
1202
+
1203
+ However, custom tables can be implemented using elements other than the standard table components described above. In the
1204
+ screenshot below, an inspection of the table reveals that it is comprised of `div` elements representing the table, body,
1205
+ rows, columns, header, header row, and header columns.
1206
+
1207
+ ![Custom Table](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomTable.png "Custom Table")
1208
+
1209
+ The `Table.define_table_elements` method provides a means of specifying the various elements that make up the key
1210
+ components of a `table`. The method accepts a hash of element designators (key) and a CSS or Xpath expression (value)
1211
+ that uniquely identifies the element. Valid element designators are `:table_header`, `:header_row`, `:header_column`,
1212
+ `:table_body`, `:table_row`, and `:table_column`.
1004
1213
 
1005
- The basic HTML list is typically composed of the parent `ul` object, and one or more `li` elements representing the items
1006
- in the list. However, list controls implemented using JS component libraries can be composed of multiple elements representing the
1007
- components of a list implementation.
1214
+ The `CustomControlsPage` page object's `initialize` method in the code snippet below demonstrates the use of the
1215
+ `Table.define_table_elements` method to define the components that make up the responsive `table`.
1008
1216
 
1009
- The `List.define_list_elements` method provides a means of specifying the elements that make up the key components of a `list` control.
1010
- The method accepts a hash of element designators (key) and a CSS or Xpath expression (value) that expression that uniquely identifies
1011
- the element. Valid element designators are `list_item:`and `selected_item:`.
1217
+ class CustomControlsPage < TestCentricity::PageObject
1218
+ trait(:page_name) { 'Custom Controls' }
1219
+ trait(:page_locator) { 'div.custom-controls-page-body' }
1012
1220
 
1221
+ # Custom Controls page UI elements
1222
+ table :custom_table, 'div#resp-table'
1223
+
1224
+ def initialize
1225
+ super
1226
+ # define the custom element components for the table
1227
+ table_spec = {
1228
+ table_header: 'div.resp-table-header',
1229
+ header_row: 'div.resp-table-row',
1230
+ header_column: 'div.table-header-cell',
1231
+ table_body: 'div.resp-table-body',
1232
+ table_row: 'div.resp-table-row',
1233
+ table_column: 'div.table-body-cell'
1234
+ }
1235
+ custom_table.define_table_elements(table_spec)
1236
+ end
1237
+ end
1013
1238
 
1014
- ## Instantiating your PageObjects
1015
1239
 
1016
- Before you can call the methods in your `PageObjects` and `PageSections`, you must instantiate the `PageObjects` of your web
1017
- application, as well as create instance variables which can be used when calling a `PageObject`'s methods from your step definitions.
1018
- There are several ways to instantiate your `PageObjects`.
1240
+ ---
1241
+ ## Instantiating Your PageObjects
1242
+
1243
+ Before you can call the methods in your `PageObjects` and `PageSections`, you must instantiate the `PageObjects` of your
1244
+ web application, as well as create instance variables which can be used when calling a `PageObject`'s methods from your
1245
+ step definitions. There are several ways to instantiate your `PageObjects`.
1019
1246
 
1020
1247
  One common implementation is shown below:
1021
1248
 
@@ -1023,81 +1250,82 @@ One common implementation is shown below:
1023
1250
  def login_page
1024
1251
  @login_page ||= LoginPage.new
1025
1252
  end
1026
-
1253
+
1027
1254
  def home_page
1028
1255
  @home_page ||= HomePage.new
1029
1256
  end
1030
-
1257
+
1031
1258
  def registration_page
1032
1259
  @registration_page ||= RegistrationPage.new
1033
1260
  end
1034
-
1261
+
1035
1262
  def search_results_page
1036
1263
  @search_results_page ||= SearchResultsPage.new
1037
1264
  end
1038
1265
  end
1039
-
1266
+
1040
1267
  World(WorldPages)
1041
1268
 
1042
- 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
1043
- `features/support` folder.
1269
+ The `WorldPages` module above can be defined in your `env.rb` file, or you can define it in a separate `world_pages.rb`
1270
+ file in the `features/support` folder.
1044
1271
 
1045
- While this approach is effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly becomes
1046
- cumbersome to manage if your web application has dozens of `PageObjects` that need to be instantiated and managed.
1272
+ While this approach is effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly
1273
+ becomes cumbersome to manage if your web application has dozens of `PageObjects` that need to be instantiated and managed.
1047
1274
 
1048
1275
  ### Using the PageManager
1049
1276
 
1050
- The `PageManager` class provides methods for supporting the instantiation and management of `PageObjects`. In the code example below,
1051
- the `page_objects` method contains a hash table of your `PageObject` instances and their associated `PageObject` classes to be
1052
- instantiated by `PageManager`:
1053
-
1277
+ The `PageManager` class provides methods for supporting the instantiation and management of `PageObjects`. In the code
1278
+ example below, the `page_objects` method contains a hash table of your `PageObject` instances and their associated
1279
+ `PageObject` classes to be instantiated by `PageManager`:
1280
+
1054
1281
  module WorldPages
1055
1282
  def page_objects
1056
1283
  {
1057
- login_page: LoginPage,
1058
- home_page: HomePage,
1059
- registration_page: RegistrationPage,
1060
- search_results_page: SearchResultsPage,
1061
- products_grid_page: ProductsCollectionPage,
1062
- product_detail_page: ProductDetailPage,
1063
- shopping_basket_page: ShoppingBasketPage,
1064
- payment_method_page: PaymentMethodPage,
1065
- confirm_purchase_page: PurchaseConfirmationPage,
1066
- my_account_page: MyAccountPage,
1067
- my_order_history_page: MyOrderHistoryPage,
1068
- my_ship_to_addresses_page: MyShipToAddressesPage,
1069
- terms_conditions_page: TermsConditionsPage,
1070
- privacy_policy_page: PrivacyPolicyPage,
1071
- faqs_page: FAQsPage,
1072
- contact_us_page: ContactUsPage
1284
+ login_page: LoginPage,
1285
+ home_page: HomePage,
1286
+ registration_page: RegistrationPage,
1287
+ search_results_page: SearchResultsPage,
1288
+ products_grid_page: ProductsCollectionPage,
1289
+ product_detail_page: ProductDetailPage,
1290
+ shopping_basket_page: ShoppingBasketPage,
1291
+ payment_method_page: PaymentMethodPage,
1292
+ confirm_purchase_page: PurchaseConfirmationPage,
1293
+ my_account_page: MyAccountPage,
1294
+ my_order_history_page: MyOrderHistoryPage,
1295
+ my_ship_to_addresses_page: MyShipToAddressesPage,
1296
+ terms_conditions_page: TermsConditionsPage,
1297
+ privacy_policy_page: PrivacyPolicyPage,
1298
+ faqs_page: FAQsPage,
1299
+ contact_us_page: ContactUsPage
1073
1300
  }
1074
1301
  end
1075
1302
  end
1076
-
1303
+
1077
1304
  World(WorldPages)
1078
1305
 
1079
1306
 
1080
1307
  The `WorldPages` module above should be defined in the `world_pages.rb` file in the `features/support` folder.
1081
1308
 
1082
- Include the code below in your `env.rb` file to ensure that your `PageObjects` are instantiated before your Cucumber scenarios are
1083
- executed:
1084
-
1309
+ Include the code below in your `env.rb` file to ensure that your `PageObjects` are instantiated before your Cucumber
1310
+ scenarios are executed:
1311
+
1085
1312
  include WorldPages
1086
1313
  WorldPages.instantiate_page_objects
1087
-
1088
- **NOTE:** If you intend to use the `PageManager`, you must define a `page_name` trait for each of the `PageObjects` to be registered.
1089
1314
 
1315
+ **NOTE:** If you intend to use the `PageManager`, you must define a `page_name` trait for each of the `PageObjects` to
1316
+ be registered.
1090
1317
 
1091
- ### Leveraging the PageManager in your Cucumber tests
1092
1318
 
1093
- Many Cucumber based automated tests suites include scenarios that verify that web pages are correctly loaded, displayed, or can be
1094
- navigated to by clicking associated links. One such Cucumber navigation scenario is displayed below:
1319
+ ### Leveraging the PageManager in Your Cucumber Tests
1320
+
1321
+ Many Cucumber based automated tests suites include scenarios that verify that web pages are correctly loaded, displayed,
1322
+ or can be navigated to by clicking associated links. One such Cucumber navigation scenario is displayed below:
1095
1323
 
1096
1324
  Scenario Outline: Verify Home page navigation links
1097
1325
  Given I am on the Home page
1098
1326
  When I click the <page name> navigation link
1099
1327
  Then I expect the <page name> page to be correctly displayed
1100
-
1328
+
1101
1329
  Examples:
1102
1330
  |page name |
1103
1331
  |Registration |
@@ -1107,25 +1335,25 @@ navigated to by clicking associated links. One such Cucumber navigation scenario
1107
1335
  |FAQs |
1108
1336
  |Contact Us |
1109
1337
 
1110
- In the above example, the step definitions associated with the 3 steps might be implemented using a `page_dispatcher` method using a
1111
- `case` statement to parse the `page` parameter as in the example below:
1338
+ In the above example, the step definitions associated with the 3 steps might be implemented using a `page_dispatcher`
1339
+ method using a `case` statement to parse the `page` parameter as in the example below:
1112
1340
 
1113
1341
  Given(/^I am on the (.*) page$/) do |page_name|
1114
1342
  target_page = page_dispatcher(page_name)
1115
1343
  target_page.load_page
1116
1344
  end
1117
-
1345
+
1118
1346
  When(/^I click the (.*) navigation link$/) do |link_name|
1119
1347
  target_page = page_dispatcher(link_name)
1120
1348
  target_page.navigate_to
1121
1349
  end
1122
-
1350
+
1123
1351
  Then(/^I expect the (.*) page to be correctly displayed$/) do |page_name|
1124
1352
  target_page = page_dispatcher(page_name)
1125
1353
  target_page.verify_page_exists
1126
1354
  target_page.verify_page_ui
1127
1355
  end
1128
-
1356
+
1129
1357
  # this method takes a page name as a parameter and returns an instance of the associated Page Object
1130
1358
  def page_dispatcher(page_name)
1131
1359
  page = case page_name
@@ -1147,32 +1375,33 @@ In the above example, the step definitions associated with the 3 steps might be
1147
1375
  end
1148
1376
 
1149
1377
 
1150
- While this approach may be effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly becomes
1151
- cumbersome to manage if your web application has dozens of `PageObjects` that need to be managed.
1378
+ While this approach may be effective for small web applications with only a few pages (and hence few `PageObjects`), it
1379
+ quickly becomes cumbersome to manage if your web application has dozens of `PageObjects` that need to be managed.
1152
1380
 
1153
- The `PageManager` class provides a `find_page` method that replaces the cumbersome and difficult to maintain `case` statement used in the
1154
- above example. The `PageManager.current_page` method allows you to set or get an instance of the currently active Page Object.
1381
+ The `PageManager` class provides a `find_page` method that replaces the cumbersome and difficult to maintain `case`
1382
+ statement used in the above example. The `PageManager.current_page` method allows you to set or get an instance of the
1383
+ currently active Page Object.
1155
1384
 
1156
- To use these `PageManager` methods, include the step definitions and code below in a `page_steps.rb` or `generic_steps.rb` file in the
1157
- `features/step_definitions` folder:
1385
+ To use these `PageManager` methods, include the step definitions and code below in a `page_steps.rb` or `generic_steps.rb`
1386
+ file in the `features/step_definitions` folder:
1158
1387
 
1159
1388
  include TestCentricity
1160
-
1389
+
1161
1390
  Given(/^I am on the (.*) page$/) do |page_name|
1162
1391
  target_page = PageManager.find_page(page_name)
1163
1392
  target_page.load_page
1164
1393
  end
1165
-
1394
+
1166
1395
  When(/^I click the (.*) navigation link$/) do |page_name|
1167
1396
  target_page = PageManager.find_page(page_name)
1168
1397
  target_page.navigate_to
1169
1398
  end
1170
-
1399
+
1171
1400
  Then(/^I expect to see the (.*) page$/) do |page_name|
1172
1401
  target_page = PageManager.find_page(page_name)
1173
1402
  target_page.verify_page_exists
1174
1403
  end
1175
-
1404
+
1176
1405
  Then(/^I expect the (.*) page to be correctly displayed$/) do |page_name|
1177
1406
  target_page = PageManager.find_page(page_name)
1178
1407
  target_page.verify_page_exists
@@ -1180,213 +1409,487 @@ To use these `PageManager` methods, include the step definitions and code below
1180
1409
  end
1181
1410
 
1182
1411
 
1412
+ ---
1413
+ ## Connecting to Web Browsers
1414
+
1415
+ Since its inception, TestCentricity has provided support for establishing a single connection to a target desktop or mobile
1416
+ web browser by instantiating a WebDriver object. **Environment Variables** are used to specify the local, grid, or remote
1417
+ cloud hosted target web browser, and the various WebDriver capability parameters required to configure the driver object.
1418
+ The appropriate **Environment Variables** are typically specified in the command line at runtime through the use of profiles
1419
+ set in a `cucumber.yml` file (Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below).
1420
+
1421
+ However, for those use cases requiring the instantiation of multiple WebDriver objects within a test case or test scenario,
1422
+ **Environment Variables** are a less effective means of specifying multiple driver capabilities. And even in those use cases
1423
+ where only a single WebDriver object is required, there are a growing number of optional Selenium and Appium capabilities
1424
+ that are being offered by cloud hosted browser service providers (like BrowserStack, Sauce Labs, TestingBot, or LambdaTest)
1425
+ that **Environment Variables** may not effectively address.
1426
+
1427
+ Beginning with TestCentricity version 4.4.0, the `TestCentricity::WebDriverConnect.initialize_web_driver` method accepts
1428
+ an optional `options` hash for specifying desired capabilities (using the W3C protocol), driver type, driver name, endpoint
1429
+ URL, device type, and desktop web browser window size information. TestCentricity also now supports the instantiation of
1430
+ multiple WebDriver objects to establish connections with, and coordinate test execution between multiple desktop and/or
1431
+ mobile web browser instances.
1432
+
1433
+ Some use cases for the verification of real-time multiple user interactions across multiple concurrent browsers or devices are:
1434
+ - Chat, Messaging, or Social Media apps/web portals used by one or more users interacting in real time (posts, reposts, likes)
1435
+ - Ride Hailing/Sharing Services with separate Rider and Driver experience apps/web portals
1436
+ - Food Delivery Services with a Customer app for finding restaurants and ordering food, a Restaurant app for fulfilling
1437
+ the food order and coordinating delivery, and a Driver app for ensuring delivery of the order to the customer
1438
+ - Learning Management/Student Engagement platforms that allow teachers to monitor student engagement and progress on assigned
1439
+ activities and support for remote real-time collaboration between students and teachers
1440
+
1441
+ If the optional `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
1442
+ then **Environment Variables** must be used to specify the target local or remote web browser, and the various webdriver
1443
+ capability parameters required to establish a connection with a single target web browser.
1444
+
1445
+ ### Specifying Options and Capabilities in the `options` Hash
1183
1446
 
1184
- ## Connecting to a Web Browser
1447
+ For those test scenarios requiring the instantiation of multiple WebDriver objects, or where cumbersome **Environment
1448
+ Variables** are less than ideal, call the `TestCentricity::WebDriverConnect.initialize_web_driver` method with an `options`
1449
+ hash that specifies the WebDriver desired capabilities and the driver type, as depicted in the example below:
1185
1450
 
1186
- The `TestCentricity::WebDriverConnect.initialize_web_driver` method configures the appropriate Selenium-Webdriver capabilities required to
1187
- establish a connection with a target web browser, and sets the base host URL of the web site you are running your tests against.
1451
+ options = {
1452
+ capabilities: { browserName: :firefox },
1453
+ driver: :webdriver
1454
+ }
1455
+ WebDriverConnect.initialize_web_driver(options)
1188
1456
 
1189
- The `TestCentricity::WebDriverConnect.initialize_web_driver` method accepts a single optional parameter - the base host URL. Cucumber
1190
- **Environment Variables** are used to specify the target local or remote web browser, and the various webdriver capability parameters required
1191
- to configure the connection.
1457
+ Additional options that can be specified in an `options` hash include the following:
1192
1458
 
1459
+ | Option | Purpose |
1460
+ |-----------------|--------------------------------------------------------------------------------------------|
1461
+ | `browser_size:` | optional desktop web browser window size (width and height) |
1462
+ | `driver_name:` | optional driver name |
1463
+ | `endpoint:` | optional endpoint URL for remote grid or cloud hosted browser service providers |
1464
+ | `device_type:` | only used for locally or cloud hosted mobile device browser - set to `:phone` or `:tablet` |
1193
1465
 
1194
- ### Locally hosted desktop web browser
1466
+ Details on specifying desired capabilities, driver type, endpoint URL, and default driver names are provided in each of the
1467
+ browser hosting sections below.
1195
1468
 
1196
- For locally hosted desktop web browsers running on macOS or Windows platforms, the `WEB_BROWSER` Environment Variable must be set to one of the
1197
- values from the table below:
1469
+ #### Specifying the Driver Type
1198
1470
 
1199
- | `WEB_BROWSER` | **Desktop Platform** |
1200
- |--------------------|------------------------------------------------|
1201
- | `chrome` | macOS or Windows |
1202
- | `chrome_headless` | macOS or Windows (headless - no visible UI) |
1203
- | `firefox` | macOS or Windows |
1204
- | `firefox_headless` | macOS or Windows (headless - no visible UI) |
1205
- | `edge` | macOS or Windows |
1206
- | `edge_headless` | macOS or Windows (headless - no visible UI) |
1207
- | `safari` | macOS only |
1208
- | `ie` | Windows only (IE version 10.x or greater only) |
1471
+ The `driver:` type is a required entry in the `options` hash when instantiating a WebDriver object using the `initialize_web_driver`
1472
+ method. Valid `driver:` type values are listed in the table below:
1209
1473
 
1210
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1474
+ | `driver:` | **Driver Type** |
1475
+ |-----------------|--------------------------------------------------------------------------------------------|
1476
+ | `:webdriver` | locally hosted desktop or emulated mobile browser |
1477
+ | `:grid` | Selenium Grid 4 hosted browser |
1478
+ | `:appium` | locally hosted native iOS/Android mobile browser using device simulator or physical device |
1479
+ | `:browserstack` | remote browser hosted on BrowserStack |
1480
+ | `:saucelabs` | remote browser hosted on Sauce Labs |
1481
+ | `:testingbot` | remote browser hosted on TestingBot |
1482
+ | `:lambdatest` | remote browser hosted on LambdaTest |
1211
1483
 
1484
+ #### Specifying a Driver Name
1212
1485
 
1213
- #### Setting desktop browser window size
1486
+ An optional user defined `driver_name:` can be specified in the `options` hash when instantiating a WebDriver object using
1487
+ the `TestCentricity::WebDriverConnect.initialize_web_driver` method. If a driver name is not specified, the `initialize_web_driver`
1488
+ method will assign a default driver name comprised of the specified driver type (`driver:`) and the `browserName:` specified
1489
+ in the `capabilities:` hash. Details on default driver names are provided in each of the browser hosting sections below.
1490
+
1491
+ For those test scenarios requiring the instantiation of multiple WebDriver objects, each driver object should be assigned a
1492
+ unique driver name, which is used when switching between driver contexts. For instance, when performing end-to-end testing
1493
+ of a Food Delivery Service which consists of separate web portals for the Customer Experience (find, order, and pay for food),
1494
+ the Restaurant Experience (menu management, order fulfillment, and order delivery dispatch), and the Delivery Driver Experience
1495
+ (customer location and tracking), 3 driver objects must be instantiated.
1496
+
1497
+ Assigning meaningful unique driver names for the 3 driver objects (`:customer_portal`, `:merchant_portal`, `:delivery_portal`)
1498
+ in the `options` hash when calling `TestCentricity::WebDriverConnect.initialize_web_driver` method reduces confusion when
1499
+ switching between the driver objects using the `TestCentricity:WebDriverConnect.activate_driver(driver_name)` method, which
1500
+ expects a driver name, specified as a `Symbol`.
1501
+
1502
+ ### Setting Desktop Browser Window Size
1503
+
1504
+ #### Using `:browser_size` in the `options` Hash
1505
+
1506
+ The size (width and height) of a desktop browser window can be specified in the `options` hash for browsers that are hosted
1507
+ locally, in a Selenium Grid, or by a cloud hosted browser service provider. You cannot set the size of a mobile device web
1508
+ browser, which is determined by the mobile device's screen size.
1509
+
1510
+ To set the size of a desktop browser window in the `options` hash, you specify a `:browser_size` with the desired width and
1511
+ height in pixels as shown below:
1512
+
1513
+ options = {
1514
+ browser_size: [1100, 900],
1515
+ capabilities: { browserName: :edge },
1516
+ driver: :webdriver
1517
+ }
1518
+ WebDriverConnect.initialize_web_driver(options)
1519
+
1520
+ To maximize a desktop browser window, you specify a `:browser_size` of 'max' as shown below:
1521
+
1522
+ options = {
1523
+ browser_size: 'max',
1524
+ capabilities: { browserName: :chrome },
1525
+ driver: :webdriver
1526
+ }
1527
+ WebDriverConnect.initialize_web_driver(options)
1528
+
1529
+ If a `:browser_size` is not specified, then the default size of a desktop browser window will be set to the size specified
1530
+ in the `BROWSER_SIZE` Environment Variable (if it has been specified) or to a default width and height of 1650 by 1000 pixels.
1531
+
1532
+ #### Using the `BROWSER_SIZE` Environment Variable
1533
+
1534
+ To set the size of a desktop browser window without using an `options` hash, you set the `BROWSER_SIZE` Environment Variable
1535
+ to the desired width and height in pixels as shown below:
1214
1536
 
1215
- To set the size of a desktop browser window, you set the `BROWSER_SIZE` Environment Variable to the desired width and height in pixels as shown below:
1216
-
1217
1537
  BROWSER_SIZE=1600,1000
1218
1538
 
1219
1539
  To maximize a desktop browser window, you set the `BROWSER_SIZE` Environment Variable to 'max' as shown below:
1220
-
1540
+
1221
1541
  BROWSER_SIZE=max
1222
1542
 
1543
+ If the `BROWSER_SIZE` Environment Variable is not specified, then the default size of a desktop browser window will be set
1544
+ to a width and height of 1650 by 1000 pixels.
1545
+
1546
+
1547
+ ### Locally Hosted Desktop Web Browsers
1548
+
1549
+ For locally hosted desktop web browsers running on macOS, Windows, or Linux platforms, the browser type and driver type
1550
+ must be specified when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method. The table below contains
1551
+ the values that can be used to specify the locally hosted desktop web browser to be instantiated when calling the
1552
+ `initialize_web_driver` method:
1553
+
1554
+ | `browserName:` or `WEB_BROWSER` | **Desktop Platform** |
1555
+ |---------------------------------|-----------------------------------------------------|
1556
+ | `chrome` | macOS, Windows, or Linux |
1557
+ | `chrome_headless` | macOS, Windows, or Linux (headless - no visible UI) |
1558
+ | `firefox` | macOS, Windows, or Linux |
1559
+ | `firefox_headless` | macOS, Windows, or Linux (headless - no visible UI) |
1560
+ | `edge` | macOS or Windows |
1561
+ | `edge_headless` | macOS or Windows (headless - no visible UI) |
1562
+ | `safari` | macOS only |
1563
+
1564
+ #### Local Desktop Browser using Environment Variables
1565
+
1566
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method, then
1567
+ the following Environment Variables must be set as described in the table below:
1568
+
1569
+ | **Environment Variable** | **Description** |
1570
+ |--------------------------|-------------------------------------------------------------------|
1571
+ | `WEB_BROWSER` | Must be set to one of the values from the table above |
1572
+ | `DRIVER` | Must be set to `webdriver` |
1573
+ | `BROWSER_SIZE` | [Optional] Set to _'width in pixels, heigh in pixels'_ or _'max'_ |
1574
+
1575
+ Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
1576
+
1577
+
1578
+ #### Local Desktop Browser in the `options` Hash
1579
+
1580
+ When using the `options` hash, the following options and capabilities must be specified:
1581
+ - `driver:` must be set to `:webdriver`
1582
+ - `browserName:` in the `capabilities:` hash must be set to one of the values from the table above
1223
1583
 
1224
- #### Testing file downloads with desktop browsers
1225
-
1226
- File download functionality can be tested with locally hosted instances of Chrome, Edge, or Firefox desktop browsers. Your automation project must include
1227
- a `/downloads` folder at the same level as the `/config` and `/features` folders, as depicted below:
1228
-
1229
- my_automation_project
1230
- ├── config
1231
- ├── downloads
1232
- ├── features
1233
- ├── Gemfile
1234
- └── README.md
1235
-
1236
-
1237
- When running tests in multiple concurrent threads using the `parallel_tests` gem, a new folder will be created within the `/downloads` folder for each
1238
- test thread. This is to ensure that files downloaded in each test thread are isolated from tests running in other parallel threads. An example of the
1239
- `/downloads` folder structure for 4 parallel threads is depicted below:
1240
-
1241
- my_automation_project
1242
- ├── config
1243
- ├── downloads
1244
- │ ├── 1
1245
- │ ├── 2
1246
- │ ├── 3
1247
- │ └── 4
1248
- ├── features
1249
- ├── Gemfile
1250
- └── README.md
1251
-
1252
-
1253
- When testing file downloads using a local instance of Firefox, you will need to specify the MIME types of the various file types that your tests will
1254
- be downloading. This is accomplished by setting the `MIME_TYPES` Environment Variable to a comma-delimited string containing the list of MIME types to
1255
- be accepted. This list is required as it will prevent Firefox from displaying the File Download modal dialog, which will halt your automated tests. An
1256
- example of a list of MIME types is depicted below:
1257
-
1258
- MIME_TYPES='images/jpeg, application/pdf, application/octet-stream'
1259
-
1260
- A detailed list of file MIME types can be found [here](https://www.freeformatter.com/mime-types-list.html)
1261
-
1262
-
1263
- ### Locally hosted emulated mobile web browser
1264
-
1265
- You can run your tests against mobile device browsers that are emulated within a locally hosted instance of a Chrome desktop browser on macOS or
1266
- Windows. The specified mobile browser's user agent, CSS screen dimensions, and default screen orientation will be automatically set within the
1267
- local Chrome browser instance. You may even specify the emulated device's screen orientation. For locally hosted emulated mobile web browsers,
1268
- the `WEB_BROWSER` Environment Variable must be set to one of the values from the table below:
1269
-
1270
- | `WEB_BROWSER` | `HOST_BROWSER` | **CSS Screen Dimensions** | **Default Orientation** | **OS Version** |
1271
- |-----------------------|----------------|---------------------------|-------------------------|-------------------------------------------|
1272
- | `ipad` | `chrome` | 1024 x 768 | landscape | iOS 12 |
1273
- | `ipad_pro` | `chrome` | 1366 x 1024 | landscape | iOS 12 |
1274
- | `ipad_pro_10_5` | `chrome` | 1112 x 834 | landscape | iOS 12.2 |
1275
- | `ipad_pro_11` | `chrome` | 1194 x 834 | landscape | iOS 12.2 |
1276
- | `ipad_pro_12_9` | `chrome` | 1366 x 1024 | landscape | iOS 13.1 |
1277
- | `ipad_chrome` | `chrome` | 1024 x 768 | landscape | iOS 12.2 - Mobile Chrome browser for iOS |
1278
- | `ipad_firefox` | `chrome` | 1024 x 768 | landscape | iOS 12.2 - Mobile Firefox browser for iOS |
1279
- | `ipad_edge` | `chrome` | 1024 x 768 | landscape | iOS 12.2 - Mobile Edge browser for iOS |
1280
- | `kindle_fire` | `chrome` | 1024 x 600 | landscape | |
1281
- | `kindle_firehd7` | `chrome` | 800 x 480 | landscape | Fire OS 3 |
1282
- | `kindle_firehd8` | `chrome` | 1280 x 800 | landscape | Fire OS 5 |
1283
- | `kindle_firehd10` | `chrome` | 1920 x 1200 | landscape | Fire OS 5 |
1284
- | `surface` | `chrome` | 1366 x 768 | landscape | |
1285
- | `blackberry_playbook` | `chrome` | 1024 x 600 | landscape | BlackBerry Tablet OS |
1286
- | `samsung_galaxy_tab` | `chrome` | 1280 x 800 | landscape | Android 4.0.4 |
1287
- | `google_nexus7` | `chrome` | 960 x 600 | landscape | Android 4.4.4 |
1288
- | `google_nexus9` | `chrome` | 1024 x 768 | landscape | Android 5.1 |
1289
- | `google_nexus10` | `chrome` | 1280 x 800 | landscape | Android 5.1 |
1290
- | `iphone6` | `chrome` | 375 x 667 | portrait | iOS 12 |
1291
- | `iphone6_plus` | `chrome` | 414 x 736 | portrait | iOS 12 |
1292
- | `iphone7` | `chrome` | 375 x 667 | portrait | iOS 12 |
1293
- | `iphone7_plus` | `chrome` | 414 x 736 | portrait | iOS 12 |
1294
- | `iphone7_chrome` | `chrome` | 375 x 667 | portrait | iOS 12.2 - Mobile Chrome browser for iOS |
1295
- | `iphone7_firefox` | `chrome` | 375 x 667 | portrait | iOS 12.2 - Mobile Firefox browser for iOS |
1296
- | `iphone7_edge` | `chrome` | 375 x 667 | portrait | iOS 12.2 - Microsoft Edge browser for iOS |
1297
- | `iphone8` | `chrome` | 375 x 667 | portrait | iOS 12 |
1298
- | `iphone8_plus` | `chrome` | 414 x 736 | portrait | iOS 12 |
1299
- | `iphone_x` | `chrome` | 375 x 812 | portrait | iOS 12.2 |
1300
- | `iphone_xr` | `chrome` | 414 x 896 | portrait | iOS 12.2 |
1301
- | `iphone_xs` | `chrome` | 375 x 812 | portrait | iOS 12.2 |
1302
- | `iphone_xs_max` | `chrome` | 414 x 896 | portrait | iOS 12.2 |
1303
- | `iphone_11` | `chrome` | 414 x 896 | portrait | iOS 13.1 |
1304
- | `iphone_11_pro` | `chrome` | 375 x 812 | portrait | iOS 13.1 |
1305
- | `iphone_11_pro_max` | `chrome` | 414 x 896 | portrait | iOS 13.1 |
1306
- | `nexus6` | `chrome` | 411 x 731 | portrait | Android 6 |
1307
- | `pixel` | `chrome` | 411 x 731 | portrait | Android 8 |
1308
- | `pixel_xl` | `chrome` | 411 x 731 | portrait | Android 8 |
1309
- | `samsung_galaxy_s4` | `chrome` | 360 x 640 | portrait | Android 5.0.1 |
1310
- | `samsung_galaxy_s5` | `chrome` | 360 x 640 | portrait | Android 6.0.1 |
1311
- | `samsung_galaxy_s6` | `chrome` | 360 x 640 | portrait | Android 6.0.1 |
1312
- | `windows_phone7` | `chrome` | 320 x 480 | portrait | Windows Phone OS 7.5 |
1313
- | `windows_phone8` | `chrome` | 320 x 480 | portrait | Windows Phone OS 8.0 |
1314
- | `lumia_950_xl` | `chrome` | 360 x 640 | portrait | Windows Phone OS 10 |
1315
- | `blackberry_z10` | `chrome` | 384 x 640 | portrait | BlackBerry 10 OS |
1316
- | `blackberry_z30` | `chrome` | 360 x 640 | portrait | BlackBerry 10 OS |
1317
- | `blackberry_leap` | `chrome` | 360 x 640 | portrait | BlackBerry 10 OS |
1318
- | `blackberry_passport` | `chrome` | 504 x 504 | square | BlackBerry 10 OS |
1319
-
1320
- To change the emulated device's screen orientation from the default setting, set the `ORIENTATION` Environment Variable to either `portrait` or `landscape`.
1321
-
1322
- 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
1323
- to `chrome`.
1324
-
1325
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1326
-
1327
-
1328
- #### User defined mobile device profiles
1329
-
1330
- User defined mobile device profiles can be specified in a `device.yml` file for testing locally hosted emulated mobile web browsers running in an instance
1331
- of the Chrome desktop browser. The user specified device profiles must be located at `config/data/devices/devices.yml` as depicted below:
1332
-
1333
- my_automation_project
1334
- ├── config
1335
- │ ├── data
1336
- │ │ └── devices
1337
- │ │ └── devices.yml
1338
- │ ├── locales
1339
- │ ├── test_data
1340
- │ └── cucumber.yml
1341
- ├── downloads
1342
- ├── features
1343
- ├── Gemfile
1344
- └── README.md
1345
-
1346
- The format for a new device profile is:
1347
1584
  ```
1348
- :new_device_profile:
1349
- :name: "New Device Name"
1350
- :os: (ios, android, kindle, or blackberry)
1351
- :type: (phone or tablet)
1352
- :css_width: css width in pixels
1353
- :css_height: css height in pixels
1354
- :default_orientation: (portrait or landscape)
1355
- :user_agent: "user agent string"
1585
+ options = {
1586
+ capabilities: { browserName: value_from_table_above },
1587
+ driver: :webdriver
1588
+ }
1589
+ WebDriverConnect.initialize_web_driver(options)
1356
1590
  ```
1591
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
1592
+ `:local_<browserName>` - e.g. `:local_chrome` or `:local_edge_headless`.
1593
+
1594
+ Below is an example of an `options` hash for specifying a connection to a locally hosted Firefox desktop web browser. The
1595
+ `options` hash includes options for specifying the driver name and setting the browser window size.
1596
+
1597
+ options = {
1598
+ driver: :webdriver,
1599
+ driver_name: :customer_context,
1600
+ browser_size: [1400, 1100],
1601
+ capabilities: { browserName: :firefox }
1602
+ }
1603
+ WebDriverConnect.initialize_web_driver(options)
1604
+
1605
+
1606
+ #### Testing File Downloads With Desktop Browsers
1607
+
1608
+ File download functionality can be tested with locally hosted instances of Chrome, Edge, or Firefox desktop browsers. Your
1609
+ automation project must include a `/downloads` folder which is used as the destination for files that are downloaded by
1610
+ your automated tests. The `/downloads` folder must be at the same level as the `/config` and `/features` folders, as depicted
1611
+ below:
1612
+
1613
+ 📁 my_automation_project/
1614
+ ├── 📁 config/
1615
+ ├── 📁 downloads/
1616
+ ├── 📁 features/
1617
+ ├── 📄 Gemfile
1618
+ └── 📄 README.md
1619
+
1620
+
1621
+ When running tests in multiple concurrent threads using the `parallel_tests` gem, a new folder will be created within the
1622
+ `/downloads` folder for each test thread. This is to ensure that files downloaded in each test thread are isolated from tests
1623
+ running in other parallel threads. An example of the`/downloads` folder structure for 4 parallel threads is depicted below:
1624
+
1625
+ 📁 my_automation_project/
1626
+ ├── 📁 config/
1627
+ ├── 📁 downloads/
1628
+ │ ├── 📁 1/
1629
+ │ ├── 📁 2/
1630
+ │ ├── 📁 3/
1631
+ │ └── 📁 4/
1632
+ ├── 📁 features/
1633
+ ├── 📄 Gemfile
1634
+ └── 📄 README.md
1635
+
1636
+
1637
+ When testing file downloads using a local instance of Firefox, you will need to specify the MIME types of the various file
1638
+ types that your tests will be downloading. This is accomplished by setting the `MIME_TYPES` Environment Variable to a
1639
+ comma-delimited string containing the list of MIME types to be accepted. The `MIME_TYPES` Environment Variable should be
1640
+ set before initializing the Firefox web driver. This list of file types is required as it will prevent Firefox from displaying
1641
+ the File Download modal dialog, which will halt your automated tests. An example of a list of MIME types is depicted below:
1642
+
1643
+ # set list of all supported MIME types for testing file downloads with Firefox
1644
+ mime_types = [
1645
+ 'application/pdf',
1646
+ 'image/png',
1647
+ 'image/jpeg',
1648
+ 'image/gif',
1649
+ 'text/csv',
1650
+ 'text/plain'
1651
+ ]
1652
+ ENV['MIME_TYPES'] = mime_types.join(',')
1653
+
1654
+
1655
+ A detailed list of file MIME types can be found [here](https://www.freeformatter.com/mime-types-list.html).
1656
+
1657
+
1658
+ ### Locally Hosted Emulated Mobile Web Browsers
1659
+
1660
+ You can run your tests against mobile device browsers that are emulated within a locally hosted instance of a Chrome desktop
1661
+ browser on macOS or Windows. The specified mobile browser's user agent, CSS screen dimensions, and default screen orientation
1662
+ will be automatically set within the local Chrome browser instance. You may also specify the emulated device's screen orientation.
1663
+
1664
+ ⚠️ For best results when testing against mobile web browsers, you should run your tests against iOS and Android simulators
1665
+ or physical devices, either hosted locally or via a remotely cloud hosted service.
1666
+
1667
+ For locally hosted emulated mobile web browsers, the `WEB_BROWSER` Environment Variable must be set to one of the values
1668
+ from the table below:
1669
+
1670
+ | `browserName:` or `WEB_BROWSER` | **CSS Screen Dimensions** | **Default Orientation** | **OS Version** |
1671
+ |---------------------------------|---------------------------|-------------------------|----------------------|
1672
+ | `iphone_11` | 414 x 896 | portrait | iOS 15.5 |
1673
+ | `iphone_11_pro` | 375 x 812 | portrait | iOS 15.5 |
1674
+ | `iphone_11_pro_max` | 414 x 896 | portrait | iOS 15.5 |
1675
+ | `iphone_12_mini` | 375 x 812 | portrait | iOS 15.5 |
1676
+ | `iphone_12` | 390 x 844 | portrait | iOS 15.5 |
1677
+ | `iphone_12_pro` | 390 x 844 | portrait | iOS 15.5 |
1678
+ | `iphone_12_pro_max` | 428 x 926 | portrait | iOS 15.5 |
1679
+ | `iphone_13_mini` | 375 x 812 | portrait | iOS 15.5 |
1680
+ | `iphone_13` | 390 x 844 | portrait | iOS 15.5 |
1681
+ | `iphone_13_pro` | 390 x 844 | portrait | iOS 15.5 |
1682
+ | `iphone_13_pro_max` | 428 x 926 | portrait | iOS 15.5 |
1683
+ | `iphone_se` | 375 x 667 | portrait | iOS 15.5 |
1684
+ | `iphone_14` | 390 x 844 | portrait | iOS 16.2 |
1685
+ | `iphone_14_plus` | 428 x 926 | portrait | iOS 16.2 |
1686
+ | `iphone_14_pro` | 393 x 852 | portrait | iOS 16.2 |
1687
+ | `iphone_14_pro_max` | 430 x 932 | portrait | iOS 16.2 |
1688
+ | `ipad` | 1080 x 810 | landscape | iOS 15.5 |
1689
+ | `ipad_mini` | 1133 x 744 | landscape | iOS 15.5 |
1690
+ | `ipad_air` | 1180 x 820 | landscape | iOS 15.5 |
1691
+ | `ipad_pro_11` | 1194 x 834 | landscape | iOS 15.5 |
1692
+ | `ipad_pro_12_9` | 1366 x 1024 | landscape | iOS 15.5 |
1693
+ | `pixel_5` | 393 x 851 | portrait | Android 12 |
1694
+ | `pixel_6` | 412 x 915 | portrait | Android 12 |
1695
+ | `pixel_xl` | 412 x 732 | portrait | Android 12 |
1696
+ | `nexus_10` | 1280 x 800 | landscape | Android 12 |
1697
+ | `pixel_c` | 1280 x 900 | landscape | Android 12 |
1698
+ | `kindle_fire` | 1024 x 600 | landscape | |
1699
+ | `kindle_firehd7` | 800 x 480 | landscape | Fire OS 3 |
1700
+ | `kindle_firehd8` | 1280 x 800 | landscape | Fire OS 5 |
1701
+ | `kindle_firehd10` | 1920 x 1200 | landscape | Fire OS 5 |
1702
+ | `surface` | 1366 x 768 | landscape | |
1703
+ | `blackberry_playbook` | 1024 x 600 | landscape | BlackBerry Tablet OS |
1704
+ | `windows_phone7` | 320 x 480 | portrait | Windows Phone OS 7.5 |
1705
+ | `windows_phone8` | 320 x 480 | portrait | Windows Phone OS 8.0 |
1706
+ | `lumia_950_xl` | 360 x 640 | portrait | Windows Phone OS 10 |
1707
+ | `blackberry_z10` | 384 x 640 | portrait | BlackBerry 10 OS |
1708
+ | `blackberry_z30` | 360 x 640 | portrait | BlackBerry 10 OS |
1709
+ | `blackberry_leap` | 360 x 640 | portrait | BlackBerry 10 OS |
1710
+ | `blackberry_passport` | 504 x 504 | square | BlackBerry 10 OS |
1711
+
1712
+ #### Local Emulated Mobile Browser using Environment Variables
1713
+
1714
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
1715
+ then the following Environment Variables must be set as described in the table below:
1716
+
1717
+ | **Environment Variable** | **Description** |
1718
+ |--------------------------|-------------------------------------------------------|
1719
+ | `WEB_BROWSER` | Must be set to one of the values from the table above |
1720
+ | `DRIVER` | Must be set to `webdriver` |
1721
+ | `ORIENTATION` | [Optional] Set to `portrait` or `landscape` |
1722
+
1723
+ Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
1724
+
1725
+
1726
+ #### Local Emulated Mobile Browser in the `options` Hash
1727
+
1728
+ When using the `options` hash, the following options and capabilities must be specified:
1729
+ - `driver:` must be set to `:webdriver`
1730
+ - `browserName:` in the `capabilities:` hash must be set to one of the values from the table above
1357
1731
 
1358
- ### Selenium Grid 4 and Dockerized Selenium Grid 4 hosted desktop and emulated mobile web browsers
1732
+ ```
1733
+ options = {
1734
+ capabilities: { browserName: value_from_table_above },
1735
+ driver: :webdriver
1736
+ }
1737
+ WebDriverConnect.initialize_web_driver(options)
1738
+ ```
1739
+ To change the emulated device's screen orientation from the default setting, set the optional `orientation:` to either
1740
+ `:portrait` or `:landscape` in the `capabilities:` hash as shown in the example below:
1741
+
1742
+ options = {
1743
+ capabilities: {
1744
+ browserName: :ipad_pro_12_9,
1745
+ orientation: :portrait
1746
+ },
1747
+ driver: :webdriver
1748
+ }
1749
+ WebDriverConnect.initialize_web_driver(options)
1750
+
1751
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
1752
+ `:local_<browserName>` - e.g. `:local_ipad_pro_12_9` or `:local_pixel_6`.
1753
+
1754
+ Below is an example of an `options` hash for specifying a connection to a locally hosted emulated mobile Safari web browser
1755
+ running on an iPhone. The`options` hash includes options for specifying the driver name and setting the browser orientation
1756
+ to landscape mode.
1757
+
1758
+ options = {
1759
+ driver: :webdriver,
1760
+ driver_name: :user1,
1761
+ capabilities: {
1762
+ browserName: :iphone_13_pro_max,
1763
+ orientation: :landscape
1764
+ }
1765
+ }
1766
+ WebDriverConnect.initialize_web_driver(options)
1767
+
1768
+
1769
+ #### User Defined Emulated Mobile Browser Profiles
1770
+
1771
+ User defined mobile browser profiles can be specified in a `device.yml` file for testing locally hosted emulated mobile
1772
+ web browsers running in an instance of the Chrome desktop browser. The user specified browser profiles must be located
1773
+ at `config/data/devices/devices.yml` as depicted below:
1774
+
1775
+ 📁 my_automation_project/
1776
+ ├── 📁 config/
1777
+ │ ├── 📁 data/
1778
+ │ │ └── 📁 devices/
1779
+ │ │ └── 📄devices.yml
1780
+ │ ├── 📁 locales/
1781
+ │ ├── 📁 test_data/
1782
+ │ └── 📄 cucumber.yml
1783
+ ├── 📁 downloads/
1784
+ ├── 📁 features/
1785
+ ├── 📄 Gemfile
1786
+ └── 📄 README.md
1787
+
1788
+ The format for a new mobile browser profile is:
1789
+ ```
1790
+ :my_device_profile:
1791
+ :name: "My New Device Name"
1792
+ :os: (ios, android, kindle, or blackberry)
1793
+ :type: (phone or tablet)
1794
+ :css_width: css width in pixels
1795
+ :css_height: css height in pixels
1796
+ :default_orientation: (portrait or landscape)
1797
+ :user_agent: "user agent string"
1798
+ ```
1799
+
1800
+ To specify a user defined emulated mobile browser, set `browserName:` or the `WEB_BROWSER` Environment Variable to the
1801
+ device's profile name.
1802
+
1803
+
1804
+ ### Selenium Grid Hosted Desktop and Emulated Mobile Web Browsers
1805
+
1806
+ For remotely hosted desktop web browsers running on a Selenium 4 Grid, the browser type and driver type must be specified
1807
+ when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method. The table below contains the values that
1808
+ can be used to specify the grid hosted desktop web browser to be instantiated when calling the`initialize_web_driver` method:
1809
+
1810
+ | `browserName:` or `WEB_BROWSER` |
1811
+ |---------------------------------|
1812
+ | `chrome` |
1813
+ | `chrome_headless` |
1814
+ | `firefox` |
1815
+ | `firefox_headless` |
1816
+ | `edge` |
1817
+ | `edge_headless` |
1359
1818
 
1360
- For remote desktop and emulated mobile web browsers running on Selenium Grid 4 or Dockerized Selenium Grid 4 environments as described in the table below.
1819
+ #### Grid Browsers using Environment Variables
1361
1820
 
1362
- | **Environment Variable** | **Description** |
1363
- |--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1364
- | `WEB_BROWSER` | Must be set to one of the following desktop browsers - `chrome`, `chrome_headless`, `edge`, `edge_headless`, or `firefox`, or any of the mobile web browsers described above. |
1365
- | `SELENIUM` | Must be set to `remote` |
1366
- | `REMOTE_ENDPOINT` | Must be set to the URL of the Grid hub, which is usually `http://localhost:4444/wd/hub` |
1821
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
1822
+ then the following Environment Variables must be set as described in the table below:
1367
1823
 
1368
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1824
+ | **Environment Variable** | **Description** |
1825
+ |--------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
1826
+ | `WEB_BROWSER` | Must be set to one of the values from the table above, or any of the emulated mobile web browsers described above in section 8.4. |
1827
+ | `DRIVER` | Must be set to `grid` |
1828
+ | `REMOTE_ENDPOINT` | [Optional] Set to the URL of the Grid hub. Set to `http://localhost:4444/wd/hub` if not specified |
1829
+ | `BROWSER_SIZE` | [Optional] Set to _'width in pixels, heigh in pixels'_ or _'max'_ |
1369
1830
 
1831
+ Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
1370
1832
 
1371
- ### Mobile browsers on Simulators or Physical Devices
1372
1833
 
1373
- #### Mobile Safari browser on iOS Simulators or iOS Physical Devices
1834
+ #### Grid Browser in the `options` Hash
1835
+
1836
+ When using the `options` hash, the following options and capabilities must be specified:
1837
+ - `driver:` must be set to `:grid`
1838
+ - `browserName:` in the `capabilities:` hash must be set to one of the values from the table above
1839
+
1840
+ ```
1841
+ options = {
1842
+ capabilities: { browserName: value_from_table_above },
1843
+ driver: :grid,
1844
+ endpoint: 'http://localhost:4444/wd/hub'
1845
+ }
1846
+ WebDriverConnect.initialize_web_driver(options)
1847
+ ```
1848
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
1849
+ `:remote_<browserName>` - e.g. `:remote_chrome` or `:remote_edge_headless`.
1850
+
1851
+ ℹ️ If an `endpoint:` is not specified in the `options`hash, then the default remote endpoint URL of `http://localhost:4444/wd/hub`
1852
+ will be used.
1374
1853
 
1375
- 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
1376
- macOS. You must install Appium, XCode, and the iOS version-specific device simulators for XCode. You must also ensure that the `appium_capybara` gem is
1377
- installed and required as described in **section 3.3 (Setup - Using Appium)** above.
1854
+ Below is an example of an `options` hash for specifying a connection to a grid hosted Chrome desktop web browser. The
1855
+ `options` hash includes options for specifying the driver name and setting the browser window size.
1378
1856
 
1379
- Information about Appium setup and configuration requirements for testing on physically connected iOS devices can be found on [this page](https://github.com/appium/appium/blob/master/docs/en/drivers/ios-xcuitest-real-devices.md).
1380
- The Appium server must be running prior to invoking Cucumber to run your features/scenarios.
1857
+ options = {
1858
+ driver: :grid,
1859
+ driver_name: :admin_user,
1860
+ browser_size: [1400, 1100],
1861
+ capabilities: { browserName: :chrome }
1862
+ }
1863
+ WebDriverConnect.initialize_web_driver(options)
1381
1864
 
1382
- Once your test environment is properly configured, the following **Environment Variables** must be set as described in the table below.
1865
+
1866
+ ### Locally Hosted Mobile Browsers on Simulators or Physical Devices
1867
+
1868
+ Refer to [this page](https://appium.io/docs/en/2.2/guides/caps/) for information regarding specifying Appium capabilities.
1869
+
1870
+ #### Mobile Safari Browser on iOS Simulators or iOS Physical Devices
1871
+
1872
+ You can run your mobile web tests against the mobile Safari browser on iOS device simulators or physically connected iOS
1873
+ devices using Appium and XCode on macOS. You must install Appium, XCode, and the iOS version-specific device simulators
1874
+ for XCode. Information about Appium setup and configuration requirements with the XCUITest driver for testing on physically
1875
+ connected iOS devices can be found on [this page](https://github.com/appium/appium-xcuitest-driver/blob/master/docs/real-device-config.md). Refer to [this page](https://appium.github.io/appium-xcuitest-driver/5.12/capabilities/) for information regarding specifying
1876
+ Appium capabilities that are specific to the XCUITest driver.
1877
+
1878
+ The Appium server must be running prior to invoking Cucumber to run your features/scenarios. Refer to [**section 8.6.3 (Starting and Stopping Appium Server)**](#starting-and-stopping-appium-server) below.
1879
+
1880
+
1881
+ ##### Local Mobile Safari Browser using Environment Variables
1882
+
1883
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
1884
+ the following **Environment Variables** must be set as described in the table below.
1383
1885
 
1384
1886
  | **Environment Variable** | **Description** |
1385
1887
  |----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1386
1888
  | `DRIVER` | Must be set to `appium` |
1889
+ | `AUTOMATION_ENGINE` | Must be set to `xcuitest` |
1387
1890
  | `APP_PLATFORM_NAME` | Must be set to `iOS` |
1388
1891
  | `APP_BROWSER` | Must be set to `Safari` |
1389
- | `APP_VERSION` | Must be set to `15.4`, `14.5`, or which ever iOS version you wish to run within the XCode Simulator |
1892
+ | `APP_VERSION` | Must be set to which ever iOS version you wish to run within the XCode Simulator |
1390
1893
  | `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 |
1391
1894
  | `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
1392
1895
  | `APP_UDID` | UDID of physically connected iOS device (not used for simulators) |
@@ -1398,57 +1901,165 @@ Once your test environment is properly configured, the following **Environment V
1398
1901
  | `APP_FULL_RESET` | [Optional] Perform a complete reset. Set to `true` or `false` |
1399
1902
  | `APP_INITIAL_URL` | [Optional] Initial URL, default is a local welcome page. e.g. `http://www.apple.com` |
1400
1903
  | `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. |
1401
- | `LOCALE` | [Optional] Locale to set for the simulator. e.g. `fr_CA` |
1402
- | `LANGUAGE` | [Optional] Language to set for the simulator. e.g. `fr` |
1403
1904
  | `ORIENTATION` | [Optional] Set to `portrait` or `landscape` (only for iOS simulators) |
1404
1905
  | `NEW_COMMAND_TIMEOUT` | [Optional] Time (in Seconds) that Appium will wait for a new command from the client |
1405
1906
  | `SHOW_SIM_KEYBOARD` | [Optional] Show the simulator keyboard during text entry. Set to `true` or `false` |
1406
1907
  | `SHUTDOWN_OTHER_SIMS` | [Optional] Close any other running simulators. Set to `true` or `false`. See note below. |
1407
1908
 
1408
- The `SHUTDOWN_OTHER_SIMS` environment variable can only be set if you are running Appium Server with the `--relaxed-security` or
1409
- `--allow-insecure=shutdown_other_sims` arguments passed when starting it from the command line, or when running the server from the
1410
- Appium Server GUI app. A security violation error will occur without relaxed security enabled.
1909
+ The `SHUTDOWN_OTHER_SIMS` environment variable can only be set if you are running Appium Server with the `--relaxed-security`
1910
+ or `--allow-insecure=shutdown_other_sims` arguments passed when starting it from the command line, or when running the server
1911
+ from the Appium Server GUI app. A security violation error will occur without relaxed security enabled.
1912
+
1913
+ Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
1914
+
1915
+
1916
+ ##### Local Mobile Safari Browser in the `options` Hash
1411
1917
 
1412
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1918
+ When using the `options` hash, the following options and capabilities must be specified:
1919
+ - `driver:` must be set to `:appium`
1920
+ - `device_type:` must be set to `:tablet` or `:phone`
1921
+ - `browserName:` must be set to 'Safari' in the `capabilities:` hash
1922
+ - `platformName:` must be set to 'ios' in the `capabilities:` hash
1923
+ - `'appium:automationName':` must be set to 'xcuitest' in the `capabilities:` hash
1924
+ - `'appium:platformVersion':` must be set to the version of iOS on the simulator or physical device
1925
+ - `'appium:deviceName':` must be set to the name of the iOS simulator or physical device
1413
1926
 
1927
+ ```
1928
+ options = {
1929
+ driver: :appium,
1930
+ device_type: phone_or_tablet,
1931
+ capabilities: {
1932
+ platformName: 'ios',
1933
+ browserName: 'Safari',
1934
+ 'appium:automationName': 'xcuitest',
1935
+ 'appium:platformVersion': ios_version,
1936
+ 'appium:deviceName': device_or_simulator_name
1937
+ },
1938
+ endpoint: 'http://localhost:4723/wd/hub'
1939
+ }
1940
+ WebDriverConnect.initialize_web_driver(options)
1941
+ ```
1942
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
1943
+ `appium_safari`.
1944
+
1945
+ ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL of `http://localhost:4723/wd/hub`
1946
+ will be used.
1947
+
1948
+ Below is an example of an `options` hash for specifying a connection to a locally hosted mobile Safari web browser running
1949
+ on an iPad simulator. The `options` hash includes options for specifying the driver name and setting the simulated device
1950
+ orientation to portrait mode.
1951
+
1952
+ options = {
1953
+ driver: :appium,
1954
+ device_type: :tablet,
1955
+ driver_name: :student_ipad,
1956
+ capabilities: {
1957
+ platformName: 'ios',
1958
+ browserName: 'Safari',
1959
+ 'appium:platformVersion': '15.4',
1960
+ 'appium:deviceName': 'iPad Pro (12.9-inch) (5th generation)',
1961
+ 'appium:automationName': 'xcuitest',
1962
+ 'appium:orientation': 'PORTRAIT'
1963
+ }
1964
+ }
1965
+ WebDriverConnect.initialize_web_driver(options)
1966
+
1967
+
1968
+ #### Mobile Chrome or Android Browsers on Android Studio Virtual Device Emulators
1414
1969
 
1415
- #### Mobile Chrome or Android browsers on Android Studio Virtual Device emulators
1970
+ You can run your mobile web tests against the mobile Chrome or Android browser on emulated Android devices using Appium and
1971
+ Android Studio on macOS. You must install Android Studio, the desired Android version-specific virtual device emulators, and
1972
+ Appium. Refer to [this page](https://appium.io/docs/en/2.2/quickstart/uiauto2-driver/) for information on configuring Appium to work with the Android SDK.
1416
1973
 
1417
- You can run your mobile web tests against the mobile Chrome or Android browser on emulated Android devices using Appium and Android Studio on macOS. You
1418
- 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)
1419
- for information on configuring Appium to work with the Android SDK. You must also ensure that the `appium_capybara` gem is installed and required as
1420
- described in **section 3.3 (Setup - Using Appium)** above.
1974
+ The Appium server must be running prior to invoking Cucumber to run your features/scenarios. Refer to [**section 8.6.3 (Starting and Stopping Appium Server)**](#starting-and-stopping-appium-server) below.
1421
1975
 
1422
- The Appium server must be running prior to invoking Cucumber to run your features/scenarios. Refer to [this page](https://appium.io/docs/en/writing-running-appium/web/chromedriver/index.html)
1423
- for information on configuring Appium to use the correct version of Chromedriver required to work with the web browser supported by each Android OS version.
1424
1976
 
1425
- Once your test environment is properly configured, the following **Environment Variables** must be set as described in the table below.
1977
+ ##### Local Mobile Android Browsers using Environment Variables
1978
+
1979
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
1980
+ the following **Environment Variables** must be set as described in the table below.
1426
1981
 
1427
1982
  | **Environment Variable** | **Description** |
1428
1983
  |---------------------------|--------------------------------------------------------------------------------------------------------------------------------|
1429
1984
  | `DRIVER` | Must be set to `appium` |
1985
+ | `AUTOMATION_ENGINE` | Must be set to `UiAutomator2` |
1430
1986
  | `APP_PLATFORM_NAME` | Must be set to `Android` |
1431
1987
  | `APP_BROWSER` | Must be set to `Chrome` or `Browser` |
1432
- | `APP_VERSION` | Must be set to `12.0`, or which ever Android OS version you wish to run with the Android Virtual Device |
1988
+ | `APP_VERSION` | Must be set to which ever Android OS version you wish to run with the Android Virtual Device |
1433
1989
  | `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 |
1434
1990
  | `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
1435
1991
  | `ORIENTATION` | [Optional] Set to `portrait` or `landscape` |
1436
1992
  | `APP_INITIAL_URL` | [Optional] Initial URL, default is a local welcome page. e.g. `http://www.apple.com` |
1437
1993
  | `APP_NO_RESET` | [Optional] Don't reset app state after each test. Set to `true` or `false` |
1438
1994
  | `APP_FULL_RESET` | [Optional] Perform a complete reset. Set to `true` or `false` |
1439
- | `LOCALE` | [Optional] Locale to set for the simulator. e.g. `fr_CA` |
1440
- | `LANGUAGE` | [Optional] Language to set for the simulator. e.g. `fr` |
1441
1995
  | `NEW_COMMAND_TIMEOUT` | [Optional] Time (in Seconds) that Appium will wait for a new command from the client |
1442
- | `CHROMEDRIVER_EXECUTABLE` | [Optional] Absolute local path to webdriver executable |
1996
+ | `CHROMEDRIVER_EXECUTABLE` | [Optional] Absolute local path to ChromeDriver executable |
1443
1997
 
1444
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1998
+ Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
1445
1999
 
1446
2000
 
1447
- #### Starting and stopping Appium Server
2001
+ ##### Local Mobile Android Browser in the `options` Hash
1448
2002
 
1449
- The Appium server must be running prior to invoking Cucumber to run your features/scenarios on mobile simulators or physical
1450
- device. To programmatically control the starting and stopping of Appium server with the execution of your automated tests, place
1451
- the code shown below in your `hooks.rb` file.
2003
+ When using the `options` hash, the following options and capabilities must be specified:
2004
+ - `driver:` must be set to `:appium`
2005
+ - `device_type:` must be set to `:tablet` or `:phone`
2006
+ - `browserName:` must be set to 'Chrome' in the `capabilities:` hash
2007
+ - `platformName:` must be set to 'Android' in the `capabilities:` hash
2008
+ - `'appium:automationName':` must be set to 'UiAutomator2' in the `capabilities:` hash
2009
+ - `'appium:platformVersion':` must be set to the version of Android on the simulator or physical device
2010
+ - `'appium:deviceName':` must be set to the Android Virtual Device ID
2011
+
2012
+ ```
2013
+ options = {
2014
+ driver: :appium,
2015
+ device_type: phone_or_tablet,
2016
+ capabilities: {
2017
+ platformName: 'Android',
2018
+ browserName: 'Chrome',
2019
+ 'appium:automationName': 'UiAutomator2',
2020
+ 'appium:platformVersion': android_version,
2021
+ 'appium:deviceName': simulator_name,
2022
+ 'appium:avd': simulator_name
2023
+ },
2024
+ endpoint: 'http://localhost:4723/wd/hub'
2025
+ }
2026
+ WebDriverConnect.initialize_web_driver(options)
2027
+ ```
2028
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
2029
+ `appium_chrome`.
2030
+
2031
+ ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL of `http://localhost:4723/wd/hub`
2032
+ will be used.
2033
+
2034
+ Below is an example of an `options` hash for specifying a connection to a locally hosted mobile Chrome web browser running
2035
+ on an Android phone simulator. The `options` hash includes options for specifying the driver name, setting the simulated
2036
+ device orientation to landscape mode, and specifying the path to the ChromeDriver executable.
2037
+
2038
+ options = {
2039
+ driver: :appium,
2040
+ device_type: :phone,
2041
+ driver_name: :student_phone,
2042
+ capabilities: {
2043
+ platformName: 'Android',
2044
+ browserName: 'Chrome',
2045
+ 'appium:platformVersion': '12.0',
2046
+ 'appium:deviceName': 'Pixel_5_API_31',
2047
+ 'appium:avd': 'Pixel_5_API_31',
2048
+ 'appium:automationName': 'UiAutomator2',
2049
+ 'appium:orientation': 'LANDSCAPE',
2050
+ 'appium:chromedriverExecutable': '/Users/Shared/config/webdrivers/chromedriver'
2051
+ }
2052
+ }
2053
+ WebDriverConnect.initialize_web_driver(options)
2054
+
2055
+
2056
+ #### Starting and Stopping Appium Server
2057
+
2058
+ ##### Using Appium Server with Cucumber
2059
+
2060
+ The Appium server must be running prior to invoking Cucumber to run your features/scenarios on locally hosted mobile simulators
2061
+ or physical devices. To programmatically control the starting and stopping of Appium server with the execution of your automated
2062
+ tests, place the code shown below in your `hooks.rb` file.
1452
2063
 
1453
2064
  BeforeAll do
1454
2065
  # start Appium Server if APPIUM_SERVER = 'run' and target browser is a mobile simulator or device
@@ -1459,43 +2070,64 @@ the code shown below in your `hooks.rb` file.
1459
2070
  end
1460
2071
 
1461
2072
  AfterAll do
2073
+ # terminate all driver instances
2074
+ WebDriverConnect.close_all_drivers
1462
2075
  # terminate Appium Server if APPIUM_SERVER = 'run' and target browser is a mobile simulator or device
1463
2076
  $server.stop if ENV['APPIUM_SERVER'] == 'run' && Environ.driver == :appium && $server.running?
1464
- # close driver
1465
- Capybara.page.driver.quit
1466
- Capybara.reset_sessions!
1467
- Environ.session_state = :quit
1468
2077
  end
1469
2078
 
1470
-
1471
- The `APPIUM_SERVER` environment variable must be set to `run` in order to programmatically start and stop Appium server. This can be
1472
- set by adding the following to your `cucumber.yml` file and including `-p run_appium` in your command line when starting your Cucumber
1473
- test suite(s):
2079
+ The `APPIUM_SERVER` environment variable must be set to `run` in order to programmatically start and stop the Appium server.
2080
+ This can be set by adding the following to your `cucumber.yml` file and including `-p run_appium` in your command line when
2081
+ starting your Cucumber test suite(s):
1474
2082
 
1475
2083
  run_appium: APPIUM_SERVER=run
1476
2084
 
2085
+ Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
1477
2086
 
1478
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1479
2087
 
2088
+ ##### Using Appium Server with RSpec
1480
2089
 
1481
- ### Remote cloud hosted desktop and mobile web browsers
2090
+ The Appium server must be running prior to executing test specs on locally hosted mobile simulators or physical device. To
2091
+ control the starting and stopping of the Appium server with the execution of your specs, place the code shown below in the
2092
+ body of an example group:
1482
2093
 
1483
- You can run your automated tests against remote cloud hosted desktop and mobile web browsers using the BrowserStack, SauceLabs, TestingBot, or
1484
- LambdaTest services. If your tests are running against a web site hosted on your local computer (`localhost`), or on a staging server inside
1485
- your LAN, you must set the `TUNNELING` Environment Variable to `true`.
2094
+ before(:context) do
2095
+ # start Appium server before all of the examples in this group
2096
+ $server = TestCentricity::AppiumServer.new
2097
+ $server.start
2098
+ end
1486
2099
 
1487
- Due to lack of support for Selenium 4.x and the W3C browser capabilities protocol, support for CrossBrowserTesting and Gridlastic cloud hosted
1488
- 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
1489
- Selenium version 3.x, you should use earlier versions of this gem.
2100
+ after(:context) do
2101
+ # terminate Appium Server after all of the examples in this group
2102
+ $server.stop if Environ.driver == :appium && $server.running?
2103
+ end
1490
2104
 
1491
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1492
2105
 
2106
+ ### Remote Cloud Hosted Desktop and Mobile Web Browsers
1493
2107
 
1494
- #### Remote desktop browsers on the BrowserStack service
2108
+ You can run your automated tests against remote cloud hosted desktop and mobile web browsers using the BrowserStack, SauceLabs,
2109
+ TestingBot, or LambdaTest services. If your tests are running against a web site hosted on your local computer (`localhost`),
2110
+ or on a staging server inside your LAN, you must set the `TUNNELING` Environment Variable to `true`.
1495
2111
 
1496
- For remotely hosted desktop web browsers on the BrowserStack service, the following **Environment Variables** must be set as described in
1497
- the table below. Refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/automate/capabilities?tag=selenium-4)
1498
- for information regarding the specific capabilities.
2112
+ If the BrowserStack Local instance is running (`TUNNELING` Environment Variable is `true`), call the`TestCentricity::WebDriverConnect.close_tunnel`
2113
+ method upon completion of your test suite to stop the Local instance. Place the code shown below in your `env.rb` or
2114
+ `hooks.rb` file:
2115
+
2116
+ # code to stop BrowserStack Local instance after end of test (if tunneling is enabled)
2117
+ at_exit do
2118
+ TestCentricity::WebDriverConnect.close_tunnel if Environ.tunneling
2119
+ end
2120
+
2121
+ #### Remote Desktop Browsers on the BrowserStack Service
2122
+
2123
+ For remotely hosted desktop web browsers on the BrowserStack service, refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/automate/capabilities?tag=selenium-4)
2124
+ for information regarding the options and capabilities available for the various supported desktop operating systems and
2125
+ web browsers.
2126
+
2127
+ ##### BrowserStack Desktop Browser using Environment Variables
2128
+
2129
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
2130
+ the following **Environment Variables** must be set as described in the table below.
1499
2131
 
1500
2132
  | **Environment Variable** | **Description** |
1501
2133
  |--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -1516,20 +2148,82 @@ for information regarding the specific capabilities.
1516
2148
  | `SCREENSHOTS` | [Optional] Generate screenshots for debugging (`true` or `false`) |
1517
2149
  | `NETWORK_LOGS` | [Optional] Capture network logs (`true` or `false`) |
1518
2150
 
1519
- If the BrowserStack Local instance is running (`TUNNELING` Environment Variable is `true`), call the`TestCentricity::WebDriverConnect.close_tunnel` method
1520
- upon completion of your test suite to stop the Local instance. Place the code shown below in your `env.rb` or `hooks.rb` file.
1521
2151
 
1522
- # code to stop BrowserStack Local instance after end of test (if tunneling is enabled)
1523
- at_exit do
1524
- TestCentricity::WebDriverConnect.close_tunnel if Environ.tunneling
1525
- end
2152
+ ##### BrowserStack Desktop Browser in the `options` Hash
1526
2153
 
2154
+ When using the `options` hash, the following options and capabilities must be specified:
2155
+ - `driver:` must be set to `:browserstack`
2156
+ - `browserName:` in the `capabilities:` hash must be set to name from capability in chart
2157
+ - `browserVersion:` in the `capabilities:` hash must be set to browser version from capability in chart
1527
2158
 
1528
- #### Remote mobile browsers on the BrowserStack service
2159
+ ```
2160
+ options = {
2161
+ driver: :browserstack,
2162
+ capabilities: {
2163
+ browserName: browser_name_from_chart,
2164
+ browserVersion: browser_version_from_chart,
2165
+ 'bstack:options': {
2166
+ userName: bs_account_user_name,
2167
+ accessKey: bs_account_access_key,
2168
+ os: os_name_from_chart,
2169
+ osVersion: os_version_from_chart
2170
+ }
2171
+ }
2172
+ }
2173
+ WebDriverConnect.initialize_web_driver(options)
2174
+ ```
2175
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
2176
+ `:browserstack_<browserName>` - e.g. `:browserstack_chrome` or `:browserstack_safari`.
2177
+
2178
+ ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
2179
+
2180
+ `https://#{ENV['BS_USERNAME']}:#{ENV['BS_AUTHKEY']}@hub-cloud.browserstack.com/wd/hub`
2181
+
2182
+ This default endpoint requires that the `BS_USERNAME` Environment Variable is set to your BrowserStack account user name and
2183
+ the `BS_AUTHKEY` Environment Variable is set to your BrowserStack access key.
2184
+
2185
+ Below is an example of an `options` hash for specifying a connection to the latest version of an Edge desktop web browser
2186
+ running on macOS Sonoma hosted on BrowserStack. The `options` hash includes options for specifying the driver name, setting
2187
+ the browser window size, and capabilities for setting screen resolution, geoLocation, time zone, Selenium version, and various
2188
+ test configuration options.
2189
+
2190
+ options = {
2191
+ driver: :browserstack,
2192
+ driver_name: :admin_user,
2193
+ browser_size: [1400, 1100],
2194
+ capabilities: {
2195
+ browserName: 'Edge',
2196
+ browserVersion: 'latest',
2197
+ 'bstack:options': {
2198
+ userName: ENV['BS_USERNAME'],
2199
+ accessKey: ENV['BS_AUTHKEY'],
2200
+ projectName: 'ALP AP',
2201
+ buildName: "Test Build {ENV['BUILD_NUM']}",
2202
+ sessionName: 'AU Regression Suite',
2203
+ os: 'OS X',
2204
+ osVersion: 'Sonoma',
2205
+ resolution: '3840x2160',
2206
+ local: 'false',
2207
+ seleniumVersion: '4.15.0',
2208
+ networkLogs: 'true',
2209
+ geoLocation: 'AU',
2210
+ timezone: 'Perth'
2211
+ }
2212
+ }
2213
+ }
2214
+ WebDriverConnect.initialize_web_driver(options)
2215
+
2216
+
2217
+ #### Remote Mobile Browsers on the BrowserStack Service
1529
2218
 
1530
- For remotely hosted mobile web browsers on the BrowserStack service, the following **Environment Variables** must be set as described in
1531
- the table below. Refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/automate/capabilities?tag=selenium-4)
1532
- for information regarding the specific capabilities.
2219
+ For remotely hosted mobile web browsers on the BrowserStack service, refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/automate/capabilities?tag=selenium-4)
2220
+ for information regarding the options and capabilities available for the various supported mobile operating systems, devices,
2221
+ and web browsers.
2222
+
2223
+ ##### BrowserStack Mobile Browser using Environment Variables
2224
+
2225
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
2226
+ the following **Environment Variables** must be set as described in the table below.
1533
2227
 
1534
2228
  | **Environment Variable** | **Description** |
1535
2229
  |--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -1537,6 +2231,7 @@ for information regarding the specific capabilities.
1537
2231
  | `BS_USERNAME` | Must be set to your BrowserStack account user name |
1538
2232
  | `BS_AUTHKEY` | Must be set to your BrowserStack account access key |
1539
2233
  | `BS_OS` | Must be set to `ios` or `android` |
2234
+ | `BS_OS_VERSION` | Refer to `osVersion` capability in chart |
1540
2235
  | `BS_BROWSER` | Must be set to `Safari` (for iOS) or `Chrome` (for Android) |
1541
2236
  | `BS_DEVICE` | Refer to `deviceName` capability in chart |
1542
2237
  | `BS_REAL_MOBILE` | Set to `true` if running against a real device |
@@ -1551,11 +2246,81 @@ for information regarding the specific capabilities.
1551
2246
  | `APPIUM_LOGS` | [Optional] Generate Appium logs (`true` or `false`) |
1552
2247
 
1553
2248
 
1554
- #### Remote desktop browsers on the Sauce Labs service
2249
+ ##### BrowserStack Mobile Browser in the `options` Hash
2250
+
2251
+ When using the `options` hash, the following options and capabilities must be specified:
2252
+ - `driver:` must be set to `:browserstack`
2253
+ - `device_type:` must be set to `:tablet` or `:phone`
2254
+ - `browserName:` in the `capabilities:` hash must be set to name from capability in chart
2255
+
2256
+ ```
2257
+ options = {
2258
+ driver: :browserstack,
2259
+ device_type: phone_or_tablet,
2260
+ capabilities: {
2261
+ browserName: browser_name_from_chart,
2262
+ 'bstack:options': {
2263
+ userName: bs_account_user_name,
2264
+ accessKey: bs_account_access_key,
2265
+ osVersion: os_version_from_chart,
2266
+ deviceName: device_name_from_chart
2267
+ }
2268
+ }
2269
+ }
2270
+ WebDriverConnect.initialize_web_driver(options)
2271
+ ```
2272
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
2273
+ `:browserstack_<browserName>` - e.g. `:browserstack_chrome` or `:browserstack_safari`.
2274
+
2275
+ ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
2276
+
2277
+ `https://#{ENV['BS_USERNAME']}:#{ENV['BS_AUTHKEY']}@hub-cloud.browserstack.com/wd/hub`
2278
+
2279
+ This default endpoint requires that the `BS_USERNAME` Environment Variable is set to your BrowserStack account user name and
2280
+ the `BS_AUTHKEY` Environment Variable is set to your BrowserStack access key.
2281
+
2282
+ Below is an example of an `options` hash for specifying a connection to a mobile Samsung web browser running on an Android
2283
+ tablet hosted on BrowserStack. The `options` hash includes options for specifying the driver name, and capabilities for setting
2284
+ geoLocation, time zone, Appium version, and various test configuration options.
2285
+
2286
+ options = {
2287
+ driver: :browserstack,
2288
+ driver_name: :admin_tablet,
2289
+ capabilities: {
2290
+ browserName: 'samsung',
2291
+ device_type: :tablet,
2292
+ 'bstack:options': {
2293
+ userName: ENV['BS_USERNAME'],
2294
+ accessKey: ENV['BS_AUTHKEY'],
2295
+ projectName: 'ALP AP',
2296
+ buildName: "Test Build {ENV['BUILD_NUM']}",
2297
+ sessionName: 'AU Regression Suite',
2298
+ os: 'android',
2299
+ osVersion: '13.0',
2300
+ deviceName: 'Samsung Galaxy Tab S9',
2301
+ deviceOrientation: 'portrait',
2302
+ appiumVersion: '1.22.0',
2303
+ realMobile: 'true',
2304
+ local: 'false',
2305
+ networkLogs: 'true',
2306
+ geoLocation: 'AU',
2307
+ timezone: 'Perth'
2308
+ }
2309
+ }
2310
+ }
2311
+ WebDriverConnect.initialize_web_driver(options)
2312
+
1555
2313
 
1556
- For remotely hosted desktop web browsers on the Sauce Labs service, the following **Environment Variables** must be set as described in the
1557
- table below. Use the Selenium 4 selection on the [Platform Configurator page](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/)
1558
- to obtain information regarding the specific capabilities.
2314
+ #### Remote Desktop Browsers on the Sauce Labs Service
2315
+
2316
+ For remotely hosted desktop web browsers on the Sauce Labs service, refer to the [Platform Configurator page](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/)
2317
+ for information regarding the options and capabilities available for the various supported desktop operating systems and
2318
+ web browsers. Use the **Selenium 4** selection in the Config Script section of the Configurator page.
2319
+
2320
+ ##### Sauce Labs Desktop Browser using Environment Variables
2321
+
2322
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
2323
+ the following **Environment Variables** must be set as described in the table below.
1559
2324
 
1560
2325
  | **Environment Variable** | **Description** |
1561
2326
  |--------------------------|----------------------------------------------------------------------------------------------------------------------------|
@@ -1564,37 +2329,336 @@ to obtain information regarding the specific capabilities.
1564
2329
  | `SL_AUTHKEY` | Must be set to your Sauce Labs account access key |
1565
2330
  | `DATA_CENTER` | Must be set to your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`) |
1566
2331
  | `SL_OS` | Refer to `platformName` capability in the Config Script section of the Platform Configurator page |
1567
- | `SL_BROWSER` | Must be set to `chrome`, `firefox`, `safari`, `internet explorer`, or `MicrosoftEdge` |
2332
+ | `SL_BROWSER` | Must be set to `chrome`, `firefox`, `safari`, `internetExplorer`, or `MicrosoftEdge` |
1568
2333
  | `SL_VERSION` | Refer to `browserVersion` capability in the Config Script section of the Platform Configurator page |
1569
2334
  | `RESOLUTION` | [Optional] Refer to supported `screenResolution` capability in the Config Script section of the Platform Configurator page |
1570
- | `BROWSER_SIZE ` | [Optional] Specify width, height of browser window |
2335
+ | `BROWSER_SIZE` | [Optional] Specify width, height of browser window |
1571
2336
  | `RECORD_VIDEO` | [Optional] Enable screen video recording during test execution (`true` or `false`) |
1572
2337
 
1573
2338
 
1574
- #### Remote desktop browsers on the TestingBot service
2339
+ ##### Sauce Labs Desktop Browser in the `options` Hash
2340
+
2341
+ When using the `options` hash, the following options and capabilities must be specified:
2342
+ - `driver:` must be set to `:saucelabs`
2343
+ - `browserName:` in the `capabilities:` hash must be set to name from capability in chart
2344
+ - `browser_version:` in the `capabilities:` hash must be set to browser version from capability in chart
2345
+
2346
+ ```
2347
+ options = {
2348
+ driver: :saucelabs,
2349
+ capabilities: {
2350
+ browserName: browser_name_from_chart,
2351
+ browser_version: browser_version_from_chart,
2352
+ platform_name: platform_name_from_chart,
2353
+ 'sauce:options': {
2354
+ username: sl_account_user_name,
2355
+ access_key: bs_account_access_key
2356
+ }
2357
+ }
2358
+ }
2359
+ WebDriverConnect.initialize_web_driver(options)
2360
+ ```
2361
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
2362
+ `:saucelabs_<browserName>` - e.g. `:saucelabs_chrome` or `:saucelabs_safari`.
2363
+
2364
+ ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
2365
+
2366
+ `https://#{ENV['SL_USERNAME']}:#{ENV['SL_AUTHKEY']}@ondemand.#{ENV['DATA_CENTER']}.saucelabs.com:443/wd/hub`
2367
+
2368
+ This default endpoint requires that the `SL_USERNAME` Environment Variable is set to your Sauce Labs account user name, the
2369
+ `SL_AUTHKEY` Environment Variable is set to your Sauce Labs access key, and the `DATA_CENTER` Environment Variable is set to
2370
+ your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`).
2371
+
2372
+ Below is an example of an `options` hash for specifying a connection to the latest version of an Edge desktop web browser
2373
+ running on macOS Ventura hosted on Sauce Labs. The `options` hash includes options for specifying the driver name, setting
2374
+ the browser window size, and capabilities for setting screen resolution, time zone, and various test configuration options.
2375
+
2376
+ options = {
2377
+ driver: :saucelabs,
2378
+ driver_name: :admin_user,
2379
+ browser_size: [1400, 1100],
2380
+ capabilities: {
2381
+ browserName: 'MicrosoftEdge',
2382
+ browser_version: 'latest',
2383
+ platform_name: 'macOS 13',
2384
+ 'sauce:options': {
2385
+ username: ENV['SL_USERNAME'],
2386
+ access_key: ENV['SL_AUTHKEY'],
2387
+ name: 'ALP AP',
2388
+ build: "Test Build {ENV['BUILD_NUM']}",
2389
+ screenResolution: '2048x1536',
2390
+ timeZone: 'Perth',
2391
+ maxDuration: 2400,
2392
+ idleTimeout: 60
2393
+ }
2394
+ }
2395
+ }
2396
+ WebDriverConnect.initialize_web_driver(options)
2397
+
2398
+
2399
+ #### Remote Mobile Browsers on the Sauce Labs Service
2400
+
2401
+ For remotely hosted mobile web browsers on the Sauce Labs service, refer to the [Platform Configurator page](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/)
2402
+ for information regarding the options and capabilities available for the various supported mobile operating systems, devices,
2403
+ and web browsers.
2404
+
2405
+ ##### Sauce Labs Mobile Browser using Environment Variables
2406
+
2407
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
2408
+ the following **Environment Variables** must be set as described in the table below.
2409
+
2410
+ | **Environment Variable** | **Description** |
2411
+ |--------------------------|-----------------------------------------------------------------------------------------------------------------|
2412
+ | `DRIVER` | Must be set to `saucelabs` |
2413
+ | `AUTOMATION_ENGINE` | Must be set to `XCUITest` or `UiAutomator2` |
2414
+ | `SL_PLATFORM` | Must be set to `iOS` or `Android` |
2415
+ | `SL_BROWSER` | Must be set to `Safari` or `Chrome` |
2416
+ | `SL_VERSION` | Refer to `platformVersion` capability in the Config Script section of the Platform Configurator page |
2417
+ | `SL_DEVICE` | Refer to `deviceName` capability in chart |
2418
+ | `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
2419
+ | `SL_USERNAME` | Must be set to your Sauce Labs account user name or email address |
2420
+ | `SL_AUTHKEY` | Must be set to your Sauce Labs account access key |
2421
+ | `DATA_CENTER` | Must be set to your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`) |
2422
+ | `ORIENTATION` | [Optional] Set to `PORTRAIT` or `LANDSCAPE` |
2423
+
2424
+
2425
+ ##### Sauce Labs Mobile Browser in the `options` Hash
2426
+
2427
+ When using the `options` hash, the following options and capabilities must be specified:
2428
+ - `driver:` must be set to `:saucelabs`
2429
+ - `device_type:` must be set to `:tablet` or `:phone`
2430
+ - `browserName:` in the `capabilities:` hash must be set to `browserName` from capability in chart
2431
+ - `platform_name:` in the `capabilities:` hash must be set to `platform_name` from capability in chart
2432
+ - `'appium:automationName':` must be set to `automationName` from capability in chart
2433
+ - `'appium:platformVersion':` must be set to `platformVersion` from capability in chart
2434
+ - `'appium:deviceName':` must be set to `deviceName` from capability in chart
2435
+
2436
+ ```
2437
+ options = {
2438
+ driver: :saucelabs,
2439
+ device_type: phone_or_tablet,
2440
+ capabilities: {
2441
+ browserName: browser_name_from_chart,
2442
+ platform_name: platform_name_from_chart,
2443
+ 'appium:automationName': automationName_from_chart,
2444
+ 'appium:platformVersion': os_version_from_chart,
2445
+ 'appium:deviceName': device_name_from_chart,
2446
+ 'sauce:options': {
2447
+ userName: bs_account_user_name,
2448
+ accessKey: bs_account_access_key
2449
+ }
2450
+ }
2451
+ }
2452
+ WebDriverConnect.initialize_web_driver(options)
2453
+ ```
2454
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
2455
+ `:saucelabs_<browserName>` - e.g. `:saucelabs_chrome` or `:saucelabs_safari`.
2456
+
2457
+ ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
2458
+
2459
+ `https://#{ENV['SL_USERNAME']}:#{ENV['SL_AUTHKEY']}@ondemand.#{ENV['DATA_CENTER']}.saucelabs.com:443/wd/hub`
2460
+
2461
+ This default endpoint requires that the `SL_USERNAME` Environment Variable is set to your Sauce Labs account user name, the
2462
+ `SL_AUTHKEY` Environment Variable is set to your Sauce Labs access key, and the `DATA_CENTER` Environment Variable is set to
2463
+ your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`).
2464
+
2465
+ Below is an example of an `options` hash for specifying a connection to a mobile Safari web browser running on an iPad
2466
+ tablet hosted on Sauce Labs. The `options` hash includes options for specifying the driver name, and capabilities for setting
2467
+ device orientation, Appium version, and various test configuration options.
2468
+
2469
+ options = {
2470
+ driver: :saucelabs,
2471
+ device_type: :tablet,
2472
+ driver_name: :admin_tablet,
2473
+ capabilities: {
2474
+ browserName: 'Safari',
2475
+ platform_name: 'iOS',
2476
+ 'appium:automationName': 'XCUITest',
2477
+ 'appium:platformVersion': '15.4',
2478
+ 'appium:deviceName': 'iPad Pro (12.9 inch) (5th generation) Simulator',
2479
+ 'sauce:options': {
2480
+ username: ENV['SL_USERNAME'],
2481
+ access_key: ENV['SL_AUTHKEY'],
2482
+ name: 'ALP AP',
2483
+ build: "Test Build {ENV['BUILD_NUM']}",
2484
+ deviceOrientation: 'PORTRAIT',
2485
+ appiumVersion: '1.22.3'
2486
+ }
2487
+ }
2488
+ }
2489
+ WebDriverConnect.initialize_web_driver(options)
2490
+
2491
+
2492
+ #### Remote Desktop Browsers on the TestingBot Service
2493
+
2494
+ For remotely hosted desktop web browsers on the TestingBot service, refer to the [TestingBot List of Available Browsers page](https://testingbot.com/support/getting-started/browsers.html)
2495
+ and the [TestingBot Automated Test Options page](https://testingbot.com/support/other/test-options) for information regarding the options and capabilities available for
2496
+ the various supported desktop operating systems and web browsers.
2497
+
2498
+ ##### TestingBot Desktop Browser using Environment Variables
2499
+
2500
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
2501
+ the following **Environment Variables** must be set as described in the table below.
2502
+
2503
+ | **Environment Variable** | **Description** |
2504
+ |--------------------------|--------------------------------------------------------------------------------------------------------------------|
2505
+ | `DRIVER` | Must be set to `testingbot` |
2506
+ | `TB_USERNAME` | Must be set to your TestingBot account user name |
2507
+ | `TB_AUTHKEY` | Must be set to your TestingBot account access key |
2508
+ | `TB_OS` | Refer to `platform` capability in chart |
2509
+ | `TB_BROWSER` | Refer to `browserName` capability in chart |
2510
+ | `TB_VERSION` | Refer to `version` capability in chart |
2511
+ | `TUNNELING` | [Optional] Must be `true` if you are testing against internal/local servers (`true` or `false`) |
2512
+ | `RESOLUTION` | [Optional] Refer to [Change Screen Resolution](https://testingbot.com/support/other/test-options#screenresolution) |
2513
+ | `BROWSER_SIZE` | [Optional] Specify width, height of browser window |
2514
+
2515
+
2516
+ ##### TestingBot Desktop Browser in the `options` Hash
2517
+
2518
+ When using the `options` hash, the following options and capabilities must be specified:
2519
+ - `driver:` must be set to `:testingbot`
2520
+ - `browserName:` in the `capabilities:` hash must be set to name from capability in chart
2521
+ - `browser_version:` in the `capabilities:` hash must be set to browser version from capability in chart
2522
+ - `platform_name:` in the `capabilities:` hash must be set to platform name from capability in chart
2523
+
2524
+ ```
2525
+ options = {
2526
+ driver: :testingbot,
2527
+ capabilities: {
2528
+ browserName: browser_name_from_chart,
2529
+ browser_version: browser_version_from_chart,
2530
+ platform_name: platform_name_from_chart
2531
+ }
2532
+ }
2533
+ WebDriverConnect.initialize_web_driver(options)
2534
+ ```
2535
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
2536
+ `:testingbot_<browserName>` - e.g. `:testingbot_chrome` or `:testingbot_microsoftedge`.
2537
+
2538
+ ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
2539
+
2540
+ `https://#{ENV['TB_USERNAME']}:#{ENV['TB_AUTHKEY']}@hub.testingbot.com/wd/hub`
2541
+
2542
+ This default endpoint requires that the `TB_USERNAME` Environment Variable is set to your TestingBot account user name and
2543
+ the `TB_AUTHKEY` Environment Variable is set to your TestingBot access key.
2544
+
2545
+ Below is an example of an `options` hash for specifying a connection to the latest version of an Edge desktop web browser
2546
+ running on macOS Sonoma hosted on TestingBot. The `options` hash includes options for specifying the driver name, setting
2547
+ the browser window size, and capabilities for setting screen resolution, time zone, and various test configuration options.
2548
+
2549
+ options = {
2550
+ driver: :testingbot,
2551
+ driver_name: :admin_user,
2552
+ browser_size: [1400, 1100],
2553
+ capabilities: {
2554
+ browserName: 'microsoftedge',
2555
+ browser_version: 'latest',
2556
+ platform_name: 'SONOMA',
2557
+ 'tb:options': {
2558
+ name: 'ALP AP',
2559
+ build: "Test Build {ENV['BUILD_NUM']}",
2560
+ timeZone: 'Australia/Adelaide',
2561
+ 'testingbot.geoCountryCode': 'AU',
2562
+ 'screen-resolution': '2048x1536',
2563
+ 'selenium-version': '4.14.1'
2564
+ }
2565
+ }
2566
+ }
2567
+ WebDriverConnect.initialize_web_driver(options)
2568
+
2569
+
2570
+ #### Remote Mobile Browsers on the TestingBot Service
2571
+
2572
+ For remotely hosted mobile web browsers on the TestingBot service, refer to the [TestingBot List of Available Browsers page](https://testingbot.com/support/getting-started/browsers.html)
2573
+ and the [TestingBot Automated Test Options page](https://testingbot.com/support/other/test-options) for information regarding the options and capabilities available for
2574
+ the various supported mobile operating systems, devices, and web browsers.
2575
+
2576
+ ##### TestingBot Mobile Browser using Environment Variables
2577
+
2578
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
2579
+ the following **Environment Variables** must be set as described in the table below.
2580
+
2581
+ | **Environment Variable** | **Description** |
2582
+ |--------------------------|-------------------------------------------------------------------------------------------------|
2583
+ | `DRIVER` | Must be set to `testingbot` |
2584
+ | `TB_USERNAME` | Must be set to your TestingBot account user name |
2585
+ | `TB_AUTHKEY` | Must be set to your TestingBot account access key |
2586
+ | `TB_PLATFORM` | Must be set to `iOS` or `ANDROID` |
2587
+ | `TB_OS` | Must be set to `iOS` or `ANDROID` |
2588
+ | `TB_BROWSER` | Must be set to `safari` (for iOS) or `chrome` (for Android) |
2589
+ | `TB_VERSION` | Refer to `version` capability in chart |
2590
+ | `TB_DEVICE` | Refer to `deviceName` capability in chart |
2591
+ | `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
2592
+ | `TUNNELING` | [Optional] Must be `true` if you are testing against internal/local servers (`true` or `false`) |
2593
+ | `ORIENTATION` | [Optional] Set to `portrait` or `landscape` |
2594
+
2595
+
2596
+ ##### TestingBot Mobile Browser in the `options` Hash
1575
2597
 
1576
- For remotely hosted desktop web browsers on the TestingBot service, the following **Environment Variables** must be set as described in
1577
- the table below. Refer to the [TestingBot List of Available Browsers page](https://testingbot.com/support/getting-started/browsers.html) for information
1578
- regarding the specific capabilities.
2598
+ When using the `options` hash, the following options and capabilities must be specified:
2599
+ - `driver:` must be set to `:testingbot`
2600
+ - `device_type:` must be set to `:tablet` or `:phone`
2601
+ - `browserName:` in the `capabilities:` hash must be set to `browserName` from capability in chart
2602
+ - `platform_name:` in the `capabilities:` hash must be set to `platform_name` from capability in chart
1579
2603
 
1580
- | **Environment Variable** | **Description** |
1581
- |--------------------------|-------------------------------------------------------------------------------------------------------------------|
1582
- | `DRIVER` | Must be set to `testingbot` |
1583
- | `TB_USERNAME` | Must be set to your TestingBot account user name |
1584
- | `TB_AUTHKEY` | Must be set to your TestingBot account access key |
1585
- | `TB_OS` | Refer to `platform` capability in chart |
1586
- | `TB_BROWSER` | Refer to `browserName` capability in chart |
1587
- | `TB_VERSION` | Refer to `version` capability in chart |
1588
- | `TUNNELING` | [Optional] Must be `true` if you are testing against internal/local servers (`true` or `false`) |
1589
- | `RESOLUTION` | [Optional] Possible values: `800x600`, `1024x768`, `1280x960`, `1280x1024`, `1600x1200`, `1920x1200`, `2560x1440` |
1590
- | `BROWSER_SIZE` | [Optional] Specify width, height of browser window |
2604
+ ```
2605
+ options = {
2606
+ driver: :testingbot,
2607
+ device_type: phone_or_tablet,
2608
+ capabilities: {
2609
+ browserName: browser_name_from_chart,
2610
+ platform_name: platform_name_from_chart,
2611
+ browserVersion: os_version_from_chart,
2612
+ 'tb:options': {
2613
+ deviceName: device_name_from_chart
2614
+ }
2615
+ }
2616
+ }
2617
+ WebDriverConnect.initialize_web_driver(options)
2618
+ ```
2619
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
2620
+ `:testingbot_<browserName>` - e.g. `:testingbot_chrome` or `:testingbot_safari`.
2621
+
2622
+ ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
2623
+
2624
+ `https://#{ENV['TB_USERNAME']}:#{ENV['TB_AUTHKEY']}@hub.testingbot.com/wd/hub`
2625
+
2626
+ This default endpoint requires that the `TB_USERNAME` Environment Variable is set to your TestingBot account user name and
2627
+ the `TB_AUTHKEY` Environment Variable is set to your TestingBot access key.
2628
+
2629
+ Below is an example of an `options` hash for specifying a connection to a mobile Safari web browser running on an iPad
2630
+ tablet hosted on TestingBot. The `options` hash includes options for specifying the driver name, and capabilities for setting
2631
+ device orientation, Appium version, and various test configuration options.
2632
+
2633
+ options = {
2634
+ driver: :testingbot,
2635
+ device_type: :tablet,
2636
+ driver_name: :admin_tablet,
2637
+ capabilities: {
2638
+ browserName: 'safari',
2639
+ browserVersion: '15.4',
2640
+ platformName: 'iOS',
2641
+ 'tb:options': {
2642
+ deviceName: 'iPad Pro (12.9-inch) (5th generation)',
2643
+ name: 'ALP AP',
2644
+ build: "Test Build {ENV['BUILD_NUM']}",
2645
+ orientation: 'LANDSCAPE'
2646
+ }
2647
+ }
2648
+ }
2649
+ WebDriverConnect.initialize_web_driver(options)
1591
2650
 
1592
2651
 
1593
- #### Remote desktop browsers on the LambdaTest service
2652
+ #### Remote Desktop Browsers on the LambdaTest Service
1594
2653
 
1595
- For remotely hosted desktop web browsers on the LambdaTest service, the following **Environment Variables** must be set as described in the table
1596
- below. Use the Selenium 4 Configuration Wizard on the [Selenium Desired Capabilities Generator](https://www.lambdatest.com/capabilities-generator/)
1597
- to obtain information regarding the specific capabilities.
2654
+ For remotely hosted desktop web browsers on the LambdaTest service, refer to the Selenium 4 Configuration Wizard on the
2655
+ [Selenium Desired Capabilities Generator](https://www.lambdatest.com/capabilities-generator/) for information regarding the options and capabilities available for the
2656
+ various supported desktop operating systems and web browsers.
2657
+
2658
+ ##### LambdaTest Desktop Browser using Environment Variables
2659
+
2660
+ If the `options` hash is not provided when calling the `TestCentricity::WebDriverConnect.initialize_web_driver` method,
2661
+ the following **Environment Variables** must be set as described in the table below.
1598
2662
 
1599
2663
  | **Environment Variable** | **Description** |
1600
2664
  |--------------------------|------------------------------------------------------------------------------------------|
@@ -1612,116 +2676,189 @@ to obtain information regarding the specific capabilities.
1612
2676
  | `CONSOLE_LOGS` | [Optional] Used to capture browser console logs. |
1613
2677
 
1614
2678
 
1615
- ### Using Browser specific Profiles in cucumber.yml
2679
+ ##### LambdaTest Desktop Browser in the `options` Hash
2680
+
2681
+ When using the `options` hash, the following options and capabilities must be specified:
2682
+ - `driver:` must be set to `:lambdatest`
2683
+ - `browserName:` in the `capabilities:` hash must be set to name from capability in chart
2684
+ - `browserVersion:` in the `capabilities:` hash must be set to browser version from capability in chart
2685
+
2686
+ ```
2687
+ options = {
2688
+ driver: :lambdatest,
2689
+ capabilities: {
2690
+ browserName: browser_name_from_chart,
2691
+ browserVersion: browser_version_from_chart,
2692
+ 'LT:Options': {
2693
+ userName: lt_account_user_name,
2694
+ accessKey: lt_account_access_key,
2695
+ platformName: platformName_from_chart
2696
+ }
2697
+ }
2698
+ }
2699
+ WebDriverConnect.initialize_web_driver(options)
2700
+ ```
2701
+ ℹ️ If an optional user defined `driver_name:` is not specified in the `options` hash, the default driver name will be set to
2702
+ `:lambdatest_<browserName>` - e.g. `:lambdatest_chrome` or `:lambdatest_safari`.
2703
+
2704
+ ℹ️ If an `endpoint:` is not specified in the `options` hash, then the default remote endpoint URL will be set to the following:
2705
+
2706
+ `https://#{ENV['LT_USERNAME']}:#{ENV['LT_AUTHKEY']}@hub.lambdatest.com/wd/hub`
2707
+
2708
+ This default endpoint requires that the `LT_USERNAME` Environment Variable is set to your LambdaTest account user name and
2709
+ the `LT_AUTHKEY` Environment Variable is set to your LambdaTest access key.
2710
+
2711
+ Below is an example of an `options` hash for specifying a connection to the latest version of an Edge desktop web browser
2712
+ running on macOS Sonoma hosted on LambdaTest. The `options` hash includes options for specifying the driver name, setting
2713
+ the browser window size, and capabilities for setting screen resolution, geoLocation, time zone, Selenium version, and various
2714
+ test configuration options.
2715
+
2716
+ options = {
2717
+ driver: :lambdatest,
2718
+ driver_name: :admin_user,
2719
+ browser_size: [1400, 1100],
2720
+ capabilities: {
2721
+ browserName: 'MicrosoftEdge',
2722
+ browserVersion: '119.0',
2723
+ 'LT:Options': {
2724
+ platformName: 'macOS Sonoma',
2725
+ userName: ENV['LT_USERNAME'],
2726
+ accessKey: ENV['LT_AUTHKEY'],
2727
+ project: 'ALP AP',
2728
+ build: "Test Build {ENV['BUILD_NUM']}",
2729
+ resolution: '2560x1440',
2730
+ selenium_version: '4.13.0',
2731
+ networkLogs: 'true',
2732
+ geoLocation: 'AU',
2733
+ timezone: 'Adelaide',
2734
+ console: 'info',
2735
+ network: true
2736
+ }
2737
+ }
2738
+ }
2739
+ WebDriverConnect.initialize_web_driver(options)
2740
+
2741
+
2742
+ ### Closing Browser and Driver Instances
2743
+
2744
+ #### Closing Instances Using Cucumber
2745
+
2746
+ To close all browser and driver instances upon completion of your automated Cucumber features, place the code shown below
2747
+ in your `hooks.rb` file:
2748
+
2749
+ AfterAll do
2750
+ # terminate all driver instances
2751
+ WebDriverConnect.close_all_drivers
2752
+ end
1616
2753
 
1617
- While you can set **Environment Variables** in the command line when invoking Cucumber, a preferred method of specifying and managing
1618
- target web browsers is to create browser specific **Profiles** that set the appropriate **Environment Variables** for each target browser
1619
- in your `cucumber.yml` file.
1620
2754
 
1621
- Below is a list of Cucumber **Profiles** for supported locally and remotely hosted desktop and mobile web browsers (put these in in your
1622
- `cucumber.yml` file). Before you can use the BrowserStack, SauceLabs, TestingBot or LambdaTest services, you will need to replace the
1623
- *INSERT USER NAME HERE* and *INSERT PASSWORD HERE* placeholder text with your user account and authorization code for the cloud service(s)
1624
- that you intend to connect with.
2755
+ #### Closing Instances Using RSpec
2756
+
2757
+ To close all browser and driver instances upon completion of an automated spec, place the code shown below in the body
2758
+ of an example group:
2759
+
2760
+ after(:each) do
2761
+ # terminate all driver instances
2762
+ WebDriverConnect.close_all_drivers
2763
+ end
2764
+
2765
+
2766
+ ### Using Browser Specific Profiles in `cucumber.yml`
2767
+
2768
+ While you can set **Environment Variables** in the command line when invoking Cucumber, a preferred method of specifying and
2769
+ managing target web browsers is to create browser specific **Profiles** that set the appropriate **Environment Variables**
2770
+ for each target browser in your `cucumber.yml` file.
2771
+
2772
+ Below is a list of Cucumber **Profiles** for supported locally and remotely hosted desktop and mobile web browsers (put
2773
+ these in in your`cucumber.yml` file). Before you can use the BrowserStack, SauceLabs, TestingBot or LambdaTest services,
2774
+ you will need to replace the *INSERT USER NAME HERE* and *INSERT PASSWORD HERE* placeholder text with your user account
2775
+ and authorization code for the cloud service(s) that you intend to connect with.
2776
+
2777
+ ⚠️ Cloud service credentials should not be stored as text in your `cucumber.yml` file where it can be exposed by anyone
2778
+ with access to your version control system.
1625
2779
 
1626
2780
 
1627
2781
  <% desktop = "--tags @desktop --require features BROWSER_TILE=true BROWSER_SIZE=1500,1000" %>
1628
2782
  <% tablet = "--tags @desktop --require features BROWSER_TILE=true" %>
1629
2783
  <% mobile = "--tags @mobile --require features BROWSER_TILE=true" %>
1630
-
2784
+
1631
2785
  #==============
1632
2786
  # profiles for locally hosted desktop web browsers
1633
2787
  #==============
1634
-
2788
+
1635
2789
  firefox: WEB_BROWSER=firefox <%= desktop %>
1636
2790
  chrome: WEB_BROWSER=chrome <%= desktop %>
1637
2791
  edge: WEB_BROWSER=edge <%= desktop %>
1638
2792
  safari: WEB_BROWSER=safari <%= desktop %>
1639
- ie: WEB_BROWSER=ie <%= desktop %>
1640
2793
 
1641
2794
  firefox_headless: WEB_BROWSER=firefox_headless <%= desktop %>
1642
2795
  chrome_headless: WEB_BROWSER=chrome_headless <%= desktop %>
1643
2796
  edge_headless: WEB_BROWSER=edge_headless <%= desktop %>
1644
2797
 
1645
- #==============
1646
- # profile for Selenium Grid and Dockerized Selenium Grid hosted desktop web browsers
1647
- #==============
1648
- grid: SELENIUM=remote REMOTE_ENDPOINT="http://localhost:4444/wd/hub"
1649
-
1650
2798
 
1651
2799
  #==============
1652
2800
  # profiles for locally hosted mobile web browsers (emulated locally in Chrome browser)
1653
2801
  #==============
1654
-
1655
- ipad: WEB_BROWSER=ipad HOST_BROWSER=chrome <%= tablet %>
1656
- ipad_pro: WEB_BROWSER=ipad_pro HOST_BROWSER=chrome <%= tablet %>
1657
- ipad_pro_10_5: WEB_BROWSER=ipad_pro_10_5 HOST_BROWSER=chrome <%= tablet %>
1658
- ipad_pro_11: WEB_BROWSER=ipad_pro_11 HOST_BROWSER=chrome <%= tablet %>
1659
- ipad_pro_12_9: WEB_BROWSER=ipad_pro_12_9 HOST_BROWSER=chrome <%= tablet %>
1660
- ipad_chrome: WEB_BROWSER=ipad_chrome HOST_BROWSER=chrome <%= tablet %>
1661
- ipad_firefox: WEB_BROWSER=ipad_firefox HOST_BROWSER=chrome <%= tablet %>
1662
- ipad_edge: WEB_BROWSER=ipad_edge HOST_BROWSER=chrome <%= tablet %>
1663
- iphone6: WEB_BROWSER=iphone6 HOST_BROWSER=chrome <%= mobile %>
1664
- iphone6_plus: WEB_BROWSER=iphone6_plus HOST_BROWSER=chrome <%= mobile %>
1665
- iphone7: WEB_BROWSER=iphone7 HOST_BROWSER=chrome <%= mobile %>
1666
- iphone7_plus: WEB_BROWSER=iphone7_plus HOST_BROWSER=chrome <%= mobile %>
1667
- iphone7_chrome: WEB_BROWSER=iphone7_chrome HOST_BROWSER=chrome <%= mobile %>
1668
- iphone7_firefox: WEB_BROWSER=iphone7_firefox HOST_BROWSER=chrome <%= mobile %>
1669
- iphone7_edge: WEB_BROWSER=iphone7_edge HOST_BROWSER=chrome <%= mobile %>
1670
- iphone8: WEB_BROWSER=iphone8 HOST_BROWSER=chrome <%= mobile %>
1671
- iphone8_plus: WEB_BROWSER=iphone8_plus HOST_BROWSER=chrome <%= mobile %>
1672
- iphone_x: WEB_BROWSER=iphone_x HOST_BROWSER=chrome <%= mobile %>
1673
- iphone_xr: WEB_BROWSER=iphone_xr HOST_BROWSER=chrome <%= mobile %>
1674
- iphone_xr_chrome: WEB_BROWSER=iphone_xr_chrome HOST_BROWSER=chrome <%= mobile %>
1675
- iphone_xr_firefox: WEB_BROWSER=iphone_xr_firefox HOST_BROWSER=chrome <%= mobile %>
1676
- iphone_xr_edge: WEB_BROWSER=iphone_xr_edge HOST_BROWSER=chrome <%= mobile %>
1677
- iphone_xs: WEB_BROWSER=iphone_xs HOST_BROWSER=chrome <%= mobile %>
1678
- iphone_xs_max: WEB_BROWSER=iphone_xs_max HOST_BROWSER=chrome <%= mobile %>
1679
- iphone_11: WEB_BROWSER=iphone_11 HOST_BROWSER=chrome <%= mobile %>
1680
- iphone_11_pro: WEB_BROWSER=iphone_11_pro HOST_BROWSER=chrome <%= mobile %>
1681
- iphone_11_pro_max: WEB_BROWSER=iphone_11_pro_max HOST_BROWSER=chrome <%= mobile %>
1682
- nexus6: WEB_BROWSER=nexus6 HOST_BROWSER=chrome <%= mobile %>
1683
- kindle_fire: WEB_BROWSER=kindle_fire HOST_BROWSER=chrome <%= tablet %>
1684
- kindle_firehd7: WEB_BROWSER=kindle_firehd7 HOST_BROWSER=chrome <%= tablet %>
1685
- kindle_firehd8: WEB_BROWSER=kindle_firehd8 HOST_BROWSER=chrome <%= tablet %>
1686
- kindle_firehd10: WEB_BROWSER=kindle_firehd10 HOST_BROWSER=chrome <%= tablet %>
1687
- surface: WEB_BROWSER=surface HOST_BROWSER=chrome <%= tablet %>
1688
- blackberry_playbook: WEB_BROWSER=blackberry_playbook HOST_BROWSER=chrome <%= tablet %>
1689
- samsung_galaxy_tab: WEB_BROWSER=samsung_galaxy_tab HOST_BROWSER=chrome <%= tablet %>
1690
- google_nexus7: WEB_BROWSER=google_nexus7 HOST_BROWSER=chrome <%= tablet %>
1691
- google_nexus9: WEB_BROWSER=google_nexus9 HOST_BROWSER=chrome <%= tablet %>
1692
- google_nexus10: WEB_BROWSER=google_nexus10 HOST_BROWSER=chrome <%= tablet %>
1693
- samsung_galaxy_s4: WEB_BROWSER=samsung_galaxy_s4 HOST_BROWSER=chrome <%= mobile %>
1694
- samsung_galaxy_s5: WEB_BROWSER=samsung_galaxy_s5 HOST_BROWSER=chrome <%= mobile %>
1695
- samsung_galaxy_s6: WEB_BROWSER=samsung_galaxy_s6 HOST_BROWSER=chrome <%= mobile %>
1696
- pixel: WEB_BROWSER=pixel HOST_BROWSER=chrome <%= mobile %>
1697
- pixel_xl: WEB_BROWSER=pixel_xl HOST_BROWSER=chrome <%= mobile %>
1698
- windows_phone7: WEB_BROWSER=windows_phone7 HOST_BROWSER=chrome <%= mobile %>
1699
- windows_phone8: WEB_BROWSER=windows_phone8 HOST_BROWSER=chrome <%= mobile %>
1700
- lumia_950_xl: WEB_BROWSER=lumia_950_xl HOST_BROWSER=chrome <%= mobile %>
1701
- blackberry_z10: WEB_BROWSER=blackberry_z10 HOST_BROWSER=chrome <%= mobile %>
1702
- blackberry_z30: WEB_BROWSER=blackberry_z30 HOST_BROWSER=chrome <%= mobile %>
1703
- blackberry_leap: WEB_BROWSER=blackberry_leap HOST_BROWSER=chrome <%= mobile %>
1704
- blackberry_passport: WEB_BROWSER=blackberry_passport HOST_BROWSER=chrome <%= mobile %>
1705
2802
 
1706
-
2803
+ iphone_11: WEB_BROWSER=iphone_11 <%= mobile %>
2804
+ iphone_11_pro: WEB_BROWSER=iphone_11_pro <%= mobile %>
2805
+ iphone_11_pro_max: WEB_BROWSER=iphone_11_pro_max <%= mobile %>
2806
+ iphone_12_mini: WEB_BROWSER=iphone_12_mini <%= mobile %>
2807
+ iphone_12: WEB_BROWSER=iphone_12 <%= mobile %>
2808
+ iphone_12_pro: WEB_BROWSER=iphone_12_pro <%= mobile %>
2809
+ iphone_12_pro_max: WEB_BROWSER=iphone_12_pro_max <%= mobile %>
2810
+ iphone_13_mini: WEB_BROWSER=iphone_13_mini <%= mobile %>
2811
+ iphone_13: WEB_BROWSER=iphone_13 <%= mobile %>
2812
+ iphone_13_pro: WEB_BROWSER=iphone_13_pro <%= mobile %>
2813
+ iphone_13_pro_max: WEB_BROWSER=iphone_13_pro_max <%= mobile %>
2814
+ iphone_se: WEB_BROWSER=iphone_se <%= mobile %>
2815
+ iphone_14: WEB_BROWSER=iphone_14 <%= mobile %>
2816
+ iphone_14_plus: WEB_BROWSER=iphone_14_plus <%= mobile %>
2817
+ iphone_14_pro: WEB_BROWSER=iphone_14_pro <%= mobile %>
2818
+ iphone_14_pro_max: WEB_BROWSER=iphone_14_pro_max <%= mobile %>
2819
+ ipad: WEB_BROWSER=ipad <%= tablet %>
2820
+ ipad_mini: WEB_BROWSER=ipad_mini <%= tablet %>
2821
+ ipad_air: WEB_BROWSER=ipad_air <%= tablet %>
2822
+ ipad_pro_11: WEB_BROWSER=ipad_pro_11 <%= tablet %>
2823
+ ipad_pro_12_9: WEB_BROWSER=ipad_pro_12_9 <%= tablet %>
2824
+ pixel_5: WEB_BROWSER=pixel_5 <%= mobile %>
2825
+ pixel_6: WEB_BROWSER=pixel_6 <%= mobile %>
2826
+ pixel_xl: WEB_BROWSER=pixel_xl <%= mobile %>
2827
+ windows_phone7: WEB_BROWSER=windows_phone7 <%= mobile %>
2828
+ windows_phone8: WEB_BROWSER=windows_phone8 <%= mobile %>
2829
+ lumia_950_xl: WEB_BROWSER=lumia_950_xl <%= mobile %>
2830
+ blackberry_z10: WEB_BROWSER=blackberry_z10 <%= mobile %>
2831
+ blackberry_z30: WEB_BROWSER=blackberry_z30 <%= mobile %>
2832
+ blackberry_leap: WEB_BROWSER=blackberry_leap <%= mobile %>
2833
+ blackberry_passport: WEB_BROWSER=blackberry_passport <%= mobile %>
2834
+ pixel_c: WEB_BROWSER=pixel_c <%= tablet %>
2835
+ nexus_10: WEB_BROWSER=nexus_10 <%= tablet %>
2836
+ kindle_fire: WEB_BROWSER=kindle_fire <%= tablet %>
2837
+ kindle_firehd7: WEB_BROWSER=kindle_firehd7 <%= tablet %>
2838
+ kindle_firehd8: WEB_BROWSER=kindle_firehd8 <%= tablet %>
2839
+ kindle_firehd10: WEB_BROWSER=kindle_firehd10 <%= tablet %>
2840
+ surface: WEB_BROWSER=surface <%= tablet %>
2841
+ blackberry_playbook: WEB_BROWSER=blackberry_playbook <%= tablet %>
2842
+
2843
+
1707
2844
  #==============
1708
2845
  # profiles for mobile device screen orientation
1709
2846
  #==============
1710
-
2847
+
1711
2848
  portrait: ORIENTATION=portrait
1712
2849
  landscape: ORIENTATION=landscape
1713
2850
 
1714
-
2851
+
1715
2852
  #==============
1716
2853
  # profile to start Appium Server prior to running mobile browser tests on iOS or Android simulators or physical devices
1717
2854
  #==============
1718
-
2855
+
1719
2856
  run_appium: APPIUM_SERVER=run
1720
2857
 
1721
2858
 
1722
2859
  #==============
1723
2860
  # profiles for mobile Safari web browsers hosted within XCode iOS simulator
1724
- # NOTE: Requires installation of XCode, iOS version specific target simulators, Appium, and the appium_capybara gem
2861
+ # NOTE: Requires installation of XCode, iOS version specific target simulators, and Appium
1725
2862
  #==============
1726
2863
 
1727
2864
  appium_ios: DRIVER=appium AUTOMATION_ENGINE=XCUITest APP_PLATFORM_NAME="ios" APP_BROWSER="Safari" NEW_COMMAND_TIMEOUT=30 SHOW_SIM_KEYBOARD=false
@@ -1733,7 +2870,7 @@ that you intend to connect with.
1733
2870
 
1734
2871
  #==============
1735
2872
  # profiles for mobile Safari web browsers running on physically connected iOS devices
1736
- # NOTE: Requires installation of XCode, Appium, and the appium_capybara gem
2873
+ # NOTE: Requires installation of XCode and Appium
1737
2874
  #==============
1738
2875
 
1739
2876
  my_ios_15_iphone: --profile app_ios_15 DEVICE_TYPE=phone APP_DEVICE="My Test iPhoneX" APP_UDID="INSERT YOUR DEVICE UDID"
@@ -1742,30 +2879,30 @@ that you intend to connect with.
1742
2879
 
1743
2880
  #==============
1744
2881
  # profiles for Android mobile web browsers hosted within Android Studio Android Virtual Device emulators
1745
- # NOTE: Requires installation of Android Studio, Android version specific virtual device simulators, Appium, and the appium_capybara gem
2882
+ # NOTE: Requires installation of Android Studio, Android version specific virtual device simulators, and Appium
1746
2883
  #==============
1747
2884
 
1748
2885
  appium_android: DRIVER=appium APP_PLATFORM_NAME="Android" <%= mobile %>
1749
2886
  app_android_12: --profile appium_android APP_BROWSER="Chrome" APP_VERSION="12.0"
1750
2887
  pixel_c_api31_sim: --profile app_android_12 DEVICE_TYPE=tablet APP_DEVICE="Pixel_C_API_31"
1751
2888
 
1752
-
2889
+
1753
2890
  #==============
1754
2891
  # profiles for remotely hosted web browsers on the BrowserStack service
1755
- # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with access
1756
- # to your version control system
2892
+ # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with
2893
+ # access to your version control system
1757
2894
  #==============
1758
-
2895
+
1759
2896
  browserstack: DRIVER=browserstack BS_USERNAME="<INSERT USER NAME HERE>" BS_AUTHKEY="<INSERT PASSWORD HERE>"
1760
- bs_desktop: --profile browserstack <%= desktop %> RESOLUTION="1920x1080"
1761
- bs_mobile: --profile browserstack <%= mobile %>
1762
-
2897
+ bs_desktop: --profile browserstack <%= desktop %> RESOLUTION="1920x1080"
2898
+ bs_mobile: --profile browserstack <%= mobile %>
2899
+
1763
2900
  # BrowserStack macOS desktop browser profiles
1764
- bs_macos_monterey: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="Monterey"
1765
- bs_chrome_monterey: --profile bs_macos_monterey BS_BROWSER="Chrome" BS_VERSION="latest"
1766
- bs_edge_monterey: --profile bs_macos_monterey BS_BROWSER="Edge" BS_VERSION="latest"
1767
- bs_safari_monterey: --profile bs_macos_monterey BS_BROWSER="Safari" BS_VERSION="latest"
1768
-
2901
+ bs_macos_sonoma: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="Sonoma"
2902
+ bs_chrome_sonoma: --profile bs_macos_sonoma BS_BROWSER="Chrome" BS_VERSION="latest"
2903
+ bs_edge_sonoma: --profile bs_macos_sonoma BS_BROWSER="Edge" BS_VERSION="latest"
2904
+ bs_safari_sonoma: --profile bs_macos_sonoma BS_BROWSER="Safari" BS_VERSION="latest"
2905
+
1769
2906
  # BrowserStack Windows desktop browser profiles
1770
2907
  bs_win11: --profile bs_desktop BS_OS="Windows" BS_OS_VERSION="11"
1771
2908
  bs_chrome_win11: --profile bs_win11 BS_BROWSER="Chrome" BS_VERSION="latest"
@@ -1776,52 +2913,52 @@ that you intend to connect with.
1776
2913
  # BrowserStack iOS mobile browser profiles
1777
2914
  bs_ipad: --profile bs_mobile BS_OS=ios BS_BROWSER=Safari DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
1778
2915
  bs_ipad_pro_12: --profile bs_ipad BS_DEVICE="iPad Pro 12.9 2018" BS_OS_VERSION="15"
1779
-
2916
+
1780
2917
  # BrowserStack Android mobile browser profiles
1781
2918
  bs_android: --profile bs_mobile BS_OS=android BS_BROWSER=Chrome DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
1782
2919
  bs_android_tablet: --profile bs_android BS_DEVICE="Samsung Galaxy Tab S7" BS_OS_VERSION="10.0"
1783
2920
 
1784
-
2921
+
1785
2922
  #==============
1786
2923
  # profiles for remotely hosted web browsers on the SauceLabs service
1787
- # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with access
1788
- # to your version control system
2924
+ # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with
2925
+ # access to your version control system
1789
2926
  #==============
1790
-
2927
+
1791
2928
  saucelabs: DRIVER=saucelabs SL_USERNAME="<INSERT USER NAME HERE>" SL_AUTHKEY="<INSERT PASSWORD HERE>" DATA_CENTER="<INSERT DATA CENTER HERE"
1792
2929
  sl_desktop: --profile saucelabs <%= desktop %>
1793
2930
  sl_mobile: --profile saucelabs <%= mobile %>
1794
-
2931
+
1795
2932
  # SauceLabs macOS desktop browser profiles
1796
- sl_macos_monterey: --profile sl_desktop SL_OS="macOS 12" RESOLUTION="1920x1440"
1797
- sl_chrome_monterey: --profile sl_macos_monterey SL_BROWSER="chrome" SL_VERSION="latest"
1798
- sl_edge_monterey: --profile sl_macos_monterey SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
1799
- sl_firefox_monterey: --profile sl_macos_monterey SL_BROWSER="Firefox" SL_VERSION="latest"
1800
-
2933
+ sl_macos_ventura: --profile sl_desktop SL_OS="macOS 13" RESOLUTION="1920x1440"
2934
+ sl_chrome_ventura: --profile sl_macos_ventura SL_BROWSER="chrome" SL_VERSION="latest"
2935
+ sl_edge_ventura: --profile sl_macos_ventura SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
2936
+ sl_firefox_ventura: --profile sl_macos_ventura SL_BROWSER="Firefox" SL_VERSION="latest"
2937
+
1801
2938
  # SauceLabs Windows desktop browser profiles
1802
2939
  sl_windows: --profile sl_desktop RESOLUTION="1920x1200"
1803
2940
  sl_edge_win11: --profile sl_windows SL_OS="Windows 11" SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
1804
2941
  sl_ie_win10: --profile sl_windows SL_OS="Windows 10" SL_BROWSER="internet explorer" SL_VERSION="11"
1805
-
2942
+
1806
2943
  # SauceLabs iOS mobile browser profiles
1807
2944
  sl_ipad: --profile sl_mobile DEVICE_TYPE=tablet SL_PLATFORM=iOS SL_BROWSER=Safari
1808
2945
  sl_ipad_pro_12: --profile sl_ipad SL_DEVICE="iPad Pro (12.9 inch) (5th generation) Simulator" SL_VERSION="15.0"
1809
-
1810
-
2946
+
2947
+
1811
2948
  #==============
1812
2949
  # profiles for remotely hosted web browsers on the TestingBot service
1813
- # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with access
1814
- # to your version control system
2950
+ # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with
2951
+ # access to your version control system
1815
2952
  #==============
1816
-
2953
+
1817
2954
  testingbot: DRIVER=testingbot TB_USERNAME="<INSERT USER NAME HERE>" TB_AUTHKEY="<INSERT PASSWORD HERE>"
1818
2955
  tb_desktop: --profile testingbot <%= desktop %> RESOLUTION="1920x1200"
1819
-
2956
+
1820
2957
  # TestingBot macOS desktop browser profiles
1821
- tb_macos_monterey: --profile tb_desktop TB_OS="MONTEREY"
1822
- tb_chrome_monterey: --profile tb_macos_monterey TB_BROWSER="chrome" TB_VERSION="latest"
1823
- tb_edge_monterey: --profile tb_macos_monterey TB_BROWSER="microsoftedge" TB_VERSION="latest"
1824
-
2958
+ tb_macos_sonoma: --profile tb_desktop TB_OS="SONOMA"
2959
+ tb_chrome_sonoma: --profile tb_macos_sonoma TB_BROWSER="chrome" TB_VERSION="latest"
2960
+ tb_edge_sonoma: --profile tb_macos_sonoma TB_BROWSER="microsoftedge" TB_VERSION="latest"
2961
+
1825
2962
  # TestingBot Windows desktop browser profiles
1826
2963
  tb_win11: --profile tb_desktop TB_OS="WIN11"
1827
2964
  tb_edge_win11: --profile tb_win11 TB_BROWSER="microsoftedge" TB_VERSION="latest"
@@ -1831,18 +2968,18 @@ that you intend to connect with.
1831
2968
 
1832
2969
  #==============
1833
2970
  # profiles for remotely hosted web browsers on the LambdaTest service
1834
- # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with access
1835
- # to your version control system
2971
+ # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with
2972
+ # access to your version control system
1836
2973
  #==============
1837
-
2974
+
1838
2975
  lambdatest: DRIVER=lambdatest LT_USERNAME=<INSERT USER NAME HERE> LT_AUTHKEY=<INSERT PASSWORD HERE>
1839
2976
  lt_desktop: --profile lambdatest <%= desktop %> RESOLUTION="2560x1440"
1840
-
2977
+
1841
2978
  # LambdaTest macOS desktop browser profiles
1842
2979
  lt_macos_monterey: --profile lt_desktop LT_OS="MacOS Monterey"
1843
2980
  lt_chrome_monterey: --profile lt_macos_monterey LT_BROWSER="Chrome" LT_VERSION="98.0"
1844
2981
  lt_edge_monterey: --profile lt_macos_monterey LT_BROWSER="MicrosoftEdge" LT_VERSION="97.0"
1845
-
2982
+
1846
2983
  # LambdaTest Windows desktop browser profiles
1847
2984
  lt_win11: --profile lt_desktop LT_OS="Windows 11"
1848
2985
  lt_edge_win11: --profile lt_win11 LT_BROWSER="MicrosoftEdge" LT_VERSION="98.0"
@@ -1850,101 +2987,94 @@ that you intend to connect with.
1850
2987
  lt_i0_win11: --profile lt_win10 LT_BROWSER="Internet Explorer" LT_VERSION="11.0"
1851
2988
 
1852
2989
 
1853
- To specify a locally hosted target browser using a profile at runtime, you use the flag `--profile` or `-p` followed by the profile name when
1854
- invoking Cucumber in the command line. For instance, the following command invokes Cucumber and specifies that a local instance of Firefox
1855
- will be used as the target web browser:
2990
+ To specify a locally hosted target browser using a profile at runtime, you use the flag `--profile` or `-p` followed by the
2991
+ profile name when invoking Cucumber in the command line. For instance, the following command invokes Cucumber and specifies
2992
+ that a local instance of Firefox will be used as the target web browser:
1856
2993
 
1857
2994
  cucumber -p firefox
1858
2995
 
1859
2996
 
1860
- The following command specifies that Cucumber will run tests against an instance of Chrome hosted within a Dockerized Selenium Grid 4
1861
- environment:
2997
+ The following command specifies that Cucumber will run tests against an instance of Chrome hosted within a Dockerized Selenium
2998
+ Grid 4 environment:
1862
2999
 
1863
3000
  cucumber -p chrome -p grid
1864
3001
 
1865
3002
 
1866
- The following command specifies that Cucumber will run tests against a local instance of Chrome, which will be used to emulate an iPad Pro
1867
- in landscape orientation:
3003
+ The following command specifies that Cucumber will run tests against a local instance of Chrome, which will be used to emulate
3004
+ an iPad Pro in landscape orientation:
1868
3005
 
1869
3006
  cucumber -p ipad_pro -p landscape
1870
3007
 
1871
3008
 
1872
- The following command specifies that Cucumber will run tests against an iPad Pro (12.9-inch) (5th generation) with iOS version 15.4 in an
1873
- XCode Simulator in landscape orientation:
3009
+ The following command specifies that Cucumber will run tests against an iPad Pro (12.9-inch) (5th generation) with iOS version
3010
+ 15.4 in an XCode Simulator in landscape orientation:
1874
3011
 
1875
3012
  cucumber -p ipad_pro_12_15_sim -p landscape
1876
3013
 
1877
- NOTE: Appium must be running prior to executing this command
3014
+ ⚠️ Appium must be running prior to executing this command
1878
3015
 
1879
3016
  You can ensure that Appium Server is running by including `-p run_appium` in your command line:
1880
3017
 
1881
3018
  cucumber -p ipad_pro_12_15_sim -p landscape -p run_appium
1882
3019
 
1883
3020
 
1884
- The following command specifies that Cucumber will run tests against a remotely hosted Safari web browser running on a macOS Monterey
1885
- virtual machine on the BrowserStack service:
1886
-
1887
- cucumber -p bs_safari_monterey
3021
+ The following command specifies that Cucumber will run tests against a remotely hosted Safari web browser running on a macOS
3022
+ Sonoma virtual machine on the BrowserStack service:
1888
3023
 
3024
+ cucumber -p bs_safari_sonoma
1889
3025
 
1890
3026
 
3027
+ ---
1891
3028
  ## Recommended Project Organization and Structure
1892
3029
 
1893
3030
  Below is an example of the project structure of a typical Cucumber based test automation framework with a Page Object Model
1894
3031
  architecture. `PageObject` class definitions should be stored in the `/features/support/pages` folder, organized in functional
1895
3032
  area sub-folders as needed. Likewise, `PageSection` class definitions should be stored in the `/features/support/sections` folder.
1896
3033
 
1897
- my_automation_project
1898
- ├── config
1899
- │ ├── locales
1900
- │ ├── test_data
1901
- │ └── cucumber.yml
1902
- ├── downloads
1903
- ├── features
1904
- │ ├── step_definitions
1905
- │ └── support
1906
- ├── pages
1907
- ├── sections
1908
- ├── env.rb
1909
- ├── hooks.rb
1910
- └── world_pages.rb
1911
- ├── Gemfile
1912
- └── README.md
3034
+ 📁 my_automation_project/
3035
+ ├── 📁 config/
3036
+ │ ├── 📁 locales/
3037
+ │ ├── 📁 test_data/
3038
+ │ └── 📄 cucumber.yml
3039
+ ├── 📁 downloads/
3040
+ ├── 📁 features/
3041
+ │ ├── 📁 step_definitions/
3042
+ │ └── 📁 support/
3043
+ ├── 📁 pages/
3044
+ ├── 📁 sections/
3045
+ ├── 📄 env.rb
3046
+ ├── 📄 hooks.rb
3047
+ └── 📄 world_pages.rb
3048
+ ├── 📄 Gemfile
3049
+ └── 📄 README.md
3050
+
3051
+
3052
+ ---
3053
+ ## Web Test Automation Framework Implementation
1913
3054
 
3055
+ ![TestCentricity Web Framework Overview](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/tc_overview.jpg "TestCentricity Web Framework Overview")
1914
3056
 
1915
3057
 
1916
- ## Web Test Automation Framework Implementation
3058
+ ---
3059
+ ## Copyright and License
1917
3060
 
1918
- <img src="https://i.imgur.com/lCT9HbK.jpg" alt="TestCentricity Web Framework Overview" title="TestCentricity Web Framework Overview">
3061
+ TestCentricity Framework is Copyright (c) 2014-2023, Tony Mrozinski.
3062
+ All rights reserved.
1919
3063
 
3064
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
3065
+ conditions are met:
1920
3066
 
3067
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
1921
3068
 
1922
- ## Copyright and License
3069
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
3070
+ in the documentation and/or other materials provided with the distribution.
1923
3071
 
1924
- TestCentricity™ Framework is Copyright (c) 2014-2022, Tony Mrozinski.
1925
- All rights reserved.
3072
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
3073
+ from this software without specific prior written permission.
1926
3074
 
1927
- Redistribution and use in source and binary forms, with or without
1928
- modification, are permitted provided that the following conditions are met:
1929
-
1930
- 1. Redistributions of source code must retain the above copyright notice,
1931
- this list of conditions and the following disclaimer.
1932
-
1933
- 2. Redistributions in binary form must reproduce the above copyright
1934
- notice, this list of conditions and the following disclaimer in the
1935
- documentation and/or other materials provided with the distribution.
1936
-
1937
- 3. Neither the name of the copyright holder nor the names of its contributors
1938
- may be used to endorse or promote products derived from this software without
1939
- specific prior written permission.
1940
-
1941
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1942
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1943
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1944
- IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
1945
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1946
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
1947
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1948
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1949
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1950
- POSSIBILITY OF SUCH DAMAGE.
3075
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
3076
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
3077
+ SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3078
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3079
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
3080
+ OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.