testcentricity_web 3.2.25 → 4.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +43 -0
- data/README.md +66 -33
- data/lib/testcentricity_web/browser_helper.rb +21 -13
- data/lib/testcentricity_web/data_objects/data_objects_helper.rb +34 -5
- data/lib/testcentricity_web/data_objects/environment.rb +30 -5
- data/lib/testcentricity_web/data_objects/excel_helper.rb +1 -25
- data/lib/testcentricity_web/version.rb +1 -1
- data/lib/testcentricity_web/web_core/page_object.rb +1 -93
- data/lib/testcentricity_web/web_core/page_objects_helper.rb +1 -7
- data/lib/testcentricity_web/web_core/page_section.rb +0 -91
- data/lib/testcentricity_web/web_core/webdriver_helper.rb +100 -41
- data/lib/testcentricity_web/web_elements/checkbox.rb +1 -15
- data/lib/testcentricity_web/web_elements/file_field.rb +1 -1
- data/lib/testcentricity_web/web_elements/radio.rb +1 -1
- data/lib/testcentricity_web/web_elements/select_list.rb +0 -52
- data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +5 -14
- data/lib/testcentricity_web/world_extensions.rb +1 -1
- data/lib/testcentricity_web.rb +1 -11
- metadata +6 -18
- data/Gemfile.lock +0 -114
- data/lib/testcentricity_web/web_elements/cell_button.rb +0 -8
- data/lib/testcentricity_web/web_elements/cell_checkbox.rb +0 -38
- data/lib/testcentricity_web/web_elements/cell_element.rb +0 -69
- data/lib/testcentricity_web/web_elements/cell_image.rb +0 -8
- data/lib/testcentricity_web/web_elements/cell_radio.rb +0 -31
- data/lib/testcentricity_web/web_elements/list_button.rb +0 -8
- data/lib/testcentricity_web/web_elements/list_checkbox.rb +0 -38
- data/lib/testcentricity_web/web_elements/list_element.rb +0 -61
- data/lib/testcentricity_web/web_elements/list_radio.rb +0 -31
- data/lib/testcentricity_web/web_elements/siebel_open_ui_helper.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95e4b5025304d6ad72f56f0ba7379d10e3cb2448ae5dbabf045bf735f63543c6
|
4
|
+
data.tar.gz: f867be4fb98cc322b6899a07d013c2261fed2571dca60535239a82e8eebe9288
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: deb2523e2d4e451f86774d44bee720a5d702274f3edb06c0a456ed996f433633a0ea0092f807126f790b12047a64732e0ab64d989ff0b51b219f9b78ee0a784c
|
7
|
+
data.tar.gz: 8d62e8d210fe3696bf522228e002c544d175f78bdecb87c3a62510c88ca581731c15501bf4ca77619103ad33792b69b74fd486a8be920bec07323529f694e6d3
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,49 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [4.0.2] - 30-DEC-2021
|
5
|
+
|
6
|
+
### Changed
|
7
|
+
* Primary test data path has been changed from `features/test_data/` to `config/test_data/`.
|
8
|
+
|
9
|
+
### Fixed
|
10
|
+
* No longer throws a `NoMethodError: undefined method 'World' for main:Object` error when RSpec.
|
11
|
+
|
12
|
+
## [4.0.0] - 18-APR-2021
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
* `WebDriverConnect.initialize_web_driver` method now accepts an `options` hash as an optional parameter, which can be used to
|
16
|
+
specify an optional base host URL and/or the desired Selenium-Webdriver capabilities required to establish a connection with
|
17
|
+
a cloud hosted target web browser.
|
18
|
+
* User defined mobile device profiles can be specified in a `device.yml` file for testing locally hosted emulated mobile
|
19
|
+
web browsers running in an instance of the Chrome desktop browser. The user specified device profiles must be located at
|
20
|
+
`config/data/devices/devices.yml`. Refer to the **User defined mobile device profiles** section of the {file:README.md README} file.
|
21
|
+
|
22
|
+
### Removed
|
23
|
+
* Removed support for the following legacy UI elements:
|
24
|
+
* `CellElement`
|
25
|
+
* `CellButton`
|
26
|
+
* `CellCheckBox`
|
27
|
+
* `CellRadio`
|
28
|
+
* `CellImage`
|
29
|
+
* `ListElement`
|
30
|
+
* `ListButton`
|
31
|
+
* `ListCheckBox`
|
32
|
+
* Removed support for Siebel Open UI objects. This includes removal of the following legacy methods:
|
33
|
+
* `CheckBox.set_siebel_checkbox_state`
|
34
|
+
* `SelectList.choose_siebel_option`
|
35
|
+
* `SelectList.get_siebel_options`
|
36
|
+
* `SelectList.verify_siebel_options`
|
37
|
+
* `SelectList.read_only?`
|
38
|
+
* `UIElement.invoke_siebel_dialog`
|
39
|
+
* `UIElement.invoke_siebel_popup`
|
40
|
+
* `UIElement.get_siebel_object_type`
|
41
|
+
|
42
|
+
## [3.3.0] - 14-MAR-2021
|
43
|
+
|
44
|
+
### Fixed
|
45
|
+
* `WebDriverConnect.initialize_web_driver` method now correctly sets local Chrome browser Download directory when running
|
46
|
+
with headless Chrome.
|
4
47
|
|
5
48
|
## [3.2.25] - 11-MAR-2021
|
6
49
|
|
data/README.md
CHANGED
@@ -23,7 +23,6 @@ The TestCentricity™ Web gem supports running automated tests against the follo
|
|
23
23
|
* [Gridlastic](https://www.gridlastic.com/test-environments.html)
|
24
24
|
* [LambdaTest](https://www.lambdatest.com/selenium-automation)
|
25
25
|
* web portals utilizing JavaScript front end application frameworks like Ember, React, Angular, and GWT
|
26
|
-
* enterprise web portals built using Siebel Open UI
|
27
26
|
* web pages containing HTML5 Video and Audio objects
|
28
27
|
|
29
28
|
|
@@ -483,6 +482,7 @@ With TestCentricity, all UI elements are based on the **UIElement** class, and i
|
|
483
482
|
element.click_at(x, y)
|
484
483
|
element.hover
|
485
484
|
element.hover_at(x, y)
|
485
|
+
element.scroll_to(position)
|
486
486
|
element.drag_by(right_offset, down_offset)
|
487
487
|
element.drag_and_drop(target, right_offset, down_offset)
|
488
488
|
|
@@ -638,11 +638,11 @@ navigated to by clicking associated links. One such Cucumber navigation scenario
|
|
638
638
|
|
639
639
|
Scenario Outline: Verify Home page navigation links
|
640
640
|
Given I am on the Home page
|
641
|
-
When I click the <
|
642
|
-
Then I expect the <
|
641
|
+
When I click the <page name> navigation link
|
642
|
+
Then I expect the <page name> page to be correctly displayed
|
643
643
|
|
644
644
|
Examples:
|
645
|
-
|
|
645
|
+
|page name |
|
646
646
|
|Registration |
|
647
647
|
|My Account |
|
648
648
|
|Terms & Conditions |
|
@@ -653,41 +653,42 @@ navigated to by clicking associated links. One such Cucumber navigation scenario
|
|
653
653
|
In the above example, the step definitions associated with the 3 steps might be implemented using a `page_dispatcher` method using a
|
654
654
|
`case` statement to parse the `page` parameter as in the example below:
|
655
655
|
|
656
|
-
Given(/^I am on the (
|
656
|
+
Given(/^I am on the (.*) page$/) do |page_name|
|
657
657
|
target_page = page_dispatcher(page_name)
|
658
658
|
target_page.load_page
|
659
659
|
end
|
660
660
|
|
661
|
-
When(/^I click the (
|
661
|
+
When(/^I click the (.*) navigation link$/) do |link_name|
|
662
662
|
target_page = page_dispatcher(link_name)
|
663
663
|
target_page.navigate_to
|
664
664
|
end
|
665
665
|
|
666
|
-
Then(/^I expect the (
|
666
|
+
Then(/^I expect the (.*) page to be correctly displayed$/) do |page_name|
|
667
667
|
target_page = page_dispatcher(page_name)
|
668
668
|
target_page.verify_page_exists
|
669
669
|
target_page.verify_page_ui
|
670
670
|
end
|
671
671
|
|
672
672
|
# this method takes a page name as a parameter and returns an instance of the associated Page Object
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
673
|
+
def page_dispatcher(page_name)
|
674
|
+
page = case page_name
|
675
|
+
when 'Registration'
|
676
|
+
registration_page
|
677
|
+
when 'My Account'
|
678
|
+
my_account_page
|
679
|
+
when 'Terms & Conditions'
|
680
|
+
terms_conditions_page
|
681
|
+
when 'Privacy Policy'
|
682
|
+
privacy_policy_page
|
683
|
+
when 'Contact Us'
|
684
|
+
contact_us_page
|
685
|
+
when 'FAQs'
|
686
|
+
faqs_page
|
687
|
+
end
|
688
|
+
raise "No page object defined for page named '#{page_name}'" unless page
|
689
|
+
page
|
687
690
|
end
|
688
|
-
|
689
|
-
page
|
690
|
-
end
|
691
|
+
|
691
692
|
|
692
693
|
|
693
694
|
While this approach may be effective for small web applications with only a few pages (and hence few **Page Objects**), it quickly becomes
|
@@ -701,22 +702,22 @@ To use these **PageManager** methods, include the step definitions and code belo
|
|
701
702
|
|
702
703
|
include TestCentricity
|
703
704
|
|
704
|
-
Given(/^I am on the (
|
705
|
+
Given(/^I am on the (.*) page$/) do |page_name|
|
705
706
|
target_page = PageManager.find_page(page_name)
|
706
707
|
target_page.load_page
|
707
708
|
end
|
708
709
|
|
709
|
-
When(/^I click the (
|
710
|
+
When(/^I click the (.*) navigation link$/) do |page_name|
|
710
711
|
target_page = PageManager.find_page(page_name)
|
711
712
|
target_page.navigate_to
|
712
713
|
end
|
713
714
|
|
714
|
-
Then(/^I expect to see the (
|
715
|
+
Then(/^I expect to see the (.*) page$/) do |page_name|
|
715
716
|
target_page = PageManager.find_page(page_name)
|
716
717
|
target_page.verify_page_exists
|
717
718
|
end
|
718
719
|
|
719
|
-
Then(/^I expect the (
|
720
|
+
Then(/^I expect the (.*) page to be correctly displayed$/) do |page_name|
|
720
721
|
target_page = PageManager.find_page(page_name)
|
721
722
|
target_page.verify_page_exists
|
722
723
|
target_page.verify_page_ui
|
@@ -767,11 +768,11 @@ a `/downloads` folder at the same level as the `/config` and `/features` folders
|
|
767
768
|
|
768
769
|
my_automation_project
|
769
770
|
├── config
|
771
|
+
│ └── test_data
|
770
772
|
├── downloads
|
771
773
|
├── features
|
772
774
|
│ ├── step_definitions
|
773
|
-
│
|
774
|
-
│ └── test_data
|
775
|
+
│ └── support
|
775
776
|
├── Gemfile
|
776
777
|
└── README.md
|
777
778
|
|
@@ -782,6 +783,7 @@ test thread. This is to ensure that files downloaded in each test thread are iso
|
|
782
783
|
|
783
784
|
my_automation_project
|
784
785
|
├── config
|
786
|
+
│ └── test_data
|
785
787
|
├── downloads
|
786
788
|
│ ├── 1
|
787
789
|
│ ├── 2
|
@@ -789,8 +791,7 @@ test thread. This is to ensure that files downloaded in each test thread are iso
|
|
789
791
|
│ └── 4
|
790
792
|
├── features
|
791
793
|
│ ├── step_definitions
|
792
|
-
│
|
793
|
-
│ └── test_data
|
794
|
+
│ └── support
|
794
795
|
├── Gemfile
|
795
796
|
└── README.md
|
796
797
|
|
@@ -870,6 +871,38 @@ To use a local instance of the Chrome desktop browser to host the emulated mobil
|
|
870
871
|
to `chrome`.
|
871
872
|
|
872
873
|
|
874
|
+
#### User defined mobile device profiles
|
875
|
+
|
876
|
+
User defined mobile device profiles can be specified in a `device.yml` file for testing locally hosted emulated mobile web browsers running in an instance
|
877
|
+
of the Chrome desktop browser. The user specified device profiles must be located at `config/data/devices/devices.yml` as depicted below:
|
878
|
+
|
879
|
+
my_automation_project
|
880
|
+
├── config
|
881
|
+
│ ├── data
|
882
|
+
│ │ └── devices
|
883
|
+
│ │ └── devices.yml
|
884
|
+
│ ├── locales
|
885
|
+
│ ├── test_data
|
886
|
+
│ └── cucumber.yml
|
887
|
+
├── downloads
|
888
|
+
├── features
|
889
|
+
│ ├── step_definitions
|
890
|
+
│ └── support
|
891
|
+
├── Gemfile
|
892
|
+
└── README.md
|
893
|
+
|
894
|
+
The format for a new device profile is:
|
895
|
+
```
|
896
|
+
:new_device_profile:
|
897
|
+
:name: "New Device Name"
|
898
|
+
:os: (ios, android, kindle, or blackberry)
|
899
|
+
:type: (phone or tablet)
|
900
|
+
:css_width: css width in pixels
|
901
|
+
:css_height: css height in pixels
|
902
|
+
:default_orientation: (portrait or landscape)
|
903
|
+
:user_agent: "user agent string"
|
904
|
+
```
|
905
|
+
|
873
906
|
### Selenium Grid and Dockerized Selenium Grid hosted desktop and emulated mobile web browsers
|
874
907
|
|
875
908
|
For desktop and emulated mobile web browsers running on Selenium Grid or Dockerized Selenium Grid environments ([like Zalenium](https://opensource.zalando.com/zalenium/)), the following **Environment Variables** must be set
|
@@ -877,7 +910,7 @@ as described in the table below.
|
|
877
910
|
|
878
911
|
**Environment Variable** | **Description**
|
879
912
|
--------------- | ----------------
|
880
|
-
`WEB_BROWSER` | Must be set to one of the following desktop browsers - `chrome`, `chrome_headless`, `firefox`,
|
913
|
+
`WEB_BROWSER` | Must be set to one of the following desktop browsers - `chrome`, `chrome_headless`, or `firefox`, or any of the mobile web browsers described above.
|
881
914
|
`SELENIUM` | Must be set to `remote`
|
882
915
|
`REMOTE_ENDPOINT` | Must be set to the URL of the Grid hub, which is usually `http://localhost:4444/wd/hub`
|
883
916
|
|
@@ -2,9 +2,11 @@ require 'yaml'
|
|
2
2
|
|
3
3
|
|
4
4
|
module TestCentricity
|
5
|
-
|
5
|
+
class Browsers
|
6
6
|
include Capybara::DSL
|
7
7
|
|
8
|
+
@devices = {}
|
9
|
+
|
8
10
|
# Sets the size of the browser window.
|
9
11
|
#
|
10
12
|
# @param resolution [Array] the desired [width, height]
|
@@ -73,8 +75,8 @@ module TestCentricity
|
|
73
75
|
|
74
76
|
def self.close_all_browser_instances
|
75
77
|
Capybara.page.driver.browser.window_handles.each do |handle|
|
76
|
-
page.driver.browser.switch_to.window(handle)
|
77
|
-
page.driver.browser.close
|
78
|
+
Capybara.page.driver.browser.switch_to.window(handle)
|
79
|
+
Capybara.page.driver.browser.close
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
@@ -126,17 +128,15 @@ module TestCentricity
|
|
126
128
|
end
|
127
129
|
end
|
128
130
|
|
129
|
-
def self.mobile_device_agent(
|
130
|
-
|
131
|
-
device = get_devices[device_name]
|
131
|
+
def self.mobile_device_agent(browser)
|
132
|
+
device = get_device(browser)
|
132
133
|
agent_string = device[:user_agent]
|
133
134
|
raise "Device '#{device}' is not defined" unless agent_string
|
134
135
|
agent_string
|
135
136
|
end
|
136
137
|
|
137
|
-
def self.mobile_device_name(
|
138
|
-
|
139
|
-
device = get_devices[device_name]
|
138
|
+
def self.mobile_device_name(browser)
|
139
|
+
device = get_device(browser)
|
140
140
|
name = device[:name]
|
141
141
|
raise "Device '#{device}' is not defined" unless name
|
142
142
|
Environ.device_os = device[:os]
|
@@ -145,8 +145,7 @@ module TestCentricity
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def self.browser_size(browser, orientation)
|
148
|
-
|
149
|
-
device = get_devices[device_name]
|
148
|
+
device = get_device(browser)
|
150
149
|
if device
|
151
150
|
width = device[:css_width]
|
152
151
|
height = device[:css_height]
|
@@ -170,8 +169,17 @@ module TestCentricity
|
|
170
169
|
|
171
170
|
private
|
172
171
|
|
173
|
-
def self.
|
174
|
-
|
172
|
+
def self.get_device(device)
|
173
|
+
if @devices.blank?
|
174
|
+
@devices = YAML.load_file File.expand_path('../../devices/devices.yml', __FILE__)
|
175
|
+
# read in user defined list of devices
|
176
|
+
external_device_file = 'config/data/devices/devices.yml'
|
177
|
+
unless File.size?(external_device_file).nil?
|
178
|
+
ext_devices = YAML.load_file(external_device_file)
|
179
|
+
@devices = @devices.merge(ext_devices)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
@devices[device.gsub(/\s+/, '').downcase.to_sym]
|
175
183
|
end
|
176
184
|
end
|
177
185
|
end
|
@@ -1,12 +1,18 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'json'
|
3
3
|
require 'virtus'
|
4
|
+
require 'time'
|
5
|
+
require 'chronic'
|
6
|
+
require 'faker'
|
4
7
|
|
5
8
|
|
6
9
|
module TestCentricity
|
7
10
|
|
8
|
-
|
9
|
-
|
11
|
+
PRIMARY_DATA_PATH ||= 'config/test_data/'
|
12
|
+
PRIMARY_DATA_FILE ||= "#{PRIMARY_DATA_PATH}data."
|
13
|
+
XL_PRIMARY_DATA_FILE ||= "#{PRIMARY_DATA_FILE}xls"
|
14
|
+
YML_PRIMARY_DATA_FILE ||= "#{PRIMARY_DATA_FILE}yml"
|
15
|
+
JSON_PRIMARY_DATA_FILE ||= "#{PRIMARY_DATA_FILE}json"
|
10
16
|
|
11
17
|
|
12
18
|
class DataObject
|
@@ -81,7 +87,7 @@ module TestCentricity
|
|
81
87
|
attr_accessor :node
|
82
88
|
|
83
89
|
def read_yaml_node_data(file_name, node_name)
|
84
|
-
@file_path = "#{
|
90
|
+
@file_path = "#{PRIMARY_DATA_PATH}#{file_name}"
|
85
91
|
@node = node_name
|
86
92
|
data = YAML.load_file(@file_path)
|
87
93
|
data[node_name]
|
@@ -94,7 +100,7 @@ module TestCentricity
|
|
94
100
|
end
|
95
101
|
|
96
102
|
def read_json_node_data(file_name, node_name)
|
97
|
-
@file_path = "#{
|
103
|
+
@file_path = "#{PRIMARY_DATA_PATH}#{file_name}"
|
98
104
|
@node = node_name
|
99
105
|
raw_data = File.read(@file_path)
|
100
106
|
data = JSON.parse(raw_data)
|
@@ -106,6 +112,28 @@ module TestCentricity
|
|
106
112
|
data[node_name] = node_data
|
107
113
|
File.write(@file_path, data.to_json)
|
108
114
|
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def self.calculate_dynamic_value(value)
|
119
|
+
test_value = value.split('!', 2)
|
120
|
+
parameter = test_value[1].split('.', 2)
|
121
|
+
case parameter[0]
|
122
|
+
when 'Date'
|
123
|
+
result = eval("Chronic.parse('#{parameter[1]}')")
|
124
|
+
when 'FormattedDate', 'FormatDate'
|
125
|
+
date_time_params = parameter[1].split(' format! ', 2)
|
126
|
+
date_time = eval("Chronic.parse('#{date_time_params[0].strip}')")
|
127
|
+
result = date_time.to_s.format_date_time("#{date_time_params[1].strip}")
|
128
|
+
else
|
129
|
+
result = if Faker.constants.include?(parameter[0].to_sym)
|
130
|
+
eval("Faker::#{parameter[0]}.#{parameter[1]}")
|
131
|
+
else
|
132
|
+
eval(test_value[1])
|
133
|
+
end
|
134
|
+
end
|
135
|
+
result.to_s
|
136
|
+
end
|
109
137
|
end
|
110
138
|
|
111
139
|
|
@@ -117,7 +145,7 @@ module TestCentricity
|
|
117
145
|
@worksheet = sheet
|
118
146
|
if ENV['TEST_ENVIRONMENT']
|
119
147
|
environment = ENV['TEST_ENVIRONMENT']
|
120
|
-
data_file = "#{
|
148
|
+
data_file = "#{PRIMARY_DATA_PATH}#{environment}_data.xls"
|
121
149
|
data_file = XL_PRIMARY_DATA_FILE unless ExcelData.row_spec_exists?(data_file, @worksheet, row_spec)
|
122
150
|
else
|
123
151
|
data_file = XL_PRIMARY_DATA_FILE
|
@@ -147,3 +175,4 @@ module TestCentricity
|
|
147
175
|
end
|
148
176
|
end
|
149
177
|
end
|
178
|
+
|
@@ -1,21 +1,45 @@
|
|
1
1
|
module TestCentricity
|
2
2
|
class EnvironData < TestCentricity::ExcelDataSource
|
3
3
|
attr_accessor :current
|
4
|
+
attr_accessor :generic_data
|
5
|
+
attr_accessor :environ_specific_data
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
def find_environ(environ_name, source_type = :excel)
|
7
|
+
def self.find_environ(environ_name, source_type = :excel)
|
8
8
|
data = case source_type
|
9
9
|
when :excel
|
10
|
-
ExcelData.read_row_data(XL_PRIMARY_DATA_FILE,
|
10
|
+
ExcelData.read_row_data(XL_PRIMARY_DATA_FILE, 'Environments', environ_name)
|
11
11
|
when :yaml
|
12
|
-
|
12
|
+
# read generic test data from data.yml file
|
13
|
+
@generic_data ||= YAML.load_file(YML_PRIMARY_DATA_FILE)
|
14
|
+
# read environment specific test data
|
15
|
+
data_file = "#{PRIMARY_DATA_PATH}#{environ_name}_data.yml"
|
16
|
+
@environ_specific_data ||= YAML.load_file(data_file)
|
17
|
+
|
18
|
+
read('Environments', environ_name)
|
13
19
|
when :json
|
14
20
|
read_json_node_data('environments.json', environ_name)
|
15
21
|
end
|
16
22
|
@current = Environ.new(data)
|
17
23
|
Environ.current = @current
|
18
24
|
end
|
25
|
+
|
26
|
+
def self.read(key_name, node_name)
|
27
|
+
if @environ_specific_data.key?(key_name) && @environ_specific_data[key_name].key?(node_name)
|
28
|
+
node_data = @environ_specific_data[key_name][node_name]
|
29
|
+
else
|
30
|
+
raise "No key named #{key_name} in generic and environment-specific data" unless @generic_data.key?(key_name)
|
31
|
+
raise "No node named #{node_name} in #{key_name} section of generic and environment-specific data" unless @generic_data[key_name].key?(node_name)
|
32
|
+
|
33
|
+
node_data = @generic_data[key_name][node_name]
|
34
|
+
end
|
35
|
+
|
36
|
+
if node_data.is_a?(Hash)
|
37
|
+
node_data.each do |key, value|
|
38
|
+
node_data[key] = calculate_dynamic_value(value) if value.to_s.start_with?('eval!')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
node_data
|
42
|
+
end
|
19
43
|
end
|
20
44
|
|
21
45
|
|
@@ -355,3 +379,4 @@ module TestCentricity
|
|
355
379
|
end
|
356
380
|
end
|
357
381
|
end
|
382
|
+
|
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'time'
|
2
|
-
require 'chronic'
|
3
|
-
require 'faker'
|
4
1
|
require 'spreadsheet'
|
5
2
|
|
6
3
|
|
@@ -273,27 +270,6 @@ module TestCentricity
|
|
273
270
|
# rename new Excel document, replacing the original
|
274
271
|
File.rename(outfile, file)
|
275
272
|
end
|
276
|
-
|
277
|
-
private
|
278
|
-
|
279
|
-
def self.calculate_dynamic_value(value)
|
280
|
-
test_value = value.split('!', 2)
|
281
|
-
parameter = test_value[1].split('.', 2)
|
282
|
-
case parameter[0]
|
283
|
-
when 'Date'
|
284
|
-
result = eval("Chronic.parse('#{parameter[1]}')")
|
285
|
-
when 'FormattedDate', 'FormatDate'
|
286
|
-
date_time_params = parameter[1].split(' format! ', 2)
|
287
|
-
date_time = eval("Chronic.parse('#{date_time_params[0].strip}')")
|
288
|
-
result = date_time.to_s.format_date_time("#{date_time_params[1].strip}")
|
289
|
-
else
|
290
|
-
result = if Faker.constants.include?(parameter[0].to_sym)
|
291
|
-
eval("Faker::#{parameter[0]}.#{parameter[1]}")
|
292
|
-
else
|
293
|
-
eval(test_value[1])
|
294
|
-
end
|
295
|
-
end
|
296
|
-
result.to_s
|
297
|
-
end
|
298
273
|
end
|
299
274
|
end
|
275
|
+
|
@@ -5,8 +5,7 @@ module TestCentricity
|
|
5
5
|
# @param element_name [Symbol] name of UI object (as a symbol)
|
6
6
|
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
7
7
|
# @example
|
8
|
-
# element :
|
9
|
-
# element :siebel_busy, "//html[contains(@class, 'siebui-busy')]"
|
8
|
+
# element :settings_item, 'a#userPreferencesTrigger'
|
10
9
|
#
|
11
10
|
def self.element(element_name, locator)
|
12
11
|
define_page_element(element_name, TestCentricity::UIElement, locator)
|
@@ -288,97 +287,6 @@ module TestCentricity
|
|
288
287
|
element_hash.each(&method(:filefield))
|
289
288
|
end
|
290
289
|
|
291
|
-
# Declare and instantiate a cell button in a table column on this page object.
|
292
|
-
#
|
293
|
-
# @param element_name [Symbol] name of cell button object (as a symbol)
|
294
|
-
# @param locator [String] XPath expression that uniquely identifies cell button within row and column of parent table object
|
295
|
-
# @param table [Symbol] Name (as a symbol) of parent table object
|
296
|
-
# @param column [Integer] 1-based index of table column that contains the cell button object
|
297
|
-
# @example
|
298
|
-
# cell_button :show_button, "a[@class='show']", :data_table, 5
|
299
|
-
# cell_button :edit_button, "a[@class='edit']", :data_table, 5
|
300
|
-
#
|
301
|
-
def self.cell_button(element_name, locator, table, column)
|
302
|
-
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellButton.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column});end))
|
303
|
-
end
|
304
|
-
|
305
|
-
# Declare and instantiate a cell checkbox in a table column on this page object.
|
306
|
-
#
|
307
|
-
# @param element_name [Symbol] name of cell checkbox object (as a symbol)
|
308
|
-
# @param locator [String] XPath expression that uniquely identifies cell checkbox within row and column of parent table object
|
309
|
-
# @param table [Symbol] Name (as a symbol) of parent table object
|
310
|
-
# @param column [Integer] 1-based index of table column that contains the cell checkbox object
|
311
|
-
# @example
|
312
|
-
# cell_checkbox :is_registered_check, "a[@class='registered']", :data_table, 4
|
313
|
-
#
|
314
|
-
def self.cell_checkbox(element_name, locator, table, column, proxy = nil)
|
315
|
-
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellCheckBox.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column}, #{proxy});end))
|
316
|
-
end
|
317
|
-
|
318
|
-
# Declare and instantiate a cell radio in a table column on this page object.
|
319
|
-
#
|
320
|
-
# @param element_name [Symbol] name of cell radio object (as a symbol)
|
321
|
-
# @param locator [String] XPath expression that uniquely identifies cell radio within row and column of parent table object
|
322
|
-
# @param table [Symbol] Name (as a symbol) of parent table object
|
323
|
-
# @param column [Integer] 1-based index of table column that contains the cell radio object
|
324
|
-
# @example
|
325
|
-
# cell_radio :track_a_radio, "a[@class='track_a']", :data_table, 8
|
326
|
-
#
|
327
|
-
def self.cell_radio(element_name, locator, table, column, proxy = nil)
|
328
|
-
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellRadio.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column}, #{proxy});end))
|
329
|
-
end
|
330
|
-
|
331
|
-
# Declare and instantiate a cell image in a table column on this page object.
|
332
|
-
#
|
333
|
-
# @param element_name [Symbol] name of cell image object (as a symbol)
|
334
|
-
# @param locator [String] XPath expression that uniquely identifies cell image within row and column of parent table object
|
335
|
-
# @param table [Symbol] Name (as a symbol) of parent table object
|
336
|
-
# @param column [Integer] 1-based index of table column that contains the cell image object
|
337
|
-
# @example
|
338
|
-
# cell_image :ready_icon, "img[@class='ready']", :data_table, 3
|
339
|
-
# cell_image :send_icon, "img[@class='send']", :data_table, 3
|
340
|
-
#
|
341
|
-
def self.cell_image(element_name, locator, table, column)
|
342
|
-
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellImage.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column});end))
|
343
|
-
end
|
344
|
-
|
345
|
-
# Declare and instantiate a list button in a row of a list object on this page object.
|
346
|
-
#
|
347
|
-
# @param element_name [Symbol] name of list button object (as a symbol)
|
348
|
-
# @param locator [String] XPath expression that uniquely identifies list button within row of parent list object
|
349
|
-
# @param list [Symbol] Name (as a symbol) of parent list object
|
350
|
-
# @example
|
351
|
-
# list_button :delete_button, "a[@class='delete']", :icon_list
|
352
|
-
# list_button :edit_button, "a[@class='edit']", :icon_list
|
353
|
-
#
|
354
|
-
def self.list_button(element_name, locator, list)
|
355
|
-
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListButton.new("#{element_name}", self, "#{locator}", :page, #{list});end))
|
356
|
-
end
|
357
|
-
|
358
|
-
# Declare and instantiate a list checkbox in a row of a list object on this page object.
|
359
|
-
#
|
360
|
-
# @param element_name [Symbol] name of list checkbox object (as a symbol)
|
361
|
-
# @param locator [String] XPath expression that uniquely identifies list checkbox within row of parent list object
|
362
|
-
# @param list [Symbol] Name (as a symbol) of parent list object
|
363
|
-
# @example
|
364
|
-
# list_checkbox :is_registered_check, "a[@class='registered']", :data_list
|
365
|
-
#
|
366
|
-
def self.list_checkbox(element_name, locator, list, proxy = nil)
|
367
|
-
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListCheckBox.new("#{element_name}", self, "#{locator}", :page, #{list}, #{proxy});end))
|
368
|
-
end
|
369
|
-
|
370
|
-
# Declare and instantiate a list radio in a row of a list object on this page object.
|
371
|
-
#
|
372
|
-
# @param element_name [Symbol] name of list radio object (as a symbol)
|
373
|
-
# @param locator [String] XPath expression that uniquely identifies list radio within row of parent list object
|
374
|
-
# @param list [Symbol] Name (as a symbol) of parent list object
|
375
|
-
# @example
|
376
|
-
# list_radio :sharing_radio, "a[@class='sharing']", :data_list
|
377
|
-
#
|
378
|
-
def self.list_radio(element_name, locator, list, proxy = nil)
|
379
|
-
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListRadio.new("#{element_name}", self, "#{locator}", :page, #{list}, #{proxy});end))
|
380
|
-
end
|
381
|
-
|
382
290
|
# Instantiate a single PageSection object for this page object.
|
383
291
|
#
|
384
292
|
# @param section_name [Symbol] name of PageSection object (as a symbol)
|
@@ -137,8 +137,6 @@ module TestCentricity
|
|
137
137
|
ui_object.count(visible = true)
|
138
138
|
when :count_all
|
139
139
|
ui_object.count(visible = :all)
|
140
|
-
when :siebel_options
|
141
|
-
ui_object.get_siebel_options
|
142
140
|
when :style
|
143
141
|
ui_object.style
|
144
142
|
when :href
|
@@ -282,11 +280,7 @@ module TestCentricity
|
|
282
280
|
check_state = data_param.is_a?(String) ? data_param.to_bool : data_param
|
283
281
|
data_field.set_checkbox_state(check_state)
|
284
282
|
when :selectlist
|
285
|
-
|
286
|
-
data_field.set("#{data_param}\t")
|
287
|
-
else
|
288
|
-
data_field.choose_option(data_param)
|
289
|
-
end
|
283
|
+
data_field.choose_option(data_param)
|
290
284
|
when :radio
|
291
285
|
check_state = data_param.is_a?(String) ? data_param.to_bool : data_param
|
292
286
|
data_field.set_selected_state(check_state)
|