testcentricity_web 4.3.1 → 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 +42 -12
  3. data/LICENSE.md +1 -1
  4. data/README.md +1794 -697
  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 -13
  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 +379 -252
  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,24 +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
10
  The TestCentricity™ Web core framework for desktop and mobile web browser-based app testing implements a Page Object Model
8
- DSL for use with Cucumber (version 7.x or greater), Capybara (version 3.37), and Selenium-Webdriver (version 4.3). It also
9
- facilitates the configuration of the appropriate Selenium-Webdriver capabilities required to establish a connection with a
10
- local or cloud hosted desktop or mobile web browser.
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.
11
14
 
12
- The TestCentricity™ Web gem supports running automated tests against the following web test targets:
13
- * 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)
14
17
  * locally hosted "headless" Chrome, Firefox, or Edge browsers
15
- *
16
18
  * remote desktop and emulated mobile web browsers hosted on Selenium Grid 4 and Dockerized Selenium Grid 4 environments
17
19
  * mobile Safari browsers on iOS device simulators or physical iOS devices (using Appium and XCode on macOS)
18
- * mobile Chrome or Android browsers on Android Studio virtual device emulators (using Appium and Android Studio on macOS)
19
- * 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:
20
22
  * [Browserstack](https://www.browserstack.com/list-of-browsers-and-platforms?product=automate)
21
- * [Sauce Labs](https://saucelabs.com/open-source#automated-testing-platform)
23
+ * [Sauce Labs](https://saucelabs.com/platform/cross-browser-testing)
22
24
  * [TestingBot](https://testingbot.com/features)
23
25
  * [LambdaTest](https://www.lambdatest.com/selenium-automation)
24
26
  * web portals utilizing JavaScript front end application frameworks like Ember, React, Angular, and GWT
@@ -38,8 +40,8 @@ can be found [here](https://github.com/TestCentricity/tc_web_sample).
38
40
 
39
41
  ## Installation
40
42
 
41
- TestCentricity Web version 4.1 and above requires Ruby 2.7.5 or later. To install the TestCentricity Web gem, add this line
42
- to your 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`:
43
45
 
44
46
  gem 'testcentricity_web'
45
47
 
@@ -47,7 +49,7 @@ And then execute:
47
49
 
48
50
  $ bundle
49
51
 
50
- Or install it yourself as:
52
+ Or install it yourself using:
51
53
 
52
54
  $ gem install testcentricity_web
53
55
 
@@ -65,27 +67,11 @@ If you are using Cucumber, you need to require the following in your `env.rb` fi
65
67
 
66
68
  If you are using RSpec instead, you need to require the following in your `spec_helper.rb` file:
67
69
 
68
- require 'capybara'
69
70
  require 'capybara/rspec'
70
71
  require 'testcentricity_web'
71
72
 
72
73
 
73
- ### Using Appium
74
-
75
- If you will be running your tests on mobile Safari browsers on simulated iOS devices using Appium and XCode Simulators, you
76
- need to require the following in your `env.rb` and/or `spec_helper.rb` file:
77
-
78
- require 'appium_capybara'
79
-
80
- You also need to add this line to your automation project's Gemfile:
81
-
82
- gem 'appium_capybara'
83
-
84
- And then execute:
85
-
86
- $ bundle
87
-
88
-
74
+ ---
89
75
  ## PageObjects
90
76
 
91
77
  The **Page Object Model** is a test automation pattern that aims to create an abstraction of your web app's User Interface
@@ -98,7 +84,7 @@ location - in the **Page Object** class definition. By adopting a **Page Object
98
84
  definitions are no longer required to hold specific information about a page's UI objects, thus minimizing maintenance
99
85
  requirements. If any element on, or property of a page changes (URL path, text field attributes, button captions, etc.),
100
86
  maintenance is performed in the `PageObject` class definition only, typically with no need to update the affected feature
101
- file, scenarios, or step definitions.
87
+ files, scenarios, or step definitions.
102
88
 
103
89
 
104
90
  ### Defining a PageObject
@@ -118,14 +104,19 @@ of your test automation project. You define new `PageObjects` as shown below:
118
104
  end
119
105
 
120
106
 
121
- ### Adding Traits to your PageObject
107
+ class UserAccountPage < TestCentricity::PageObject
108
+ end
109
+
110
+
111
+ ### Adding Traits to a PageObject
122
112
 
123
113
  Web pages typically have names and URLs associated with them. Web pages also typically have a unique object or attribute
124
114
  that, when present, indicates that the page's contents have fully loaded.
125
115
 
126
116
  The `page_name` trait is registered with the `PageManager` object, which includes a `find_page` method that takes a page
127
117
  name as a parameter and returns an instance of the associated `PageObject`. If you intend to use the `PageManager`, you
128
- must define a `page_name` trait for each `PageObject` to be registered.
118
+ must define a `page_name` trait for each `PageObject` to be registered. Refer to [**section 7 (Instantiating Your PageObjects)**](#instantiating-your-pageobjects).
119
+
129
120
 
130
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`
131
122
  method. `page_name` traits are case and white-space sensitive. For pages that may be referenced with multiple names, the
@@ -135,8 +126,8 @@ A `page_locator` trait is defined if a page has a unique object or attribute tha
135
126
  loaded. The `page_locator` trait is a CSS or Xpath expression that uniquely identifies the object or attribute. The
136
127
  `verify_page_exists` method waits for the `page_locator` trait to exist.
137
128
 
138
- 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
139
- specify a base URL when calling the `WebDriverConnect.initialize_web_driver` method, then your `page_url` trait can be the
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
140
131
  relative URL slug that will be appended to the base URL specified in `app_host`. Specifying a `page_url` trait is optional,
141
132
  as not all web pages can be directly loaded via a URL.
142
133
 
@@ -164,7 +155,14 @@ You define your page's **Traits** as shown below:
164
155
  end
165
156
 
166
157
 
167
- ### 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
168
166
 
169
167
  Web pages are made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists, buttons, etc.
170
168
  **UI Elements** are added to your `PageObject` class definition as shown below:
@@ -173,7 +171,7 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes,
173
171
  trait(:page_name) { 'Login' }
174
172
  trait(:page_url) { '/sign_in' }
175
173
  trait(:page_locator) { 'body.login-body' }
176
-
174
+
177
175
  # Login page UI elements
178
176
  textfield :user_id_field, 'input#userName'
179
177
  textfield :password_field, 'input#password'
@@ -181,13 +179,13 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes,
181
179
  checkbox :remember_checkbox, 'input#rememberUser'
182
180
  label :error_message_label, 'div#statusBar.login-error'
183
181
  end
184
-
182
+
185
183
 
186
184
  class RegistrationPage < TestCentricity::PageObject
187
185
  trait(:page_name) { 'Registration' }
188
186
  trait(:page_url) { '/register' }
189
187
  trait(:page_locator) { 'body.registration' }
190
-
188
+
191
189
  # Registration page UI elements
192
190
  textfields first_name_field: 'input#firstName',
193
191
  last_name_field: 'input#lastName',
@@ -206,7 +204,7 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes,
206
204
  end
207
205
 
208
206
 
209
- ### Adding Methods to your PageObject
207
+ ### Adding Methods to a PageObject
210
208
 
211
209
  It is good practice for your Cucumber step definitions to call high level methods in your your `PageObject` instead of
212
210
  directly accessing and interacting with a page object's UI elements. You can add high level methods to your `PageObject`
@@ -216,7 +214,7 @@ class definition for interacting with the UI to hide implementation details, as
216
214
  trait(:page_name) { 'Login' }
217
215
  trait(:page_url) { '/sign_in' }
218
216
  trait(:page_locator) { 'body.login-body' }
219
-
217
+
220
218
  # Login page UI elements
221
219
  textfield :user_id_field, 'input#userName'
222
220
  textfield :password_field, 'input#password'
@@ -224,7 +222,7 @@ class definition for interacting with the UI to hide implementation details, as
224
222
  checkbox :remember_checkbox, 'input#rememberUser'
225
223
  label :error_message_label, 'div#statusBar.login-error'
226
224
  link :forgot_password_link, 'a.forgotPassword'
227
-
225
+
228
226
  # log in to web app
229
227
  def login(user_id, password)
230
228
  user_id_field.set(user_id)
@@ -240,24 +238,44 @@ class definition for interacting with the UI to hide implementation details, as
240
238
  # verify Login page default UI state
241
239
  def verify_page_ui
242
240
  ui = {
243
- self => { title: 'Login' },
244
- login_button => { visible: true, caption: 'LOGIN' },
245
- user_id_field => { visible: true, enabled: true, value: '', placeholder: 'User name' },
246
- password_field => { visible: true, enabled: true, value: '', placeholder: 'Password' },
247
- remember_checkbox => { exists: true, enabled: true, checked: false },
248
- forgot_password_link => { visible: true, caption: 'Forgot your password?' },
249
- 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 }
250
268
  }
251
269
  verify_ui_states(ui)
252
270
  end
253
271
  end
254
-
272
+
255
273
 
256
274
  class RegistrationPage < TestCentricity::PageObject
257
275
  trait(:page_name) { 'Registration' }
258
276
  trait(:page_url) { '/register' }
259
277
  trait(:page_locator) { 'body.registration' }
260
-
278
+
261
279
  # Registration page UI elements
262
280
  textfields first_name_field: 'input#firstName',
263
281
  last_name_field: 'input#lastName',
@@ -274,7 +292,7 @@ class definition for interacting with the UI to hide implementation details, as
274
292
  checkbox :email_opt_in_check, 'input#marketingEmailsOptIn'
275
293
  buttons sign_up_button: 'button#registrationSignUp',
276
294
  cancel_button: 'button#registrationCancel'
277
-
295
+
278
296
  # populate Registration page fields with profile data
279
297
  def enter_profile_data(profile)
280
298
  fields = { title_select => profile.title,
@@ -301,23 +319,28 @@ class definition for interacting with the UI to hide implementation details, as
301
319
  Once your `PageObjects` have been instantiated, you can call your methods as shown below:
302
320
 
303
321
  login_page.remember_me(true)
304
- login_page.login('snicklefritz', 'Pa55w0rd')
305
-
322
+ login_page.login(user_id = 'snicklefritz', password = 'Pa55w0rd')
306
323
 
307
324
 
325
+ ---
308
326
  ## PageSections
309
327
 
310
328
  A `PageSection` is a collection of **UI Elements** that may appear in multiple locations on a page, or on multiple pages
311
329
  in a web app. It is a collection of **UI Elements** that represent a conceptual area of functionality, like a navigation
312
- bar, a search capability, or a menu. **UI Elements** and functional behavior are confined to the scope of a `PageSection`
313
- object.
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")
314
336
 
315
- <img src="https://i.imgur.com/BTgi59R.jpg" alt="Navigation Header" title="Navigation Header">
337
+ -
316
338
 
317
- <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")
318
340
 
319
- <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 -
320
342
 
343
+ ![Shopping Bag Popup](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/ShoppingBagPopUp.png "Shopping Bag Popup")
321
344
 
322
345
  A `PageSection` may contain other `PageSection` objects.
323
346
 
@@ -327,7 +350,7 @@ A `PageSection` may contain other `PageSection` objects.
327
350
  Your `PageSection` class definitions should be contained within individual `.rb` files in the `features/support/sections`
328
351
  folder of your test automation project. You define new `PageSection` as shown below:
329
352
 
330
- class SearchForm < TestCentricity::PageSection
353
+ class BagViewPopup < TestCentricity::PageSection
331
354
  end
332
355
 
333
356
 
@@ -338,42 +361,64 @@ specifies the CSS or Xpath expression that uniquely identifies that root node ob
338
361
 
339
362
  You define your section's **Traits** as shown below:
340
363
 
341
- class SearchForm < TestCentricity::PageSection
342
- trait(:section_locator) { 'form#gnav-search' }
343
- 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' }
344
367
  end
345
368
 
346
369
 
347
- ### Adding UI Elements to your PageSection
370
+ ### Adding UI Elements to a PageSection
348
371
 
349
372
  `PageSections` are typically made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists,
350
373
  buttons, etc. **UI Elements** are added to your `PageSection` class definition as shown below:
351
374
 
352
- class SearchForm < TestCentricity::PageSection
353
- trait(:section_locator) { 'form#gnav-search' }
354
- trait(:section_name) { 'Search widget' }
355
-
356
- # Search Form UI elements
357
- textfield :search_field, 'input#search-query'
358
- 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"]'
359
384
  end
360
385
 
361
386
 
362
- ### Adding Methods to your PageSection
387
+ ### Adding Methods to a PageSection
363
388
 
364
389
  You can add high level methods to your `PageSection` class definition, as shown below:
365
390
 
366
- class SearchForm < TestCentricity::PageSection
367
- trait(:section_locator) { 'form#gnav-search' }
368
- trait(:section_name) { 'Search widget' }
369
-
370
- # Search Form UI elements
371
- textfield :search_field, 'input#search-query'
372
- button :search_button, 'button[type=submit]'
373
-
374
- def search_for(value)
375
- search_field.set(value)
376
- 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
377
422
  end
378
423
  end
379
424
 
@@ -383,10 +428,10 @@ You can add high level methods to your `PageSection` class definition, as shown
383
428
  You add a `PageSection` to its associated `PageObject` as shown below:
384
429
 
385
430
  class HomePage < TestCentricity::PageObject
386
- trait(:page_name) { 'Home' }
387
- trait(:page_url) { '/dashboard' }
388
- trait(:page_locator) { 'body.dashboard' }
389
-
431
+ trait(:page_name) { 'Home' }
432
+ trait(:page_url) { '/dashboard' }
433
+ trait(:page_locator) { 'body.dashboard' }
434
+
390
435
  # Home page Section Objects
391
436
  section :search_form, SearchForm
392
437
  end
@@ -396,11 +441,12 @@ Once your `PageObject` has been instantiated, you can call its `PageSection` met
396
441
  home_page.search_form.search_for('ocarina')
397
442
 
398
443
 
444
+ ---
399
445
  ## UIElements
400
446
 
401
- `PageObjects` and `PageSections` are typically made up of **UI Element** like text fields, check boxes, select lists (combo
402
- boxes), radio buttons, tables, ordered and unordered lists, buttons, images, HTML5 video objects, HTML5 audio objects, etc.
403
- **UI Elements** are declared and instantiated within the class definition of the `PageObject` or `PageSection` in which they
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
404
450
  are contained. With TestCentricity Web, all UI elements are based on the `UIElement` class.
405
451
 
406
452
 
@@ -424,58 +470,58 @@ Supported `UIElement` elementTypes and their declarations have the following for
424
470
 
425
471
  class SamplePage < TestCentricity::PageObject
426
472
 
427
- button :button_name, locator
428
- textfield :field_name, locator
429
- checkbox :checkbox_name, locator
430
- radio :radio_button_name, locator
431
- label :label_name, locator
432
- link :link_name, locator
433
- selectlist :select_name, locator
434
- list :list_name, locator
435
- table :table_name, locator
436
- range :range_name, locator
437
- image :image_name, locator
438
- video :video_name, locator
439
- audio :audio_name, locator
440
- filefield :filefield_name, locator
441
-
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
+
442
488
  end
443
489
 
444
490
  *Multiple element declarations:*
445
491
 
446
492
  class SamplePage < TestCentricity::PageObject
447
-
448
- buttons button_1_name: locator,
449
- button_2_name: locator,
450
- button_X_name: locator
451
- textfields field_1_name: locator,
452
- field_2_name: locator,
453
- field_X_name: locator
454
- checkboxes check_1_name: locator,
455
- check_2_name: locator,
456
- check_X_name: locator
457
- radios radio_1_name: locator,
458
- radio_X_name: locator
459
- labels label_1_name: locator,
460
- label_X_name: locator
461
- links link_1_name: locator,
462
- link_X_name: locator
463
- selectlists selectlist_1_name: locator,
464
- selectlist_X_name: locator
465
- lists list_1_name: locator,
466
- list_X_name: locator
467
- tables table_1_name: locator,
468
- table_X_name: locator
469
- ranges range_1_name: locator,
470
- range_X_name: locator
471
- images image_1_name: locator,
472
- image_X_name: locator
473
- videos video_1_name: locator,
474
- video_X_name: locator
475
- audios audio_1_name: locator,
476
- audio_X_name: locator
477
- filefields filefield_1_name: locator,
478
- 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
479
525
 
480
526
  end
481
527
 
@@ -525,7 +571,6 @@ With TestCentricity, all UI elements are based on the `UIElement` class, and inh
525
571
  element.y
526
572
  element.get_attribute(attrib)
527
573
  element.get_native_attribute(attrib)
528
- element.inspect
529
574
 
530
575
  **Waiting methods:**
531
576
 
@@ -574,7 +619,7 @@ With TestCentricity, all UI elements are based on the `UIElement` class, and inh
574
619
  element.aria_busy?
575
620
 
576
621
 
577
- ### Populating your PageObject or PageSection with data
622
+ ### Populating a PageObject or PageSection With Data
578
623
 
579
624
  A typical automated test may be required to perform the entry of test data by interacting with various `UIElements` on your
580
625
  `PageObject` or `PageSection`. This data entry can be performed using the various object action methods (listed above) for
@@ -585,8 +630,8 @@ collection of `UIElements`. The `populate_data_fields` method accepts a hash con
585
630
  their associated data to be entered. Data values must be in the form of a `String` for `textfield`, `selectlist`, and `filefield`
586
631
  controls. For `checkbox` and `radio` controls, data must either be a `Boolean` or a `String` that evaluates to a `Boolean`
587
632
  value (Yes, No, 1, 0, true, false). For `range` controls, data must be an `Integer`. For `input(type='color')` color picker
588
- controls, which are specified as a `textfield`, data must be in the form of a hex color `String`. For `section` objects, data
589
- values must be a `String`, and the `section` object must have a `set` method defined.
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.
590
635
 
591
636
  The `populate_data_fields` method verifies that data attributes associated with each `UIElement` is not `nil` or `empty`
592
637
  before attempting to enter data into the `UIElement`.
@@ -611,7 +656,7 @@ states are changed. If the wait time is `nil`, then the wait time will be 5 seco
611
656
  end
612
657
 
613
658
 
614
- ### Verifying UIElements on your PageObject or PageSection
659
+ ### Verifying UIElements on a PageObject or PageSection
615
660
 
616
661
  A typical automated test executes one or more interactions with the user interface, and then performs a validation to verify
617
662
  whether the expected state of the UI has been achieved. This verification can be performed using the various object state
@@ -670,7 +715,7 @@ The `verify_ui_states` method supports the following property/state pairs:
670
715
  :max Integer
671
716
  :step Integer
672
717
 
673
- Text Field Constraint validation
718
+ Text Field Constraint Validation
674
719
 
675
720
  :validation_message String
676
721
  :badInput Boolean
@@ -756,7 +801,7 @@ The `verify_ui_states` method supports the following property/state pairs:
756
801
  :active_track_source String
757
802
  :track_source String
758
803
 
759
- #### ARIA accessibility property/state pairs
804
+ #### ARIA Accessibility Property/State Pairs
760
805
 
761
806
  The `verify_ui_states` method supports the following ARIA accessibility property/state pairs:
762
807
 
@@ -817,14 +862,44 @@ values appear in the associated text fields after entering data and performing a
817
862
  def verify_changes_saved
818
863
  # verify saved user data is correctly displayed
819
864
  ui = {
820
- first_name_field => { visible: true, aria_invalid: false, value: User.current.first_name },
821
- last_name_field => { visible: true, aria_invalid: false, value: User.current.last_name },
822
- email_field => { visible: true, aria_invalid: false, value: User.current.email },
823
- phone_number_field => { visible: true, aria_invalid: false, value: User.current.phone_number },
824
- time_zone_select => { visible: true, aria_invalid: false, value: User.current.time_zone },
825
- language_select => { visible: true, aria_invalid: false, value: User.current.language },
826
- avatar_container => { visible: true },
827
- 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
+ },
828
903
  error_message_label => { visible: false }
829
904
  }
830
905
  verify_ui_states(ui)
@@ -848,25 +923,89 @@ The `verify_ui_states` method also supports I18n string translations using prope
848
923
  :translate_capitalize String
849
924
  :translate_titlecase String
850
925
 
851
- The example below depicts the usage of the `verify_ui_states` method to verify that the captions for menu items are correctly
852
- translated.
853
-
854
- def verify_menu
855
- ui = {
856
- account_settings_item => { visible: true, caption: { translate: 'Header.settings.account' } },
857
- help_item => { visible: true, caption: { translate: 'Header.settings.help' } },
858
- feedback_item => { visible: true, caption: { translate: 'Header.settings.feedback' } },
859
- legal_item => { visible: true, caption: { translate: 'Header.settings.legal' } },
860
- institution_item => { visible: true, caption: { translate: 'Header.settings.institution' } },
861
- configurations_item => { visible: true, caption: { translate: 'Header.settings.configurations' } },
862
- contact_us_item => { visible: true, caption: { translate: 'Header.settings.contact' } },
863
- downloads_item => { visible: true, caption: { translate: 'Header.settings.downloads' } }
864
- }
865
- 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
866
964
  end
867
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
+
868
1006
  Each supported language/locale combination has a corresponding `.yml` file. I18n `.yml` file naming convention uses
869
- [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:
870
1009
 
871
1010
  | Language (Country) | File name |
872
1011
  |-----------------------|-----------|
@@ -879,151 +1018,231 @@ Each supported language/locale combination has a corresponding `.yml` file. I18n
879
1018
  | Portuguese (Brazil) | pt-BR.yml |
880
1019
  | Portuguese (Portugal) | pt-PT.yml |
881
1020
 
882
- I18n `.yml` files contain key/value pairs representing the name of a translated string (key) and the string value.
883
-
884
1021
  Baseline translation strings are stored in `.yml` files in the `config/locales/` folder.
885
1022
 
886
- my_automation_project
887
- ├── config
888
- │ ├── locales
889
- │ │ ├── en.yml
890
- │ │ ├── es.yml
891
- │ │ ├── fr.yml
892
- │ │ ├── fr-CA.yml
893
- │ │ └── en-AU.yml
894
- │ ├── test_data
895
- └── cucumber.yml
896
- ├── downloads
897
- ├── features
898
- ├── Gemfile
899
- └── README.md
900
-
901
-
902
- ### Working with custom UIElements
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
903
1043
 
904
1044
  Many responsive and touch-enabled web based user interfaces are implemented using front-end JavaScript libraries for building
905
- user interfaces based on UI components. Popular JS libraries include React, Angular, and Ember.js. These stylized and adorned
906
- controls can present a challenge when attempting to interact with them using Capybara and Selenium based automated tests.
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.
907
1048
 
908
1049
  #### Radio and Checkbox UIElements
909
1050
 
910
1051
  Sometimes, radio buttons and checkboxes implemented using JS component libraries cannot be interacted with due to other UI
911
- elements being overlaid on top of them and the base `input(type='radio')` or `input(type='checkbox')` element not being visible.
912
-
913
- In the screenshots below of an airline flight search and booking page, the **Roundtrip** and **One-way** radio buttons are
914
- adorned by `label` elements that also acts as proxies for their associated `input(type='radio')` elements, and they intercept
915
- the `click` actions that would normally be handled by the `input(type='radio')` elements.
916
-
917
- <img src="https://i.imgur.com/7bW5u4c.jpg" alt="Roundtrip Radio button Input" title="Roundtrip Radio button Input">
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.
918
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.
919
1058
 
920
- 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")
921
1060
 
922
- <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.
923
1063
 
1064
+ ![Custom Checkbox controls](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomCheckbox.png "Custom Checkbox controls")
924
1065
 
925
- The checkbox controls in this web UI are also adorned with `label` elements that act as proxies for their associated `input(type='checkbox')`
926
- elements.
927
1066
 
928
- <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.
929
1071
 
930
-
931
- The `Radio.define_custom_elements` and `CheckBox.define_custom_elements` methods provide a way to specify the `input`, `proxy`
932
- and/or `label` elements associated with the `input(type='radio')` or `input(type='checkbox')` elements. The `define_custom_elements`
933
- method should be called from an `initialize` method for the `PageObject` or `PageSection` where the `radio` or `checkbox` element is
934
- instantiated. The code snippet below demonstrates the use of the `Radio.define_custom_elements` and `CheckBox.define_custom_elements`
935
- methods to resolve the testability issues posed by the adorned **Roundtrip** and **One-way** radio buttons and the **Flexible dates**
936
- 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.
937
1074
 
938
1075
  class FlightBookingPage < TestCentricity::PageObject
939
1076
  trait(:page_name) { 'Flight Booking Home' }
940
- trait(:page_locator) { "div[class*='bookerContainer']" }
941
-
1077
+ trait(:page_locator) { 'div[class*="bookerContainer"]' }
1078
+
942
1079
  # Flight Booking page UI elements
943
- radios roundtrip_radio: "label[for='roundtrip']",
944
- one_way_radio: "label[for='oneway']"
945
- checkbox :flexible_check, 'input#flexibleDates'
946
-
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
+
947
1088
  def initialize
948
- # define the custom element components for the Round Trip and One Way radio buttons
949
- 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
+ }
950
1094
  roundtrip_radio.define_custom_elements(radio_spec)
951
1095
  one_way_radio.define_custom_elements(radio_spec)
952
- # define the custom element components for the Flexible Date checkbox
953
- check_spec = { proxy: 'label#flexDatesLabel' }
954
- 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)
955
1141
  end
956
1142
  end
957
1143
 
958
1144
 
959
1145
  #### SelectList UIElements
960
1146
 
961
- The basic HTML `select` element is typically composed of the parent `select` object, and one or more `option` elements representing
962
- the selectable items in the drop-down list. However, `select` type controls implemented using JS component libraries can be composed
963
- 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.
964
1151
 
965
- In the screenshots below of an airline flight search and booking page, there are no `select` or `option` elements associated with the
966
- **Month**, **Day**, and **Cabin Type** drop-down style selectors. An inspection of the **Month** selector reveals that it is a `div`
967
- element that contains a `button` element (outlined in red) for triggering the drop-down list, a `ul` element (outlined in green) that
968
- contains the drop-down list, and multiple `li` elements (outlined in blue) that represent the list items or options that can be
969
- selected. The currently selected item or option can be identified by either the `listBoxOptionSelected` snippet in its `class` name or
970
- the `aria-selected` attribute (outlined in orange).
1152
+ ![Custom SelectList](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomSelectList1.png "Custom SelectList")
971
1153
 
972
- Further examination of the **Day** and **Cabin Type** drop-down style selectors reveal that their composition is identical to the
973
- **Month** selector.
974
1154
 
975
- <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).
976
1161
 
1162
+ ![Custom SelectList](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/CustomSelectList.jpg "Custom SelectList")
977
1163
 
978
- The `SelectList.define_list_elements` method provides a means of specifying the various elements that make up the key components of
979
- a `selectlist` control. The method accepts a hash of element designators (key) and a CSS or Xpath expression (value) that expression
980
- that uniquely identifies the element. Valid element designators are `list_item:`, `options_list:`, `list_trigger:`, `selected_item:`,
981
- `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`.
982
1168
 
983
- The code snippet below demonstrates the use of the `SelectList.define_list_elements` method to define the common components that make
984
- up the **Month**, **Day**, and **Cabin Type** drop-down style selectors. Note the use of the ARIA `role` and `aria-selected` attributes
985
- 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.
986
1171
 
987
- class FlightBookingPage < TestCentricity::PageObject
988
- trait(:page_name) { 'Flight Booking Home' }
989
- trait(:page_locator) { "div[class*='bookerContainer']" }
990
-
991
- # Flight Booking page UI elements
992
- selectlists month_select: "div[class*='expandFlexMonth']",
993
- duration_select: "div[class*='expandFlexDay']",
994
- 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'
995
1179
 
996
1180
  def initialize
997
- # 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
998
1183
  list_spec = {
999
- selected_item: "li[aria-selected=true]",
1000
- options_list: "ul[role='listbox']",
1001
- list_item: "li[role='option']",
1002
- 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'
1003
1190
  }
1004
- month_select.define_list_elements(list_spec)
1005
- duration_select.define_list_elements(list_spec)
1006
- cabin_type_select.define_list_elements(list_spec)
1191
+ country_select.define_list_elements(list_spec)
1192
+ team_select.define_list_elements(list_spec)
1007
1193
  end
1008
1194
  end
1009
1195
 
1010
1196
 
1011
- #### 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`.
1012
1213
 
1013
- The basic HTML list is typically composed of the parent `ul` object, and one or more `li` elements representing the items
1014
- in the list. However, list controls implemented using JS component libraries can be composed of multiple elements representing
1015
- the 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`.
1016
1216
 
1017
- The `List.define_list_elements` method provides a means of specifying the elements that make up the key components of a `list`
1018
- control. The method accepts a hash of element designators (key) and a CSS or Xpath expression (value) that expression that
1019
- uniquely identifies 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' }
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
1020
1238
 
1021
1239
 
1022
- ## Instantiating your PageObjects
1240
+ ---
1241
+ ## Instantiating Your PageObjects
1023
1242
 
1024
- Before you can call the methods in your `PageObjects` and `PageSections`, you must instantiate the `PageObjects` of your web
1025
- application, as well as create instance variables which can be used when calling a `PageObject`'s methods from your step
1026
- definitions. There are several ways to instantiate your `PageObjects`.
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`.
1027
1246
 
1028
1247
  One common implementation is shown below:
1029
1248
 
@@ -1031,81 +1250,82 @@ One common implementation is shown below:
1031
1250
  def login_page
1032
1251
  @login_page ||= LoginPage.new
1033
1252
  end
1034
-
1253
+
1035
1254
  def home_page
1036
1255
  @home_page ||= HomePage.new
1037
1256
  end
1038
-
1257
+
1039
1258
  def registration_page
1040
1259
  @registration_page ||= RegistrationPage.new
1041
1260
  end
1042
-
1261
+
1043
1262
  def search_results_page
1044
1263
  @search_results_page ||= SearchResultsPage.new
1045
1264
  end
1046
1265
  end
1047
-
1266
+
1048
1267
  World(WorldPages)
1049
1268
 
1050
- The `WorldPages` module above can be defined in your `env.rb` file, or you can define it in a separate `world_pages.rb` file
1051
- in the `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.
1052
1271
 
1053
1272
  While this approach is effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly
1054
1273
  becomes cumbersome to manage if your web application has dozens of `PageObjects` that need to be instantiated and managed.
1055
1274
 
1056
1275
  ### Using the PageManager
1057
1276
 
1058
- The `PageManager` class provides methods for supporting the instantiation and management of `PageObjects`. In the code example
1059
- below, the `page_objects` method contains a hash table of your `PageObject` instances and their associated `PageObject` classes
1060
- to be instantiated by `PageManager`:
1061
-
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
+
1062
1281
  module WorldPages
1063
1282
  def page_objects
1064
1283
  {
1065
- login_page: LoginPage,
1066
- home_page: HomePage,
1067
- registration_page: RegistrationPage,
1068
- search_results_page: SearchResultsPage,
1069
- products_grid_page: ProductsCollectionPage,
1070
- product_detail_page: ProductDetailPage,
1071
- shopping_basket_page: ShoppingBasketPage,
1072
- payment_method_page: PaymentMethodPage,
1073
- confirm_purchase_page: PurchaseConfirmationPage,
1074
- my_account_page: MyAccountPage,
1075
- my_order_history_page: MyOrderHistoryPage,
1076
- my_ship_to_addresses_page: MyShipToAddressesPage,
1077
- terms_conditions_page: TermsConditionsPage,
1078
- privacy_policy_page: PrivacyPolicyPage,
1079
- faqs_page: FAQsPage,
1080
- 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
1081
1300
  }
1082
1301
  end
1083
1302
  end
1084
-
1303
+
1085
1304
  World(WorldPages)
1086
1305
 
1087
1306
 
1088
1307
  The `WorldPages` module above should be defined in the `world_pages.rb` file in the `features/support` folder.
1089
1308
 
1090
- Include the code below in your `env.rb` file to ensure that your `PageObjects` are instantiated before your Cucumber scenarios
1091
- are executed:
1092
-
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
+
1093
1312
  include WorldPages
1094
1313
  WorldPages.instantiate_page_objects
1095
-
1096
- **NOTE:** If you intend to use the `PageManager`, you must define a `page_name` trait for each of the `PageObjects` to be registered.
1097
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.
1098
1317
 
1099
- ### Leveraging the PageManager in your Cucumber tests
1100
1318
 
1101
- Many Cucumber based automated tests suites include scenarios that verify that web pages are correctly loaded, displayed, or
1102
- can be 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:
1103
1323
 
1104
1324
  Scenario Outline: Verify Home page navigation links
1105
1325
  Given I am on the Home page
1106
1326
  When I click the <page name> navigation link
1107
1327
  Then I expect the <page name> page to be correctly displayed
1108
-
1328
+
1109
1329
  Examples:
1110
1330
  |page name |
1111
1331
  |Registration |
@@ -1115,25 +1335,25 @@ can be navigated to by clicking associated links. One such Cucumber navigation s
1115
1335
  |FAQs |
1116
1336
  |Contact Us |
1117
1337
 
1118
- In the above example, the step definitions associated with the 3 steps might be implemented using a `page_dispatcher` method
1119
- using a `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:
1120
1340
 
1121
1341
  Given(/^I am on the (.*) page$/) do |page_name|
1122
1342
  target_page = page_dispatcher(page_name)
1123
1343
  target_page.load_page
1124
1344
  end
1125
-
1345
+
1126
1346
  When(/^I click the (.*) navigation link$/) do |link_name|
1127
1347
  target_page = page_dispatcher(link_name)
1128
1348
  target_page.navigate_to
1129
1349
  end
1130
-
1350
+
1131
1351
  Then(/^I expect the (.*) page to be correctly displayed$/) do |page_name|
1132
1352
  target_page = page_dispatcher(page_name)
1133
1353
  target_page.verify_page_exists
1134
1354
  target_page.verify_page_ui
1135
1355
  end
1136
-
1356
+
1137
1357
  # this method takes a page name as a parameter and returns an instance of the associated Page Object
1138
1358
  def page_dispatcher(page_name)
1139
1359
  page = case page_name
@@ -1155,33 +1375,33 @@ using a `case` statement to parse the `page` parameter as in the example below:
1155
1375
  end
1156
1376
 
1157
1377
 
1158
- While this approach may be effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly
1159
- becomes 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.
1160
1380
 
1161
- The `PageManager` class provides a `find_page` method that replaces the cumbersome and difficult to maintain `case` statement
1162
- used in the above example. The `PageManager.current_page` method allows you to set or get an instance of the currently active
1163
- 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.
1164
1384
 
1165
- To use these `PageManager` methods, include the step definitions and code below in a `page_steps.rb` or `generic_steps.rb` file
1166
- in the `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:
1167
1387
 
1168
1388
  include TestCentricity
1169
-
1389
+
1170
1390
  Given(/^I am on the (.*) page$/) do |page_name|
1171
1391
  target_page = PageManager.find_page(page_name)
1172
1392
  target_page.load_page
1173
1393
  end
1174
-
1394
+
1175
1395
  When(/^I click the (.*) navigation link$/) do |page_name|
1176
1396
  target_page = PageManager.find_page(page_name)
1177
1397
  target_page.navigate_to
1178
1398
  end
1179
-
1399
+
1180
1400
  Then(/^I expect to see the (.*) page$/) do |page_name|
1181
1401
  target_page = PageManager.find_page(page_name)
1182
1402
  target_page.verify_page_exists
1183
1403
  end
1184
-
1404
+
1185
1405
  Then(/^I expect the (.*) page to be correctly displayed$/) do |page_name|
1186
1406
  target_page = PageManager.find_page(page_name)
1187
1407
  target_page.verify_page_exists
@@ -1189,221 +1409,487 @@ in the `features/step_definitions` folder:
1189
1409
  end
1190
1410
 
1191
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
1192
1446
 
1193
- ## 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:
1194
1450
 
1195
- The `TestCentricity::WebDriverConnect.initialize_web_driver` method configures the appropriate Selenium-Webdriver capabilities
1196
- required to establish a connection with a target web browser, and sets the base host URL of the web site you are running your
1197
- tests against.
1451
+ options = {
1452
+ capabilities: { browserName: :firefox },
1453
+ driver: :webdriver
1454
+ }
1455
+ WebDriverConnect.initialize_web_driver(options)
1198
1456
 
1199
- The `TestCentricity::WebDriverConnect.initialize_web_driver` method accepts a single optional parameter - the base host URL.
1200
- Cucumber **Environment Variables** are used to specify the target local or remote web browser, and the various webdriver
1201
- capability parameters required to configure the connection.
1457
+ Additional options that can be specified in an `options` hash include the following:
1202
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` |
1203
1465
 
1204
- ### 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.
1205
1468
 
1206
- For locally hosted desktop web browsers running on macOS or Windows platforms, the `WEB_BROWSER` Environment Variable must
1207
- be set to one of the values from the table below:
1469
+ #### Specifying the Driver Type
1208
1470
 
1209
- | `WEB_BROWSER` | **Desktop Platform** |
1210
- |--------------------|------------------------------------------------|
1211
- | `chrome` | macOS or Windows |
1212
- | `chrome_headless` | macOS or Windows (headless - no visible UI) |
1213
- | `firefox` | macOS or Windows |
1214
- | `firefox_headless` | macOS or Windows (headless - no visible UI) |
1215
- | `edge` | macOS or Windows |
1216
- | `edge_headless` | macOS or Windows (headless - no visible UI) |
1217
- | `safari` | macOS only |
1218
- | `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:
1219
1473
 
1220
- 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 |
1221
1483
 
1484
+ #### Specifying a Driver Name
1222
1485
 
1223
- #### 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:
1224
1536
 
1225
- To set the size of a desktop browser window, you set the `BROWSER_SIZE` Environment Variable to the desired width and height
1226
- in pixels as shown below:
1227
-
1228
1537
  BROWSER_SIZE=1600,1000
1229
1538
 
1230
1539
  To maximize a desktop browser window, you set the `BROWSER_SIZE` Environment Variable to 'max' as shown below:
1231
-
1540
+
1232
1541
  BROWSER_SIZE=max
1233
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:
1234
1553
 
1235
- #### Testing file downloads with desktop browsers
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
1583
+
1584
+ ```
1585
+ options = {
1586
+ capabilities: { browserName: value_from_table_above },
1587
+ driver: :webdriver
1588
+ }
1589
+ WebDriverConnect.initialize_web_driver(options)
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
1236
1607
 
1237
1608
  File download functionality can be tested with locally hosted instances of Chrome, Edge, or Firefox desktop browsers. Your
1238
- automation project must include a `/downloads` folder at the same level as the `/config` and `/features` folders, as depicted
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
1239
1611
  below:
1240
1612
 
1241
- my_automation_project
1242
- ├── config
1243
- ├── downloads
1244
- ├── features
1245
- ├── Gemfile
1246
- └── README.md
1613
+ 📁 my_automation_project/
1614
+ ├── 📁 config/
1615
+ ├── 📁 downloads/
1616
+ ├── 📁 features/
1617
+ ├── 📄 Gemfile
1618
+ └── 📄 README.md
1247
1619
 
1248
1620
 
1249
1621
  When running tests in multiple concurrent threads using the `parallel_tests` gem, a new folder will be created within the
1250
1622
  `/downloads` folder for each test thread. This is to ensure that files downloaded in each test thread are isolated from tests
1251
1623
  running in other parallel threads. An example of the`/downloads` folder structure for 4 parallel threads is depicted below:
1252
1624
 
1253
- my_automation_project
1254
- ├── config
1255
- ├── downloads
1256
- │ ├── 1
1257
- │ ├── 2
1258
- │ ├── 3
1259
- │ └── 4
1260
- ├── features
1261
- ├── Gemfile
1262
- └── README.md
1625
+ 📁 my_automation_project/
1626
+ ├── 📁 config/
1627
+ ├── 📁 downloads/
1628
+ │ ├── 📁 1/
1629
+ │ ├── 📁 2/
1630
+ │ ├── 📁 3/
1631
+ │ └── 📁 4/
1632
+ ├── 📁 features/
1633
+ ├── 📄 Gemfile
1634
+ └── 📄 README.md
1635
+
1263
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:
1264
1642
 
1265
- When testing file downloads using a local instance of Firefox, you will need to specify the MIME types of the various file types
1266
- that your tests will be downloading. This is accomplished by setting the `MIME_TYPES` Environment Variable to a comma-delimited
1267
- string containing the list of MIME types to be accepted. This list is required as it will prevent Firefox from displaying the
1268
- File Download modal dialog, which will halt your automated tests. An example of a list of MIME types is depicted below:
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(',')
1269
1653
 
1270
- MIME_TYPES='images/jpeg, application/pdf, application/octet-stream'
1271
1654
 
1272
- A detailed list of file MIME types can be found [here](https://www.freeformatter.com/mime-types-list.html)
1655
+ A detailed list of file MIME types can be found [here](https://www.freeformatter.com/mime-types-list.html).
1273
1656
 
1274
1657
 
1275
- ### Locally hosted emulated mobile web browser
1658
+ ### Locally Hosted Emulated Mobile Web Browsers
1276
1659
 
1277
1660
  You can run your tests against mobile device browsers that are emulated within a locally hosted instance of a Chrome desktop
1278
1661
  browser on macOS or Windows. The specified mobile browser's user agent, CSS screen dimensions, and default screen orientation
1279
- will be automatically set within the local Chrome browser instance. You may even specify the emulated device's screen orientation.
1280
- For locally hosted emulated mobile web browsers, the `WEB_BROWSER` Environment Variable must be set to one of the values from
1281
- the table below:
1282
-
1283
- | `WEB_BROWSER` | `HOST_BROWSER` | **CSS Screen Dimensions** | **Default Orientation** | **OS Version** |
1284
- |-----------------------|----------------|---------------------------|-------------------------|-------------------------------------------|
1285
- | `ipad` | `chrome` | 1024 x 768 | landscape | iOS 12 |
1286
- | `ipad_pro` | `chrome` | 1366 x 1024 | landscape | iOS 12 |
1287
- | `ipad_pro_10_5` | `chrome` | 1112 x 834 | landscape | iOS 12.2 |
1288
- | `ipad_pro_11` | `chrome` | 1194 x 834 | landscape | iOS 12.2 |
1289
- | `ipad_pro_12_9` | `chrome` | 1366 x 1024 | landscape | iOS 13.1 |
1290
- | `ipad_chrome` | `chrome` | 1024 x 768 | landscape | iOS 12.2 - Mobile Chrome browser for iOS |
1291
- | `ipad_firefox` | `chrome` | 1024 x 768 | landscape | iOS 12.2 - Mobile Firefox browser for iOS |
1292
- | `ipad_edge` | `chrome` | 1024 x 768 | landscape | iOS 12.2 - Mobile Edge browser for iOS |
1293
- | `kindle_fire` | `chrome` | 1024 x 600 | landscape | |
1294
- | `kindle_firehd7` | `chrome` | 800 x 480 | landscape | Fire OS 3 |
1295
- | `kindle_firehd8` | `chrome` | 1280 x 800 | landscape | Fire OS 5 |
1296
- | `kindle_firehd10` | `chrome` | 1920 x 1200 | landscape | Fire OS 5 |
1297
- | `surface` | `chrome` | 1366 x 768 | landscape | |
1298
- | `blackberry_playbook` | `chrome` | 1024 x 600 | landscape | BlackBerry Tablet OS |
1299
- | `samsung_galaxy_tab` | `chrome` | 1280 x 800 | landscape | Android 4.0.4 |
1300
- | `google_nexus7` | `chrome` | 960 x 600 | landscape | Android 4.4.4 |
1301
- | `google_nexus9` | `chrome` | 1024 x 768 | landscape | Android 5.1 |
1302
- | `google_nexus10` | `chrome` | 1280 x 800 | landscape | Android 5.1 |
1303
- | `iphone6` | `chrome` | 375 x 667 | portrait | iOS 12 |
1304
- | `iphone6_plus` | `chrome` | 414 x 736 | portrait | iOS 12 |
1305
- | `iphone7` | `chrome` | 375 x 667 | portrait | iOS 12 |
1306
- | `iphone7_plus` | `chrome` | 414 x 736 | portrait | iOS 12 |
1307
- | `iphone7_chrome` | `chrome` | 375 x 667 | portrait | iOS 12.2 - Mobile Chrome browser for iOS |
1308
- | `iphone7_firefox` | `chrome` | 375 x 667 | portrait | iOS 12.2 - Mobile Firefox browser for iOS |
1309
- | `iphone7_edge` | `chrome` | 375 x 667 | portrait | iOS 12.2 - Microsoft Edge browser for iOS |
1310
- | `iphone8` | `chrome` | 375 x 667 | portrait | iOS 12 |
1311
- | `iphone8_plus` | `chrome` | 414 x 736 | portrait | iOS 12 |
1312
- | `iphone_x` | `chrome` | 375 x 812 | portrait | iOS 12.2 |
1313
- | `iphone_xr` | `chrome` | 414 x 896 | portrait | iOS 12.2 |
1314
- | `iphone_xs` | `chrome` | 375 x 812 | portrait | iOS 12.2 |
1315
- | `iphone_xs_max` | `chrome` | 414 x 896 | portrait | iOS 12.2 |
1316
- | `iphone_11` | `chrome` | 414 x 896 | portrait | iOS 13.1 |
1317
- | `iphone_11_pro` | `chrome` | 375 x 812 | portrait | iOS 13.1 |
1318
- | `iphone_11_pro_max` | `chrome` | 414 x 896 | portrait | iOS 13.1 |
1319
- | `nexus6` | `chrome` | 411 x 731 | portrait | Android 6 |
1320
- | `pixel` | `chrome` | 411 x 731 | portrait | Android 8 |
1321
- | `pixel_xl` | `chrome` | 411 x 731 | portrait | Android 8 |
1322
- | `samsung_galaxy_s4` | `chrome` | 360 x 640 | portrait | Android 5.0.1 |
1323
- | `samsung_galaxy_s5` | `chrome` | 360 x 640 | portrait | Android 6.0.1 |
1324
- | `samsung_galaxy_s6` | `chrome` | 360 x 640 | portrait | Android 6.0.1 |
1325
- | `windows_phone7` | `chrome` | 320 x 480 | portrait | Windows Phone OS 7.5 |
1326
- | `windows_phone8` | `chrome` | 320 x 480 | portrait | Windows Phone OS 8.0 |
1327
- | `lumia_950_xl` | `chrome` | 360 x 640 | portrait | Windows Phone OS 10 |
1328
- | `blackberry_z10` | `chrome` | 384 x 640 | portrait | BlackBerry 10 OS |
1329
- | `blackberry_z30` | `chrome` | 360 x 640 | portrait | BlackBerry 10 OS |
1330
- | `blackberry_leap` | `chrome` | 360 x 640 | portrait | BlackBerry 10 OS |
1331
- | `blackberry_passport` | `chrome` | 504 x 504 | square | BlackBerry 10 OS |
1332
-
1333
- To change the emulated device's screen orientation from the default setting, set the `ORIENTATION` Environment Variable to
1334
- either `portrait` or `landscape`.
1335
-
1336
- To use a local instance of the Chrome desktop browser to host the emulated mobile web browser, you must set the `HOST_BROWSER`
1337
- Environment Variable to `chrome`.
1338
-
1339
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1340
-
1341
-
1342
- #### User defined mobile device profiles
1343
-
1344
- User defined mobile device profiles can be specified in a `device.yml` file for testing locally hosted emulated mobile web
1345
- browsers running in an instance of the Chrome desktop browser. The user specified device profiles must be located at
1346
- `config/data/devices/devices.yml` as depicted below:
1347
-
1348
- my_automation_project
1349
- ├── config
1350
- │ ├── data
1351
- │ │ └── devices
1352
- │ │ └── devices.yml
1353
- │ ├── locales
1354
- │ ├── test_data
1355
- │ └── cucumber.yml
1356
- ├── downloads
1357
- ├── features
1358
- ├── Gemfile
1359
- └── README.md
1360
-
1361
- The format for a new device profile is:
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
1731
+
1732
+ ```
1733
+ options = {
1734
+ capabilities: { browserName: value_from_table_above },
1735
+ driver: :webdriver
1736
+ }
1737
+ WebDriverConnect.initialize_web_driver(options)
1362
1738
  ```
1363
- :new_device_profile:
1364
- :name: "New Device Name"
1365
- :os: (ios, android, kindle, or blackberry)
1366
- :type: (phone or tablet)
1367
- :css_width: css width in pixels
1368
- :css_height: css height in pixels
1369
- :default_orientation: (portrait or landscape)
1370
- :user_agent: "user agent string"
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:
1371
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
+
1372
1803
 
1373
- ### Selenium Grid 4 and Dockerized Selenium Grid 4 hosted desktop and emulated mobile web browsers
1804
+ ### Selenium Grid Hosted Desktop and Emulated Mobile Web Browsers
1374
1805
 
1375
- For remote desktop and emulated mobile web browsers running on Selenium Grid 4 or Dockerized Selenium Grid 4 environments
1376
- as described in the table below.
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:
1377
1809
 
1378
- | **Environment Variable** | **Description** |
1379
- |--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1380
- | `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. |
1381
- | `SELENIUM` | Must be set to `remote` |
1382
- | `REMOTE_ENDPOINT` | Must be set to the URL of the Grid hub, which is usually `http://localhost:4444/wd/hub` |
1810
+ | `browserName:` or `WEB_BROWSER` |
1811
+ |---------------------------------|
1812
+ | `chrome` |
1813
+ | `chrome_headless` |
1814
+ | `firefox` |
1815
+ | `firefox_headless` |
1816
+ | `edge` |
1817
+ | `edge_headless` |
1383
1818
 
1384
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1819
+ #### Grid Browsers using Environment Variables
1385
1820
 
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:
1386
1823
 
1387
- ### Mobile browsers on Simulators or Physical Devices
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'_ |
1388
1830
 
1389
- #### Mobile Safari browser on iOS Simulators or iOS Physical Devices
1831
+ Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
1390
1832
 
1391
- You can run your mobile web tests against the mobile Safari browser on simulated iOS devices or physically connected iOS devices
1392
- using Appium and XCode on macOS. You must install Appium, XCode, and the iOS version-specific device simulators for XCode. You
1393
- must also ensure that the `appium_capybara` gem is installed and required as described in **section 3.3 (Setup - Using Appium)** above.
1394
1833
 
1395
- Information about Appium setup and configuration requirements for testing on physically connected iOS devices can be found
1396
- on [this page](https://github.com/appium/appium/blob/master/docs/en/drivers/ios-xcuitest-real-devices.md). The Appium server
1397
- must be running prior to invoking Cucumber to run your features/scenarios.
1834
+ #### Grid Browser in the `options` Hash
1398
1835
 
1399
- Once your test environment is properly configured, the following **Environment Variables** must be set as described in the table below.
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.
1853
+
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.
1856
+
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)
1864
+
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.
1400
1885
 
1401
1886
  | **Environment Variable** | **Description** |
1402
1887
  |----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1403
1888
  | `DRIVER` | Must be set to `appium` |
1889
+ | `AUTOMATION_ENGINE` | Must be set to `xcuitest` |
1404
1890
  | `APP_PLATFORM_NAME` | Must be set to `iOS` |
1405
1891
  | `APP_BROWSER` | Must be set to `Safari` |
1406
- | `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 |
1407
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 |
1408
1894
  | `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
1409
1895
  | `APP_UDID` | UDID of physically connected iOS device (not used for simulators) |
@@ -1415,59 +1901,165 @@ Once your test environment is properly configured, the following **Environment V
1415
1901
  | `APP_FULL_RESET` | [Optional] Perform a complete reset. Set to `true` or `false` |
1416
1902
  | `APP_INITIAL_URL` | [Optional] Initial URL, default is a local welcome page. e.g. `http://www.apple.com` |
1417
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. |
1418
- | `LOCALE` | [Optional] Locale to set for the simulator. e.g. `fr_CA` |
1419
- | `LANGUAGE` | [Optional] Language to set for the simulator. e.g. `fr` |
1420
1904
  | `ORIENTATION` | [Optional] Set to `portrait` or `landscape` (only for iOS simulators) |
1421
1905
  | `NEW_COMMAND_TIMEOUT` | [Optional] Time (in Seconds) that Appium will wait for a new command from the client |
1422
1906
  | `SHOW_SIM_KEYBOARD` | [Optional] Show the simulator keyboard during text entry. Set to `true` or `false` |
1423
1907
  | `SHUTDOWN_OTHER_SIMS` | [Optional] Close any other running simulators. Set to `true` or `false`. See note below. |
1424
1908
 
1425
- The `SHUTDOWN_OTHER_SIMS` environment variable can only be set if you are running Appium Server with the `--relaxed-security` or
1426
- `--allow-insecure=shutdown_other_sims` arguments passed when starting it from the command line, or when running the server from the
1427
- 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.
1428
1914
 
1429
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1430
1915
 
1916
+ ##### Local Mobile Safari Browser in the `options` Hash
1431
1917
 
1432
- #### Mobile Chrome or Android browsers on Android Studio Virtual Device emulators
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
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
1433
1969
 
1434
1970
  You can run your mobile web tests against the mobile Chrome or Android browser on emulated Android devices using Appium and
1435
1971
  Android Studio on macOS. You must install Android Studio, the desired Android version-specific virtual device emulators, and
1436
- Appium. Refer to [this page](http://appium.io/docs/en/drivers/android-uiautomator2/index.html) for information on configuring
1437
- Appium to work with the Android SDK. You must also ensure that the `appium_capybara` gem is installed and required as described
1438
- in **section 3.3 (Setup - Using Appium)** above.
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.
1973
+
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.
1439
1975
 
1440
- 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)
1441
- for information on configuring Appium to use the correct version of Chromedriver required to work with the web browser supported
1442
- by each Android OS version.
1443
1976
 
1444
- 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.
1445
1981
 
1446
1982
  | **Environment Variable** | **Description** |
1447
1983
  |---------------------------|--------------------------------------------------------------------------------------------------------------------------------|
1448
1984
  | `DRIVER` | Must be set to `appium` |
1985
+ | `AUTOMATION_ENGINE` | Must be set to `UiAutomator2` |
1449
1986
  | `APP_PLATFORM_NAME` | Must be set to `Android` |
1450
1987
  | `APP_BROWSER` | Must be set to `Chrome` or `Browser` |
1451
- | `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 |
1452
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 |
1453
1990
  | `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
1454
1991
  | `ORIENTATION` | [Optional] Set to `portrait` or `landscape` |
1455
1992
  | `APP_INITIAL_URL` | [Optional] Initial URL, default is a local welcome page. e.g. `http://www.apple.com` |
1456
1993
  | `APP_NO_RESET` | [Optional] Don't reset app state after each test. Set to `true` or `false` |
1457
1994
  | `APP_FULL_RESET` | [Optional] Perform a complete reset. Set to `true` or `false` |
1458
- | `LOCALE` | [Optional] Locale to set for the simulator. e.g. `fr_CA` |
1459
- | `LANGUAGE` | [Optional] Language to set for the simulator. e.g. `fr` |
1460
1995
  | `NEW_COMMAND_TIMEOUT` | [Optional] Time (in Seconds) that Appium will wait for a new command from the client |
1461
- | `CHROMEDRIVER_EXECUTABLE` | [Optional] Absolute local path to webdriver executable |
1996
+ | `CHROMEDRIVER_EXECUTABLE` | [Optional] Absolute local path to ChromeDriver executable |
1997
+
1998
+ Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
1999
+
2000
+
2001
+ ##### Local Mobile Android Browser in the `options` Hash
2002
+
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)
1462
2054
 
1463
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1464
2055
 
2056
+ #### Starting and Stopping Appium Server
1465
2057
 
1466
- #### Starting and stopping Appium Server
2058
+ ##### Using Appium Server with Cucumber
1467
2059
 
1468
- The Appium server must be running prior to invoking Cucumber to run your features/scenarios on mobile simulators or physical
1469
- device. To programmatically control the starting and stopping of Appium server with the execution of your automated tests,
1470
- place the code shown below in your `hooks.rb` file.
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.
1471
2063
 
1472
2064
  BeforeAll do
1473
2065
  # start Appium Server if APPIUM_SERVER = 'run' and target browser is a mobile simulator or device
@@ -1478,43 +2070,64 @@ place the code shown below in your `hooks.rb` file.
1478
2070
  end
1479
2071
 
1480
2072
  AfterAll do
2073
+ # terminate all driver instances
2074
+ WebDriverConnect.close_all_drivers
1481
2075
  # terminate Appium Server if APPIUM_SERVER = 'run' and target browser is a mobile simulator or device
1482
2076
  $server.stop if ENV['APPIUM_SERVER'] == 'run' && Environ.driver == :appium && $server.running?
1483
- # close driver
1484
- Capybara.page.driver.quit
1485
- Capybara.reset_sessions!
1486
- Environ.session_state = :quit
1487
2077
  end
1488
2078
 
1489
-
1490
- The `APPIUM_SERVER` environment variable must be set to `run` in order to programmatically start and stop Appium server. This
1491
- can be set by adding the following to your `cucumber.yml` file and including `-p run_appium` in your command line when starting
1492
- your Cucumber 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):
1493
2082
 
1494
2083
  run_appium: APPIUM_SERVER=run
1495
2084
 
2085
+ Refer to [**section 8.9 (Using Browser Specific Profiles in `cucumber.yml`)**](#using-browser-specific-profiles-in-cucumber-yml) below.
1496
2086
 
1497
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
1498
2087
 
2088
+ ##### Using Appium Server with RSpec
1499
2089
 
1500
- ### 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:
2093
+
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
2099
+
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
2104
+
2105
+
2106
+ ### Remote Cloud Hosted Desktop and Mobile Web Browsers
1501
2107
 
1502
2108
  You can run your automated tests against remote cloud hosted desktop and mobile web browsers using the BrowserStack, SauceLabs,
1503
2109
  TestingBot, or LambdaTest services. If your tests are running against a web site hosted on your local computer (`localhost`),
1504
2110
  or on a staging server inside your LAN, you must set the `TUNNELING` Environment Variable to `true`.
1505
2111
 
1506
- Due to lack of support for Selenium 4.x and the W3C browser capabilities protocol, support for CrossBrowserTesting and Gridlastic
1507
- cloud hosted Selenium grid services was removed as of version 4.1 of this gem. If your testing requires access to either of those
1508
- services, or support for Selenium version 3.x, you should use earlier versions of this gem.
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:
1509
2115
 
1510
- Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
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
1511
2120
 
2121
+ #### Remote Desktop Browsers on the BrowserStack Service
1512
2122
 
1513
- #### Remote desktop browsers on the BrowserStack service
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.
1514
2126
 
1515
- For remotely hosted desktop web browsers on the BrowserStack service, the following **Environment Variables** must be set as
1516
- described in the table below. Refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/automate/capabilities?tag=selenium-4)
1517
- for information regarding the specific capabilities.
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.
1518
2131
 
1519
2132
  | **Environment Variable** | **Description** |
1520
2133
  |--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -1535,20 +2148,82 @@ for information regarding the specific capabilities.
1535
2148
  | `SCREENSHOTS` | [Optional] Generate screenshots for debugging (`true` or `false`) |
1536
2149
  | `NETWORK_LOGS` | [Optional] Capture network logs (`true` or `false`) |
1537
2150
 
1538
- If the BrowserStack Local instance is running (`TUNNELING` Environment Variable is `true`), call the`TestCentricity::WebDriverConnect.close_tunnel` method
1539
- upon completion of your test suite to stop the Local instance. Place the code shown below in your `env.rb` or `hooks.rb` file.
1540
2151
 
1541
- # code to stop BrowserStack Local instance after end of test (if tunneling is enabled)
1542
- at_exit do
1543
- TestCentricity::WebDriverConnect.close_tunnel if Environ.tunneling
1544
- end
2152
+ ##### BrowserStack Desktop Browser in the `options` Hash
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
2158
+
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)
1545
2215
 
1546
2216
 
1547
- #### Remote mobile browsers on the BrowserStack service
2217
+ #### Remote Mobile Browsers on the BrowserStack Service
1548
2218
 
1549
- For remotely hosted mobile web browsers on the BrowserStack service, the following **Environment Variables** must be set as described in
1550
- the table below. Refer to the [Browserstack-specific capabilities chart page](https://www.browserstack.com/automate/capabilities?tag=selenium-4)
1551
- 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.
1552
2227
 
1553
2228
  | **Environment Variable** | **Description** |
1554
2229
  |--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -1556,6 +2231,7 @@ for information regarding the specific capabilities.
1556
2231
  | `BS_USERNAME` | Must be set to your BrowserStack account user name |
1557
2232
  | `BS_AUTHKEY` | Must be set to your BrowserStack account access key |
1558
2233
  | `BS_OS` | Must be set to `ios` or `android` |
2234
+ | `BS_OS_VERSION` | Refer to `osVersion` capability in chart |
1559
2235
  | `BS_BROWSER` | Must be set to `Safari` (for iOS) or `Chrome` (for Android) |
1560
2236
  | `BS_DEVICE` | Refer to `deviceName` capability in chart |
1561
2237
  | `BS_REAL_MOBILE` | Set to `true` if running against a real device |
@@ -1570,11 +2246,81 @@ for information regarding the specific capabilities.
1570
2246
  | `APPIUM_LOGS` | [Optional] Generate Appium logs (`true` or `false`) |
1571
2247
 
1572
2248
 
1573
- #### 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
+
2313
+
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
1574
2321
 
1575
- For remotely hosted desktop web browsers on the Sauce Labs service, the following **Environment Variables** must be set as described in the
1576
- table below. Use the Selenium 4 selection on the [Platform Configurator page](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/)
1577
- to obtain information regarding the specific capabilities.
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.
1578
2324
 
1579
2325
  | **Environment Variable** | **Description** |
1580
2326
  |--------------------------|----------------------------------------------------------------------------------------------------------------------------|
@@ -1583,36 +2329,254 @@ to obtain information regarding the specific capabilities.
1583
2329
  | `SL_AUTHKEY` | Must be set to your Sauce Labs account access key |
1584
2330
  | `DATA_CENTER` | Must be set to your Sauce Labs account Data Center assignment (`us-west-1`, `eu-central-1`, `apac-southeast-1`) |
1585
2331
  | `SL_OS` | Refer to `platformName` capability in the Config Script section of the Platform Configurator page |
1586
- | `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` |
1587
2333
  | `SL_VERSION` | Refer to `browserVersion` capability in the Config Script section of the Platform Configurator page |
1588
2334
  | `RESOLUTION` | [Optional] Refer to supported `screenResolution` capability in the Config Script section of the Platform Configurator page |
1589
- | `BROWSER_SIZE ` | [Optional] Specify width, height of browser window |
2335
+ | `BROWSER_SIZE` | [Optional] Specify width, height of browser window |
1590
2336
  | `RECORD_VIDEO` | [Optional] Enable screen video recording during test execution (`true` or `false`) |
1591
2337
 
1592
2338
 
1593
- #### 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
+
1594
2398
 
1595
- For remotely hosted desktop web browsers on the TestingBot service, the following **Environment Variables** must be set as described in
1596
- the table below. Refer to the [TestingBot List of Available Browsers page](https://testingbot.com/support/getting-started/browsers.html) for information
1597
- regarding the specific capabilities.
2399
+ #### Remote Mobile Browsers on the Sauce Labs Service
1598
2400
 
1599
- | **Environment Variable** | **Description** |
1600
- |--------------------------|-------------------------------------------------------------------------------------------------------------------|
1601
- | `DRIVER` | Must be set to `testingbot` |
1602
- | `TB_USERNAME` | Must be set to your TestingBot account user name |
1603
- | `TB_AUTHKEY` | Must be set to your TestingBot account access key |
1604
- | `TB_OS` | Refer to `platform` capability in chart |
1605
- | `TB_BROWSER` | Refer to `browserName` capability in chart |
1606
- | `TB_VERSION` | Refer to `version` capability in chart |
1607
- | `TUNNELING` | [Optional] Must be `true` if you are testing against internal/local servers (`true` or `false`) |
1608
- | `RESOLUTION` | [Optional] Possible values: `800x600`, `1024x768`, `1280x960`, `1280x1024`, `1600x1200`, `1920x1200`, `2560x1440` |
1609
- | `BROWSER_SIZE` | [Optional] Specify width, height of browser window |
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.
1610
2404
 
2405
+ ##### Sauce Labs Mobile Browser using Environment Variables
1611
2406
 
1612
- #### Remote mobile browsers on the TestingBot service
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)
1613
2490
 
1614
- For remotely hosted mobile web browsers iOS simulators and Android emulators on the TestingBot service, the following Environment
1615
- Variables must be set as described in the table below.
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.
1616
2580
 
1617
2581
  | **Environment Variable** | **Description** |
1618
2582
  |--------------------------|-------------------------------------------------------------------------------------------------|
@@ -1629,11 +2593,72 @@ Variables must be set as described in the table below.
1629
2593
  | `ORIENTATION` | [Optional] Set to `portrait` or `landscape` |
1630
2594
 
1631
2595
 
1632
- #### Remote desktop browsers on the LambdaTest service
2596
+ ##### TestingBot Mobile Browser in the `options` Hash
1633
2597
 
1634
- For remotely hosted desktop web browsers on the LambdaTest service, the following **Environment Variables** must be set as described in the table
1635
- below. Use the Selenium 4 Configuration Wizard on the [Selenium Desired Capabilities Generator](https://www.lambdatest.com/capabilities-generator/)
1636
- to obtain information 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
2603
+
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)
2650
+
2651
+
2652
+ #### Remote Desktop Browsers on the LambdaTest Service
2653
+
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.
1637
2662
 
1638
2663
  | **Environment Variable** | **Description** |
1639
2664
  |--------------------------|------------------------------------------------------------------------------------------|
@@ -1651,117 +2676,189 @@ to obtain information regarding the specific capabilities.
1651
2676
  | `CONSOLE_LOGS` | [Optional] Used to capture browser console logs. |
1652
2677
 
1653
2678
 
1654
- ### 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
2753
+
2754
+
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`
1655
2767
 
1656
2768
  While you can set **Environment Variables** in the command line when invoking Cucumber, a preferred method of specifying and
1657
- managing target web browsers is to create browser specific **Profiles** that set the appropriate **Environment Variables** for
1658
- each target browser in your `cucumber.yml` file.
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.
1659
2776
 
1660
- Below is a list of Cucumber **Profiles** for supported locally and remotely hosted desktop and mobile web browsers (put these
1661
- in in your`cucumber.yml` file). Before you can use the BrowserStack, SauceLabs, TestingBot or LambdaTest services, you will
1662
- need to replace the*INSERT USER NAME HERE* and *INSERT PASSWORD HERE* placeholder text with your user account and authorization
1663
- code for the cloud service(s) that you intend to connect with. However, cloud service credentials should not be stored as text
1664
- in your `cucumber.yml` file where it can be exposed by anyone with access to your version control system
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.
1665
2779
 
1666
2780
 
1667
2781
  <% desktop = "--tags @desktop --require features BROWSER_TILE=true BROWSER_SIZE=1500,1000" %>
1668
2782
  <% tablet = "--tags @desktop --require features BROWSER_TILE=true" %>
1669
2783
  <% mobile = "--tags @mobile --require features BROWSER_TILE=true" %>
1670
-
2784
+
1671
2785
  #==============
1672
2786
  # profiles for locally hosted desktop web browsers
1673
2787
  #==============
1674
-
2788
+
1675
2789
  firefox: WEB_BROWSER=firefox <%= desktop %>
1676
2790
  chrome: WEB_BROWSER=chrome <%= desktop %>
1677
2791
  edge: WEB_BROWSER=edge <%= desktop %>
1678
2792
  safari: WEB_BROWSER=safari <%= desktop %>
1679
- ie: WEB_BROWSER=ie <%= desktop %>
1680
2793
 
1681
2794
  firefox_headless: WEB_BROWSER=firefox_headless <%= desktop %>
1682
2795
  chrome_headless: WEB_BROWSER=chrome_headless <%= desktop %>
1683
2796
  edge_headless: WEB_BROWSER=edge_headless <%= desktop %>
1684
2797
 
1685
- #==============
1686
- # profile for Selenium Grid and Dockerized Selenium Grid hosted desktop web browsers
1687
- #==============
1688
- grid: SELENIUM=remote REMOTE_ENDPOINT="http://localhost:4444/wd/hub"
1689
-
1690
2798
 
1691
2799
  #==============
1692
2800
  # profiles for locally hosted mobile web browsers (emulated locally in Chrome browser)
1693
2801
  #==============
1694
-
1695
- ipad: WEB_BROWSER=ipad HOST_BROWSER=chrome <%= tablet %>
1696
- ipad_pro: WEB_BROWSER=ipad_pro HOST_BROWSER=chrome <%= tablet %>
1697
- ipad_pro_10_5: WEB_BROWSER=ipad_pro_10_5 HOST_BROWSER=chrome <%= tablet %>
1698
- ipad_pro_11: WEB_BROWSER=ipad_pro_11 HOST_BROWSER=chrome <%= tablet %>
1699
- ipad_pro_12_9: WEB_BROWSER=ipad_pro_12_9 HOST_BROWSER=chrome <%= tablet %>
1700
- ipad_chrome: WEB_BROWSER=ipad_chrome HOST_BROWSER=chrome <%= tablet %>
1701
- ipad_firefox: WEB_BROWSER=ipad_firefox HOST_BROWSER=chrome <%= tablet %>
1702
- ipad_edge: WEB_BROWSER=ipad_edge HOST_BROWSER=chrome <%= tablet %>
1703
- iphone6: WEB_BROWSER=iphone6 HOST_BROWSER=chrome <%= mobile %>
1704
- iphone6_plus: WEB_BROWSER=iphone6_plus HOST_BROWSER=chrome <%= mobile %>
1705
- iphone7: WEB_BROWSER=iphone7 HOST_BROWSER=chrome <%= mobile %>
1706
- iphone7_plus: WEB_BROWSER=iphone7_plus HOST_BROWSER=chrome <%= mobile %>
1707
- iphone7_chrome: WEB_BROWSER=iphone7_chrome HOST_BROWSER=chrome <%= mobile %>
1708
- iphone7_firefox: WEB_BROWSER=iphone7_firefox HOST_BROWSER=chrome <%= mobile %>
1709
- iphone7_edge: WEB_BROWSER=iphone7_edge HOST_BROWSER=chrome <%= mobile %>
1710
- iphone8: WEB_BROWSER=iphone8 HOST_BROWSER=chrome <%= mobile %>
1711
- iphone8_plus: WEB_BROWSER=iphone8_plus HOST_BROWSER=chrome <%= mobile %>
1712
- iphone_x: WEB_BROWSER=iphone_x HOST_BROWSER=chrome <%= mobile %>
1713
- iphone_xr: WEB_BROWSER=iphone_xr HOST_BROWSER=chrome <%= mobile %>
1714
- iphone_xr_chrome: WEB_BROWSER=iphone_xr_chrome HOST_BROWSER=chrome <%= mobile %>
1715
- iphone_xr_firefox: WEB_BROWSER=iphone_xr_firefox HOST_BROWSER=chrome <%= mobile %>
1716
- iphone_xr_edge: WEB_BROWSER=iphone_xr_edge HOST_BROWSER=chrome <%= mobile %>
1717
- iphone_xs: WEB_BROWSER=iphone_xs HOST_BROWSER=chrome <%= mobile %>
1718
- iphone_xs_max: WEB_BROWSER=iphone_xs_max HOST_BROWSER=chrome <%= mobile %>
1719
- iphone_11: WEB_BROWSER=iphone_11 HOST_BROWSER=chrome <%= mobile %>
1720
- iphone_11_pro: WEB_BROWSER=iphone_11_pro HOST_BROWSER=chrome <%= mobile %>
1721
- iphone_11_pro_max: WEB_BROWSER=iphone_11_pro_max HOST_BROWSER=chrome <%= mobile %>
1722
- nexus6: WEB_BROWSER=nexus6 HOST_BROWSER=chrome <%= mobile %>
1723
- kindle_fire: WEB_BROWSER=kindle_fire HOST_BROWSER=chrome <%= tablet %>
1724
- kindle_firehd7: WEB_BROWSER=kindle_firehd7 HOST_BROWSER=chrome <%= tablet %>
1725
- kindle_firehd8: WEB_BROWSER=kindle_firehd8 HOST_BROWSER=chrome <%= tablet %>
1726
- kindle_firehd10: WEB_BROWSER=kindle_firehd10 HOST_BROWSER=chrome <%= tablet %>
1727
- surface: WEB_BROWSER=surface HOST_BROWSER=chrome <%= tablet %>
1728
- blackberry_playbook: WEB_BROWSER=blackberry_playbook HOST_BROWSER=chrome <%= tablet %>
1729
- samsung_galaxy_tab: WEB_BROWSER=samsung_galaxy_tab HOST_BROWSER=chrome <%= tablet %>
1730
- google_nexus7: WEB_BROWSER=google_nexus7 HOST_BROWSER=chrome <%= tablet %>
1731
- google_nexus9: WEB_BROWSER=google_nexus9 HOST_BROWSER=chrome <%= tablet %>
1732
- google_nexus10: WEB_BROWSER=google_nexus10 HOST_BROWSER=chrome <%= tablet %>
1733
- samsung_galaxy_s4: WEB_BROWSER=samsung_galaxy_s4 HOST_BROWSER=chrome <%= mobile %>
1734
- samsung_galaxy_s5: WEB_BROWSER=samsung_galaxy_s5 HOST_BROWSER=chrome <%= mobile %>
1735
- samsung_galaxy_s6: WEB_BROWSER=samsung_galaxy_s6 HOST_BROWSER=chrome <%= mobile %>
1736
- pixel: WEB_BROWSER=pixel HOST_BROWSER=chrome <%= mobile %>
1737
- pixel_xl: WEB_BROWSER=pixel_xl HOST_BROWSER=chrome <%= mobile %>
1738
- windows_phone7: WEB_BROWSER=windows_phone7 HOST_BROWSER=chrome <%= mobile %>
1739
- windows_phone8: WEB_BROWSER=windows_phone8 HOST_BROWSER=chrome <%= mobile %>
1740
- lumia_950_xl: WEB_BROWSER=lumia_950_xl HOST_BROWSER=chrome <%= mobile %>
1741
- blackberry_z10: WEB_BROWSER=blackberry_z10 HOST_BROWSER=chrome <%= mobile %>
1742
- blackberry_z30: WEB_BROWSER=blackberry_z30 HOST_BROWSER=chrome <%= mobile %>
1743
- blackberry_leap: WEB_BROWSER=blackberry_leap HOST_BROWSER=chrome <%= mobile %>
1744
- blackberry_passport: WEB_BROWSER=blackberry_passport HOST_BROWSER=chrome <%= mobile %>
1745
2802
 
1746
-
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
+
1747
2844
  #==============
1748
2845
  # profiles for mobile device screen orientation
1749
2846
  #==============
1750
-
2847
+
1751
2848
  portrait: ORIENTATION=portrait
1752
2849
  landscape: ORIENTATION=landscape
1753
2850
 
1754
-
2851
+
1755
2852
  #==============
1756
2853
  # profile to start Appium Server prior to running mobile browser tests on iOS or Android simulators or physical devices
1757
2854
  #==============
1758
-
2855
+
1759
2856
  run_appium: APPIUM_SERVER=run
1760
2857
 
1761
2858
 
1762
2859
  #==============
1763
2860
  # profiles for mobile Safari web browsers hosted within XCode iOS simulator
1764
- # 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
1765
2862
  #==============
1766
2863
 
1767
2864
  appium_ios: DRIVER=appium AUTOMATION_ENGINE=XCUITest APP_PLATFORM_NAME="ios" APP_BROWSER="Safari" NEW_COMMAND_TIMEOUT=30 SHOW_SIM_KEYBOARD=false
@@ -1773,7 +2870,7 @@ in your `cucumber.yml` file where it can be exposed by anyone with access to you
1773
2870
 
1774
2871
  #==============
1775
2872
  # profiles for mobile Safari web browsers running on physically connected iOS devices
1776
- # NOTE: Requires installation of XCode, Appium, and the appium_capybara gem
2873
+ # NOTE: Requires installation of XCode and Appium
1777
2874
  #==============
1778
2875
 
1779
2876
  my_ios_15_iphone: --profile app_ios_15 DEVICE_TYPE=phone APP_DEVICE="My Test iPhoneX" APP_UDID="INSERT YOUR DEVICE UDID"
@@ -1782,30 +2879,30 @@ in your `cucumber.yml` file where it can be exposed by anyone with access to you
1782
2879
 
1783
2880
  #==============
1784
2881
  # profiles for Android mobile web browsers hosted within Android Studio Android Virtual Device emulators
1785
- # 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
1786
2883
  #==============
1787
2884
 
1788
2885
  appium_android: DRIVER=appium APP_PLATFORM_NAME="Android" <%= mobile %>
1789
2886
  app_android_12: --profile appium_android APP_BROWSER="Chrome" APP_VERSION="12.0"
1790
2887
  pixel_c_api31_sim: --profile app_android_12 DEVICE_TYPE=tablet APP_DEVICE="Pixel_C_API_31"
1791
2888
 
1792
-
2889
+
1793
2890
  #==============
1794
2891
  # profiles for remotely hosted web browsers on the BrowserStack service
1795
- # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with access
1796
- # 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
1797
2894
  #==============
1798
-
2895
+
1799
2896
  browserstack: DRIVER=browserstack BS_USERNAME="<INSERT USER NAME HERE>" BS_AUTHKEY="<INSERT PASSWORD HERE>"
1800
- bs_desktop: --profile browserstack <%= desktop %> RESOLUTION="1920x1080"
1801
- bs_mobile: --profile browserstack <%= mobile %>
1802
-
2897
+ bs_desktop: --profile browserstack <%= desktop %> RESOLUTION="1920x1080"
2898
+ bs_mobile: --profile browserstack <%= mobile %>
2899
+
1803
2900
  # BrowserStack macOS desktop browser profiles
1804
- bs_macos_monterey: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="Monterey"
1805
- bs_chrome_monterey: --profile bs_macos_monterey BS_BROWSER="Chrome" BS_VERSION="latest"
1806
- bs_edge_monterey: --profile bs_macos_monterey BS_BROWSER="Edge" BS_VERSION="latest"
1807
- bs_safari_monterey: --profile bs_macos_monterey BS_BROWSER="Safari" BS_VERSION="latest"
1808
-
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
+
1809
2906
  # BrowserStack Windows desktop browser profiles
1810
2907
  bs_win11: --profile bs_desktop BS_OS="Windows" BS_OS_VERSION="11"
1811
2908
  bs_chrome_win11: --profile bs_win11 BS_BROWSER="Chrome" BS_VERSION="latest"
@@ -1816,52 +2913,52 @@ in your `cucumber.yml` file where it can be exposed by anyone with access to you
1816
2913
  # BrowserStack iOS mobile browser profiles
1817
2914
  bs_ipad: --profile bs_mobile BS_OS=ios BS_BROWSER=Safari DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
1818
2915
  bs_ipad_pro_12: --profile bs_ipad BS_DEVICE="iPad Pro 12.9 2018" BS_OS_VERSION="15"
1819
-
2916
+
1820
2917
  # BrowserStack Android mobile browser profiles
1821
2918
  bs_android: --profile bs_mobile BS_OS=android BS_BROWSER=Chrome DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
1822
2919
  bs_android_tablet: --profile bs_android BS_DEVICE="Samsung Galaxy Tab S7" BS_OS_VERSION="10.0"
1823
2920
 
1824
-
2921
+
1825
2922
  #==============
1826
2923
  # profiles for remotely hosted web browsers on the SauceLabs service
1827
- # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with access
1828
- # 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
1829
2926
  #==============
1830
-
2927
+
1831
2928
  saucelabs: DRIVER=saucelabs SL_USERNAME="<INSERT USER NAME HERE>" SL_AUTHKEY="<INSERT PASSWORD HERE>" DATA_CENTER="<INSERT DATA CENTER HERE"
1832
2929
  sl_desktop: --profile saucelabs <%= desktop %>
1833
2930
  sl_mobile: --profile saucelabs <%= mobile %>
1834
-
2931
+
1835
2932
  # SauceLabs macOS desktop browser profiles
1836
- sl_macos_monterey: --profile sl_desktop SL_OS="macOS 12" RESOLUTION="1920x1440"
1837
- sl_chrome_monterey: --profile sl_macos_monterey SL_BROWSER="chrome" SL_VERSION="latest"
1838
- sl_edge_monterey: --profile sl_macos_monterey SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
1839
- sl_firefox_monterey: --profile sl_macos_monterey SL_BROWSER="Firefox" SL_VERSION="latest"
1840
-
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
+
1841
2938
  # SauceLabs Windows desktop browser profiles
1842
2939
  sl_windows: --profile sl_desktop RESOLUTION="1920x1200"
1843
2940
  sl_edge_win11: --profile sl_windows SL_OS="Windows 11" SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
1844
2941
  sl_ie_win10: --profile sl_windows SL_OS="Windows 10" SL_BROWSER="internet explorer" SL_VERSION="11"
1845
-
2942
+
1846
2943
  # SauceLabs iOS mobile browser profiles
1847
2944
  sl_ipad: --profile sl_mobile DEVICE_TYPE=tablet SL_PLATFORM=iOS SL_BROWSER=Safari
1848
2945
  sl_ipad_pro_12: --profile sl_ipad SL_DEVICE="iPad Pro (12.9 inch) (5th generation) Simulator" SL_VERSION="15.0"
1849
-
1850
-
2946
+
2947
+
1851
2948
  #==============
1852
2949
  # profiles for remotely hosted web browsers on the TestingBot service
1853
- # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with access
1854
- # 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
1855
2952
  #==============
1856
-
2953
+
1857
2954
  testingbot: DRIVER=testingbot TB_USERNAME="<INSERT USER NAME HERE>" TB_AUTHKEY="<INSERT PASSWORD HERE>"
1858
2955
  tb_desktop: --profile testingbot <%= desktop %> RESOLUTION="1920x1200"
1859
-
2956
+
1860
2957
  # TestingBot macOS desktop browser profiles
1861
- tb_macos_monterey: --profile tb_desktop TB_OS="MONTEREY"
1862
- tb_chrome_monterey: --profile tb_macos_monterey TB_BROWSER="chrome" TB_VERSION="latest"
1863
- tb_edge_monterey: --profile tb_macos_monterey TB_BROWSER="microsoftedge" TB_VERSION="latest"
1864
-
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
+
1865
2962
  # TestingBot Windows desktop browser profiles
1866
2963
  tb_win11: --profile tb_desktop TB_OS="WIN11"
1867
2964
  tb_edge_win11: --profile tb_win11 TB_BROWSER="microsoftedge" TB_VERSION="latest"
@@ -1871,18 +2968,18 @@ in your `cucumber.yml` file where it can be exposed by anyone with access to you
1871
2968
 
1872
2969
  #==============
1873
2970
  # profiles for remotely hosted web browsers on the LambdaTest service
1874
- # WARNING: Credentials should not be stored as text in your cucumber.yml file where it can be exposed by anyone with access
1875
- # 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
1876
2973
  #==============
1877
-
2974
+
1878
2975
  lambdatest: DRIVER=lambdatest LT_USERNAME=<INSERT USER NAME HERE> LT_AUTHKEY=<INSERT PASSWORD HERE>
1879
2976
  lt_desktop: --profile lambdatest <%= desktop %> RESOLUTION="2560x1440"
1880
-
2977
+
1881
2978
  # LambdaTest macOS desktop browser profiles
1882
2979
  lt_macos_monterey: --profile lt_desktop LT_OS="MacOS Monterey"
1883
2980
  lt_chrome_monterey: --profile lt_macos_monterey LT_BROWSER="Chrome" LT_VERSION="98.0"
1884
2981
  lt_edge_monterey: --profile lt_macos_monterey LT_BROWSER="MicrosoftEdge" LT_VERSION="97.0"
1885
-
2982
+
1886
2983
  # LambdaTest Windows desktop browser profiles
1887
2984
  lt_win11: --profile lt_desktop LT_OS="Windows 11"
1888
2985
  lt_edge_win11: --profile lt_win11 LT_BROWSER="MicrosoftEdge" LT_VERSION="98.0"
@@ -1914,7 +3011,7 @@ The following command specifies that Cucumber will run tests against an iPad Pro
1914
3011
 
1915
3012
  cucumber -p ipad_pro_12_15_sim -p landscape
1916
3013
 
1917
- NOTE: Appium must be running prior to executing this command
3014
+ ⚠️ Appium must be running prior to executing this command
1918
3015
 
1919
3016
  You can ensure that Appium Server is running by including `-p run_appium` in your command line:
1920
3017
 
@@ -1922,46 +3019,46 @@ You can ensure that Appium Server is running by including `-p run_appium` in you
1922
3019
 
1923
3020
 
1924
3021
  The following command specifies that Cucumber will run tests against a remotely hosted Safari web browser running on a macOS
1925
- Monterey virtual machine on the BrowserStack service:
1926
-
1927
- cucumber -p bs_safari_monterey
3022
+ Sonoma virtual machine on the BrowserStack service:
1928
3023
 
3024
+ cucumber -p bs_safari_sonoma
1929
3025
 
1930
3026
 
3027
+ ---
1931
3028
  ## Recommended Project Organization and Structure
1932
3029
 
1933
3030
  Below is an example of the project structure of a typical Cucumber based test automation framework with a Page Object Model
1934
3031
  architecture. `PageObject` class definitions should be stored in the `/features/support/pages` folder, organized in functional
1935
3032
  area sub-folders as needed. Likewise, `PageSection` class definitions should be stored in the `/features/support/sections` folder.
1936
3033
 
1937
- my_automation_project
1938
- ├── config
1939
- │ ├── locales
1940
- │ ├── test_data
1941
- │ └── cucumber.yml
1942
- ├── downloads
1943
- ├── features
1944
- │ ├── step_definitions
1945
- │ └── support
1946
- ├── pages
1947
- ├── sections
1948
- ├── env.rb
1949
- ├── hooks.rb
1950
- └── world_pages.rb
1951
- ├── Gemfile
1952
- └── README.md
1953
-
1954
-
1955
-
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
+ ---
1956
3053
  ## Web Test Automation Framework Implementation
1957
3054
 
1958
- <img src="https://i.imgur.com/lCT9HbK.jpg" alt="TestCentricity Web Framework Overview" title="TestCentricity Web Framework Overview">
1959
-
3055
+ ![TestCentricity Web Framework Overview](https://raw.githubusercontent.com/TestCentricity/testcentricity_web/main/.github/images/tc_overview.jpg "TestCentricity Web Framework Overview")
1960
3056
 
1961
3057
 
3058
+ ---
1962
3059
  ## Copyright and License
1963
3060
 
1964
- TestCentricity™ Framework is Copyright (c) 2014-2022, Tony Mrozinski.
3061
+ TestCentricity™ Framework is Copyright (c) 2014-2023, Tony Mrozinski.
1965
3062
  All rights reserved.
1966
3063
 
1967
3064
  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following