Ifd_Automation 1.9.2 → 2.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/documentation_generator.rb +1 -1
- data/lib/Ifd_Automation/REST_steps.rb +105 -0
- data/lib/Ifd_Automation/SOAP_steps.rb +54 -0
- data/lib/Ifd_Automation/database_steps.rb +17 -47
- data/lib/Ifd_Automation/dynamic_store_vavue_steps.rb +25 -0
- data/lib/Ifd_Automation/email_steps.rb +32 -36
- data/lib/Ifd_Automation/file_steps.rb +7 -58
- data/lib/Ifd_Automation/require_libs.rb +6 -0
- data/lib/Ifd_Automation/ssh_steps.rb +14 -23
- data/lib/Ifd_Automation/version.rb +1 -1
- data/lib/Ifd_Automation/web_steps.rb +58 -293
- data/lib/helper/assertion_helpers.rb +100 -0
- data/lib/helper/auto_utils.rb +67 -0
- data/lib/{Ifd_Automation_support → helper}/connection_helpers.rb +2 -2
- data/lib/{Ifd_Automation_support → helper}/core.rb +154 -60
- data/lib/{Ifd_Automation_support → helper}/mail_helpers.rb +2 -2
- data/lib/helper/web_steps_helpers.rb +123 -0
- data/project/Gemfile +1 -2
- data/project/features/Screenshot/failed_sample.png +0 -0
- data/project/features/TestData/globalData.yml +4 -1
- data/project/features/TestSuite/test.feature +1 -4
- data/project/features/step_definitions/lib_steps/test.rb +5 -3
- data/project/features/step_definitions/repositories/project_object.yml +2 -2
- data/project/features/support/env.rb +53 -52
- data/project/features/support/hooks.rb +2 -0
- data/project/features/support/project_config.yml +6 -6
- metadata +36 -148
- data/lib/Ifd_Automation/javascript_steps.rb +0 -33
- data/lib/Ifd_Automation/required_libs.rb +0 -7
- data/lib/Ifd_Automation/response.rb +0 -105
- data/lib/Ifd_Automation/webservice_steps.rb +0 -281
- data/lib/Ifd_Automation_support/assertion_helpers.rb +0 -205
- data/lib/Ifd_Automation_support/javascript_helpers.rb +0 -45
- data/lib/Ifd_Automation_support/selenium_sync_issues.rb +0 -62
- data/lib/Ifd_Automation_support/web_steps_helpers.rb +0 -296
- data/project/Gemfile.lock +0 -203
- data/project/Rakefile +0 -46
@@ -1,33 +0,0 @@
|
|
1
|
-
require_relative 'required_libs'
|
2
|
-
|
3
|
-
Then(/^I accept pop-up alert$/) do
|
4
|
-
handle_alert('accept')
|
5
|
-
end
|
6
|
-
|
7
|
-
Then(/^I dismiss pop-up alert$/) do
|
8
|
-
handle_alert('dismiss')
|
9
|
-
end
|
10
|
-
|
11
|
-
And /^I focus in new open page$/ do
|
12
|
-
switch_to_windows(last)
|
13
|
-
end
|
14
|
-
|
15
|
-
And /^I focus in previous page$/ do
|
16
|
-
switch_to_windows(first)
|
17
|
-
end
|
18
|
-
|
19
|
-
And /^I close current windows$/ do
|
20
|
-
close_windows
|
21
|
-
end
|
22
|
-
|
23
|
-
Given /^I go back to the previous page$/ do
|
24
|
-
get_browser_back
|
25
|
-
end
|
26
|
-
|
27
|
-
When /^I refresh this page$/ do
|
28
|
-
refresh_page
|
29
|
-
end
|
30
|
-
|
31
|
-
And /^I open new browser windows$/ do
|
32
|
-
open_new_windows_browser
|
33
|
-
end
|
@@ -1,7 +0,0 @@
|
|
1
|
-
require_relative '../Ifd_Automation_support/assertion_helpers.rb'
|
2
|
-
require_relative '../Ifd_Automation_support/connection_helpers.rb'
|
3
|
-
require_relative '../Ifd_Automation_support/core.rb'
|
4
|
-
require_relative '../Ifd_Automation_support/javascript_helpers.rb'
|
5
|
-
require_relative '../Ifd_Automation_support/mail_helpers.rb'
|
6
|
-
require_relative '../Ifd_Automation_support/selenium_sync_issues.rb'
|
7
|
-
require_relative '../Ifd_Automation_support/web_steps_helpers.rb'
|
@@ -1,105 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'jsonpath'
|
3
|
-
require 'rest-client'
|
4
|
-
|
5
|
-
module CucumberApi
|
6
|
-
|
7
|
-
# Extension of {RestClient::Response} with support for JSON path traversal and validation
|
8
|
-
module Response
|
9
|
-
|
10
|
-
# include RestClient::Response
|
11
|
-
|
12
|
-
# Create a Response with JSON path support
|
13
|
-
# @param response [RestClient::Response] original response
|
14
|
-
# @return [Response] self
|
15
|
-
def self.create response
|
16
|
-
# include RestClient::Response
|
17
|
-
result = response
|
18
|
-
result.extend Response
|
19
|
-
result
|
20
|
-
end
|
21
|
-
|
22
|
-
# Check if given JSON path exists
|
23
|
-
# @param json_path [String] a valid JSON path expression
|
24
|
-
# @param json [String] optional JSON from which to check JSON path, default to response body
|
25
|
-
# @return [true, false] true if JSON path is valid and exists, false otherwise
|
26
|
-
def has json_path, json=nil
|
27
|
-
if json.nil?
|
28
|
-
json = JSON.parse body
|
29
|
-
end
|
30
|
-
not JsonPath.new(json_path).on(json).empty?
|
31
|
-
end
|
32
|
-
|
33
|
-
# Retrieve value of the first JSON element with given JSON path
|
34
|
-
# @param json_path [String] a valid JSON path expression
|
35
|
-
# @param json [String] optional JSON from which to apply JSON path, default to response body
|
36
|
-
# @return [Object] value of first retrieved JSON element in form of Ruby object
|
37
|
-
# @raise [Exception] if JSON path is invalid or no matching JSON element found
|
38
|
-
def get json_path, json=nil
|
39
|
-
if json.nil?
|
40
|
-
json = JSON.parse body
|
41
|
-
end
|
42
|
-
results = JsonPath.new(json_path).on(json)
|
43
|
-
if results.empty?
|
44
|
-
raise %/Expected json path '#{json_path}' not found\n#{to_json_s}/
|
45
|
-
end
|
46
|
-
results.first
|
47
|
-
end
|
48
|
-
|
49
|
-
# Retrieve value of the first JSON element with given JSON path as given type
|
50
|
-
# @param json_path [String] a valid JSON path expression
|
51
|
-
# @param type [String] required type, possible values are 'numeric', 'array', 'string', 'boolean', 'numeric_string'
|
52
|
-
# or 'object'
|
53
|
-
# @param json [String] optional JSON from which to apply JSON path, default to response body
|
54
|
-
# @return [Object] value of first retrieved JSON element in form of given type
|
55
|
-
# @raise [Exception] if JSON path is invalid or no matching JSON element found or matching element does not match
|
56
|
-
# required type
|
57
|
-
def get_as_type json_path, type, json=nil
|
58
|
-
value = get json_path, json
|
59
|
-
case type
|
60
|
-
when 'numeric'
|
61
|
-
valid = value.is_a? Numeric
|
62
|
-
when 'array'
|
63
|
-
valid = value.is_a? Array
|
64
|
-
when 'string'
|
65
|
-
valid = value.is_a? String
|
66
|
-
when 'boolean'
|
67
|
-
valid = !!value == value
|
68
|
-
when 'numeric_string'
|
69
|
-
valid = value.is_a?(Numeric) or value.is_a?(String)
|
70
|
-
when 'object'
|
71
|
-
valid = value.is_a? Hash
|
72
|
-
else
|
73
|
-
raise %/Invalid expected type '#{type}'/
|
74
|
-
end
|
75
|
-
|
76
|
-
unless valid
|
77
|
-
raise %/Expect '#{json_path}' as a '#{type}' but was '#{value.class}'\n#{to_json_s}/
|
78
|
-
end
|
79
|
-
value
|
80
|
-
end
|
81
|
-
|
82
|
-
# Retrieve value of the first JSON element with given JSON path as given type, with nil value allowed
|
83
|
-
# @param json_path [String] a valid JSON path expression
|
84
|
-
# @param type [String] required type, possible values are 'numeric', 'array', 'string', 'boolean', 'numeric_string'
|
85
|
-
# or 'object'
|
86
|
-
# @param json [String] optional JSON from which to apply JSON path, default to response body
|
87
|
-
# @return [Object] value of first retrieved JSON element in form of given type or nil
|
88
|
-
# @raise [Exception] if JSON path is invalid or no matching JSON element found or matching element does not match
|
89
|
-
# required type
|
90
|
-
def get_as_type_or_null json_path, type, json=nil
|
91
|
-
value = get json_path, json
|
92
|
-
value.nil? ? value : get_as_type(json_path, type, json)
|
93
|
-
end
|
94
|
-
|
95
|
-
# Retrieve pretty JSON response for logging
|
96
|
-
# @return [String] pretty JSON response if verbose setting is true, empty string otherwise
|
97
|
-
def to_json_s
|
98
|
-
if ENV['cucumber_api_verbose'] == 'true'
|
99
|
-
JSON.pretty_generate(JSON.parse to_s)
|
100
|
-
else
|
101
|
-
''
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
@@ -1,281 +0,0 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'json-schema'
|
3
|
-
require 'savon'
|
4
|
-
require_relative 'required_libs'
|
5
|
-
require_relative 'response'
|
6
|
-
|
7
|
-
if ENV['webservice_verbose'] == 'true'
|
8
|
-
RestClient.log = 'stdout'
|
9
|
-
end
|
10
|
-
|
11
|
-
$cache = {}
|
12
|
-
|
13
|
-
Given /^I set headers:$/ do |headers|
|
14
|
-
@headers = headers.hashes[0]
|
15
|
-
p @headers
|
16
|
-
end
|
17
|
-
|
18
|
-
Given /^I send and accept (XML|JSON)$/ do |type|
|
19
|
-
@headers = {
|
20
|
-
:'Accept' => "application/#{type.downcase}",
|
21
|
-
:'Content-Type' => "application/#{type.downcase}"
|
22
|
-
}
|
23
|
-
p @headers
|
24
|
-
end
|
25
|
-
|
26
|
-
# Example
|
27
|
-
# When I get SOAP operations list from 'http://ws.cdyne.com/emailverify/Emailvernotestemail.asmx?wsdl'
|
28
|
-
When /^I get SOAP operations list from '(.*?)'$/ do |url|
|
29
|
-
request_url = URI.encode check_match_url url
|
30
|
-
@client = Savon.client(ssl_verify_mode: :none, wsdl: "#{request_url}")
|
31
|
-
p @client.operations
|
32
|
-
end
|
33
|
-
|
34
|
-
When /^I get SOAP operations list$/ do
|
35
|
-
p @client.operations
|
36
|
-
end
|
37
|
-
|
38
|
-
When /^I create new SOAP request with:$/ do |params|
|
39
|
-
soap_params = {}
|
40
|
-
soap_params[:ssl_verify_mode] = :none
|
41
|
-
params.hashes[0].each { |k, v| soap_params[k.to_sym] = v }
|
42
|
-
@client = Savon.client(soap_params)
|
43
|
-
end
|
44
|
-
|
45
|
-
When /^I send "(.*?)" SOAP request with namespace "(.*)" and the following:$/ do |operation, namespace, json|
|
46
|
-
params = JSON.parse(json)
|
47
|
-
@response = @client.call(operation.downcase.to_sym, :message => params, soap_action: namespace)
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
# Example
|
52
|
-
# When I send "verify_email" SOAP request with the following:
|
53
|
-
# """
|
54
|
-
# { "email": "soap@example.com",
|
55
|
-
# "LicenseKey": "?" }
|
56
|
-
# """
|
57
|
-
When /^I send "(.*?)" SOAP request with the following:$/ do |operation, json|
|
58
|
-
params = JSON.parse(json)
|
59
|
-
@response = @client.call(operation.downcase.to_sym, :message => params)
|
60
|
-
# p JSON.parse(@response.body)
|
61
|
-
# p response_text = response.body[:verify_email_response][:verify_email_result][:response_text]
|
62
|
-
end
|
63
|
-
|
64
|
-
# Example
|
65
|
-
# Then the SOAP response node should have "$..response_text" with text "Email Domain Not Found"
|
66
|
-
Then /^the SOAP response node should have "(.*?)" with text "(.*?)"$/ do |json_path, text|
|
67
|
-
json = JSON.parse(@response.body.to_json)
|
68
|
-
results = JsonPath.new(json_path).on(json).to_a.map(&:to_s)
|
69
|
-
IFD_Assertion.assert_string_equal(text, results)
|
70
|
-
end
|
71
|
-
|
72
|
-
When(/^I set JSON request body to '(.*?)'$/) do |body|
|
73
|
-
@body = JSON.parse body
|
74
|
-
end
|
75
|
-
|
76
|
-
When(/^I set form request body from:$/) do |json|
|
77
|
-
params = check_match_url json
|
78
|
-
@body = JSON.parse(params)
|
79
|
-
p @body
|
80
|
-
end
|
81
|
-
|
82
|
-
When(/^I set request body from file "(.*?).(yml|json)"$/) do |filename, extension|
|
83
|
-
path = $test_data_dir+filename+".#{extension}"
|
84
|
-
if File.file? path
|
85
|
-
case extension
|
86
|
-
when 'yml'
|
87
|
-
@body = YAML.load File.open(path)
|
88
|
-
when 'json'
|
89
|
-
@body = JSON.parse File.read(path)
|
90
|
-
else
|
91
|
-
raise %/Unsupported file type: '#{path}'/
|
92
|
-
end
|
93
|
-
else
|
94
|
-
raise %/File not found: '#{path}'/
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# Example
|
99
|
-
# When I grab "$[0]" as "id"
|
100
|
-
When(/^I grab "(.*?)" (REST|SOAP) as "(.*?)"$/) do |json_path, method, place_holder|
|
101
|
-
if @response.nil?
|
102
|
-
raise 'No response found, a request need to be made first before you can grab response'
|
103
|
-
end
|
104
|
-
@grabbed = {} if @grabbed.nil?
|
105
|
-
case method
|
106
|
-
when /REST/
|
107
|
-
@grabbed[%/#{place_holder}/] = @response.get json_path
|
108
|
-
p @grabbed
|
109
|
-
else
|
110
|
-
json = JSON.parse(@response.body.to_json)
|
111
|
-
results = JsonPath.new(json_path).on(json).to_a.map(&:to_s)
|
112
|
-
@grabbed[%/#{place_holder}/] = results[0]
|
113
|
-
p @grabbed
|
114
|
-
end
|
115
|
-
|
116
|
-
|
117
|
-
end
|
118
|
-
# Example
|
119
|
-
# And I send a GET request to "https://hacker-news.firebaseio.com/v0/item/8863.json" with:
|
120
|
-
# | print |
|
121
|
-
# | pretty |
|
122
|
-
When(/^I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)" with:$/) do |method, url, params|
|
123
|
-
unless params.hashes.empty?
|
124
|
-
query = params.hashes.first.map { |key, value| %/#{key}=#{value}/ }.join("&")
|
125
|
-
url = url.include?('?') ? %/#{url}&#{query}/ : %/#{url}?#{query}/
|
126
|
-
end
|
127
|
-
steps %Q{
|
128
|
-
When I send a #{method} request to "#{url}"
|
129
|
-
}
|
130
|
-
end
|
131
|
-
|
132
|
-
# Example
|
133
|
-
# And I send a POST request to "https://hacker-news.firebaseio.com/v0/item/8863.json?print=pretty"
|
134
|
-
When(/^I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)"$/) do |method, url|
|
135
|
-
request_url = URI.encode check_match_url url
|
136
|
-
if 'GET' == %/#{method}/ and $cache.has_key? %/#{request_url}/
|
137
|
-
@response = $cache[%/#{request_url}/]
|
138
|
-
@headers = nil
|
139
|
-
@body = nil
|
140
|
-
@grabbed = nil
|
141
|
-
next
|
142
|
-
end
|
143
|
-
|
144
|
-
@headers = {} if @headers.nil?
|
145
|
-
begin
|
146
|
-
case method
|
147
|
-
when 'GET'
|
148
|
-
response = RestClient.get request_url, @headers
|
149
|
-
when 'POST'
|
150
|
-
response = RestClient.post request_url, @body, @headers
|
151
|
-
when 'PATCH'
|
152
|
-
response = RestClient.patch request_url, @body, @headers
|
153
|
-
when 'PUT'
|
154
|
-
response = RestClient.put request_url, @body, @headers
|
155
|
-
else
|
156
|
-
response = RestClient.delete request_url, @headers
|
157
|
-
end
|
158
|
-
rescue RestClient::Exception => e
|
159
|
-
response = e.response
|
160
|
-
end
|
161
|
-
@response = CucumberApi::Response.create response
|
162
|
-
@headers = nil
|
163
|
-
@body = nil
|
164
|
-
@grabbed = nil
|
165
|
-
$cache[%/#{request_url}/] = @response if 'GET' == %/#{method}/
|
166
|
-
end
|
167
|
-
|
168
|
-
# Example
|
169
|
-
# Then the response status should be "200"
|
170
|
-
Then(/^the response status should be "(\d+)"$/) do |status_code|
|
171
|
-
raise %/Expect #{status_code} but was #{@response.code}/ if @response.code != status_code.to_i
|
172
|
-
end
|
173
|
-
|
174
|
-
# Example
|
175
|
-
# Then the JSON response should be:
|
176
|
-
# """
|
177
|
-
# {
|
178
|
-
# "test" : "anh pham"
|
179
|
-
# }
|
180
|
-
# """
|
181
|
-
Then /^the JSON response should be:$/ do |json|
|
182
|
-
expected = JSON.parse(json)
|
183
|
-
actual = JSON.parse(@response.body)
|
184
|
-
|
185
|
-
if self.respond_to?(:expect)
|
186
|
-
# expect(actual).to eq(expected)
|
187
|
-
IFD_Assertion.assert_string_equal(actual, expected)
|
188
|
-
else
|
189
|
-
IFD_Assertion.assert_string_equal(actual, @response)
|
190
|
-
# assert_equal actual, response
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
# Example
|
195
|
-
# Then the JSON response should have "$..id"
|
196
|
-
Then /^the JSON response should have "(.*)"$/ do |json_path|
|
197
|
-
json = JSON.parse(@response.body)
|
198
|
-
results = JsonPath.new(json_path).on(json).to_a.map(&:to_s)
|
199
|
-
if self.respond_to?(:expect)
|
200
|
-
expect(results).not_to be_empty
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
Then(/^the JSON response root should be (object|array)$/) do |type|
|
205
|
-
steps %Q{
|
206
|
-
Then the JSON response should have required key "$" of type #{type}
|
207
|
-
}
|
208
|
-
end
|
209
|
-
|
210
|
-
Then(/^the JSON response should have key "([^\"]*)"$/) do |json_path|
|
211
|
-
steps %Q{
|
212
|
-
Then the JSON response should have required key "#{json_path}" of type any
|
213
|
-
}
|
214
|
-
end
|
215
|
-
|
216
|
-
|
217
|
-
Then(/^the JSON response should have (required|optional) key "(.*?)" of type \
|
218
|
-
(numeric|string|array|boolean|numeric_string|object|array|any)( or null)?$/) do |optionality, json_path, type, null_allowed|
|
219
|
-
next if optionality == 'optional' and not @response.has(json_path) # if optional and no such key then skip
|
220
|
-
if 'any' == type
|
221
|
-
@response.get json_path
|
222
|
-
elsif null_allowed.nil?
|
223
|
-
@response.get_as_type json_path, type
|
224
|
-
else
|
225
|
-
@response.get_as_type_or_null json_path, type
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
# Example
|
230
|
-
# Then the JSON response should have "$..kids" with a length of 2
|
231
|
-
Then /^the JSON response should have "(.*)" with a length of (\d+)$/ do |json_path, length|
|
232
|
-
json = JSON.parse(@response.body)
|
233
|
-
results = JsonPath.new(json_path).on(json)
|
234
|
-
if self.respond_to?(:expect)
|
235
|
-
expect(results.length).to eq(length.to_i)
|
236
|
-
else
|
237
|
-
assert_equal length.to_i, results.length
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
# Example
|
242
|
-
# Then the JSON response node should have "$..by" with the text "dhouston"
|
243
|
-
Then /^the JSON response node should have "(.*)" with the text "(.*)"$/ do |json_path, text|
|
244
|
-
json = JSON.parse(@response.body)
|
245
|
-
results = JsonPath.new(json_path).on(json).to_a.map(&:to_s)
|
246
|
-
if self.respond_to?(:expect)
|
247
|
-
expect(results).to include(text)
|
248
|
-
else
|
249
|
-
assert results.include?(text)
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
# Bind grabbed values into placeholders in given URL
|
254
|
-
# Ex: http://example.com?id={id} with {id => 1} becomes http://example.com?id=1
|
255
|
-
# @param url [String] parameterized URL with placeholders
|
256
|
-
# @return [String] binded URL or original URL if no placeholders
|
257
|
-
# def resolve url
|
258
|
-
# unless @grabbed.nil?
|
259
|
-
# @grabbed.each { |key, value| url = url.gsub /\{#{key}\}/, %/#{value}/ }
|
260
|
-
# end
|
261
|
-
# url
|
262
|
-
# end
|
263
|
-
|
264
|
-
Then /^show me SOAP response$/ do
|
265
|
-
puts @response.body
|
266
|
-
end
|
267
|
-
|
268
|
-
Then /^show me REST (unparsed)?\s?response$/ do |unparsed|
|
269
|
-
last_response = @response
|
270
|
-
if unparsed == 'unparsed'
|
271
|
-
puts last_response.body
|
272
|
-
elsif last_response.headers['Content-Type'] =~ /json/
|
273
|
-
json_response = JSON.parse(last_response.body)
|
274
|
-
puts JSON.pretty_generate(json_response)
|
275
|
-
elsif last_response.headers['Content-Type'] =~ /xml/
|
276
|
-
puts Nokogiri::XML(last_response.body)
|
277
|
-
else
|
278
|
-
puts last_response.headers
|
279
|
-
puts last_response.body
|
280
|
-
end
|
281
|
-
end
|
@@ -1,205 +0,0 @@
|
|
1
|
-
class IFD_Assertion
|
2
|
-
#Assert two files, rows not in order and REMOVE 1 COLUMN OF ID
|
3
|
-
def self.do_assertion_csv_tab_non_order(expected_obj, actual_obj)
|
4
|
-
for i in (1..expected_obj.length - 1)
|
5
|
-
expected_row = expected_obj[i].drop(1).to_s.split("\t")
|
6
|
-
found = false
|
7
|
-
for j in (1..actual_obj.length - 1)
|
8
|
-
actual_row = actual_obj[j].drop(1).to_s.split("\t")
|
9
|
-
if (expected_row == actual_row)
|
10
|
-
found = true
|
11
|
-
break
|
12
|
-
end
|
13
|
-
end
|
14
|
-
assert(found, "Expected Record: [#{expected_obj[i].to_s}] is not included in reporting file")
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# Assert 2 values
|
19
|
-
def self.reg_compare sActual, regValue, isSpecialChar=false
|
20
|
-
begin
|
21
|
-
if !isSpecialChar
|
22
|
-
sActual = sActual.strip
|
23
|
-
regValue = regValue.strip.gsub("[", "\\[").gsub("]", "\\]").gsub("(", "\\(").gsub(")", "\\)").gsub(">", "\\>")
|
24
|
-
end
|
25
|
-
rescue StandardError => myStandardError
|
26
|
-
put_log "\n>>> Error: #{myStandardError}"
|
27
|
-
end
|
28
|
-
|
29
|
-
# put_log "\nsActual:#{sActual}, regValue:#{regValue}"
|
30
|
-
if ((sActual.nil? and regValue.nil?) or (!sActual.nil? and sActual.empty? and !regValue.nil? and regValue.empty?))
|
31
|
-
return true
|
32
|
-
end
|
33
|
-
|
34
|
-
if ((sActual.nil? and !regValue.nil?) or (!sActual.nil? and regValue.nil?))
|
35
|
-
return false
|
36
|
-
end
|
37
|
-
|
38
|
-
if (!sActual.nil? and !sActual.empty?)
|
39
|
-
sCookActual = sActual.gsub(/\n|\r/, " ")
|
40
|
-
if (sCookActual == regValue or (isSpecialChar and sCookActual.include? regValue) or (!isSpecialChar and sCookActual =~ /^.*#{regValue}.*$/))
|
41
|
-
return true
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
return false
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.do_assertion_json(expected_obj, actual_obj, options = {})
|
49
|
-
# puts "\n\n actual_obj.class: #{actual_obj.class}"
|
50
|
-
# puts "\n\n expected_obj.class: #{expected_obj.class}"
|
51
|
-
|
52
|
-
if expected_obj.kind_of? Hash
|
53
|
-
# if options['isIncludedAssertion'].nil? or options['isIncludedAssertion'] == false
|
54
|
-
# do_assertion(expected_obj.keys.size, actual_obj.keys.size)
|
55
|
-
# end
|
56
|
-
expected_obj.keys.each do |key|
|
57
|
-
# puts "\n\n key: #{key}"
|
58
|
-
# puts "\n\n value: #{expected_obj[key]}"
|
59
|
-
# puts "\n\n value: #{actual_obj[key]}"
|
60
|
-
if actual_obj[key].nil?
|
61
|
-
raise "[%s] expected [%s] but actual value was nil." % [key, expected_obj[key].to_s]
|
62
|
-
else
|
63
|
-
IFD_Assertion.do_assertion_json(expected_obj[key], actual_obj[key], options)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
elsif expected_obj.kind_of? Array
|
67
|
-
if options['isIncludedAssertion'].nil? or options['isIncludedAssertion'] == false
|
68
|
-
IFD_Assertion.do_assertion_json(expected_obj.size, actual_obj.size)
|
69
|
-
end
|
70
|
-
for i in (0..expected_obj.length-1)
|
71
|
-
IFD_Assertion.do_assertion_json(expected_obj[i], actual_obj[i], options)
|
72
|
-
end
|
73
|
-
else
|
74
|
-
begin
|
75
|
-
IFD_Assertion.assert_string_equal(expected_obj.to_s, actual_obj.to_s)
|
76
|
-
rescue => e
|
77
|
-
raise("Assert fail. \n\n Expected: '#{expected_obj}' \n\n Got: '#{actual_obj}'. Detail info: #{e.message}")
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.assert_string_contain(expected, actual)
|
83
|
-
unless (actual.to_s).include? (expected.to_s)
|
84
|
-
raise ("*** ASSERTION ERROR: \nExpected: #{expected}. \nGot: #{actual}.")
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def self.assert_string_equal(expected, actual)
|
89
|
-
if expected.to_s != actual.to_s
|
90
|
-
raise ("*** ASSERTION ERROR: \nExpected: #{expected}. \nGot: #{actual}.")
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
# Method to find difference between images
|
96
|
-
def self.does_images_similar?(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
|
97
|
-
if !compare_image(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
|
98
|
-
raise TestCaseFailed, 'Actual image is different from expected image'
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# Method to compare two images
|
103
|
-
# param 1 : String : Locator type (id, name, class, xpath, css, url)
|
104
|
-
# param 2 : String : Locator value
|
105
|
-
# param 3 : String : Locator type (id, name, class, xpath, css, url, image_name)
|
106
|
-
# param 4 : String : Locator value
|
107
|
-
def self.compare_image(actual_img_access_type, actual_img_access_name, excp_img_access_type, excp_img_access_name)
|
108
|
-
if actual_img_access_type == 'url'
|
109
|
-
actual_img_url = actual_img_access_name
|
110
|
-
elsif actual_img_access_type == 'image_name'
|
111
|
-
actual_img_url = $test_data_dir + '/actual_images/' + actual_img_access_name
|
112
|
-
else
|
113
|
-
actual_img_url = get_element_attribute(actual_img_access_type, actual_img_access_name, 'src')
|
114
|
-
end
|
115
|
-
|
116
|
-
if excp_img_access_type == 'url'
|
117
|
-
expected_img_url = excp_img_access_name
|
118
|
-
elsif excp_img_access_type == 'image_name'
|
119
|
-
expected_img_url = $test_data_dir + '/expected_images/' + excp_img_access_name
|
120
|
-
else
|
121
|
-
expected_img_url = get_element_attribute(excp_img_access_type, excp_img_access_name, 'src')
|
122
|
-
end
|
123
|
-
|
124
|
-
# replace 'https' with 'http' from actual image url
|
125
|
-
if actual_img_url.include? 'https'
|
126
|
-
actual_img_url['https'] = 'http'
|
127
|
-
end
|
128
|
-
|
129
|
-
# replace 'https' with 'http' from expected image url
|
130
|
-
if expected_img_url.include? 'https'
|
131
|
-
expected_img_url['https'] = 'http'
|
132
|
-
end
|
133
|
-
|
134
|
-
if expected_img_url.include? '.png'
|
135
|
-
image_type = 'png'
|
136
|
-
else
|
137
|
-
image_type = 'jpg'
|
138
|
-
end
|
139
|
-
|
140
|
-
# Storing actual image locally
|
141
|
-
open($test_data_dir + '/actual_images/actual_image.' + image_type, 'wb') do |file|
|
142
|
-
file << open(actual_img_url).read
|
143
|
-
end
|
144
|
-
|
145
|
-
if actual_img_access_type == 'url'
|
146
|
-
actual_img_url = $test_data_dir + '/actual_images/actual_image.' + image_type
|
147
|
-
end
|
148
|
-
|
149
|
-
# Storing Expected image locally
|
150
|
-
if excp_img_access_type != 'image_name'
|
151
|
-
open($test_data_dir + '/expected_images/expected_image.' + image_type, 'wb') do |file|
|
152
|
-
file << open(expected_img_url).read
|
153
|
-
end
|
154
|
-
expected_img_url = $test_data_dir + '/expected_images/expected_image.' + image_type
|
155
|
-
end
|
156
|
-
|
157
|
-
# Verify image extension and call respective compare function
|
158
|
-
if image_type == 'png'
|
159
|
-
return compare_png_images(expected_img_url, actual_img_url)
|
160
|
-
end
|
161
|
-
|
162
|
-
compare_jpeg_images(expected_img_url, actual_img_url)
|
163
|
-
end
|
164
|
-
|
165
|
-
# Comparing jpg images
|
166
|
-
def self.compare_jpeg_images(expected_img_url, actual_img_url)
|
167
|
-
if open(expected_img_url).read == open(actual_img_url).read
|
168
|
-
return true
|
169
|
-
else
|
170
|
-
puts 'Difference in images'
|
171
|
-
return false
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
# Comparing png images
|
176
|
-
def self.compare_png_images(expected_img_url, actual_img_url)
|
177
|
-
images = [
|
178
|
-
ChunkyPNG::Image.from_file(expected_img_url),
|
179
|
-
ChunkyPNG::Image.from_file(actual_img_url)
|
180
|
-
]
|
181
|
-
|
182
|
-
diff = []
|
183
|
-
|
184
|
-
images.first.height.times do |y|
|
185
|
-
images.first.row(y).each_with_index do |pixel, x|
|
186
|
-
diff << [x, y] unless pixel == images.last[x, y]
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
if diff.length != 0
|
191
|
-
puts "\npixels (total): #{images.first.pixels.length}"
|
192
|
-
puts "pixels changed: #{diff.length}"
|
193
|
-
puts "pixels changed (%): #{(diff.length.to_f / images.first.pixels.length) * 100}%"
|
194
|
-
|
195
|
-
x, y = diff.map { |xy| xy[0] }, diff.map { |xy| xy[1] }
|
196
|
-
images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0, 255, 0))
|
197
|
-
cur_time = Time.now.strftime('%Y%m%d%H%M%S%L')
|
198
|
-
images.last.save($test_data_dir + "/image_difference/difference_#{cur_time}.png")
|
199
|
-
|
200
|
-
puts "\nDifference between images saved as : difference_#{cur_time}.png\n"
|
201
|
-
return false
|
202
|
-
end
|
203
|
-
true
|
204
|
-
end
|
205
|
-
end
|