testcentricity_web 4.1.1 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -6,8 +6,6 @@
6
6
  The TestCentricity™ Web core generic framework for desktop and mobile web browser-based app testing implements a Page Object and Data
7
7
  Object Model DSL for use with Cucumber, Capybara (version 3.x), and Selenium-Webdriver (version 4.x).
8
8
 
9
- **An example project that demonstrates the implementation of a page object model framework using Cucumber and TestCentricity™ can be found [here](https://github.com/TestCentricity/tc_web_sample).**
10
-
11
9
  The TestCentricity™ Web gem supports running automated tests against the following web test targets:
12
10
  * locally hosted desktop browsers (Firefox, Chrome, Edge, Safari, or IE)
13
11
  * locally hosted emulated iOS Mobile Safari, Android, Windows Phone, or Blackberry mobile browsers (running within a local instance of Chrome)
@@ -28,10 +26,13 @@ The TestCentricity™ Web gem supports running automated tests against the follo
28
26
 
29
27
  A complete history of bug fixes and new features can be found in the {file:CHANGELOG.md CHANGELOG} file.
30
28
 
29
+ An example project that demonstrates the implementation of a page object model framework using Cucumber and TestCentricity™
30
+ can be found [here](https://github.com/TestCentricity/tc_web_sample).
31
+
31
32
 
32
33
  ## Installation
33
34
 
34
- TestCentricity requires Ruby 2.7 or later. To install the TestCentricity gem, add this line to your automation project's Gemfile:
35
+ TestCentricity version 4.1 and above requires Ruby 2.7 or later. To install the TestCentricity gem, add this line to your automation project's Gemfile:
35
36
 
36
37
  gem 'testcentricity_web'
37
38
 
@@ -78,7 +79,7 @@ And then execute:
78
79
  $ bundle
79
80
 
80
81
 
81
- ## Page Objects
82
+ ## PageObjects
82
83
 
83
84
  The **Page Object Model** is a test automation pattern that aims to create an abstraction of your web app's User Interface that can be used
84
85
  in tests. A **Page Object** is an object that represents a single page in your AUT (Application Under Test). **Page Objects** encapsulate the
@@ -87,14 +88,14 @@ implementation details of a web page and expose an API that supports interaction
87
88
  **Page Objects** makes it easier to maintain automated tests because changes to page UI elements are updated in only one location - in the
88
89
  **Page Object** class definition. By adopting a **Page Object Model**, Cucumber Feature files and step definitions are no longer required to
89
90
  hold specific information about a page's UI objects, thus minimizing maintenance requirements. If any element on, or property of a page changes
90
- (URL path, text field attributes, button captions, etc.), maintenance is performed in the **Page Object** class definition only, typically with
91
+ (URL path, text field attributes, button captions, etc.), maintenance is performed in the `PageObject` class definition only, typically with
91
92
  no need to update the affected feature file, scenarios, or step definitions.
92
93
 
93
94
 
94
- ### Defining a Page Object
95
+ ### Defining a PageObject
95
96
 
96
- Your **Page Object** class definitions should be contained within individual `.rb` files in the `features/support/pages` folder of your
97
- test automation project. You define new **Page Objects** as shown below:
97
+ Your `PageObject` class definitions should be contained within individual `.rb` files in the `features/support/pages` folder of your
98
+ test automation project. You define new `PageObjects` as shown below:
98
99
 
99
100
  class LoginPage < TestCentricity::PageObject
100
101
  end
@@ -108,14 +109,14 @@ test automation project. You define new **Page Objects** as shown below:
108
109
  end
109
110
 
110
111
 
111
- ### Adding Traits to your Page Object
112
+ ### Adding Traits to your PageObject
112
113
 
113
114
  Web pages typically have names and URLs associated with them. Web pages also typically have a unique object or attribute that, when present,
114
115
  indicates that the page's contents have fully loaded.
115
116
 
116
- The `page_name` trait is registered with the **PageManager** object, which includes a `find_page` method that takes a page name as a
117
- parameter and returns an instance of the associated **Page Object**. If you intend to use the **PageManager**, you must define a `page_name`
118
- trait for each of the **Page Objects** to be registered.
117
+ The `page_name` trait is registered with the `PageManager` object, which includes a `find_page` method that takes a page name as a
118
+ parameter and returns an instance of the associated `Page Object`. If you intend to use the `PageManager`, you must define a `page_name`
119
+ trait for each `PageObject` to be registered.
119
120
 
120
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` method.
121
122
  `page_name` traits are case and white-space sensitive. For pages that may be referenced with multiple names, the `page_name` trait may also be
@@ -133,36 +134,36 @@ for the `page_locator` trait to exist.
133
134
  You define your page's **Traits** as shown below:
134
135
 
135
136
  class LoginPage < TestCentricity::PageObject
136
- trait(:page_name) { 'Login' }
137
- trait(:page_url) { '/sign_in' }
138
- trait(:page_locator) { 'body.login-body' }
137
+ trait(:page_name) { 'Login' }
138
+ trait(:page_url) { '/sign_in' }
139
+ trait(:page_locator) { 'body.login-body' }
139
140
  end
140
141
 
141
142
 
142
143
  class HomePage < TestCentricity::PageObject
143
144
  # this page may be referred to as 'Home' or 'Dashboard' page so page_name trait is an Array of Strings
144
- trait(:page_name) { ['Home', 'Dashboard'] }
145
- trait(:page_url) { '/dashboard' }
146
- trait(:page_locator) { 'body.dashboard' }
145
+ trait(:page_name) { ['Home', 'Dashboard'] }
146
+ trait(:page_url) { '/dashboard' }
147
+ trait(:page_locator) { 'body.dashboard' }
147
148
  end
148
149
 
149
150
 
150
151
  class RegistrationPage < TestCentricity::PageObject
151
- trait(:page_name) { 'Registration' }
152
- trait(:page_url) { '/register' }
153
- trait(:page_locator) { 'body.registration' }
152
+ trait(:page_name) { 'Registration' }
153
+ trait(:page_url) { '/register' }
154
+ trait(:page_locator) { 'body.registration' }
154
155
  end
155
156
 
156
157
 
157
- ### Adding UI Elements to your Page Object
158
+ ### Adding UI Elements to your PageObject
158
159
 
159
160
  Web pages are made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists, buttons, etc.
160
- **UI Elements** are added to your **Page Object** class definition as shown below:
161
+ **UI Elements** are added to your `PageObject` class definition as shown below:
161
162
 
162
163
  class LoginPage < TestCentricity::PageObject
163
- trait(:page_name) { 'Login' }
164
- trait(:page_url) { '/sign_in' }
165
- trait(:page_locator) { 'body.login-body' }
164
+ trait(:page_name) { 'Login' }
165
+ trait(:page_url) { '/sign_in' }
166
+ trait(:page_locator) { 'body.login-body' }
166
167
 
167
168
  # Login page UI elements
168
169
  textfield :user_id_field, 'input#userName'
@@ -174,9 +175,9 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes,
174
175
 
175
176
 
176
177
  class RegistrationPage < TestCentricity::PageObject
177
- trait(:page_name) { 'Registration' }
178
- trait(:page_url) { '/register' }
179
- trait(:page_locator) { 'body.registration' }
178
+ trait(:page_name) { 'Registration' }
179
+ trait(:page_url) { '/register' }
180
+ trait(:page_locator) { 'body.registration' }
180
181
 
181
182
  # Registration page UI elements
182
183
  textfields first_name_field: 'input#firstName',
@@ -196,16 +197,16 @@ Web pages are made up of UI elements like text fields, check boxes, combo boxes,
196
197
  end
197
198
 
198
199
 
199
- ### Adding Methods to your Page Object
200
+ ### Adding Methods to your PageObject
200
201
 
201
- It is good practice for your Cucumber step definitions to call high level methods in your your **Page Object** instead of directly accessing
202
- and interacting with a page object's UI elements. You can add high level methods to your **Page Object** class definition for interacting with
202
+ It is good practice for your Cucumber step definitions to call high level methods in your your `PageObject` instead of directly accessing
203
+ and interacting with a page object's UI elements. You can add high level methods to your `PageObject` class definition for interacting with
203
204
  the UI to hide implementation details, as shown below:
204
205
 
205
206
  class LoginPage < TestCentricity::PageObject
206
- trait(:page_name) { 'Login' }
207
- trait(:page_url) { '/sign_in' }
208
- trait(:page_locator) { 'body.login-body' }
207
+ trait(:page_name) { 'Login' }
208
+ trait(:page_url) { '/sign_in' }
209
+ trait(:page_locator) { 'body.login-body' }
209
210
 
210
211
  # Login page UI elements
211
212
  textfield :user_id_field, 'input#userName'
@@ -232,9 +233,9 @@ the UI to hide implementation details, as shown below:
232
233
  ui = {
233
234
  self => { title: 'Login' },
234
235
  login_button => { visible: true, caption: 'LOGIN' },
235
- user_id_field => { visible: true, enabled: true },
236
+ user_id_field => { visible: true, enabled: true, value: '', placeholder: 'User name' },
236
237
  password_field => { visible: true, enabled: true, value: '', placeholder: 'Password' },
237
- remember_checkbox => { :exists => true, enabled: true, checked: false },
238
+ remember_checkbox => { exists: true, enabled: true, checked: false },
238
239
  forgot_password_link => { visible: true, caption: 'Forgot your password?' },
239
240
  error_message_label => { visible: false }
240
241
  }
@@ -244,9 +245,9 @@ the UI to hide implementation details, as shown below:
244
245
 
245
246
 
246
247
  class RegistrationPage < TestCentricity::PageObject
247
- trait(:page_name) { 'Registration' }
248
- trait(:page_url) { '/register' }
249
- trait(:page_locator) { 'body.registration' }
248
+ trait(:page_name) { 'Registration' }
249
+ trait(:page_url) { '/register' }
250
+ trait(:page_locator) { 'body.registration' }
250
251
 
251
252
  # Registration page UI elements
252
253
  textfields first_name_field: 'input#firstName',
@@ -278,7 +279,8 @@ the UI to hide implementation details, as shown below:
278
279
  state_select => profile.state,
279
280
  post_code_field => profile.postal_code,
280
281
  password_field => profile.password,
281
- pword_confirm_field => profile.confirm_password
282
+ pword_confirm_field => profile.confirm_password,
283
+ email_opt_in_check => profile.email_opt_in
282
284
  }
283
285
  populate_data_fields(fields)
284
286
  sign_up_button.click
@@ -287,52 +289,59 @@ the UI to hide implementation details, as shown below:
287
289
 
288
290
 
289
291
 
290
- Once your **Page Objects** have been instantiated, you can call your methods as shown below:
292
+ Once your `PageObjects` have been instantiated, you can call your methods as shown below:
291
293
 
292
294
  login_page.remember_me(true)
293
295
  login_page.login('snicklefritz', 'Pa55w0rd')
294
296
 
295
297
 
296
298
 
297
- ## PageSection Objects
299
+ ## PageSections
298
300
 
299
- A **PageSection Object** is a collection of **UI Elements** that may appear in multiple locations on a page, or on multiple pages in a web
301
+ A `PageSection` is a collection of **UI Elements** that may appear in multiple locations on a page, or on multiple pages in a web
300
302
  app. It is a collection of **UI Elements** that represent a conceptual area of functionality, like a navigation bar, a search capability,
301
- or a menu. **UI Elements** and functional behavior are confined to the scope of a **PageSection Object**.
303
+ or a menu. **UI Elements** and functional behavior are confined to the scope of a `PageSection` object.
304
+
305
+ <img src="https://i.imgur.com/BTgi59R.jpg" alt="Navigation Header" title="Navigation Header">
306
+
307
+ <img src="https://i.imgur.com/dkxloE5.jpg" alt="Navigation Header" title="Navigation Header">
308
+
309
+ <img src="https://i.imgur.com/Yqgw4sP.jpg" alt="User Profile Popup" title="User Profile Popup">
310
+
302
311
 
303
- A **PageSection Object** may contain other **PageSection Objects**.
312
+ A `PageSection` may contain other `PageSection` objects.
304
313
 
305
314
 
306
- ### Defining a PageSection Object
315
+ ### Defining a PageSection
307
316
 
308
- Your **PageSection** class definitions should be contained within individual `.rb` files in the `features/support/sections` folder of
309
- your test automation project. You define new **PageSection Objects** as shown below:
317
+ Your `PageSection` class definitions should be contained within individual `.rb` files in the `features/support/sections` folder of
318
+ your test automation project. You define new `PageSection` as shown below:
310
319
 
311
320
  class SearchForm < TestCentricity::PageSection
312
321
  end
313
322
 
314
323
 
315
- ### Adding Traits to a PageSection Object
324
+ ### Adding Traits to a PageSection
316
325
 
317
- A **PageSection Object** typically has a root node object that encapsulates a collection of **UI Elements**. The `section_locator` trait
326
+ A `PageSection` typically has a root node object that encapsulates a collection of `UIElements`. The `section_locator` trait
318
327
  specifies the CSS or Xpath expression that uniquely identifies that root node object.
319
328
 
320
- You define your page section's **Traits** as shown below:
329
+ You define your section's **Traits** as shown below:
321
330
 
322
331
  class SearchForm < TestCentricity::PageSection
323
- trait(:section_locator) { 'form#gnav-search' }
324
- trait(:section_name) { 'Search widget' }
332
+ trait(:section_locator) { 'form#gnav-search' }
333
+ trait(:section_name) { 'Search widget' }
325
334
  end
326
335
 
327
336
 
328
- ### Adding UI Elements to your PageSection Object
337
+ ### Adding UI Elements to your PageSection
329
338
 
330
- Page sections are typically made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists, buttons, etc.
331
- **UI Elements** are added to your **PageSection** class definition as shown below:
339
+ `PageSections` are typically made up of UI elements like text fields, check boxes, combo boxes, radio buttons, tables, lists, buttons, etc.
340
+ **UI Elements** are added to your `PageSection` class definition as shown below:
332
341
 
333
342
  class SearchForm < TestCentricity::PageSection
334
- trait(:section_locator) { 'form#gnav-search' }
335
- trait(:section_name) { 'Search widget' }
343
+ trait(:section_locator) { 'form#gnav-search' }
344
+ trait(:section_name) { 'Search widget' }
336
345
 
337
346
  # Search Form UI elements
338
347
  textfield :search_field, 'input#search-query'
@@ -340,13 +349,13 @@ Page sections are typically made up of UI elements like text fields, check boxes
340
349
  end
341
350
 
342
351
 
343
- ### Adding Methods to your PageSection Object
352
+ ### Adding Methods to your PageSection
344
353
 
345
- You can add high level methods to your **PageSection** class definition, as shown below:
354
+ You can add high level methods to your `PageSection` class definition, as shown below:
346
355
 
347
356
  class SearchForm < TestCentricity::PageSection
348
- trait(:section_locator) { 'form#gnav-search' }
349
- trait(:section_name) { 'Search widget' }
357
+ trait(:section_locator) { 'form#gnav-search' }
358
+ trait(:section_name) { 'Search widget' }
350
359
 
351
360
  # Search Form UI elements
352
361
  textfield :search_field, 'input#search-query'
@@ -359,48 +368,48 @@ You can add high level methods to your **PageSection** class definition, as show
359
368
  end
360
369
 
361
370
 
362
- ### Adding PageSection Objects to your Page Object
371
+ ### Adding PageSections to your PageObject
363
372
 
364
- You add a **PageSection Object** to its associated **Page Object** as shown below:
373
+ You add a `PageSection` to its associated `PageObject` as shown below:
365
374
 
366
375
  class HomePage < TestCentricity::PageObject
367
- trait(:page_name) { 'Home' }
368
- trait(:page_url) { '/dashboard' }
369
- trait(:page_locator) { 'body.dashboard' }
376
+ trait(:page_name) { 'Home' }
377
+ trait(:page_url) { '/dashboard' }
378
+ trait(:page_locator) { 'body.dashboard' }
370
379
 
371
380
  # Home page Section Objects
372
381
  section :search_form, SearchForm
373
382
  end
374
383
 
375
- Once your **Page Object** has been instantiated, you can call its **PageSection** methods as shown below:
384
+ Once your `PageObject` has been instantiated, you can call its `PageSection` methods as shown below:
376
385
 
377
386
  home_page.search_form.search_for('ocarina')
378
387
 
379
388
 
380
389
 
381
- ## UI Elements
390
+ ## UIElements
382
391
 
383
- **Page Objects** and **PageSection Objects** are typically made up of **UI Element** like text fields, check boxes, combo boxes, radio buttons,
384
- tables, lists, buttons, images, HTML5 video objects, HTML5 audio objects, etc. **UI Elements** are declared and instantiated within the class
385
- definition of the **Page Object** or **PageSection Object** in which they are contained. With TestCentricity Web, all UI elements are based on
386
- the **UIElement** class.
392
+ `PageObjects` and `PageSections` are typically made up of **UI Element** like text fields, check boxes, select lists (combo boxes),
393
+ radio buttons, tables, ordered and unordered lists, buttons, images, HTML5 video objects, HTML5 audio objects, etc. **UI Elements** are declared
394
+ and instantiated within the class definition of the `PageObject` or `PageSection` in which they are contained. With TestCentricity Web,
395
+ all UI elements are based on the `UIElement` class.
387
396
 
388
397
 
389
- ### Declaring and Instantiating UI Element
398
+ ### Declaring and Instantiating UIElements
390
399
 
391
- Single **UIElement** declarations have the following format:
400
+ Single `UIElement` declarations have the following format:
392
401
 
393
402
  elementType :element Name, locator
394
403
 
395
- * The `element name` is the unique name that you will use to refer to the UI element and is specified as a symbol.
396
- * The `locator` is the CSS or XPath attribute that uniquely and unambiguously identifies the UI element.
404
+ * The `element name` is the unique name that you will use to refer to the UI element and is specified as a `Symbol`.
405
+ * The `locator` is the CSS or XPath attribute that uniquely and unambiguously identifies the `UIElement`.
397
406
 
398
- Multiple **UIElement** declarations for a collection of elements of the same type can be performed by passing a hash table containing the
407
+ Multiple `UIElement` declarations for a collection of elements of the same type can be performed by passing a hash table containing the
399
408
  names and locators of each individual element.
400
409
 
401
- ### Example UI Element Declarations
410
+ ### Example UIElement Declarations
402
411
 
403
- Supported **UI Element** elementTypes and their declarations have the following format:
412
+ Supported `UIElement` elementTypes and their declarations have the following format:
404
413
 
405
414
  *Single element declarations:*
406
415
 
@@ -462,14 +471,14 @@ Supported **UI Element** elementTypes and their declarations have the following
462
471
  end
463
472
 
464
473
 
465
- Refer to the Class List documentation for the **PageObject** and **PageSection** classes for details on the class methods used for declaring
466
- and instantiating **UI Elements**. Examples of UI element declarations can be found in the ***Adding UI Elements to your Page Object*** and
474
+ Refer to the Class List documentation for the `PageObject` and `PageSection` classes for details on the class methods used for declaring
475
+ and instantiating `UIElements`. Examples of UI element declarations can be found in the ***Adding UI Elements to your Page Object*** and
467
476
  ***Adding UI Elements to your PageSection Object*** sections above.
468
477
 
469
478
 
470
479
  ### UIElement Inherited Methods
471
480
 
472
- With TestCentricity, all UI elements are based on the **UIElement** class, and inherit the following methods:
481
+ With TestCentricity, all UI elements are based on the `UIElement` class, and inherit the following methods:
473
482
 
474
483
  **Action methods:**
475
484
 
@@ -551,11 +560,295 @@ With TestCentricity, all UI elements are based on the **UIElement** class, and i
551
560
  element.aria_busy?
552
561
 
553
562
 
554
- ## Instantiating your Page Objects
563
+ ### Populating your PageObject or PageSection with data
564
+
565
+ A typical automated test may be required to perform the entry of test data by interacting with various `UIElements` on your `PageObject` or
566
+ `PageSection`. This data entry can be performed using the various object action methods (listed above) for each `UIElement` that needs to be
567
+ interacted with.
568
+
569
+ The `PageObject.populate_data_fields` and `PageSection.populate_data_fields` methods support the entry of test data into a collection of
570
+ `UIElements`. The `populate_data_fields` method accepts a hash containing key/hash pairs of `UIElements` and their associated data to be
571
+ entered. Data values must be in the form of a `String` for `textfield` and `selectlist` controls. For `checkbox` and `radio` controls, data
572
+ must either be a `Boolean` or a `String` that evaluates to a `Boolean` value (Yes, No, 1, 0, true, false). For `section` objects, data values
573
+ must be a `String`, and the `section` object must have a `set` method defined.
574
+
575
+ The `populate_data_fields` method verifies that data attributes associated with each `UIElement` is not `nil` or `empty` before attempting to
576
+ enter data into the `UIElement`.
577
+
578
+ The optional `wait_time` parameter is used to specify the time (in seconds) to wait for each `UIElement` to become become viable for data entry
579
+ (the `UIElement` must be visible and enabled) before entering the associated data value. This option is useful in situations where entering data,
580
+ or setting the state of a `UIElement` might cause other `UIElements` to become visible or active. Specifying a wait_time value ensures that the
581
+ subsequent `UIElements` will be ready to be interacted with as states are changed. If the wait time is `nil`, then the wait time will be 5 seconds.
582
+
583
+ def enter_data(user_data)
584
+ fields = {
585
+ first_name_field => user_data.first_name,
586
+ last_name_field => user_data.last_name,
587
+ email_field => user_data.email,
588
+ country_code_select => user_data.country_code,
589
+ phone_number_field => user_data.phone_number,
590
+ time_zone_select => user_data.time_zone,
591
+ language_select => user_data.language
592
+ }
593
+ populate_data_fields(fields, wait_time = 2)
594
+ end
595
+
596
+
597
+ ### Verifying UIElements on your PageObject or PageSection
598
+
599
+ A typical automated test executes one or more interactions with the user interface, and then performs a validation to verify whether
600
+ the expected state of the UI has been achieved. This verification can be performed using the various object state methods (listed above)
601
+ for each `UIElement` that requires verification. Depending on the complexity and number of `UIElements` to be verified, the code required to
602
+ verify the presence of `UIElements` and their correct states can become cumbersome.
603
+
604
+ The `PageObject.verify_ui_states` and `PageSection.verify_ui_states` methods support the verification of multiple properties of multiple
605
+ UI elements on a `PageObject` or `PageSection`. The `verify_ui_states` method accepts a hash containing key/hash pairs of UI
606
+ elements and their properties or attributes to be verified.
607
+
608
+ ui = {
609
+ object1 => { property: state },
610
+ object2 => { property: state, property: state },
611
+ object3 => { property: state }
612
+ }
613
+ verify_ui_states(ui)
614
+
615
+ The `verify_ui_states` method queues up any exceptions that occur while verifying each object's properties until all `UIElements` and their
616
+ properties have been checked, and then posts any exceptions encountered upon completion. Posted exceptions include a screenshot with a red
617
+ dashed highlight around the UI element that did not match the expected results.
618
+
619
+ The `verify_ui_states` method supports the following property/state pairs:
620
+
621
+ **All Objects:**
622
+
623
+ :exists Boolean
624
+ :enabled Boolean
625
+ :disabled Boolean
626
+ :visible Boolean
627
+ :hidden Boolean
628
+ :displayed Boolean
629
+ :width Integer
630
+ :height Integer
631
+ :x Integer
632
+ :y Integer
633
+ :class String
634
+ :value or :caption String
635
+ :attribute Hash
636
+
637
+ **Text Fields:**
638
+
639
+ :readonly Boolean
640
+ :placeholder String
641
+ :maxlength Integer
642
+ :min Integer
643
+ :max Integer
644
+ :step Integer
645
+
646
+ **Checkboxes:**
647
+
648
+ :checked Boolean
649
+
650
+ **Radio Buttons:**
651
+
652
+ :selected Boolean
653
+
654
+ **Images**
655
+
656
+ :loaded Boolean
657
+ :broken Boolean
658
+ :src String
659
+ :alt String
660
+
661
+ **Lists**
662
+
663
+ :items Array of Strings
664
+ :itemcount Integer
665
+ :item Hash
666
+ :selected String
667
+
668
+ **Select Lists** (ComboBoxes):
669
+
670
+ :items or :options Array of Strings
671
+ :itemcount or :optioncount Integer
672
+ :selected String
673
+
674
+ **Tables**
675
+
676
+ :rowcount Integer
677
+ :columncount Integer
678
+ :columnheaders Array of String
679
+ :cell Hash
680
+ :row Hash
681
+ :column Hash
682
+
683
+ **Audio/Video Media Objects**
684
+
685
+ :autoplay Boolean
686
+ :ended Boolean
687
+ :controls Boolean
688
+ :loop Boolean
689
+ :muted Boolean
690
+ :default_muted Boolean
691
+ :paused Boolean
692
+ :seeking Boolean
693
+ :src String
694
+ :current_time Float
695
+ :default_playback_rate Float
696
+ :duration Float
697
+ :playback_rate Float
698
+ :ready_state Integer
699
+ :volume Float
700
+ :crossorigin String
701
+ :preload String
702
+ :poster String
703
+
704
+ #### ARIA accessibility property/state pairs
705
+
706
+ The `verify_ui_states` method supports the following ARIA accessibility property/state pairs:
707
+
708
+ **All Objects:**
709
+
710
+ :aria_label String
711
+ :aria_disabled Boolean
712
+ :aria_labelledby String
713
+ :aria_describedby String
714
+ :aria_live Boolean
715
+ :aria_selected Boolean
716
+ :aria_hidden Boolean
717
+ :aria_expanded Boolean
718
+ :aria_required Boolean
719
+ :aria_invalid Boolean
720
+ :aria_checked Boolean
721
+ :aria_readonly Boolean
722
+ :aria_pressed Boolean
723
+ :aria_haspopup Boolean
724
+ :aria_sort String
725
+ :aria_rowcount String
726
+ :aria_colcount String
727
+ :aria_valuemax String
728
+ :aria_valuemin String
729
+ :aria_valuenow String
730
+ :aria_valuetext String
731
+ :aria_orientation String
732
+ :aria_keyshortcuts String
733
+ :aria_roledescription String
734
+ :aria_autocomplete String
735
+ :aria_controls String
736
+ :aria_modal String
737
+ :aria_multiline Boolean
738
+ :aria_multiselectable Boolean
739
+ :content_editable Boolean
740
+
741
+ #### Comparison States
742
+ The `verify_ui_states` method supports comparison states using property/comparison state pairs:
743
+
744
+ object => { property: { comparison_state: value } }
745
+
746
+ Comparison States:
747
+
748
+ :lt or :less_than Integer or String
749
+ :lt_eq or :less_than_or_equal Integer or String
750
+ :gt or :greater_than Integer or String
751
+ :gt_eq or :greater_than_or_equal Integer or String
752
+ :starts_with String
753
+ :ends_with String
754
+ :contains String
755
+ :not_contains or :does_not_contain Integer or String
756
+ :not_equal Integer, String, or Boolean
757
+
758
+ The example below depicts a `verify_changes_saved` method that uses the `verify_ui_states` method to verify that all expected
759
+ values appear in the associated text fields after entering data and performing a save operation.
760
+
761
+ def verify_changes_saved
762
+ # verify saved user data is correctly displayed
763
+ ui = {
764
+ first_name_field => { visible: true, aria_invalid: false, value: User.current.first_name },
765
+ last_name_field => { visible: true, aria_invalid: false, value: User.current.last_name },
766
+ email_field => { visible: true, aria_invalid: false, value: User.current.email },
767
+ phone_number_field => { visible: true, aria_invalid: false, value: User.current.phone_number },
768
+ time_zone_select => { visible: true, aria_invalid: false, value: User.current.time_zone },
769
+ language_select => { visible: true, aria_invalid: false, value: User.current.language },
770
+ avatar_container => { visible: true },
771
+ avatar_image => { visible: true, broken: false, src: { contains: User.current.avatar_file_name } },
772
+ error_message_label => { visible: false }
773
+ }
774
+ verify_ui_states(ui)
775
+
776
+ # verify avatar src url does not contain /null/ institution id
777
+ verify_ui_states(avatar_image => { src: { does_not_contain: "/null/" } })
778
+ end
779
+
780
+
781
+ #### I18n Translation Validation
782
+
783
+ The `verify_ui_states` method also supports I18n string translations using property/I18n key name pairs:
784
+
785
+ object => { property: { translate_key: 'name of key in I18n compatible .yml file' } }
786
+
787
+ **I18n Translation Keys:**
788
+
789
+ :translate String
790
+ :translate_upcase String
791
+ :translate_downcase String
792
+ :translate_capitalize String
793
+ :translate_titlecase String
794
+
795
+ The example below depicts the usage of the `verify_ui_states` method to verify that the captions for menu items are correctly
796
+ translated.
797
+
798
+ def verify_menu
799
+ ui = {
800
+ account_settings_item => { visible: true, caption: { translate: 'Header.settings.account' } },
801
+ help_item => { visible: true, caption: { translate: 'Header.settings.help' } },
802
+ feedback_item => { visible: true, caption: { translate: 'Header.settings.feedback' } },
803
+ legal_item => { visible: true, caption: { translate: 'Header.settings.legal' } },
804
+ institution_item => { visible: true, caption: { translate: 'Header.settings.institution' } },
805
+ configurations_item => { visible: true, caption: { translate: 'Header.settings.configurations' } },
806
+ contact_us_item => { visible: true, caption: { translate: 'Header.settings.contact' } },
807
+ downloads_item => { visible: true, caption: { translate: 'Header.settings.downloads' } }
808
+ }
809
+ verify_ui_states(ui)
810
+ end
811
+
812
+ Each supported language/locale combination has a corresponding `.yml` file. I18n `.yml` file naming convention uses
813
+ [ISO-639 language codes and ISO-3166 country codes](https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html). For example:
814
+
815
+ | Language (Country) | File name |
816
+ |-----------------------|-----------|
817
+ | English | en.yml |
818
+ | English (Canada) | en-CA.yml |
819
+ | French (Canada) | fr-CA.yml |
820
+ | French | fr.yml |
821
+ | Spanish | es.yml |
822
+ | German | de.yml |
823
+ | Portuguese (Brazil) | pt-BR.yml |
824
+ | Portuguese (Portugal) | pt-PT.yml |
555
825
 
556
- Before you can call the methods in your **Page Objects** and **PageSection Objects**, you must instantiate the **Page Objects** of your
557
- web application, as well as create instance variables which can be used when calling a **Page Objects** methods from your step definitions.
558
- There are several ways to instantiate your **Page Objects**.
826
+ I18n `.yml` files contain key/value pairs representing the name of a translated string (key) and the string value.
827
+
828
+ Baseline translation strings are stored in `.yml` files in the `config/locales/` folder.
829
+
830
+ my_automation_project
831
+ ├── config
832
+ │ ├── locales
833
+ │ │ ├── en.yml
834
+ │ │ ├── es.yml
835
+ │ │ ├── fr.yml
836
+ │ │ ├── fr-CA.yml
837
+ │ │ └── en-AU.yml
838
+ │ ├── test_data
839
+ │ └── cucumber.yml
840
+ ├── downloads
841
+ ├── features
842
+ ├── Gemfile
843
+ └── README.md
844
+
845
+
846
+
847
+ ## Instantiating your PageObjects
848
+
849
+ Before you can call the methods in your `PageObjects` and `PageSections`, you must instantiate the `PageObjects` of your web
850
+ application, as well as create instance variables which can be used when calling a `PageObject`'s methods from your step definitions.
851
+ There are several ways to instantiate your `PageObjects`.
559
852
 
560
853
  One common implementation is shown below:
561
854
 
@@ -582,14 +875,14 @@ One common implementation is shown below:
582
875
  The `WorldPages` module above can be defined in your `env.rb` file, or you can define it in a separate `world_pages.rb` file in the
583
876
  `features/support` folder.
584
877
 
585
- While this approach is effective for small web applications with only a few pages (and hence few **Page Objects**), it quickly becomes
586
- cumbersome to manage if your web application has dozens of **Page Objects** that need to be instantiated and managed.
878
+ While this approach is effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly becomes
879
+ cumbersome to manage if your web application has dozens of `PageObjects` that need to be instantiated and managed.
587
880
 
588
881
  ### Using the PageManager
589
882
 
590
- The **PageManager** class provides methods for supporting the instantiation and management of **Page Objects**. In the code example below,
591
- the `page_objects` method contains a hash table of your **Page Object** instances and their associated **Page Object** class names
592
- to be instantiated by **PageManager**:
883
+ The `PageManager` class provides methods for supporting the instantiation and management of `PageObjects`. In the code example below,
884
+ the `page_objects` method contains a hash table of your `PageObject` instances and their associated `PageObject` class names to be
885
+ instantiated by `PageManager`:
593
886
 
594
887
  module WorldPages
595
888
  def page_objects
@@ -619,13 +912,13 @@ to be instantiated by **PageManager**:
619
912
 
620
913
  The `WorldPages` module above should be defined in the `world_pages.rb` file in the `features/support` folder.
621
914
 
622
- Include the code below in your `env.rb` file to ensure that your **Page Objects** are instantiated before your Cucumber scenarios are
915
+ Include the code below in your `env.rb` file to ensure that your `PageObjects` are instantiated before your Cucumber scenarios are
623
916
  executed:
624
917
 
625
918
  include WorldPages
626
919
  WorldPages.instantiate_page_objects
627
920
 
628
- **NOTE:** If you intend to use the **PageManager**, you must define a `page_name` trait for each of the **Page Objects** to be registered.
921
+ **NOTE:** If you intend to use the `PageManager`, you must define a `page_name` trait for each of the `PageObjects` to be registered.
629
922
 
630
923
 
631
924
  ### Leveraging the PageManager in your Cucumber tests
@@ -687,14 +980,13 @@ In the above example, the step definitions associated with the 3 steps might be
687
980
  end
688
981
 
689
982
 
983
+ While this approach may be effective for small web applications with only a few pages (and hence few `PageObjects`), it quickly becomes
984
+ cumbersome to manage if your web application has dozens of `PageObjects` that need to be managed.
690
985
 
691
- While this approach may be effective for small web applications with only a few pages (and hence few **Page Objects**), it quickly becomes
692
- cumbersome to manage if your web application has dozens of **Page Objects** that need to be managed.
693
-
694
- The **PageManager** class provides a `find_page` method that replaces the cumbersome and difficult to maintain `case` statement used in the
695
- above example. The **PageManager** `current_page` method allows you to set or get an instance of the currently active Page Object.
986
+ The `PageManager` class provides a `find_page` method that replaces the cumbersome and difficult to maintain `case` statement used in the
987
+ above example. The `PageManager.current_page` method allows you to set or get an instance of the currently active Page Object.
696
988
 
697
- To use these **PageManager** methods, include the step definitions and code below in a `page_steps.rb` or `generic_steps.rb` file in the
989
+ To use these `PageManager` methods, include the step definitions and code below in a `page_steps.rb` or `generic_steps.rb` file in the
698
990
  `features/step_definitions` folder:
699
991
 
700
992
  include TestCentricity
@@ -764,16 +1056,13 @@ To maximize a desktop browser window, you set the `BROWSER_SIZE` Environment Var
764
1056
 
765
1057
  #### Testing file downloads with desktop browsers
766
1058
 
767
- File download functionality can be tested with locally hosted instances of Chrome or Firefox desktop browsers. Your automation project must include
1059
+ File download functionality can be tested with locally hosted instances of Chrome, Edge, or Firefox desktop browsers. Your automation project must include
768
1060
  a `/downloads` folder at the same level as the `/config` and `/features` folders, as depicted below:
769
1061
 
770
1062
  my_automation_project
771
1063
  ├── config
772
- │ └── test_data
773
1064
  ├── downloads
774
1065
  ├── features
775
- │ ├── step_definitions
776
- │ └── support
777
1066
  ├── Gemfile
778
1067
  └── README.md
779
1068
 
@@ -784,15 +1073,12 @@ test thread. This is to ensure that files downloaded in each test thread are iso
784
1073
 
785
1074
  my_automation_project
786
1075
  ├── config
787
- │ └── test_data
788
1076
  ├── downloads
789
1077
  │ ├── 1
790
1078
  │ ├── 2
791
1079
  │ ├── 3
792
1080
  │ └── 4
793
1081
  ├── features
794
- │ ├── step_definitions
795
- │ └── support
796
1082
  ├── Gemfile
797
1083
  └── README.md
798
1084
 
@@ -824,7 +1110,6 @@ the `WEB_BROWSER` Environment Variable must be set to one of the values from the
824
1110
  | `ipad_chrome` | `chrome` | 1024 x 768 | landscape | iOS 12.2 - Mobile Chrome browser for iOS |
825
1111
  | `ipad_firefox` | `chrome` | 1024 x 768 | landscape | iOS 12.2 - Mobile Firefox browser for iOS |
826
1112
  | `ipad_edge` | `chrome` | 1024 x 768 | landscape | iOS 12.2 - Mobile Edge browser for iOS |
827
- | `android_tablet` | `chrome` | 1024 x 768 | landscape | Android 3.0 |
828
1113
  | `kindle_fire` | `chrome` | 1024 x 600 | landscape | |
829
1114
  | `kindle_firehd7` | `chrome` | 800 x 480 | landscape | Fire OS 3 |
830
1115
  | `kindle_firehd8` | `chrome` | 1280 x 800 | landscape | Fire OS 5 |
@@ -851,7 +1136,6 @@ the `WEB_BROWSER` Environment Variable must be set to one of the values from the
851
1136
  | `iphone_11` | `chrome` | 414 x 896 | portrait | iOS 13.1 |
852
1137
  | `iphone_11_pro` | `chrome` | 375 x 812 | portrait | iOS 13.1 |
853
1138
  | `iphone_11_pro_max` | `chrome` | 414 x 896 | portrait | iOS 13.1 |
854
- | `android_phone` | `chrome` | 360 x 640 | portrait | Android 4.2.1 |
855
1139
  | `nexus6` | `chrome` | 411 x 731 | portrait | Android 6 |
856
1140
  | `pixel` | `chrome` | 411 x 731 | portrait | Android 8 |
857
1141
  | `pixel_xl` | `chrome` | 411 x 731 | portrait | Android 8 |
@@ -889,8 +1173,6 @@ of the Chrome desktop browser. The user specified device profiles must be locate
889
1173
  │ └── cucumber.yml
890
1174
  ├── downloads
891
1175
  ├── features
892
- │ ├── step_definitions
893
- │ └── support
894
1176
  ├── Gemfile
895
1177
  └── README.md
896
1178
 
@@ -930,29 +1212,33 @@ The Appium server must be running prior to invoking Cucumber to run your feature
930
1212
 
931
1213
  Once your test environment is properly configured, the following **Environment Variables** must be set as described in the table below.
932
1214
 
933
- | **Environment Variable** | **Description** |
934
- |----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
935
- | `WEB_BROWSER` | Must be set to `appium` |
936
- | `APP_PLATFORM_NAME` | Must be set to `iOS` |
937
- | `APP_BROWSER` | Must be set to `Safari` |
938
- | `APP_VERSION` | Must be set to `12.2`, `11.4`, `10.3.1`, or which ever iOS version you wish to run within the XCode Simulator |
939
- | `APP_DEVICE` | Set to iOS device name supported by the iOS Simulator (`iPhone 6s Plus`, `iPad Pro (10.5-inch)`, `iPad Air 2`, etc.) or name of physically connected iOS device |
940
- | `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
941
- | `APP_UDID` | UDID of physically connected iOS device (not used for simulators) |
942
- | `TEAM_ID` | unique 10-character Apple developer team identifier string (not used for simulators) |
943
- | `TEAM_NAME` | String representing a signing certificate (not used for simulators) |
944
- | `APP_ALLOW_POPUPS` | [Optional] Allow javascript to open new windows in Safari. Set to `true` or `false` |
945
- | `APP_IGNORE_FRAUD_WARNING` | [Optional] Prevent Safari from showing a fraudulent website warning. Set to `true` or `false` |
946
- | `APP_NO_RESET` | [Optional] Don't reset app state after each test. Set to `true` or `false` |
947
- | `APP_FULL_RESET` | [Optional] Perform a complete reset. Set to `true` or `false` |
948
- | `APP_INITIAL_URL` | [Optional] Initial URL, default is a local welcome page. e.g. `http://www.apple.com` |
949
- | `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. |
950
- | `LOCALE` | [Optional] Locale to set for the simulator. e.g. `fr_CA` |
951
- | `LANGUAGE` | [Optional] Language to set for the simulator. e.g. `fr` |
952
- | `ORIENTATION` | [Optional] Set to `portrait` or `landscape` (only for iOS simulators) |
953
- | `NEW_COMMAND_TIMEOUT` | [Optional] Time (in Seconds) that Appium will wait for a new command from the client |
954
- | `SHOW_SIM_KEYBOARD` | [Optional] Show the simulator keyboard during text entry. Set to `true` or `false` |
955
- | `SHUTDOWN_OTHER_SIMS` | [Optional] Close any other running simulators. Set to `true` or `false` |
1215
+ | **Environment Variable** | **Description** |
1216
+ |----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1217
+ | `WEB_BROWSER` | Must be set to `appium` |
1218
+ | `APP_PLATFORM_NAME` | Must be set to `iOS` |
1219
+ | `APP_BROWSER` | Must be set to `Safari` |
1220
+ | `APP_VERSION` | Must be set to `15.2`, `14.5`, or which ever iOS version you wish to run within the XCode Simulator |
1221
+ | `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 |
1222
+ | `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
1223
+ | `APP_UDID` | UDID of physically connected iOS device (not used for simulators) |
1224
+ | `TEAM_ID` | unique 10-character Apple developer team identifier string (not used for simulators) |
1225
+ | `TEAM_NAME` | String representing a signing certificate (not used for simulators) |
1226
+ | `APP_ALLOW_POPUPS` | [Optional] Allow javascript to open new windows in Safari. Set to `true` or `false` |
1227
+ | `APP_IGNORE_FRAUD_WARNING` | [Optional] Prevent Safari from showing a fraudulent website warning. Set to `true` or `false` |
1228
+ | `APP_NO_RESET` | [Optional] Don't reset app state after each test. Set to `true` or `false` |
1229
+ | `APP_FULL_RESET` | [Optional] Perform a complete reset. Set to `true` or `false` |
1230
+ | `APP_INITIAL_URL` | [Optional] Initial URL, default is a local welcome page. e.g. `http://www.apple.com` |
1231
+ | `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. |
1232
+ | `LOCALE` | [Optional] Locale to set for the simulator. e.g. `fr_CA` |
1233
+ | `LANGUAGE` | [Optional] Language to set for the simulator. e.g. `fr` |
1234
+ | `ORIENTATION` | [Optional] Set to `portrait` or `landscape` (only for iOS simulators) |
1235
+ | `NEW_COMMAND_TIMEOUT` | [Optional] Time (in Seconds) that Appium will wait for a new command from the client |
1236
+ | `SHOW_SIM_KEYBOARD` | [Optional] Show the simulator keyboard during text entry. Set to `true` or `false` |
1237
+ | `SHUTDOWN_OTHER_SIMS` | [Optional] Close any other running simulators. Set to `true` or `false`. See note below. |
1238
+
1239
+ The `SHUTDOWN_OTHER_SIMS` environment variable can only be set if you are running Appium Server with the `--relaxed-security` or
1240
+ `--allow-insecure=shutdown_other_sims` arguments passed when starting it from the command line, or when running the server from the
1241
+ Appium Server GUI app. A security violation error will occur without relaxed secutity enabled.
956
1242
 
957
1243
  Refer to **section 8.7 (Using Browser specific Profiles in cucumber.yml)** below.
958
1244
 
@@ -1127,26 +1413,28 @@ Below is a list of Cucumber **Profiles** for supported locally and remotely host
1127
1413
  that you intend to connect with.
1128
1414
 
1129
1415
 
1130
- <% desktop = "--tags @desktop --require features BROWSER_TILE=true BROWSER_SIZE=1500,1000" %>
1131
- <% tablet = "--tags @desktop --require features BROWSER_TILE=true" %>
1132
- <% mobile = "--tags @mobile --require features BROWSER_TILE=true" %>
1416
+ <% desktop = "--tags @desktop --require features BROWSER_TILE=true BROWSER_SIZE=1500,1000" %>
1417
+ <% tablet = "--tags @desktop --require features BROWSER_TILE=true" %>
1418
+ <% mobile = "--tags @mobile --require features BROWSER_TILE=true" %>
1133
1419
 
1134
1420
  #==============
1135
1421
  # profiles for locally hosted desktop web browsers
1136
1422
  #==============
1137
1423
 
1138
- firefox: WEB_BROWSER=firefox <%= desktop %>
1139
- chrome: WEB_BROWSER=chrome <%= desktop %>
1140
- safari: WEB_BROWSER=safari <%= desktop %>
1141
- ie: WEB_BROWSER=ie <%= desktop %>
1424
+ firefox: WEB_BROWSER=firefox <%= desktop %>
1425
+ chrome: WEB_BROWSER=chrome <%= desktop %>
1426
+ edge: WEB_BROWSER=edge <%= desktop %>
1427
+ safari: WEB_BROWSER=safari <%= desktop %>
1428
+ ie: WEB_BROWSER=ie <%= desktop %>
1142
1429
 
1143
- chrome_headless: WEB_BROWSER=chrome_headless <%= desktop %>
1144
- firefox_headless: WEB_BROWSER=firefox_headless <%= desktop %>
1430
+ firefox_headless: WEB_BROWSER=firefox_headless <%= desktop %>
1431
+ chrome_headless: WEB_BROWSER=chrome_headless <%= desktop %>
1432
+ edge_headless: WEB_BROWSER=edge_headless <%= desktop %>
1145
1433
 
1146
1434
  #==============
1147
1435
  # profile for Selenium Grid and Dockerized Selenium Grid hosted desktop web browsers
1148
1436
  #==============
1149
- grid: SELENIUM=remote REMOTE_ENDPOINT="http://localhost:4444/wd/hub"
1437
+ grid: SELENIUM=remote REMOTE_ENDPOINT="http://localhost:4444/wd/hub"
1150
1438
 
1151
1439
 
1152
1440
  #==============
@@ -1180,9 +1468,7 @@ that you intend to connect with.
1180
1468
  iphone_11: WEB_BROWSER=iphone_11 HOST_BROWSER=chrome <%= mobile %>
1181
1469
  iphone_11_pro: WEB_BROWSER=iphone_11_pro HOST_BROWSER=chrome <%= mobile %>
1182
1470
  iphone_11_pro_max: WEB_BROWSER=iphone_11_pro_max HOST_BROWSER=chrome <%= mobile %>
1183
- android_phone: WEB_BROWSER=android_phone HOST_BROWSER=chrome <%= mobile %>
1184
1471
  nexus6: WEB_BROWSER=nexus6 HOST_BROWSER=chrome <%= mobile %>
1185
- android_tablet: WEB_BROWSER=android_tablet HOST_BROWSER=chrome <%= tablet %>
1186
1472
  kindle_fire: WEB_BROWSER=kindle_fire HOST_BROWSER=chrome <%= tablet %>
1187
1473
  kindle_firehd7: WEB_BROWSER=kindle_firehd7 HOST_BROWSER=chrome <%= tablet %>
1188
1474
  kindle_firehd8: WEB_BROWSER=kindle_firehd8 HOST_BROWSER=chrome <%= tablet %>
@@ -1211,43 +1497,19 @@ that you intend to connect with.
1211
1497
  # profiles for mobile device screen orientation
1212
1498
  #==============
1213
1499
 
1214
- portrait: ORIENTATION=portrait
1215
- landscape: ORIENTATION=landscape
1500
+ portrait: ORIENTATION=portrait
1501
+ landscape: ORIENTATION=landscape
1216
1502
 
1217
1503
 
1218
1504
  #==============
1219
1505
  # profiles for mobile Safari web browsers hosted within XCode iOS simulator
1220
1506
  # NOTE: Requires installation of XCode, iOS version specific target simulators, Appium, and the appium_capybara gem
1221
1507
  #==============
1222
-
1223
- appium_ios: WEB_BROWSER=appium APP_PLATFORM_NAME="iOS" APP_BROWSER="Safari" <%= mobile %>
1224
- app_ios_10: --profile appium_ios APP_VERSION="10.3"
1225
- app_ios_11: --profile appium_ios APP_VERSION="11.2"
1226
-
1227
- iphone_7_plus_10_sim: --profile app_ios_10 DEVICE_TYPE=phone APP_DEVICE="iPhone 7 Plus"
1228
- iphone_7_10_sim: --profile app_ios_10 DEVICE_TYPE=phone APP_DEVICE="iPhone 7"
1229
- iphone_7se_10_sim: --profile app_ios_10 DEVICE_TYPE=phone APP_DEVICE="iPhone SE"
1230
- iphone_6s_plus_10_sim: --profile app_ios_10 DEVICE_TYPE=phone APP_DEVICE="iPhone 6s Plus"
1231
- iphone_6s_10_sim: --profile app_ios_10 DEVICE_TYPE=phone APP_DEVICE="iPhone 6s"
1232
- iphone_SE_10_sim: --profile app_ios_10 DEVICE_TYPE=phone APP_DEVICE="iPhone SE"
1233
- iphone_X_11_sim: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="iPhone X"
1234
- iphone_8_11_sim: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="iPhone 8"
1235
- iphone_8_plus_11_sim: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="iPhone 8 Plus"
1236
- iphone_7_plus_11_sim: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="iPhone 7 Plus"
1237
- iphone_7_11_sim: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="iPhone 7"
1238
- iphone_7se_11_sim: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="iPhone SE"
1239
- iphone_6s_plus_11_sim: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="iPhone 6s Plus"
1240
- iphone_6s_11_sim: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="iPhone 6s"
1241
- iphone_SE_11_sim: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="iPhone SE"
1242
-
1243
- ipad_pro_12_9_11_sim: --profile app_ios_11 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (12.9-inch)"
1244
- ipad_pro_12_9_10_sim: --profile app_ios_10 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (12.9-inch)"
1245
- ipad_pro_10_5_11_sim: --profile app_ios_11 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (10.5-inch)"
1246
- ipad_pro_10_5_10_sim: --profile app_ios_10 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (10.5-inch)"
1247
- ipad_pro_9_7_11_sim: --profile app_ios_11 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (9.7-inch)"
1248
- ipad_pro_9_7_10_sim: --profile app_ios_10 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (9.7-inch)"
1249
- ipad_air_2_11_sim: --profile app_ios_11 DEVICE_TYPE=tablet APP_DEVICE="iPad Air 2"
1250
- ipad_air_2_10_sim: --profile app_ios_10 DEVICE_TYPE=tablet APP_DEVICE="iPad Air 2"
1508
+
1509
+ appium_ios: WEB_BROWSER=appium AUTOMATION_ENGINE=XCUITest APP_PLATFORM_NAME="ios" APP_BROWSER="Safari" NEW_COMMAND_TIMEOUT=30 SHOW_SIM_KEYBOARD=false
1510
+ app_ios_15: --profile appium_ios APP_VERSION="15.2"
1511
+ ipad_pro_12_9_15_sim: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (12.9-inch) (5th generation)" <%= desktop %>
1512
+ ipad_air_15_sim: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad Air (4th generation)" <%= desktop %>
1251
1513
 
1252
1514
 
1253
1515
  #==============
@@ -1255,227 +1517,110 @@ that you intend to connect with.
1255
1517
  # NOTE: Requires installation of XCode, Appium, and the appium_capybara gem
1256
1518
  #==============
1257
1519
 
1258
- my_ios_11_3_iphone: --profile app_ios_11 DEVICE_TYPE=phone APP_DEVICE="My Test iPhoneX" APP_UDID="INSERT YOUR DEVICE UDID"
1259
- my_ios_10_3_ipad: --profile app_ios_10 DEVICE_TYPE=tablet APP_DEVICE="My Test iPad Pro" APP_UDID="INSERT YOUR DEVICE UDID"
1520
+ my_ios_15_iphone: --profile app_ios_15 DEVICE_TYPE=phone APP_DEVICE="My Test iPhoneX" APP_UDID="INSERT YOUR DEVICE UDID"
1521
+ my_ios_15_ipad: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="My Test iPad Pro" APP_UDID="INSERT YOUR DEVICE UDID"
1260
1522
 
1261
1523
 
1262
1524
  #==============
1263
1525
  # profiles for Android mobile web browsers hosted within Android Studio Android Virtual Device emulators
1264
1526
  # NOTE: Requires installation of Android Studio, Android version specific virtual device simulators, Appium, and the appium_capybara gem
1265
1527
  #==============
1266
-
1267
- appium_android: WEB_BROWSER=appium APP_PLATFORM_NAME="Android" <%= mobile %>
1268
- android_api_26: --profile appium_android APP_BROWSER="Chrome" APP_VERSION="8.0"
1269
- android_api_23: --profile appium_android APP_BROWSER="Browser" APP_VERSION="6.0"
1270
- pixel_xl_api26_sim: --profile android_api_26 DEVICE_TYPE=phone APP_DEVICE="Pixel_XL_API_26"
1271
- pixel_2_xl_api26_sim: --profile android_api_26 DEVICE_TYPE=phone APP_DEVICE="Pixel_2_XL_API_26"
1272
- nexus_6_api23_sim: --profile android_api_23 DEVICE_TYPE=phone APP_DEVICE="Nexus_6_API_23"
1528
+
1529
+ appium_android: WEB_BROWSER=appium APP_PLATFORM_NAME="Android" <%= mobile %>
1530
+ app_android_12: --profile appium_android APP_BROWSER="Chrome" APP_VERSION="12.0"
1531
+ pixel_c_api31_sim: --profile app_android_12 DEVICE_TYPE=tablet APP_DEVICE="Pixel_C_API_31"
1532
+
1273
1533
 
1274
1534
  #==============
1275
1535
  # profiles for remotely hosted web browsers on the BrowserStack service
1276
1536
  #==============
1277
1537
 
1278
- browserstack: WEB_BROWSER=browserstack BS_USERNAME="<INSERT USER NAME HERE>" BS_AUTHKEY="<INSERT PASSWORD HERE>"
1279
- bs_desktop: --profile browserstack <%= desktop %> RESOLUTION="1920x1080"
1280
- bs_mobile: --profile browserstack <%= mobile %>
1281
-
1282
- # BrowserStack OS X desktop browser profiles
1283
- bs_macos_mojave: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="Mojave"
1284
- bs_ff_mojave: --profile bs_macos_mojave BS_BROWSER="Firefox"
1285
- bs_chrome_mojave: --profile bs_macos_mojave BS_BROWSER="Chrome"
1286
- bs_safari_mojave: --profile bs_macos_mojave BS_BROWSER="Safari"
1287
-
1288
- bs_macos_high_sierra: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="High Sierra"
1289
- bs_ff_high_sierra: --profile bs_macos_high_sierra BS_BROWSER="Firefox"
1290
- bs_chrome_high_sierra: --profile bs_macos_high_sierra BS_BROWSER="Chrome"
1291
- bs_safari_high_sierra: --profile bs_macos_high_sierra BS_BROWSER="Safari"
1292
-
1293
- bs_macos_sierra: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="Sierra"
1294
- bs_ff_sierra: --profile bs_macos_sierra BS_BROWSER="Firefox"
1295
- bs_chrome_sierra: --profile bs_macos_sierra BS_BROWSER="Chrome"
1296
- bs_safari_sierra: --profile bs_macos_sierra BS_BROWSER="Safari"
1297
-
1298
- bs_osx_el_capitan: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="El Capitan"
1299
- bs_ff_el_cap: --profile bs_osx_el_capitan BS_BROWSER="Firefox"
1300
- bs_chrome_el_cap: --profile bs_osx_el_capitan BS_BROWSER="Chrome"
1301
- bs_safari_el_cap: --profile bs_osx_el_capitan BS_BROWSER="Safari"
1302
-
1303
- bs_osx_yosemite: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="Yosemite"
1304
- bs_ff_yos: --profile bs_osx_yosemite BS_BROWSER="Firefox"
1305
- bs_chrome_yos: --profile bs_osx_yosemite BS_BROWSER="Chrome"
1306
- bs_safari_yos: --profile bs_osx_yosemite BS_BROWSER="Safari"
1538
+ browserstack: WEB_BROWSER=browserstack BS_USERNAME="<INSERT USER NAME HERE>" BS_AUTHKEY="<INSERT PASSWORD HERE>"
1539
+ bs_desktop: --profile browserstack <%= desktop %> RESOLUTION="1920x1080"
1540
+ bs_mobile: --profile browserstack <%= mobile %>
1307
1541
 
1542
+ # BrowserStack macOS desktop browser profiles
1543
+ bs_macos_monterey: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="Monterey"
1544
+ bs_chrome_monterey: --profile bs_macos_monterey BS_BROWSER="Chrome" BS_VERSION="latest"
1545
+ bs_edge_monterey: --profile bs_macos_monterey BS_BROWSER="Edge" BS_VERSION="latest"
1546
+ bs_safari_monterey: --profile bs_macos_monterey BS_BROWSER="Safari" BS_VERSION="latest"
1547
+
1308
1548
  # BrowserStack Windows desktop browser profiles
1309
- bs_win8: --profile bs_desktop BS_OS="Windows" BS_OS_VERSION="8"
1310
- bs_win10: --profile bs_desktop BS_OS="Windows" BS_OS_VERSION="10"
1311
- bs_ff_win8: --profile bs_win8 BS_BROWSER="Firefox"
1312
- bs_ff_win10: --profile bs_win10 BS_BROWSER="Firefox"
1313
- bs_chrome_win8: --profile bs_win8 BS_BROWSER="Chrome"
1314
- bs_chrome_win10: --profile bs_win10 BS_BROWSER="Chrome"
1315
-
1316
- bs_ie10_win8: --profile bs_win8 BS_BROWSER="IE" BS_VERSION="10.0"
1317
- bs_ie11_win8: --profile bs_desktop BS_OS="Windows" BS_OS_VERSION="8.1" BS_BROWSER="IE" BS_VERSION="11.0"
1318
- bs_ie11_win10: --profile bs_win10 BS_BROWSER="IE" BS_VERSION="11.0"
1319
- bs_edge_win10: --profile bs_win10 BS_BROWSER="Edge" BS_VERSION="15.0"
1320
-
1549
+ bs_win11: --profile bs_desktop BS_OS="Windows" BS_OS_VERSION="11"
1550
+ bs_chrome_win11: --profile bs_win11 BS_BROWSER="Chrome" BS_VERSION="latest"
1551
+ bs_edge_win11: --profile bs_win11 BS_BROWSER="Edge" BS_VERSION="latest"
1552
+ bs_win10: --profile bs_desktop BS_OS="Windows" BS_OS_VERSION="10"
1553
+ bs_ie_win10: --profile bs_win10 BS_BROWSER="IE" BS_VERSION="11.0"
1554
+
1321
1555
  # BrowserStack iOS mobile browser profiles
1322
- bs_iphone: --profile bs_mobile BS_PLATFORM=MAC BS_OS=ios BS_BROWSER=iPhone DEVICE_TYPE=phone
1323
- bs_iphone6s_plus: --profile bs_iphone BS_DEVICE="iPhone 6S Plus"
1324
- bs_iphone6s: --profile bs_iphone BS_DEVICE="iPhone 6S"
1325
- bs_iphone6_plus: --profile bs_iphone BS_DEVICE="iPhone 6 Plus"
1326
- bs_iphone6: --profile bs_iphone BS_DEVICE="iPhone 6"
1327
- bs_iphone5s: --profile bs_iphone BS_DEVICE="iPhone 5S"
1328
- bs_iphone4s: --profile bs_iphone BS_DEVICE="iPhone 4S (6.0)"
1329
-
1330
- bs_ipad: --profile bs_mobile BS_PLATFORM=MAC BS_BROWSER=iPad DEVICE_TYPE=tablet
1331
- bs_ipad_pro: --profile bs_ipad BS_DEVICE="iPad Pro"
1332
- bs_ipad_air2: --profile bs_ipad BS_DEVICE="iPad Air 2"
1333
- bs_ipad_air: --profile bs_ipad BS_DEVICE="iPad Air"
1334
- bs_ipad_mini: --profile bs_ipad BS_DEVICE="iPad Mini 4"
1335
-
1336
- # BrowserStack iOS real device mobile browser profiles
1337
- bs_iphone_device: --profile bs_iphone BS_REAL_MOBILE="true"
1338
- bs_iphoneX: --profile bs_iphone_device BS_OS_VERSION="11.0" BS_DEVICE="iPhone X"
1339
- bs_iphone8_plus: --profile bs_iphone_device BS_OS_VERSION="11.0" BS_DEVICE="iPhone 8 Plus"
1340
- bs_iphone8: --profile bs_iphone_device BS_OS_VERSION="11.0" BS_DEVICE="iPhone 8"
1341
- bs_iphone7_plus: --profile bs_iphone_device BS_OS_VERSION="10.3" BS_DEVICE="iPhone 7 Plus"
1342
- bs_iphone7: --profile bs_iphone_device BS_OS_VERSION="10.3" BS_DEVICE="iPhone 7"
1343
-
1344
- bs_ipad_device: --profile bs_ipad BS_REAL_MOBILE="true"
1345
- bs_ipad5: --profile bs_ipad_device BS_OS_VERSION="11.0" BS_DEVICE="iPad 5th"
1556
+ bs_ipad: --profile bs_mobile BS_OS=ios BS_BROWSER=Safari DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
1557
+ bs_ipad_pro_12: --profile bs_ipad BS_DEVICE="iPad Pro 12.9 2018" BS_OS_VERSION="15"
1346
1558
 
1347
1559
  # BrowserStack Android mobile browser profiles
1348
- bs_android: --profile bs_mobile BS_PLATFORM=ANDROID BS_BROWSER=android BS_OS=android
1349
- bs_android_phone: --profile bs_android DEVICE_TYPE=phone
1350
- bs_galaxy_s5: --profile bs_android_phone BS_DEVICE="Samsung Galaxy S5"
1351
- bs_nexus5: --profile bs_android_phone BS_DEVICE="Google Nexus 5"
1352
- bs_moto_razr: --profile bs_android_phone BS_DEVICE="Motorola Razr"
1353
- bs_sony_xperia: --profile bs_android_phone BS_DEVICE="Sony Xperia Tipo"
1354
-
1355
- bs_android_tablet: --profile bs_android DEVICE_TYPE=tablet
1356
- bs_kindle_fire_hd89: --profile bs_android_tablet BS_DEVICE="Amazon Kindle Fire HD 8.9"
1357
- bs_kindle_fire_hdx7: --profile bs_android_tablet BS_DEVICE="Amazon Kindle Fire HDX 7"
1358
- bs_kindle_fire2: --profile bs_android_tablet BS_DEVICE="Amazon Kindle Fire 2"
1359
- bs_nexus7: --profile bs_android_tablet BS_DEVICE="Google Nexus 7"
1360
-
1361
- # BrowserStack Android real device mobile browser profiles
1362
- bs_android_device: --profile bs_mobile BS_BROWSER=android BS_OS=android BS_REAL_MOBILE="true"
1363
- bs_google_pixel8: --profile bs_android_device BS_DEVICE="Google Pixel" BS_OS_VERSION="8.0" DEVICE_TYPE=phone
1364
- bs_google_pixel71: --profile bs_android_device BS_DEVICE="Google Pixel" BS_OS_VERSION="7.1" DEVICE_TYPE=phone
1365
- bs_nexus6: --profile bs_android_device BS_DEVICE="Google Nexus 6" DEVICE_TYPE=phone
1366
- bs_galaxy_s8_plus: --profile bs_android_device BS_DEVICE="Samsung Galaxy S8 Plus" DEVICE_TYPE=phone
1367
- bs_galaxy_s8: --profile bs_android_device BS_DEVICE="Samsung Galaxy S8" DEVICE_TYPE=phone
1368
- bs_galaxy_s7: --profile bs_android_device BS_DEVICE="Samsung Galaxy S7" DEVICE_TYPE=phone
1369
- bs_galaxy_s6: --profile bs_android_device BS_DEVICE="Samsung Galaxy S6" DEVICE_TYPE=phone
1370
- bs_galaxy_note4: --profile bs_android_device BS_DEVICE="Samsung Galaxy Note 4" DEVICE_TYPE=tablet
1371
- bs_nexus9: --profile bs_android_device BS_DEVICE="Google Nexus 9" DEVICE_TYPE=tablet
1560
+ bs_android: --profile bs_mobile BS_OS=android BS_BROWSER=Chrome DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
1561
+ bs_android_tablet: --profile bs_android BS_DEVICE="Samsung Galaxy Tab S7" BS_OS_VERSION="10.0"
1372
1562
 
1373
1563
 
1374
1564
  #==============
1375
1565
  # profiles for remotely hosted web browsers on the SauceLabs service
1376
1566
  #==============
1377
1567
 
1378
- saucelabs: WEB_BROWSER=saucelabs SL_USERNAME="<INSERT USER NAME HERE>" SL_AUTHKEY="<INSERT PASSWORD HERE>"
1379
- sl_desktop: --profile saucelabs <%= desktop %>
1380
-
1381
- # SauceLabs OS X desktop browser profiles
1382
- sl_osx_sierra: --profile sl_desktop SL_OS="macOS 10.12"
1383
- sl_ff_sierra: --profile sl_osx_sierra SL_BROWSER="firefox"
1384
- sl_chrome_sierra: --profile sl_osx_sierra SL_BROWSER="chrome"
1385
- sl_safari_sierra: --profile sl_osx_sierra SL_BROWSER="safari"
1386
-
1387
- sl_osx_el_capitan: --profile sl_desktop SL_OS="OS X 10.11"
1388
- sl_ff_el_cap: --profile sl_osx_el_capitan SL_BROWSER="firefox"
1389
- sl_chrome_el_cap: --profile sl_osx_el_capitan SL_BROWSER="chrome"
1390
- sl_safari_el_cap: --profile sl_osx_el_capitan SL_BROWSER="safari"
1568
+ saucelabs: WEB_BROWSER=saucelabs SL_USERNAME="<INSERT USER NAME HERE>" SL_AUTHKEY="<INSERT PASSWORD HERE>" DATA_CENTER="<INSERT DATA CENTER HERE"
1569
+ sl_desktop: --profile saucelabs <%= desktop %>
1570
+ sl_mobile: --profile saucelabs <%= mobile %>
1391
1571
 
1392
- sl_osx_yosemite: --profile sl_desktop SL_OS="OS X 10.10" RESOLUTION="1920x1200"
1393
- sl_ff_yos: --profile sl_osx_yosemite SL_BROWSER="firefox"
1394
- sl_chrome_yos: --profile sl_osx_yosemite SL_BROWSER="chrome"
1395
- sl_safari_yos: --profile sl_osx_yosemite SL_BROWSER="safari"
1572
+ # SauceLabs macOS desktop browser profiles
1573
+ sl_macos_monterey: --profile sl_desktop SL_OS="macOS 12" RESOLUTION="1920x1440"
1574
+ sl_chrome_monterey: --profile sl_macos_monterey SL_BROWSER="chrome" SL_VERSION="latest"
1575
+ sl_edge_monterey: --profile sl_macos_monterey SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
1576
+ sl_firefox_monterey: --profile sl_macos_monterey SL_BROWSER="Firefox" SL_VERSION="latest"
1396
1577
 
1397
1578
  # SauceLabs Windows desktop browser profiles
1398
- sl_win8: --profile sl_desktop SL_OS="Windows 8.1" RESOLUTION="1280x1024"
1399
- sl_win10: --profile sl_desktop SL_OS="Windows 10" RESOLUTION="1280x1024"
1400
- sl_ff_win8: --profile sl_win8 SL_BROWSER="firefox"
1401
- sl_ff_win10: --profile sl_win10 SL_BROWSER="firefox"
1402
- sl_chrome_win8: --profile sl_win8 SL_BROWSER="chrome"
1403
- sl_chrome_win10: --profile sl_win10 SL_BROWSER="chrome"
1579
+ sl_windows: --profile sl_desktop RESOLUTION="1920x1200"
1580
+ sl_edge_win11: --profile sl_windows SL_OS="Windows 11" SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
1581
+ sl_ie_win10: --profile sl_windows SL_OS="Windows 10" SL_BROWSER="internet explorer" SL_VERSION="11"
1404
1582
 
1405
- sl_ie11_win8: --profile sl_win8 SL_BROWSER="internet explorer" SL_VERSION="11.0"
1406
- sl_ie11_win10: --profile sl_win10 SL_BROWSER="internet explorer"
1583
+ # SauceLabs iOS mobile browser profiles
1584
+ sl_ipad: --profile sl_mobile DEVICE_TYPE=tablet SL_PLATFORM=iOS SL_BROWSER=Safari
1585
+ sl_ipad_pro_12: --profile sl_ipad SL_DEVICE="iPad Pro (12.9 inch) (5th generation) Simulator" SL_VERSION="15.0"
1407
1586
 
1408
1587
 
1409
1588
  #==============
1410
1589
  # profiles for remotely hosted web browsers on the TestingBot service
1411
1590
  #==============
1412
1591
 
1413
- testingbot: WEB_BROWSER=testingbot TB_USERNAME="<INSERT USER NAME HERE>" TB_AUTHKEY="<INSERT PASSWORD HERE>"
1414
- tb_desktop: --profile testingbot <%= desktop %> RESOLUTION="1920x1200"
1415
- tb_mobile: --profile testingbot <%= mobile %>
1592
+ testingbot: WEB_BROWSER=testingbot TB_USERNAME="<INSERT USER NAME HERE>" TB_AUTHKEY="<INSERT PASSWORD HERE>"
1593
+ tb_desktop: --profile testingbot <%= desktop %> RESOLUTION="1920x1200"
1416
1594
 
1417
- # TestingBot OS X desktop browser profiles
1418
- tb_macos_sierra: --profile tb_desktop TB_OS="SIERRA"
1419
- tb_ff_sierra: --profile tb_macos_sierra TB_BROWSER="firefox"
1420
- tb_chrome_sierra: --profile tb_macos_sierra TB_BROWSER="chrome"
1421
- tb_safari_sierra: --profile tb_macos_sierra TB_BROWSER="safari" TB_VERSION="10"
1422
-
1423
- tb_osx_el_capitan: --profile tb_desktop TB_OS="CAPITAN"
1424
- tb_ff_el_cap: --profile tb_osx_el_capitan TB_BROWSER="firefox"
1425
- tb_chrome_el_cap: --profile tb_osx_el_capitan TB_BROWSER="chrome"
1426
- tb_safari_el_cap: --profile tb_osx_el_capitan TB_BROWSER="safari" TB_VERSION="9"
1427
-
1428
- tb_osx_yosemite: --profile tb_desktop TB_OS="YOSEMITE"
1429
- tb_ff_yos: --profile tb_osx_yosemite TB_BROWSER="firefox"
1430
- tb_chrome_yos: --profile tb_osx_yosemite TB_BROWSER="chrome"
1431
- tb_safari_yos: --profile tb_osx_yosemite TB_BROWSER="safari" TB_VERSION="8"
1595
+ # TestingBot macOS desktop browser profiles
1596
+ tb_macos_monterey: --profile tb_desktop TB_OS="MONTEREY"
1597
+ tb_chrome_monterey: --profile tb_macos_monterey TB_BROWSER="chrome" TB_VERSION="latest"
1598
+ tb_edge_monterey: --profile tb_macos_monterey TB_BROWSER="microsoftedge" TB_VERSION="latest"
1432
1599
 
1433
1600
  # TestingBot Windows desktop browser profiles
1434
- tb_win8: --profile tb_desktop TB_OS="WIN8"
1435
- tb_win10: --profile tb_desktop TB_OS="WIN10"
1436
- tb_ff_win8: --profile tb_win8 TB_BROWSER="firefox"
1437
- tb_ff_win10: --profile tb_win10 TB_BROWSER="firefox"
1438
- tb_chrome_win8: --profile tb_win8 TB_BROWSER="chrome"
1439
- tb_chrome_win10: --profile tb_win10 TB_BROWSER="chrome"
1440
-
1441
- tb_ie11_win8: --profile tb_win8 TB_BROWSER="internet explorer" TB_VERSION="11"
1442
- tb_ie10_win8: --profile tb_win8 TB_BROWSER="internet explorer" TB_VERSION="10"
1443
- tb_ie11_win10: --profile tb_win10 TB_BROWSER="internet explorer" TB_VERSION="11"
1444
- tb_edge_win10: --profile tb_win10 TB_BROWSER="microsoftedge" TB_VERSION="14"
1601
+ tb_win11: --profile tb_desktop TB_OS="WIN11"
1602
+ tb_edge_win11: --profile tb_win11 TB_BROWSER="microsoftedge" TB_VERSION="latest"
1603
+ tb_win10: --profile tb_desktop TB_OS="WIN10"
1604
+ tb_ie_win10: --profile tb_win10 TB_BROWSER="internet explorer" TB_VERSION="11"
1445
1605
 
1446
1606
 
1447
1607
  #==============
1448
1608
  # profiles for remotely hosted web browsers on the LambdaTest service
1449
1609
  #==============
1450
1610
 
1451
- lambdatest: WEB_BROWSER=lambdatest LT_USERNAME=<INSERT USER NAME HERE> LT_AUTHKEY=<INSERT PASSWORD HERE>
1452
- lt_desktop: --profile lambdatest <%= desktop %> RESOLUTION="1920x1080"
1453
- lt_firefox: LT_BROWSER="Firefox" LT_VERSION="67.0"
1454
- lt_chrome: LT_BROWSER="Chrome" LT_VERSION="76.0"
1455
- lt_safari: LT_BROWSER="Safari" ALLOW_COOKIES="true" ALLOW_POPUPS="true"
1611
+ lambdatest: WEB_BROWSER=lambdatest LT_USERNAME=<INSERT USER NAME HERE> LT_AUTHKEY=<INSERT PASSWORD HERE>
1612
+ lt_desktop: --profile lambdatest <%= desktop %> RESOLUTION="2560x1440"
1456
1613
 
1457
- # LambdaTest OS X desktop browser profiles
1458
- lt_macos_mojave: --profile lt_desktop LT_OS="macOS Mojave"
1459
- lt_ff_mojave: --profile lt_macos_mojave --profile lt_firefox
1460
- lt_chrome_mojave: --profile lt_macos_mojave --profile lt_chrome
1461
- lt_safari_mojave: --profile lt_macos_mojave --profile lt_safari LT_VERSION="12.0"
1462
-
1463
- lt_macos_high_sierra: --profile lt_desktop LT_OS="macOS High Sierra"
1464
- lt_ff_high_sierra: --profile lt_macos_high_sierra --profile lt_firefox
1465
- lt_chrome_high_sierra: --profile lt_macos_high_sierra --profile lt_chrome
1466
- lt_safari_high_sierra: --profile lt_macos_high_sierra --profile lt_safari LT_VERSION="11.0"
1467
-
1468
- lt_macos_sierra: --profile lt_desktop LT_OS="macOS Sierra"
1469
- lt_ff_sierra: --profile lt_macos_sierra --profile lt_firefox
1470
- lt_chrome_sierra: --profile lt_macos_sierra --profile lt_chrome
1471
- lt_safari_sierra: --profile lt_macos_sierra --profile lt_safari LT_VERSION="10.0"
1614
+ # LambdaTest macOS desktop browser profiles
1615
+ lt_macos_monterey: --profile lt_desktop LT_OS="MacOS Monterey"
1616
+ lt_chrome_monterey: --profile lt_macos_monterey LT_BROWSER="Chrome" LT_VERSION="98.0"
1617
+ lt_edge_monterey: --profile lt_macos_monterey LT_BROWSER="MicrosoftEdge" LT_VERSION="97.0"
1472
1618
 
1473
1619
  # LambdaTest Windows desktop browser profiles
1474
- lt_win10: --profile lt_desktop LT_OS="Windows 10"
1475
- lt_ff_win10: --profile lt_win10 --profile lt_firefox
1476
- lt_chrome_win10: --profile lt_win10 --profile lt_chrome
1477
- lt_ie11_win10: --profile lt_win10 LT_BROWSER="Internet Explorer" LT_VERSION="11.0"
1478
- lt_edge_win10: --profile lt_win10 LT_BROWSER="MicrosoftEdge" LT_VERSION="18.0"
1620
+ lt_win11: --profile lt_desktop LT_OS="Windows 11"
1621
+ lt_edge_win11: --profile lt_win11 LT_BROWSER="MicrosoftEdge" LT_VERSION="98.0"
1622
+ lt_win10: --profile lt_desktop LT_OS="Windows 10"
1623
+ lt_i0_win11: --profile lt_win10 LT_BROWSER="Internet Explorer" LT_VERSION="11.0"
1479
1624
 
1480
1625
 
1481
1626
  To specify a locally hosted target browser using a profile at runtime, you use the flag `--profile` or `-p` followed by the profile name when
@@ -1517,10 +1662,34 @@ landscape orientation running on the BrowserStack service:
1517
1662
 
1518
1663
 
1519
1664
 
1520
- ## Web Test Automation Framework Implementation
1665
+ ## Recommended Project Organization and Structure
1666
+
1667
+ Below is an example of the project structure of a typical Cucumber based test automation framework with a Page Object Model
1668
+ architecture. `PageObject` class definitions should be stored in the `/features/support/pages` folder, organized in functional
1669
+ area sub-folders as needed. Likewise, `PageSection` class definitions should be stored in the `/features/support/sections` folder.
1670
+
1671
+ my_automation_project
1672
+ ├── config
1673
+ │ ├── locales
1674
+ │ ├── test_data
1675
+ │ └── cucumber.yml
1676
+ ├── downloads
1677
+ ├── features
1678
+ │ ├── step_definitions
1679
+ │ └── support
1680
+ │ │ ├── pages
1681
+ │ │ ├── sections
1682
+ │ │ ├── env.rb
1683
+ │ │ ├── hooks.rb
1684
+ │ │ └── world_pages.rb
1685
+ ├── Gemfile
1686
+ └── README.md
1687
+
1521
1688
 
1522
- ![TestCentricity Web Framework Overview](/doc/images/TC_Web.jpg)
1523
1689
 
1690
+ ## Web Test Automation Framework Implementation
1691
+
1692
+ <img src="https://i.imgur.com/eukmEan.jpg" alt="TestCentricity Web Framework Overview" title="TestCentricity Web Framework Overview">
1524
1693
 
1525
1694
 
1526
1695