itms_automation 2.3 → 2.6.0
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.
- checksums.yaml +4 -4
- data/bin/generate.rb +3 -37
- data/bin/helper.rb +23 -10
- data/bin/itms_automation +18 -23
- data/doc/installation.md +16 -0
- data/doc/itms-automation-API.md +103 -0
- data/doc/itms-automation-help.md +18 -0
- data/example/android/android_app/android_app_calculator.zip +0 -0
- data/example/android/android_app/android_app_calculator/AndroidCalculator.apk +0 -0
- data/example/android/android_app/android_app_calculator/features/calculator.feature +36 -0
- data/example/android/android_app/android_app_calculator/features/my_first.feature +13 -0
- data/example/android/android_app/android_app_calculator/features/screenshots/test.png +0 -0
- data/example/android/android_app/android_app_calculator/features/step_definitions/custom_steps.rb +5 -0
- data/example/android/android_app/android_app_calculator/features/support/env.rb +52 -0
- data/example/android/android_app/android_app_calculator/features/support/hooks.rb +26 -0
- data/example/android/android_web/android_web_gmail_login.zip +0 -0
- data/example/android/android_web/android_web_gmail_login/features/gmail_login.feature +12 -0
- data/example/android/android_web/android_web_gmail_login/features/my_first.feature +1 -0
- data/example/android/android_web/android_web_gmail_login/features/screenshots/test.png +0 -0
- data/example/android/android_web/android_web_gmail_login/features/step_definitions/custom_steps.rb +5 -0
- data/example/android/android_web/android_web_gmail_login/features/support/env.rb +51 -0
- data/example/android/android_web/android_web_gmail_login/features/support/hooks.rb +27 -0
- data/example/desktop web/desktop_web_gmail_login.zip +0 -0
- data/example/desktop web/desktop_web_gmail_login/features/gmail_login.feature +9 -0
- data/example/desktop web/desktop_web_gmail_login/features/gmail_multi_login.feature +21 -0
- data/example/desktop web/desktop_web_gmail_login/features/my_first.feature +1 -0
- data/example/desktop web/desktop_web_gmail_login/features/screenshots/test.png +0 -0
- data/example/desktop web/desktop_web_gmail_login/features/step_definitions/custom_steps.rb +5 -0
- data/example/desktop web/desktop_web_gmail_login/features/support/env.rb +106 -0
- data/example/desktop web/desktop_web_gmail_login/features/support/hooks.rb +38 -0
- data/features-skeleton/my_first.feature +5 -0
- data/features-skeleton/screenshots/test.png +0 -0
- data/features-skeleton/step_definitions/custom_steps.rb +5 -0
- data/features-skeleton/step_definitions/repositories/project_object.yml +1 -0
- data/features-skeleton/support/env.rb +108 -0
- data/features-skeleton/support/hooks.rb +38 -0
- data/lib/itms_automation.rb +1 -3
- data/lib/itms_automation/assertion_steps.rb +68 -0
- data/lib/itms_automation/click_elements_steps.rb +24 -0
- data/lib/itms_automation/configuration_steps.rb +7 -0
- data/lib/itms_automation/input_steps.rb +59 -0
- data/lib/itms_automation/javascript_handling_steps.rb +10 -0
- data/lib/itms_automation/methods/assertion_methods.rb +333 -0
- data/lib/itms_automation/methods/click_elements_methods.rb +23 -0
- data/lib/itms_automation/methods/configuration_methods.rb +35 -0
- data/lib/itms_automation/methods/error_handling_methods.rb +93 -0
- data/lib/itms_automation/methods/input_methods.rb +69 -0
- data/lib/itms_automation/methods/javascript_handling_methods.rb +9 -0
- data/lib/itms_automation/methods/misc_methods.rb +63 -0
- data/lib/itms_automation/methods/navigate_methods.rb +123 -0
- data/lib/itms_automation/methods/progress_methods.rb +15 -0
- data/lib/itms_automation/methods/required_files.rb +9 -0
- data/lib/itms_automation/methods/screenshot_methods.rb +6 -0
- data/lib/itms_automation/navigation_steps.rb +79 -0
- data/lib/itms_automation/progress_steps.rb +17 -0
- data/lib/itms_automation/screenshot_steps.rb +6 -0
- data/lib/itms_automation/version.rb +5 -3
- metadata +93 -90
- data/bin/console +0 -14
- data/bin/documentation_generator.rb +0 -119
- data/bin/setup +0 -8
- data/lib/itms_automation/all_steps.rb +0 -8
- data/lib/itms_automation/assertion_helper.rb +0 -29
- data/lib/itms_automation/auto_util.rb +0 -702
- data/lib/itms_automation/database_steps_helper.rb +0 -125
- data/lib/itms_automation/web_steps_helper.rb +0 -844
- data/project/Gemfile +0 -3
- data/project/Gemfile.lock +0 -92
- data/project/README.md +0 -34
- data/project/Rakefile +0 -24
- data/project/config/chrome_headless_options.yaml +0 -1
- data/project/config/chrome_options.yaml +0 -6
- data/project/config/firefox_headless_options.yaml +0 -1
- data/project/config/firefox_options.yaml +0 -1
- data/project/config/ie_options.yaml +0 -1
- data/project/config/remote_options.yaml +0 -6
- data/project/config/safari_options.yaml +0 -1
- data/project/cucumber.yml +0 -4
- data/project/features/TestSuite/WebGUI.feature +0 -5
- data/project/features/step_definitions/lib_steps/steps_definition.rb +0 -46
- data/project/features/step_definitions/repositories/project_object.yml +0 -26
- data/project/features/support/env.rb +0 -9
- data/project/features/support/hooks.rb +0 -128
data/lib/itms_automation.rb
CHANGED
@@ -0,0 +1,68 @@
|
|
1
|
+
# require 'cucumber'
|
2
|
+
# require_relative 'methods/assertion_methods'
|
3
|
+
|
4
|
+
# # page title checking
|
5
|
+
# Then(/^I should\s*((?:not)?)\s+see page title as "(.*?)"$/) do |present, title|
|
6
|
+
# check_title(title, present.empty?)
|
7
|
+
# end
|
8
|
+
|
9
|
+
# Then(/^I should\s*((?:not)?)\s+see page title having partial text as "(.*?)"$/) do |present, partial_text_title|
|
10
|
+
# check_partial_title(partial_text_title, present.empty?)
|
11
|
+
# end
|
12
|
+
|
13
|
+
# # step to check element text
|
14
|
+
# Then(/^element "([^\"]*)" should\s*((?:not)?)\s+have text as "(.*?)"$/) do |element, present, value |
|
15
|
+
# check_element_text(element, value, present.empty?)
|
16
|
+
# end
|
17
|
+
|
18
|
+
# # step to check element partial text
|
19
|
+
# Then(/^element "([^\"]*)" should\s*((?:not)?)\s+have partial text as "(.*?)"$/) do |element, present, value |
|
20
|
+
# check_element_partial_text(element, value, present.empty?)
|
21
|
+
# end
|
22
|
+
|
23
|
+
# # step to check attribute value
|
24
|
+
# Then(/^element "([^\"]*)" should\s*((?:not)?)\s+have attribute "(.*?)" with value "(.*?)"$/) do |element, present, attrb, value|
|
25
|
+
# check_element_attribute(element, attrb, value, present.empty?)
|
26
|
+
# end
|
27
|
+
|
28
|
+
# # step to check element enabled or not
|
29
|
+
# Then(/^element "([^\"]*)" should\s*((?:not)?)\s+be (enabled|disabled)$/) do |element, present, state|
|
30
|
+
# flag = state == 'enabled'
|
31
|
+
# flag = !flag unless present.empty?
|
32
|
+
# check_element_enable(element, flag)
|
33
|
+
# end
|
34
|
+
|
35
|
+
# # step to check element present or not
|
36
|
+
# Then(/^element "(.*?)" should\s*((?:not)?)\s+be present$/) do |element, present|
|
37
|
+
# check_element_presence(element, present.empty?)
|
38
|
+
# end
|
39
|
+
|
40
|
+
# # step to assert checkbox is checked or unchecked
|
41
|
+
# Then(/^checkbox "(.*?)" should be (checked|unchecked)$/) do |element, state|
|
42
|
+
# flag = state == 'checked'
|
43
|
+
# is_checkbox_checked(element, flag)
|
44
|
+
# end
|
45
|
+
|
46
|
+
# # steps to assert radio button checked or unchecked
|
47
|
+
# Then(/^radio button"(.*?)" should be (selected|unselected)$/) do |element, state|
|
48
|
+
# flag = state == 'selected'
|
49
|
+
# is_radio_button_selected(element, flag)
|
50
|
+
# end
|
51
|
+
|
52
|
+
# # steps to assert option by text from radio button group selected/unselected
|
53
|
+
# Then(/^option "(.*?)" by (.+) from radio button group "(.*?)" should be (selected|unselected)$/) do |option, attrb, element, state|
|
54
|
+
# flag = state == 'selected'
|
55
|
+
# is_option_from_radio_button_group_selected(element, attrb, option, flag)
|
56
|
+
# end
|
57
|
+
|
58
|
+
# # step to assert javascript pop-up alert text
|
59
|
+
# Then(/^I should see alert text as "(.*?)"$/) do |actual_value|
|
60
|
+
# check_alert_text(actual_value)
|
61
|
+
# end
|
62
|
+
|
63
|
+
# # step to assert dropdown list
|
64
|
+
# Then(/^option "(.*?)" by (.+) from dropdown "(.*?)" should be (selected|unselected)$/) do |option, by, element, state|
|
65
|
+
# flag = state == 'selected'
|
66
|
+
# is_option_from_dropdown_selected(element, by, option, state)
|
67
|
+
# end
|
68
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# require 'cucumber'
|
2
|
+
# require_relative 'methods/click_elements_methods'
|
3
|
+
|
4
|
+
# # click on web element
|
5
|
+
# When(/^I click on element"(.*?)"$/) do |element|
|
6
|
+
# click(element)
|
7
|
+
# end
|
8
|
+
|
9
|
+
# Then(/^I forcefully click on element "(.*?)"$/) do |element|
|
10
|
+
# click_forcefully(element)
|
11
|
+
# end
|
12
|
+
|
13
|
+
# # double click on web element
|
14
|
+
# Then(/^I double click on element "(.*?)"$/) do |element|
|
15
|
+
# double_click(element)
|
16
|
+
# end
|
17
|
+
|
18
|
+
# When(/^I tap on element"(.*?)"$/) do |element|
|
19
|
+
# click(element)
|
20
|
+
# end
|
21
|
+
|
22
|
+
# Then(/^I long press on element "(.*?)"$/) do |element|
|
23
|
+
# long_press(element, duration)
|
24
|
+
# end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# require 'cucumber'
|
2
|
+
# require_relative 'methods/input_methods'
|
3
|
+
|
4
|
+
# # enter text into input field steps
|
5
|
+
# Then(/^I enter "([^\"]*)" into element "(.*?)"$/) do |text, element|
|
6
|
+
# enter_text(type, element)
|
7
|
+
# end
|
8
|
+
|
9
|
+
# # clear input field steps
|
10
|
+
# Then(/^I clear input element "(.*?)"$/) do |type, element|
|
11
|
+
# clear_text(type, element)
|
12
|
+
# end
|
13
|
+
|
14
|
+
# # select option by text/value from dropdown/multiselect
|
15
|
+
# Then(/^I select "(.*?)" option by (.+) from\s*((?:multiselect)?)\sdropdown "(.*?)"$/) do |option, option_by, present, element|
|
16
|
+
# validate_option_by option_by
|
17
|
+
# select_option_from_dropdown(element, option_by, option)
|
18
|
+
# end
|
19
|
+
|
20
|
+
# # select option by index from dropdown/multiselect
|
21
|
+
# Then(/^I select (\d+) option by index from\s*((?:multiselect)?)\sdropdown "(.*?)"$/) do |option, present, element|
|
22
|
+
# select_option_from_dropdown(element, 'index', (option.to_i) -1)
|
23
|
+
# end
|
24
|
+
|
25
|
+
# # step to select option from mutliselect dropdown list
|
26
|
+
# Then(/^I select all options from multiselect dropdown "(.*?)"$/) do |element|
|
27
|
+
# select_all_option_from_multiselect_dropdown(element)
|
28
|
+
# end
|
29
|
+
|
30
|
+
# # step to unselect option from mutliselect dropdown list
|
31
|
+
# Then(/^I unselect all options from multiselect dropdown "(.*?)"$/) do |element|
|
32
|
+
# unselect_all_option_from_multiselect_dropdown(element)
|
33
|
+
# end
|
34
|
+
|
35
|
+
# # check checkbox steps
|
36
|
+
# Then(/^I check the checkbox "(.*?)"$/) do |element|
|
37
|
+
# check_checkbox(element)
|
38
|
+
# end
|
39
|
+
|
40
|
+
# # uncheck checkbox steps
|
41
|
+
# Then(/^I uncheck the checkbox "(.*?)"$/) do |element|
|
42
|
+
# uncheck_checkbox(element)
|
43
|
+
# end
|
44
|
+
|
45
|
+
# # steps to toggle checkbox
|
46
|
+
# Then(/^I toggle checkbox "(.*?)"$/) do |element|
|
47
|
+
# toggle_checkbox(element)
|
48
|
+
# end
|
49
|
+
|
50
|
+
# # step to select radio button
|
51
|
+
# Then(/^I select radio button "(.*?)"$/) do |element|
|
52
|
+
# select_radio_button(element)
|
53
|
+
# end
|
54
|
+
|
55
|
+
# # steps to select option by text from radio button group
|
56
|
+
# Then(/^I select "(.*?)" option by (.+) from radio button group "(.*?)"$/) do |option, option_by, element|
|
57
|
+
# validate_option_by option_by
|
58
|
+
# select_option_from_radio_button_group(element, option_by, option)
|
59
|
+
# end
|
@@ -0,0 +1,333 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require_relative 'required_files'
|
3
|
+
|
4
|
+
# This file contains assertion methods which are called from assertion_steps.rb
|
5
|
+
|
6
|
+
# Method to return page title
|
7
|
+
def get_page_title
|
8
|
+
$driver.title
|
9
|
+
end
|
10
|
+
|
11
|
+
# Method to verify title
|
12
|
+
# param 1 : String : expected title
|
13
|
+
# param 2 : Boolean : test case [true or flase]
|
14
|
+
def check_title(title, test_case)
|
15
|
+
page_title = get_page_title
|
16
|
+
if test_case
|
17
|
+
if page_title != "#{title}"
|
18
|
+
raise TestCaseFailed, "Page Title Not Matched, Actual Page Title : #{page_title}"
|
19
|
+
end
|
20
|
+
else
|
21
|
+
if page_title == "#{title}"
|
22
|
+
raise TestCaseFailed, "Page Title Matched, Actual Page Title:#{page_title}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Method to verify partial title
|
28
|
+
# param 1 : String : partial title string
|
29
|
+
# param 2 : Boolean : test case [true or flase]
|
30
|
+
def check_partial_title(partial_text_title, test_case)
|
31
|
+
page_title = get_page_title
|
32
|
+
if test_case
|
33
|
+
if not page_title.include? "#{partial_text_title}"
|
34
|
+
raise TestCaseFailed, 'Partial Page Title Not Present'
|
35
|
+
end
|
36
|
+
else
|
37
|
+
if page_title.include? "#{partial_text_title}"
|
38
|
+
raise TestCaseFailed, 'Page Title Matched'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Method to get element text
|
44
|
+
# param : String
|
45
|
+
def get_element_text(element)
|
46
|
+
WAIT.until { find_object(element) }.text
|
47
|
+
end
|
48
|
+
|
49
|
+
# Method to check element text
|
50
|
+
# param 1 : String : Element
|
51
|
+
# param 2 : String : Expected element text
|
52
|
+
# param 3 : Boolean : test case [true or flase]
|
53
|
+
def check_element_text(element, actual_value, test_case)
|
54
|
+
element_text = get_element_text(element)
|
55
|
+
|
56
|
+
if test_case
|
57
|
+
if element_text != actual_value
|
58
|
+
raise TestCaseFailed, 'Text Not Matched'
|
59
|
+
end
|
60
|
+
else
|
61
|
+
if element_text == actual_value
|
62
|
+
raise TestCaseFailed, 'Text Matched'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Method to check partial element text
|
68
|
+
# param 1 : String : Element
|
69
|
+
# param 2 : String : Expected element partial text
|
70
|
+
# param 3 : Boolean : test case [true or flase]
|
71
|
+
def check_element_partial_text(element, actual_value, test_case)
|
72
|
+
element_text = get_element_text(element)
|
73
|
+
|
74
|
+
if test_case
|
75
|
+
if not element_text.include? "#{actual_value}"
|
76
|
+
raise TestCaseFailed, 'Text Not Matched'
|
77
|
+
end
|
78
|
+
else
|
79
|
+
if element_text.include? "#{actual_value}"
|
80
|
+
raise TestCaseFailed, 'Text Matched'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Method to return element status - enabled?
|
86
|
+
# param : String : Element
|
87
|
+
def is_element_enabled(element)
|
88
|
+
WAIT.until{ find_object(element) }.enabled?
|
89
|
+
end
|
90
|
+
|
91
|
+
# Element enabled checking
|
92
|
+
# param 1 : String : Element
|
93
|
+
# param 2 : Boolean : test case [true or flase]
|
94
|
+
def check_element_enable(element, test_case)
|
95
|
+
result = is_element_enabled(element)
|
96
|
+
|
97
|
+
if test_case
|
98
|
+
raise TestCaseFailed, 'Element Not Enabled' unless result
|
99
|
+
else
|
100
|
+
raise TestCaseFailed, 'Element Enabled' unless !result
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# method to get attribute value
|
105
|
+
# param 1 : String : Element
|
106
|
+
# param 2 : String : atrribute name
|
107
|
+
def get_element_attribute(element, attribute_name)
|
108
|
+
WAIT.until{ find_object(element) }.attribute("#{attribute_name}")
|
109
|
+
end
|
110
|
+
|
111
|
+
# method to check attribute value
|
112
|
+
# param 1 : String : Element
|
113
|
+
# param 2 : String : atrribute name
|
114
|
+
# param 3 : String : atrribute value
|
115
|
+
# param 4 : Boolean : test case [true or flase]
|
116
|
+
def check_element_attribute(element, attribute_name, attribute_value, test_case)
|
117
|
+
|
118
|
+
attr_val = get_element_attribute(element, attribute_name)
|
119
|
+
|
120
|
+
if test_case
|
121
|
+
if attr_val != attribute_value
|
122
|
+
raise TestCaseFailed, 'Attribute Value Not Matched'
|
123
|
+
end
|
124
|
+
else
|
125
|
+
if attr_val == attribute_value
|
126
|
+
raise TestCaseFailed, 'Attribute Value Matched'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# method to get element status - displayed?
|
132
|
+
# param : String : Element
|
133
|
+
def is_element_displayed(element)
|
134
|
+
WAIT.until{ find_object(element) }.displayed?
|
135
|
+
end
|
136
|
+
|
137
|
+
# method to check element presence
|
138
|
+
# param 1 : String : Element
|
139
|
+
# param 2 : Boolean : test case [true or flase]
|
140
|
+
def check_element_presence(element, test_case)
|
141
|
+
if test_case
|
142
|
+
if !is_element_displayed(element)
|
143
|
+
raise TestCaseFailed, 'Element Not Present'
|
144
|
+
end
|
145
|
+
else
|
146
|
+
begin
|
147
|
+
if is_element_displayed(element)
|
148
|
+
raise 'Present' # since it is negative test and we found element
|
149
|
+
end
|
150
|
+
rescue Exception => e
|
151
|
+
if e.message == 'Present' # only raise if it present
|
152
|
+
raise TestCaseFailed, 'Element Present'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# method to assert checkbox check/uncheck
|
159
|
+
# param 1 : String : Element
|
160
|
+
# param 2 : Boolean : test case [true or flase]
|
161
|
+
def is_checkbox_checked(element, should_be_checked = true)
|
162
|
+
checkbox = WAIT.until{ find_object(element) }
|
163
|
+
|
164
|
+
if !checkbox.selected? && should_be_checked
|
165
|
+
raise TestCaseFailed, 'Checkbox is not checked'
|
166
|
+
elsif checkbox.selected? && !should_be_checked
|
167
|
+
raise TestCaseFailed, 'Checkbox is checked'
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# method to assert radio button selected/unselected
|
172
|
+
# param 1 : String : Element
|
173
|
+
# param 2 : Boolean : test case [true or flase]
|
174
|
+
def is_radio_button_selected(element, should_be_selected = true)
|
175
|
+
radio_button = WAIT.until{ find_object(element) }
|
176
|
+
|
177
|
+
if !radio_button.selected? && should_be_selected
|
178
|
+
raise TestCaseFailed, 'Radio Button not selected'
|
179
|
+
elsif radio_button.selected? && !should_be_selected
|
180
|
+
raise TestCaseFailed, 'Radio Button is selected'
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# method to assert option from radio button group is selected/unselected
|
185
|
+
def is_option_from_radio_button_group_selected(element, by, option, should_be_selected = true)
|
186
|
+
radio_button_group = WAIT.until{ find_object(element) }
|
187
|
+
|
188
|
+
getter = ->(rb, by) { by == 'value' ? rb.attribute('value') : rb.text }
|
189
|
+
|
190
|
+
ele = radio_button_group.find { |rb| getter.call(rb, by) == option }
|
191
|
+
|
192
|
+
if !ele.selected? && should_be_selected
|
193
|
+
raise TestCaseFailed, 'Radio button is not selected'
|
194
|
+
elsif ele.selected? && !should_be_selected
|
195
|
+
raise TestCaseFailed, 'Radio button is selected'
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# method to get javascript pop-up alert text
|
200
|
+
def get_alert_text
|
201
|
+
$driver.switch_to.alert.text
|
202
|
+
end
|
203
|
+
|
204
|
+
# method to check javascript pop-up alert text
|
205
|
+
def check_alert_text(text)
|
206
|
+
if get_alert_text != text
|
207
|
+
raise TestCaseFailed, 'Text on alert pop up not matched'
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def is_option_from_dropdown_selected(element, by, option, should_be_selected=true)
|
212
|
+
dropdown = WAIT.until { find_object(element) }
|
213
|
+
select_list = Selenium::WebDriver::Support::Select.new(dropdown)
|
214
|
+
|
215
|
+
if by == 'text'
|
216
|
+
actual_value = select_list.first_selected_option.text
|
217
|
+
else
|
218
|
+
actual_value = select_list.first_selected_option.attribute('value')
|
219
|
+
end
|
220
|
+
|
221
|
+
if !actual_value == option && should_be_selected
|
222
|
+
raise TestCaseFailed, 'Option Not Selected From Dropwdown'
|
223
|
+
elsif actual_value == option && !should_be_selected
|
224
|
+
raise TestCaseFailed, 'Option Selected From Dropwdown'
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Method to find difference between images
|
229
|
+
def does_images_similar?(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
|
230
|
+
if !compare_image(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
|
231
|
+
raise TestCaseFailed, 'Actual image is different from expected image'
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# Method to compare two images
|
236
|
+
# param 1 : String : Locator type (id, name, class, xpath, css, url)
|
237
|
+
# param 2 : String : Locator value
|
238
|
+
# param 3 : String : Locator type (id, name, class, xpath, css, url, image_name)
|
239
|
+
# param 4 : String : Locator value
|
240
|
+
def compare_image(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
|
241
|
+
if actual_img_access_type == 'url'
|
242
|
+
actual_img_url = actual_img_access_name
|
243
|
+
else
|
244
|
+
actual_img_url = get_element_attribute(actual_img_access_type, actual_img_access_name, 'src')
|
245
|
+
end
|
246
|
+
|
247
|
+
if excp_img_access_type == 'url'
|
248
|
+
expected_img_url = excp_img_access_name
|
249
|
+
elsif excp_img_access_type == 'image_name'
|
250
|
+
expected_img_url = './features/expected_images/' + excp_img_access_name
|
251
|
+
else
|
252
|
+
expected_img_url = get_element_attribute(excp_img_access_type, excp_img_access_name, 'src')
|
253
|
+
end
|
254
|
+
|
255
|
+
# replace 'https' with 'http' from actual image url
|
256
|
+
if actual_img_url.include? 'https'
|
257
|
+
actual_img_url['https'] = 'http'
|
258
|
+
end
|
259
|
+
|
260
|
+
# replace 'https' with 'http' from expected image url
|
261
|
+
if expected_img_url.include? 'https'
|
262
|
+
expected_img_url['https'] = 'http'
|
263
|
+
end
|
264
|
+
|
265
|
+
if expected_img_url.include? '.png'
|
266
|
+
image_type = 'png'
|
267
|
+
else
|
268
|
+
image_type = 'jpg'
|
269
|
+
end
|
270
|
+
|
271
|
+
# Storing actual image locally
|
272
|
+
open('./features/actual_images/actual_image.' + image_type, 'wb') do |file|
|
273
|
+
file << open(actual_img_url).read
|
274
|
+
end
|
275
|
+
|
276
|
+
actual_img_url = './features/actual_images/actual_image.' + image_type
|
277
|
+
|
278
|
+
# Storing Expected image locally
|
279
|
+
if excp_img_access_type != 'image_name'
|
280
|
+
open('./features/expected_images/expected_image.' + image_type, 'wb') do |file|
|
281
|
+
file << open(expected_img_url).read
|
282
|
+
end
|
283
|
+
expected_img_url = './features/expected_images/expected_image.' + image_type
|
284
|
+
end
|
285
|
+
|
286
|
+
# Verify image extension and call respective compare function
|
287
|
+
if image_type == 'png'
|
288
|
+
return compare_png_images(expected_img_url, actual_img_url)
|
289
|
+
end
|
290
|
+
|
291
|
+
compare_jpeg_images(expected_img_url, actual_img_url)
|
292
|
+
end
|
293
|
+
|
294
|
+
# Comparing jpg images
|
295
|
+
def compare_jpeg_images(expected_img_url, actual_img_url)
|
296
|
+
if open(expected_img_url).read == open(actual_img_url).read
|
297
|
+
return true
|
298
|
+
else
|
299
|
+
puts 'Difference in images'
|
300
|
+
return false
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# Comparing png images
|
305
|
+
def compare_png_images(expected_img_url, actual_img_url)
|
306
|
+
images = [
|
307
|
+
ChunkyPNG::Image.from_file(expected_img_url),
|
308
|
+
ChunkyPNG::Image.from_file(actual_img_url)
|
309
|
+
]
|
310
|
+
|
311
|
+
diff = []
|
312
|
+
|
313
|
+
images.first.height.times do |y|
|
314
|
+
images.first.row(y).each_with_index do |pixel, x|
|
315
|
+
diff << [x, y] unless pixel == images.last[x, y]
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
if diff.length != 0
|
320
|
+
puts "\npixels (total): #{images.first.pixels.length}"
|
321
|
+
puts "pixels changed: #{diff.length}"
|
322
|
+
puts "pixels changed (%): #{(diff.length.to_f / images.first.pixels.length) * 100}%"
|
323
|
+
|
324
|
+
x, y = diff.map { |xy| xy[0] }, diff.map { |xy| xy[1] }
|
325
|
+
images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0, 255, 0))
|
326
|
+
cur_time = Time.now.strftime('%Y%m%d%H%M%S%L')
|
327
|
+
images.last.save("./features/image_difference/difference_#{cur_time}.png")
|
328
|
+
|
329
|
+
puts "\nDifference between images saved as : difference_#{cur_time}.png\n"
|
330
|
+
return false
|
331
|
+
end
|
332
|
+
true
|
333
|
+
end
|