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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/bin/generate.rb +3 -37
  3. data/bin/helper.rb +23 -10
  4. data/bin/itms_automation +18 -23
  5. data/doc/installation.md +16 -0
  6. data/doc/itms-automation-API.md +103 -0
  7. data/doc/itms-automation-help.md +18 -0
  8. data/example/android/android_app/android_app_calculator.zip +0 -0
  9. data/example/android/android_app/android_app_calculator/AndroidCalculator.apk +0 -0
  10. data/example/android/android_app/android_app_calculator/features/calculator.feature +36 -0
  11. data/example/android/android_app/android_app_calculator/features/my_first.feature +13 -0
  12. data/example/android/android_app/android_app_calculator/features/screenshots/test.png +0 -0
  13. data/example/android/android_app/android_app_calculator/features/step_definitions/custom_steps.rb +5 -0
  14. data/example/android/android_app/android_app_calculator/features/support/env.rb +52 -0
  15. data/example/android/android_app/android_app_calculator/features/support/hooks.rb +26 -0
  16. data/example/android/android_web/android_web_gmail_login.zip +0 -0
  17. data/example/android/android_web/android_web_gmail_login/features/gmail_login.feature +12 -0
  18. data/example/android/android_web/android_web_gmail_login/features/my_first.feature +1 -0
  19. data/example/android/android_web/android_web_gmail_login/features/screenshots/test.png +0 -0
  20. data/example/android/android_web/android_web_gmail_login/features/step_definitions/custom_steps.rb +5 -0
  21. data/example/android/android_web/android_web_gmail_login/features/support/env.rb +51 -0
  22. data/example/android/android_web/android_web_gmail_login/features/support/hooks.rb +27 -0
  23. data/example/desktop web/desktop_web_gmail_login.zip +0 -0
  24. data/example/desktop web/desktop_web_gmail_login/features/gmail_login.feature +9 -0
  25. data/example/desktop web/desktop_web_gmail_login/features/gmail_multi_login.feature +21 -0
  26. data/example/desktop web/desktop_web_gmail_login/features/my_first.feature +1 -0
  27. data/example/desktop web/desktop_web_gmail_login/features/screenshots/test.png +0 -0
  28. data/example/desktop web/desktop_web_gmail_login/features/step_definitions/custom_steps.rb +5 -0
  29. data/example/desktop web/desktop_web_gmail_login/features/support/env.rb +106 -0
  30. data/example/desktop web/desktop_web_gmail_login/features/support/hooks.rb +38 -0
  31. data/features-skeleton/my_first.feature +5 -0
  32. data/features-skeleton/screenshots/test.png +0 -0
  33. data/features-skeleton/step_definitions/custom_steps.rb +5 -0
  34. data/features-skeleton/step_definitions/repositories/project_object.yml +1 -0
  35. data/features-skeleton/support/env.rb +108 -0
  36. data/features-skeleton/support/hooks.rb +38 -0
  37. data/lib/itms_automation.rb +1 -3
  38. data/lib/itms_automation/assertion_steps.rb +68 -0
  39. data/lib/itms_automation/click_elements_steps.rb +24 -0
  40. data/lib/itms_automation/configuration_steps.rb +7 -0
  41. data/lib/itms_automation/input_steps.rb +59 -0
  42. data/lib/itms_automation/javascript_handling_steps.rb +10 -0
  43. data/lib/itms_automation/methods/assertion_methods.rb +333 -0
  44. data/lib/itms_automation/methods/click_elements_methods.rb +23 -0
  45. data/lib/itms_automation/methods/configuration_methods.rb +35 -0
  46. data/lib/itms_automation/methods/error_handling_methods.rb +93 -0
  47. data/lib/itms_automation/methods/input_methods.rb +69 -0
  48. data/lib/itms_automation/methods/javascript_handling_methods.rb +9 -0
  49. data/lib/itms_automation/methods/misc_methods.rb +63 -0
  50. data/lib/itms_automation/methods/navigate_methods.rb +123 -0
  51. data/lib/itms_automation/methods/progress_methods.rb +15 -0
  52. data/lib/itms_automation/methods/required_files.rb +9 -0
  53. data/lib/itms_automation/methods/screenshot_methods.rb +6 -0
  54. data/lib/itms_automation/navigation_steps.rb +79 -0
  55. data/lib/itms_automation/progress_steps.rb +17 -0
  56. data/lib/itms_automation/screenshot_steps.rb +6 -0
  57. data/lib/itms_automation/version.rb +5 -3
  58. metadata +93 -90
  59. data/bin/console +0 -14
  60. data/bin/documentation_generator.rb +0 -119
  61. data/bin/setup +0 -8
  62. data/lib/itms_automation/all_steps.rb +0 -8
  63. data/lib/itms_automation/assertion_helper.rb +0 -29
  64. data/lib/itms_automation/auto_util.rb +0 -702
  65. data/lib/itms_automation/database_steps_helper.rb +0 -125
  66. data/lib/itms_automation/web_steps_helper.rb +0 -844
  67. data/project/Gemfile +0 -3
  68. data/project/Gemfile.lock +0 -92
  69. data/project/README.md +0 -34
  70. data/project/Rakefile +0 -24
  71. data/project/config/chrome_headless_options.yaml +0 -1
  72. data/project/config/chrome_options.yaml +0 -6
  73. data/project/config/firefox_headless_options.yaml +0 -1
  74. data/project/config/firefox_options.yaml +0 -1
  75. data/project/config/ie_options.yaml +0 -1
  76. data/project/config/remote_options.yaml +0 -6
  77. data/project/config/safari_options.yaml +0 -1
  78. data/project/cucumber.yml +0 -4
  79. data/project/features/TestSuite/WebGUI.feature +0 -5
  80. data/project/features/step_definitions/lib_steps/steps_definition.rb +0 -46
  81. data/project/features/step_definitions/repositories/project_object.yml +0 -26
  82. data/project/features/support/env.rb +0 -9
  83. data/project/features/support/hooks.rb +0 -128
@@ -1,3 +1 @@
1
- require 'cucumber_priority'
2
- require "itms_automation/version"
3
- Dir[File.dirname(__FILE__) + '/itms_automation/*.rb'].each { |file| require file }
1
+ Dir[File.dirname(__FILE__) + '/itms_automation/methods/*.rb'].each { |file| require file }
@@ -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,7 @@
1
+ # require 'cucumber'
2
+ # require_relative 'methods/configuration_methods'
3
+
4
+ # # step to print configuration
5
+ # Then(/^I print configuration$/) do
6
+ # print_congifugartion
7
+ # 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,10 @@
1
+ # require 'cucumber'
2
+ # require_relative 'methods/javascript_handling_methods'
3
+
4
+ # Then(/^I accept alert$/) do
5
+ # handle_alert('accept')
6
+ # end
7
+
8
+ # Then(/^I dismiss alert$/) do
9
+ # handle_alert('dismiss')
10
+ # 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