testcentricity_web 4.1.4 → 4.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/Gemfile.lock +1 -1
- data/README.md +152 -15
- data/lib/testcentricity_web/version.rb +1 -1
- data/lib/testcentricity_web/web_core/webdriver_helper.rb +77 -120
- data/lib/testcentricity_web/web_elements/select_list.rb +10 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 022bc17f6fc489c52de9a91fdccb61b722db97cb17b2c21951a2650930adeeb8
|
4
|
+
data.tar.gz: cfeefd68b74714b35b738f865b8c5796d4ebe3c302bed0deff208cef34d4f225
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19bb489e029052084ba7c4d3c29bc7a1a5f483039624048860be14ba75d2e8960667410ac7b838a962eac263cd80bb0bf66e881b592f03ce91bcd3ebd45c2e15
|
7
|
+
data.tar.gz: 2f45f5c2dda5f485a123527c394f5480e91f1bb123c58efe1a7bf56225388bb0cbed82abbf0c01618d6c370ac7cd6b03f350a338025e06da5597b19989e849b2
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
4
|
|
5
|
+
## [4.1.5] - 15-MAR-2022
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
* `SelectList.selected?` now correctly returns selected value for custom `selectlist` controls.
|
9
|
+
|
10
|
+
### Updated
|
11
|
+
* Updated HTML documentation.
|
12
|
+
|
13
|
+
|
5
14
|
## [4.1.4] - 09-MAR-2022
|
6
15
|
|
7
16
|
### Fixed
|
@@ -19,7 +28,7 @@ All notable changes to this project will be documented in this file.
|
|
19
28
|
|
20
29
|
## [4.1.2] - 07-MAR-2022
|
21
30
|
|
22
|
-
###
|
31
|
+
### Updated
|
23
32
|
* Updated HTML documentation.
|
24
33
|
|
25
34
|
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,9 +3,9 @@
|
|
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
|
7
|
-
|
8
|
-
|
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.
|
9
9
|
|
10
10
|
The TestCentricity™ Web gem supports running automated tests against the following web test targets:
|
11
11
|
* locally hosted desktop browsers (Chrome, Edge, Firefox, Safari, or IE)
|
@@ -49,7 +49,7 @@ Or install it yourself as:
|
|
49
49
|
## Setup
|
50
50
|
### Using Cucumber
|
51
51
|
|
52
|
-
If you are using Cucumber, you need to require the following in your
|
52
|
+
If you are using Cucumber, you need to require the following in your `env.rb` file:
|
53
53
|
|
54
54
|
require 'capybara/cucumber'
|
55
55
|
require 'testcentricity_web'
|
@@ -57,7 +57,7 @@ If you are using Cucumber, you need to require the following in your *env.rb* fi
|
|
57
57
|
|
58
58
|
### Using RSpec
|
59
59
|
|
60
|
-
If you are using RSpec instead, you need to require the following in your
|
60
|
+
If you are using RSpec instead, you need to require the following in your `env.rb` file:
|
61
61
|
|
62
62
|
require 'capybara'
|
63
63
|
require 'capybara/rspec'
|
@@ -67,7 +67,7 @@ If you are using RSpec instead, you need to require the following in your *env.r
|
|
67
67
|
### Using Appium
|
68
68
|
|
69
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
|
70
|
-
the following in your
|
70
|
+
the following in your `env.rb` file:
|
71
71
|
|
72
72
|
require 'appium_capybara'
|
73
73
|
|
@@ -634,6 +634,8 @@ The `verify_ui_states` method supports the following property/state pairs:
|
|
634
634
|
:class String
|
635
635
|
:value or :caption String
|
636
636
|
:attribute Hash
|
637
|
+
:style String
|
638
|
+
:tabindex Integer
|
637
639
|
|
638
640
|
**Text Fields:**
|
639
641
|
|
@@ -646,12 +648,17 @@ The `verify_ui_states` method supports the following property/state pairs:
|
|
646
648
|
|
647
649
|
**Checkboxes:**
|
648
650
|
|
649
|
-
:checked
|
651
|
+
:checked Boolean
|
652
|
+
:indeterminate Boolean
|
650
653
|
|
651
654
|
**Radio Buttons:**
|
652
655
|
|
653
656
|
:selected Boolean
|
654
657
|
|
658
|
+
**Links:**
|
659
|
+
|
660
|
+
:href String
|
661
|
+
|
655
662
|
**Images**
|
656
663
|
|
657
664
|
:loaded Boolean
|
@@ -671,6 +678,8 @@ The `verify_ui_states` method supports the following property/state pairs:
|
|
671
678
|
:items or :options Array of Strings
|
672
679
|
:itemcount or :optioncount Integer
|
673
680
|
:selected String
|
681
|
+
:groupcount Integer
|
682
|
+
:group_headings Array of Strings
|
674
683
|
|
675
684
|
**Tables**
|
676
685
|
|
@@ -706,8 +715,6 @@ The `verify_ui_states` method supports the following property/state pairs:
|
|
706
715
|
|
707
716
|
The `verify_ui_states` method supports the following ARIA accessibility property/state pairs:
|
708
717
|
|
709
|
-
**All Objects:**
|
710
|
-
|
711
718
|
:aria_label String
|
712
719
|
:aria_disabled Boolean
|
713
720
|
:aria_labelledby String
|
@@ -738,8 +745,10 @@ The `verify_ui_states` method supports the following ARIA accessibility property
|
|
738
745
|
:aria_multiline Boolean
|
739
746
|
:aria_multiselectable Boolean
|
740
747
|
:content_editable Boolean
|
748
|
+
:role String
|
741
749
|
|
742
750
|
#### Comparison States
|
751
|
+
|
743
752
|
The `verify_ui_states` method supports comparison states using property/comparison state pairs:
|
744
753
|
|
745
754
|
object => { property: { comparison_state: value } }
|
@@ -844,6 +853,126 @@ Baseline translation strings are stored in `.yml` files in the `config/locales/`
|
|
844
853
|
└── README.md
|
845
854
|
|
846
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.
|
870
|
+
|
871
|
+
<img src="https://i.imgur.com/7bW5u4c.jpg" alt="Roundtrip Radio button Input" title="Roundtrip Radio button Input">
|
872
|
+
|
873
|
+
|
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
|
+
|
847
976
|
|
848
977
|
## Instantiating your PageObjects
|
849
978
|
|
@@ -1220,7 +1349,7 @@ Once your test environment is properly configured, the following **Environment V
|
|
1220
1349
|
| `WEB_BROWSER` | Must be set to `appium` |
|
1221
1350
|
| `APP_PLATFORM_NAME` | Must be set to `iOS` |
|
1222
1351
|
| `APP_BROWSER` | Must be set to `Safari` |
|
1223
|
-
| `APP_VERSION` | Must be set to `15.
|
1352
|
+
| `APP_VERSION` | Must be set to `15.4`, `14.5`, or which ever iOS version you wish to run within the XCode Simulator |
|
1224
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 |
|
1225
1354
|
| `DEVICE_TYPE` | Must be set to `phone` or `tablet` |
|
1226
1355
|
| `APP_UDID` | UDID of physically connected iOS device (not used for simulators) |
|
@@ -1302,6 +1431,13 @@ the code shown below in your `hooks.rb` file.
|
|
1302
1431
|
end
|
1303
1432
|
|
1304
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
|
+
|
1440
|
+
|
1305
1441
|
Refer to **section 8.6 (Using Browser specific Profiles in cucumber.yml)** below.
|
1306
1442
|
|
1307
1443
|
|
@@ -1548,9 +1684,10 @@ that you intend to connect with.
|
|
1548
1684
|
#==============
|
1549
1685
|
|
1550
1686
|
appium_ios: WEB_BROWSER=appium AUTOMATION_ENGINE=XCUITest APP_PLATFORM_NAME="ios" APP_BROWSER="Safari" NEW_COMMAND_TIMEOUT=30 SHOW_SIM_KEYBOARD=false
|
1551
|
-
app_ios_15: --profile appium_ios APP_VERSION="15.
|
1552
|
-
|
1553
|
-
ipad_air_15_sim:
|
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)"
|
1554
1691
|
|
1555
1692
|
|
1556
1693
|
#==============
|
@@ -1686,13 +1823,13 @@ in landscape orientation:
|
|
1686
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
|
1687
1824
|
XCode Simulator in landscape orientation:
|
1688
1825
|
|
1689
|
-
cucumber -p
|
1826
|
+
cucumber -p ipad_pro_12_15_sim -p landscape
|
1690
1827
|
|
1691
1828
|
NOTE: Appium must be running prior to executing this command
|
1692
1829
|
|
1693
1830
|
You can ensure that Appium Server is running by including `-p run_appium` in your command line:
|
1694
1831
|
|
1695
|
-
cucumber -p
|
1832
|
+
cucumber -p ipad_pro_12_15_sim -p landscape -p run_appium
|
1696
1833
|
|
1697
1834
|
|
1698
1835
|
The following command specifies that Cucumber will run tests against a remotely hosted Safari web browser running on a macOS Monterey
|
@@ -49,7 +49,7 @@ module TestCentricity
|
|
49
49
|
context = case browser.downcase.to_sym
|
50
50
|
when :appium
|
51
51
|
initialize_appium
|
52
|
-
'
|
52
|
+
'Appium'
|
53
53
|
when :browserstack
|
54
54
|
initialize_browserstack
|
55
55
|
'Browserstack cloud service'
|
@@ -138,7 +138,6 @@ module TestCentricity
|
|
138
138
|
Environ.device_orientation = ENV['ORIENTATION'] if ENV['ORIENTATION']
|
139
139
|
Capybara.default_driver = :appium
|
140
140
|
Environ.driver = :appium
|
141
|
-
@endpoint = 'http://localhost:4723/wd/hub' if @endpoint.nil?
|
142
141
|
desired_capabilities = {
|
143
142
|
platformName: Environ.device_os,
|
144
143
|
platformVersion: Environ.device_os_version,
|
@@ -190,14 +189,13 @@ module TestCentricity
|
|
190
189
|
desired_capabilities[:systemPort] = ENV['SYSTEM_PORT'] if ENV['SYSTEM_PORT']
|
191
190
|
end
|
192
191
|
|
193
|
-
unless @capabilities.nil?
|
194
|
-
|
195
|
-
|
192
|
+
desired_capabilities = @capabilities unless @capabilities.nil?
|
193
|
+
# specify endpoint url
|
194
|
+
@endpoint = 'http://localhost:4723/wd/hub' if @endpoint.nil?
|
196
195
|
|
197
|
-
Capybara.register_driver
|
198
|
-
appium_lib_options = { server_url: @endpoint }
|
196
|
+
Capybara.register_driver(:appium) do |app|
|
199
197
|
all_options = {
|
200
|
-
appium_lib:
|
198
|
+
appium_lib: { server_url: @endpoint },
|
201
199
|
caps: desired_capabilities
|
202
200
|
}
|
203
201
|
Appium::Capybara::Driver.new(app, all_options)
|
@@ -233,63 +231,18 @@ module TestCentricity
|
|
233
231
|
when :safari, :ie
|
234
232
|
Capybara::Selenium::Driver.new(app, browser: browser)
|
235
233
|
when :firefox, :firefox_headless
|
236
|
-
|
237
|
-
profile['browser.download.dir'] = @downloads_path
|
238
|
-
profile['browser.download.folderList'] = 2
|
239
|
-
profile['browser.download.manager.showWhenStarting'] = false
|
240
|
-
profile['browser.download.manager.closeWhenDone'] = true
|
241
|
-
profile['browser.download.manager.showAlertOnComplete'] = false
|
242
|
-
profile['browser.download.manager.alertOnEXEOpen'] = false
|
243
|
-
profile['browser.download.manager.useWindow'] = false
|
244
|
-
profile['browser.helperApps.alwaysAsk.force'] = false
|
245
|
-
profile['pdfjs.disabled'] = true
|
246
|
-
|
247
|
-
mime_types = ENV['MIME_TYPES'] || 'images/jpeg, application/pdf, application/octet-stream'
|
248
|
-
profile['browser.helperApps.neverAsk.saveToDisk'] = mime_types
|
249
|
-
|
250
|
-
profile['intl.accept_languages'] = ENV['LOCALE'] if ENV['LOCALE']
|
251
|
-
options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
|
252
|
-
options.args << '--headless' if browser == :firefox_headless
|
234
|
+
options = firefox_options(browser)
|
253
235
|
Capybara::Selenium::Driver.new(app, browser: :firefox, capabilities: [options])
|
254
236
|
when :chrome, :chrome_headless
|
255
|
-
options =
|
256
|
-
prefs = {
|
257
|
-
prompt_for_download: false,
|
258
|
-
directory_upgrade: true,
|
259
|
-
default_directory: @downloads_path
|
260
|
-
}
|
261
|
-
options.add_preference(:download, prefs)
|
262
|
-
options.add_argument('--disable-dev-shm-usage')
|
263
|
-
options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
|
264
|
-
if browser == :chrome_headless
|
265
|
-
options.add_argument('--headless')
|
266
|
-
options.add_argument('--disable-gpu')
|
267
|
-
options.add_argument('--no-sandbox')
|
268
|
-
end
|
269
|
-
|
237
|
+
options = chrome_edge_options(browser)
|
270
238
|
Capybara::Selenium::Driver.new(app, browser: :chrome, capabilities: [options])
|
271
239
|
when :edge, :edge_headless
|
272
|
-
options =
|
273
|
-
prefs = {
|
274
|
-
prompt_for_download: false,
|
275
|
-
directory_upgrade: true,
|
276
|
-
default_directory: @downloads_path
|
277
|
-
}
|
278
|
-
options.add_preference(:download, prefs)
|
279
|
-
options.add_argument('--disable-dev-shm-usage')
|
280
|
-
options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
|
281
|
-
if browser == :edge_headless
|
282
|
-
options.add_argument('--headless')
|
283
|
-
options.add_argument('--disable-gpu')
|
284
|
-
options.add_argument('--no-sandbox')
|
285
|
-
end
|
286
|
-
|
240
|
+
options = chrome_edge_options(browser)
|
287
241
|
Capybara::Selenium::Driver.new(app, browser: :edge, capabilities: [options])
|
288
242
|
else
|
289
243
|
if ENV['HOST_BROWSER'] && ENV['HOST_BROWSER'].downcase.to_sym == :chrome
|
290
244
|
user_agent = Browsers.mobile_device_agent(ENV['WEB_BROWSER'])
|
291
245
|
options = Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
|
292
|
-
options.add_argument('--disable-infobars')
|
293
246
|
options.add_argument('--disable-dev-shm-usage')
|
294
247
|
options.add_argument("--user-agent='#{user_agent}'")
|
295
248
|
options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
|
@@ -452,74 +405,31 @@ module TestCentricity
|
|
452
405
|
Environ.grid = :selenium_grid
|
453
406
|
browser = ENV['WEB_BROWSER'].downcase.to_sym
|
454
407
|
@endpoint = ENV['REMOTE_ENDPOINT'] || 'http://127.0.0.1:4444/wd/hub' if @endpoint.nil?
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
profile['browser.helperApps.alwaysAsk.force'] = false
|
471
|
-
profile['pdfjs.disabled'] = true
|
472
|
-
|
473
|
-
mime_types = ENV['MIME_TYPES'] || 'images/jpeg, application/pdf, application/octet-stream'
|
474
|
-
profile['browser.helperApps.neverAsk.saveToDisk'] = mime_types
|
475
|
-
|
476
|
-
profile['intl.accept_languages'] = ENV['LOCALE'] if ENV['LOCALE']
|
477
|
-
options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
|
478
|
-
options.args << '--headless' if browser == :firefox_headless
|
479
|
-
when :chrome, :chrome_headless
|
408
|
+
|
409
|
+
case browser
|
410
|
+
when :safari
|
411
|
+
options = Selenium::WebDriver::Safari::Options.new
|
412
|
+
when :ie
|
413
|
+
options = Selenium::WebDriver::IE::Options.new
|
414
|
+
when :firefox, :firefox_headless
|
415
|
+
options = firefox_options(browser)
|
416
|
+
when :chrome, :chrome_headless, :edge, :edge_headless
|
417
|
+
options = chrome_edge_options(browser)
|
418
|
+
else
|
419
|
+
if ENV['HOST_BROWSER'] && ENV['HOST_BROWSER'].downcase.to_sym == :chrome
|
420
|
+
Environ.platform = :mobile
|
421
|
+
Environ.device_name = Browsers.mobile_device_name(ENV['WEB_BROWSER'])
|
422
|
+
user_agent = Browsers.mobile_device_agent(ENV['WEB_BROWSER'])
|
480
423
|
options = Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
|
481
|
-
prefs = {
|
482
|
-
prompt_for_download: false,
|
483
|
-
directory_upgrade: true,
|
484
|
-
default_directory: @downloads_path
|
485
|
-
}
|
486
|
-
options.add_preference(:download, prefs)
|
487
|
-
options.add_argument('--disable-dev-shm-usage')
|
488
|
-
options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
|
489
|
-
if browser == :chrome_headless
|
490
|
-
options.add_argument('--headless')
|
491
|
-
options.add_argument('--disable-gpu')
|
492
|
-
options.add_argument('--no-sandbox')
|
493
|
-
end
|
494
|
-
when :edge, :edge_headless
|
495
|
-
options = Selenium::WebDriver::Edge::Options.new(options: {'excludeSwitches' => ['enable-automation']})
|
496
|
-
prefs = {
|
497
|
-
prompt_for_download: false,
|
498
|
-
directory_upgrade: true,
|
499
|
-
default_directory: @downloads_path
|
500
|
-
}
|
501
|
-
options.add_preference(:download, prefs)
|
502
424
|
options.add_argument('--disable-dev-shm-usage')
|
425
|
+
options.add_argument("--user-agent='#{user_agent}'")
|
503
426
|
options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
|
504
|
-
if browser == :edge_headless
|
505
|
-
options.add_argument('--headless')
|
506
|
-
options.add_argument('--disable-gpu')
|
507
|
-
options.add_argument('--no-sandbox')
|
508
|
-
end
|
509
427
|
else
|
510
|
-
|
511
|
-
Environ.platform = :mobile
|
512
|
-
Environ.device_name = Browsers.mobile_device_name(ENV['WEB_BROWSER'])
|
513
|
-
user_agent = Browsers.mobile_device_agent(ENV['WEB_BROWSER'])
|
514
|
-
options = Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
|
515
|
-
options.add_argument('--disable-infobars')
|
516
|
-
options.add_argument('--disable-dev-shm-usage')
|
517
|
-
options.add_argument("--user-agent='#{user_agent}'")
|
518
|
-
options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
|
519
|
-
else
|
520
|
-
raise "Requested browser '#{browser}' is not supported on Selenium Grid"
|
521
|
-
end
|
428
|
+
raise "Requested browser '#{browser}' is not supported on Selenium Grid"
|
522
429
|
end
|
430
|
+
end
|
431
|
+
|
432
|
+
Capybara.register_driver :remote_browser do |app|
|
523
433
|
Capybara::Selenium::Driver.new(app,
|
524
434
|
browser: :remote,
|
525
435
|
url: @endpoint,
|
@@ -645,6 +555,50 @@ module TestCentricity
|
|
645
555
|
config_file_uploads unless ENV['TB_PLATFORM']
|
646
556
|
end
|
647
557
|
|
558
|
+
def self.chrome_edge_options(browser)
|
559
|
+
options = case browser
|
560
|
+
when :chrome, :chrome_headless
|
561
|
+
Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
|
562
|
+
when :edge, :edge_headless
|
563
|
+
Selenium::WebDriver::Edge::Options.new(options: {'excludeSwitches' => ['enable-automation']})
|
564
|
+
end
|
565
|
+
prefs = {
|
566
|
+
prompt_for_download: false,
|
567
|
+
directory_upgrade: true,
|
568
|
+
default_directory: @downloads_path
|
569
|
+
}
|
570
|
+
options.add_preference(:download, prefs)
|
571
|
+
options.add_argument('--disable-dev-shm-usage')
|
572
|
+
options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
|
573
|
+
if browser == :chrome_headless || browser == :edge_headless
|
574
|
+
options.add_argument('--headless')
|
575
|
+
options.add_argument('--disable-gpu')
|
576
|
+
options.add_argument('--no-sandbox')
|
577
|
+
end
|
578
|
+
options
|
579
|
+
end
|
580
|
+
|
581
|
+
def self.firefox_options(browser)
|
582
|
+
profile = Selenium::WebDriver::Firefox::Profile.new
|
583
|
+
profile['browser.download.dir'] = @downloads_path
|
584
|
+
profile['browser.download.folderList'] = 2
|
585
|
+
profile['browser.download.manager.showWhenStarting'] = false
|
586
|
+
profile['browser.download.manager.closeWhenDone'] = true
|
587
|
+
profile['browser.download.manager.showAlertOnComplete'] = false
|
588
|
+
profile['browser.download.manager.alertOnEXEOpen'] = false
|
589
|
+
profile['browser.download.manager.useWindow'] = false
|
590
|
+
profile['browser.helperApps.alwaysAsk.force'] = false
|
591
|
+
profile['pdfjs.disabled'] = true
|
592
|
+
|
593
|
+
mime_types = ENV['MIME_TYPES'] || 'images/jpeg, application/pdf, application/octet-stream'
|
594
|
+
profile['browser.helperApps.neverAsk.saveToDisk'] = mime_types
|
595
|
+
|
596
|
+
profile['intl.accept_languages'] = ENV['LOCALE'] if ENV['LOCALE']
|
597
|
+
options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
|
598
|
+
options.args << '--headless' if browser == :firefox_headless
|
599
|
+
options
|
600
|
+
end
|
601
|
+
|
648
602
|
def self.test_context_message
|
649
603
|
context_message = if ENV['TEST_CONTEXT']
|
650
604
|
"#{Environ.test_environment.to_s.upcase} - #{ENV['TEST_CONTEXT']}"
|
@@ -662,7 +616,10 @@ module TestCentricity
|
|
662
616
|
def self.register_remote_driver(driver, browser, options)
|
663
617
|
Capybara.register_driver driver do |app|
|
664
618
|
capabilities = Selenium::WebDriver::Remote::Capabilities.send(browser.gsub(/\s+/, '_').downcase.to_sym, options)
|
665
|
-
Capybara::Selenium::Driver.new(app,
|
619
|
+
Capybara::Selenium::Driver.new(app,
|
620
|
+
browser: :remote,
|
621
|
+
url: @endpoint,
|
622
|
+
capabilities: capabilities)
|
666
623
|
end
|
667
624
|
|
668
625
|
Environ.browser = browser
|
@@ -246,13 +246,16 @@ module TestCentricity
|
|
246
246
|
def get_selected_option
|
247
247
|
@base_object, = find_element
|
248
248
|
object_not_found_exception(@base_object, nil)
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
249
|
+
trigger_list
|
250
|
+
selection = if @base_object.first(:css, @list_item, minimum: 0, wait: 1, visible: :all)
|
251
|
+
@base_object.first(:css, @selected_item, wait: 1, visible: :all).text
|
252
|
+
elsif @base_object.first(:css, @selected_item, minimum: 0, wait: 1, visible: :all)
|
253
|
+
@base_object.first(:css, @selected_item, visible: :all).text
|
254
|
+
else
|
255
|
+
@base_object.first('option[selected]', visible: :all).text
|
256
|
+
end
|
257
|
+
trigger_list
|
258
|
+
selection
|
256
259
|
end
|
257
260
|
|
258
261
|
alias selected? get_selected_option
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testcentricity_web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.
|
4
|
+
version: 4.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- A.J. Mrozinski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|