testcentricity_web 4.3.0 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
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.