testcentricity_web 4.1.2.1 → 4.1.5

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