testcentricity_web 3.3.0 → 4.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/Gemfile.lock +23 -25
- 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 +89 -31
- 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 +0 -11
- metadata +6 -17
- 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: d93f63b0f93fc833deb465d8588ef93e30db5b171929da48ef8e4449450b8c7a
|
4
|
+
data.tar.gz: 1a73bbf1521c29b0b80ca2163461795cb24e24f65107c671b5aa581b17c55d20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a250df9034b5246bc99bc9f395d8b461405a5900302814069afd1a50528bc773ba3842e53ab1b2f85fd216522f0b758a533077bfa0ec360edc25570dc6bdd02c
|
7
|
+
data.tar.gz: 856f31ba5173274eaec57ac27806a3308e939245c43fc21d5a05e62a959aece056db237b2cb5fbc67275ee6ce1edfe44eb146a0c6d3c2da40339336aa101ceba
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,43 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [4.0.3] - 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 using 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`
|
4
41
|
|
5
42
|
## [3.3.0] - 14-MAR-2021
|
6
43
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
testcentricity_web (
|
4
|
+
testcentricity_web (4.0.2)
|
5
5
|
appium_lib
|
6
6
|
browserstack-local
|
7
7
|
capybara (>= 3.1, < 4)
|
@@ -19,13 +19,13 @@ PATH
|
|
19
19
|
GEM
|
20
20
|
remote: https://rubygems.org/
|
21
21
|
specs:
|
22
|
-
addressable (2.
|
22
|
+
addressable (2.8.0)
|
23
23
|
public_suffix (>= 2.0.2, < 5.0)
|
24
24
|
appium_lib (11.2.0)
|
25
25
|
appium_lib_core (~> 4.1)
|
26
26
|
nokogiri (~> 1.8, >= 1.8.1)
|
27
27
|
tomlrb (~> 1.1)
|
28
|
-
appium_lib_core (4.
|
28
|
+
appium_lib_core (4.7.1)
|
29
29
|
faye-websocket (~> 0.11.0)
|
30
30
|
selenium-webdriver (~> 3.14, >= 3.14.1)
|
31
31
|
axiom-types (0.1.1)
|
@@ -46,61 +46,59 @@ GEM
|
|
46
46
|
chronic (0.10.2)
|
47
47
|
coercible (1.0.0)
|
48
48
|
descendants_tracker (~> 0.0.1)
|
49
|
-
concurrent-ruby (1.1.
|
49
|
+
concurrent-ruby (1.1.9)
|
50
50
|
descendants_tracker (0.0.4)
|
51
51
|
thread_safe (~> 0.3, >= 0.3.1)
|
52
|
-
equalizer (0.0.11)
|
53
52
|
eventmachine (1.2.7)
|
54
|
-
faker (2.
|
53
|
+
faker (2.19.0)
|
55
54
|
i18n (>= 1.6, < 2)
|
56
|
-
faye-websocket (0.11.
|
55
|
+
faye-websocket (0.11.1)
|
57
56
|
eventmachine (>= 0.12.0)
|
58
57
|
websocket-driver (>= 0.5.1)
|
59
|
-
ffi (1.15.
|
60
|
-
i18n (1.8.
|
58
|
+
ffi (1.15.4)
|
59
|
+
i18n (1.8.11)
|
61
60
|
concurrent-ruby (~> 1.0)
|
62
61
|
ice_nine (0.11.2)
|
63
|
-
mini_mime (1.
|
64
|
-
nokogiri (1.
|
62
|
+
mini_mime (1.1.2)
|
63
|
+
nokogiri (1.12.5-x86_64-darwin)
|
65
64
|
racc (~> 1.4)
|
66
|
-
os (1.1.
|
67
|
-
power_assert (2.0.
|
65
|
+
os (1.1.4)
|
66
|
+
power_assert (2.0.1)
|
68
67
|
public_suffix (4.0.6)
|
69
|
-
racc (1.
|
68
|
+
racc (1.6.0)
|
70
69
|
rack (2.2.3)
|
71
70
|
rack-test (1.1.0)
|
72
71
|
rack (>= 1.0, < 3)
|
73
|
-
rake (13.0.
|
74
|
-
redcarpet (3.5.
|
75
|
-
regexp_parser (2.
|
72
|
+
rake (13.0.6)
|
73
|
+
redcarpet (3.5.1)
|
74
|
+
regexp_parser (2.2.0)
|
76
75
|
ruby-ole (1.2.12.2)
|
77
|
-
rubyzip (2.3.
|
76
|
+
rubyzip (2.3.2)
|
78
77
|
selenium-webdriver (3.142.7)
|
79
78
|
childprocess (>= 0.5, < 4.0)
|
80
79
|
rubyzip (>= 1.2.2)
|
81
80
|
spreadsheet (1.1.7)
|
82
81
|
ruby-ole (>= 1.0)
|
83
|
-
test-unit (3.
|
82
|
+
test-unit (3.5.3)
|
84
83
|
power_assert
|
85
84
|
thread_safe (0.3.6)
|
86
85
|
tomlrb (1.3.0)
|
87
|
-
virtus (
|
86
|
+
virtus (2.0.0)
|
88
87
|
axiom-types (~> 0.1)
|
89
88
|
coercible (~> 1.0)
|
90
89
|
descendants_tracker (~> 0.0, >= 0.0.3)
|
91
|
-
|
92
|
-
webdrivers (4.6.0)
|
90
|
+
webdrivers (4.6.1)
|
93
91
|
nokogiri (~> 1.6)
|
94
92
|
rubyzip (>= 1.3.0)
|
95
93
|
selenium-webdriver (>= 3.0, < 4.0)
|
96
|
-
websocket-driver (0.7.
|
94
|
+
websocket-driver (0.7.5)
|
97
95
|
websocket-extensions (>= 0.1.0)
|
98
96
|
websocket-extensions (0.1.5)
|
99
97
|
xpath (3.2.0)
|
100
98
|
nokogiri (~> 1.8)
|
101
99
|
|
102
100
|
PLATFORMS
|
103
|
-
|
101
|
+
x86_64-darwin-21
|
104
102
|
|
105
103
|
DEPENDENCIES
|
106
104
|
bundler
|
@@ -109,4 +107,4 @@ DEPENDENCIES
|
|
109
107
|
testcentricity_web!
|
110
108
|
|
111
109
|
BUNDLED WITH
|
112
|
-
2.1
|
110
|
+
2.2.1
|
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
|
+
|