itms_automation 1.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 +7 -0
- data/bin/console +14 -0
- data/bin/documentation_generator.rb +119 -0
- data/bin/generate.rb +53 -0
- data/bin/helper.rb +38 -0
- data/bin/itms_automation +32 -0
- data/bin/setup +8 -0
- data/lib/itms_automation.rb +3 -0
- data/lib/itms_automation/all_steps.rb +8 -0
- data/lib/itms_automation/auto_util.rb +133 -0
- data/lib/itms_automation/version.rb +3 -0
- data/lib/itms_automation/web_steps_helper.rb +994 -0
- data/project/Gemfile +3 -0
- data/project/README.md +34 -0
- data/project/Rakefile +24 -0
- data/project/config/chrome_headless_options.yaml +1 -0
- data/project/config/chrome_options.yaml +6 -0
- data/project/config/firefox_headless_options.yaml +1 -0
- data/project/config/firefox_options.yaml +1 -0
- data/project/config/ie_options.yaml +1 -0
- data/project/config/remote_options.yaml +6 -0
- data/project/config/safari_options.yaml +1 -0
- data/project/cucumber.yml +4 -0
- data/project/features/TestSuite/WebGUI.feature +4 -0
- data/project/features/step_definitions/lib_steps/steps_definition.rb +3 -0
- data/project/features/step_definitions/repositories/project_object.yml +2 -0
- data/project/features/support/env.rb +10 -0
- data/project/features/support/hooks.rb +130 -0
- metadata +194 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f5369eaf7be36672e2fccdf1ba400a8cb807b4a09c043c741b04d16fdec9c4a5
|
4
|
+
data.tar.gz: 0f16ce745b0b433fe0171510da26d56a199cd867b03bd55fa2d824e5223a958d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 752628884608cdff4e59ad467be586f28d6b1f29d6fb867c9cd5cff444362c7666cc15b309382a1e4f517f311674c6b8b60c4d66f52025ad4214b47d2530ba72
|
7
|
+
data.tar.gz: cbe8237a0a30a988671aa44f44b780178286c70559294ee2922a0d9d9e7a3724ab24f9549ae490f22cafff036157aa70c18247aa9577448445f820ac82ca6cdd
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "itms_automation"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module DocumentationGenerator
|
2
|
+
|
3
|
+
module CommentExtractor
|
4
|
+
def parse_and_format_comment(comment)
|
5
|
+
comment.gsub!(/.*coding:.*UTF-8.*/, '')
|
6
|
+
comment.strip!
|
7
|
+
comment_lines = comment.split("\n").take_while { |line| line =~ /^\s*#/ }
|
8
|
+
comment_lines && comment_lines.join("\n").gsub(/^\s*# ?/, '')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class StepDefinition
|
13
|
+
|
14
|
+
extend CommentExtractor
|
15
|
+
|
16
|
+
def initialize(definition, comment = nil)
|
17
|
+
@definition = definition
|
18
|
+
@comment = comment
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.try_and_parse(code)
|
22
|
+
definition = code[/^\s*((When|Then|Given|AfterStep).*)do/, 1]
|
23
|
+
return unless definition
|
24
|
+
comment = parse_and_format_comment(code)
|
25
|
+
return if comment =~ /\bnodoc\b/
|
26
|
+
new(definition.strip, comment)
|
27
|
+
end
|
28
|
+
|
29
|
+
def format
|
30
|
+
<<-TEXT
|
31
|
+
* **#{format_definition}**
|
32
|
+
|
33
|
+
#{@comment.gsub(/^/, ' ')}
|
34
|
+
TEXT
|
35
|
+
end
|
36
|
+
|
37
|
+
def format_definition
|
38
|
+
if @definition =~ /AfterStep/
|
39
|
+
@definition[/@\w*/]
|
40
|
+
else
|
41
|
+
capture_groups = %w[([^\"]*) ([^"]*) (.*) (.*?) [^"]+ ([^\"]+) ([^']*) ([^/]*) (.+) (.*[^:])]
|
42
|
+
capture_groups.map! &Regexp.method(:escape)
|
43
|
+
|
44
|
+
@definition.
|
45
|
+
gsub('/^', '').
|
46
|
+
gsub('$/', '').
|
47
|
+
gsub(' ?', ' ').
|
48
|
+
gsub('(?:|I )', 'I ').
|
49
|
+
gsub('?:', '').
|
50
|
+
gsub(Regexp.new(capture_groups.join '|'), '...').
|
51
|
+
gsub(/\\\//, '/')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class StepDefinitionFile
|
57
|
+
|
58
|
+
FILE_COMMENT_END = 'FILE_COMMENT_END'
|
59
|
+
|
60
|
+
include CommentExtractor
|
61
|
+
|
62
|
+
def initialize(filename)
|
63
|
+
@filename = filename
|
64
|
+
@code = File.read(filename)
|
65
|
+
@steps = []
|
66
|
+
extract_comment
|
67
|
+
add_steps
|
68
|
+
end
|
69
|
+
|
70
|
+
def extract_comment
|
71
|
+
if @code.include?(FILE_COMMENT_END)
|
72
|
+
file_comment = @code.split(FILE_COMMENT_END).first
|
73
|
+
@comment = parse_and_format_comment(file_comment)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def add_steps
|
78
|
+
@code.split("\n\n").each do |block|
|
79
|
+
step = StepDefinition.try_and_parse(block)
|
80
|
+
if step
|
81
|
+
@steps << step
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def format
|
87
|
+
<<-TEXT
|
88
|
+
### #{format_filename}
|
89
|
+
|
90
|
+
#{@comment}
|
91
|
+
|
92
|
+
#{format_steps}
|
93
|
+
TEXT
|
94
|
+
end
|
95
|
+
|
96
|
+
def format_filename
|
97
|
+
@filename.split('/').last
|
98
|
+
end
|
99
|
+
|
100
|
+
def format_steps
|
101
|
+
@steps.collect { |step| step.format }.join("\n\n")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class StepDefinitionsDirectory
|
106
|
+
def initialize(directory)
|
107
|
+
@step_definition_files = []
|
108
|
+
Dir["#{directory}/*.rb"].to_a.sort.each do |filename|
|
109
|
+
next if filename =~ /all_steps/
|
110
|
+
@step_definition_files << StepDefinitionFile.new(filename)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def format
|
115
|
+
@step_definition_files.collect { |step_definition_file| step_definition_file.format }.join("\n\n")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
data/bin/generate.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
def itms_automation_scaffold
|
3
|
+
if File.exists?(@features_dir)
|
4
|
+
puts 'There is already cucumber directory. Please move existing cucumber directory to carry on '
|
5
|
+
exit 1
|
6
|
+
end
|
7
|
+
msg("Question") do
|
8
|
+
puts "I'm about to create a subdirectory called features."
|
9
|
+
puts "features will contain all your project tests."
|
10
|
+
puts "Please hit return to confirm that's what you want."
|
11
|
+
end
|
12
|
+
exit 2 unless STDIN.gets.chomp == ''
|
13
|
+
|
14
|
+
FileUtils.cp_r(@source_dir, @features_dir)
|
15
|
+
|
16
|
+
msg('Info') do
|
17
|
+
puts "iTMS Automation is creating 'cucumber' framework. Please have a look which files are being created\n"
|
18
|
+
end
|
19
|
+
msg('Gemfile') do
|
20
|
+
puts "iTMS Automation created Gemfile containing all required Gems\n"
|
21
|
+
end
|
22
|
+
msg('cucumber.yml') do
|
23
|
+
puts "iTMS Automation created cucumber.yml file with profiles of all needed configurations\n"
|
24
|
+
end
|
25
|
+
msg('config/chrome_headless_options.yaml') do
|
26
|
+
puts "iTMS Automation created chrome_headless_options.yml file with profiles of all needed configurations\n"
|
27
|
+
end
|
28
|
+
msg('config/firefox_headless_options.yaml') do
|
29
|
+
puts "iTMS Automation created firefox_headless_options.yml file with profiles of all needed configurations\n"
|
30
|
+
end
|
31
|
+
msg('config/chrome_options.yaml') do
|
32
|
+
puts "iTMS Automation created chrome_options.yml file with profiles of all needed configurations\n"
|
33
|
+
end
|
34
|
+
msg('config/firefox_options.yaml') do
|
35
|
+
puts "iTMS Automation created firefox_options.yml file with profiles of all needed configurations\n"
|
36
|
+
end
|
37
|
+
msg('config/ie_options.yaml') do
|
38
|
+
puts "iTMS Automation created ie_options.yml file with profiles of all needed configurations\n"
|
39
|
+
end
|
40
|
+
msg('config/remote_options.yaml') do
|
41
|
+
puts "iTMS Automation created remote_options.yml file with profiles of all needed configurations\n"
|
42
|
+
end
|
43
|
+
msg('config/safari_options.yaml') do
|
44
|
+
puts "iTMS Automation created safari_options.yml file with profiles of all needed configurations\n"
|
45
|
+
end
|
46
|
+
msg('README.md') do
|
47
|
+
puts "iTMS Automation created README.md file with template usage\n"
|
48
|
+
end
|
49
|
+
msg('Info') do
|
50
|
+
puts "All Config files created. \n"
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/bin/helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'json'
|
3
|
+
require "rubygems"
|
4
|
+
|
5
|
+
def msg(title, &block)
|
6
|
+
puts "\n" + '-' * 10 + title + '-' * 10
|
7
|
+
yield
|
8
|
+
puts '-' * 10 + '-------' + '-' * 10 + "\n"
|
9
|
+
sleep 1
|
10
|
+
end
|
11
|
+
|
12
|
+
def print_help
|
13
|
+
puts <<EOF
|
14
|
+
Author: iTMS
|
15
|
+
|
16
|
+
Usage: itms_automation <command-name> [parameters] [options]
|
17
|
+
|
18
|
+
<command-name> can be one of
|
19
|
+
help
|
20
|
+
gen
|
21
|
+
version
|
22
|
+
ls
|
23
|
+
|
24
|
+
Commands:
|
25
|
+
help : prints more detailed help information.
|
26
|
+
|
27
|
+
gen : creates a features dir. This is usually used once when
|
28
|
+
setting up itms_automation to ensure that the features folder contains
|
29
|
+
the right step definitions and environment to run with cucumber.
|
30
|
+
|
31
|
+
version : prints the gem version
|
32
|
+
|
33
|
+
ls: list all steps name of itms_automation framework
|
34
|
+
|
35
|
+
<Options>
|
36
|
+
-v, --verbose Turns on verbose logging
|
37
|
+
EOF
|
38
|
+
end
|
data/bin/itms_automation
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative 'helper.rb'
|
3
|
+
require_relative 'generate.rb'
|
4
|
+
require_relative 'documentation_generator.rb'
|
5
|
+
require 'itms_automation/version'
|
6
|
+
|
7
|
+
@features_dir = File.join(FileUtils.pwd, "project")
|
8
|
+
@source_dir = File.join(File.dirname(__FILE__), '..', 'project')
|
9
|
+
|
10
|
+
search_string = ARGV.shift
|
11
|
+
case search_string
|
12
|
+
when /version/
|
13
|
+
puts ItmsAutomation::VERSION
|
14
|
+
when /gen/
|
15
|
+
itms_automation_scaffold
|
16
|
+
when /ls/
|
17
|
+
ORDERED_KINDS = %w[Given When Then]
|
18
|
+
heading = 'All itms_automation steps'
|
19
|
+
|
20
|
+
# collect
|
21
|
+
steps_glob = File.expand_path('../../lib/itms_automation/*_steps.rb', __FILE__)
|
22
|
+
step_names = `cat #{steps_glob}`.split($/).select { |line| line =~ /^\s*(Given|When|Then)/ }
|
23
|
+
|
24
|
+
# Output
|
25
|
+
puts "\e[4;34m\n# #{heading}\e[0m" # blue underline
|
26
|
+
puts step_names
|
27
|
+
else
|
28
|
+
print_help
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
data/bin/setup
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
#-----------------------------------------------------
|
2
|
+
# support define and bind variable dynamically
|
3
|
+
#-----------------------------------------------------
|
4
|
+
$dyn_vars = nil
|
5
|
+
|
6
|
+
# set value to a variable
|
7
|
+
def set_var(var_name, var_value)
|
8
|
+
if $dyn_vars == nil
|
9
|
+
$dyn_vars = binding
|
10
|
+
end
|
11
|
+
|
12
|
+
strEval = var_name + "=" + var_value
|
13
|
+
eval strEval, $dyn_vars
|
14
|
+
end
|
15
|
+
|
16
|
+
def check_dynamic_value value
|
17
|
+
if !value.is_a? Fixnum
|
18
|
+
if value.include? "params="
|
19
|
+
resolve_params value
|
20
|
+
else
|
21
|
+
bind_with_dyn_vars value
|
22
|
+
end
|
23
|
+
else
|
24
|
+
value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# bind string with $dyn_vars context
|
29
|
+
def bind_with_dyn_vars(str)
|
30
|
+
if $dyn_vars == nil
|
31
|
+
$dyn_vars = binding
|
32
|
+
end
|
33
|
+
|
34
|
+
strEval = '"' + str + '"'
|
35
|
+
return eval strEval, $dyn_vars
|
36
|
+
end
|
37
|
+
|
38
|
+
# evaluate operation/statement with $dyn_vars context
|
39
|
+
def eval_with_dyn_vars(operation)
|
40
|
+
if $dyn_vars == nil
|
41
|
+
$dyn_vars = binding
|
42
|
+
end
|
43
|
+
|
44
|
+
eval operation, $dyn_vars
|
45
|
+
end
|
46
|
+
|
47
|
+
def bind_with_dyn_json_vars(json, bind_json)
|
48
|
+
if json.kind_of? Hash
|
49
|
+
json.each_pair do |k, v|
|
50
|
+
if v.kind_of? String
|
51
|
+
bind_json[bind_with_dyn_vars(k)] = bind_with_dyn_json_vars(v, bind_json)
|
52
|
+
elsif v.kind_of? Hash
|
53
|
+
temp = Hash.new
|
54
|
+
v.each_pair do |k1, v1|
|
55
|
+
temp[bind_with_dyn_vars(k1)] = bind_with_dyn_json_vars(v1, temp)
|
56
|
+
end
|
57
|
+
bind_json[bind_with_dyn_vars(k)] = temp
|
58
|
+
elsif v.kind_of? Array
|
59
|
+
temp1 = Array.new
|
60
|
+
v.each { |item|
|
61
|
+
temp2 = Hash.new
|
62
|
+
bind_with_dyn_json_vars(item, temp2)
|
63
|
+
temp1 << temp2
|
64
|
+
}
|
65
|
+
bind_json[bind_with_dyn_vars(k)] = temp1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
elsif json.kind_of? Array
|
69
|
+
temp1 = Array.new
|
70
|
+
json.each { |item|
|
71
|
+
temp2 = Hash.new
|
72
|
+
bind_with_dyn_json_vars(item, temp2)
|
73
|
+
temp1 << temp2
|
74
|
+
}
|
75
|
+
return temp1
|
76
|
+
else
|
77
|
+
return bind_with_dyn_vars(json)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def var_collect string_var
|
83
|
+
if string_var =~ /^.*{year}.*$/
|
84
|
+
string_var = replace_year(string_var)
|
85
|
+
end
|
86
|
+
|
87
|
+
if string_var =~ /^.*{month}.*$/
|
88
|
+
string_var = replace_month(string_var)
|
89
|
+
end
|
90
|
+
|
91
|
+
if string_var =~ /^.*{day}.*$/
|
92
|
+
string_var = replace_day(string_var)
|
93
|
+
end
|
94
|
+
|
95
|
+
if string_var =~ /^.*{store_value}.*$/
|
96
|
+
string_var = $context_value
|
97
|
+
end
|
98
|
+
|
99
|
+
return string_var
|
100
|
+
end
|
101
|
+
|
102
|
+
def replace_year str
|
103
|
+
t = Time.now()
|
104
|
+
return str.gsub("{year}", t.year.to_s)
|
105
|
+
end
|
106
|
+
|
107
|
+
def replace_month str
|
108
|
+
t = Time.now()
|
109
|
+
_month = t.month
|
110
|
+
if _month < 10
|
111
|
+
return str.gsub("{month}", "0#{_month.to_s}")
|
112
|
+
else
|
113
|
+
return str.gsub("{month}", "#{_month.to_s}")
|
114
|
+
end
|
115
|
+
return str
|
116
|
+
end
|
117
|
+
|
118
|
+
def replace_day str
|
119
|
+
t = Time.now()
|
120
|
+
_day = t.day
|
121
|
+
if _day < 10
|
122
|
+
return str.gsub("{day}", "0#{_day.to_s}")
|
123
|
+
else
|
124
|
+
return str.gsub("{day}", "#{_day.to_s}")
|
125
|
+
end
|
126
|
+
return str
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
def print_variable(variable)
|
132
|
+
puts "VALUE OF #{variable}: #{eval_with_dyn_vars(variable)}"
|
133
|
+
end
|
@@ -0,0 +1,994 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'rspec'
|
3
|
+
|
4
|
+
def execute_openbrowser(url_site)
|
5
|
+
begin
|
6
|
+
if url_site == ""
|
7
|
+
raise "❌ Error: Null web page URL."
|
8
|
+
end
|
9
|
+
visit(url_site)
|
10
|
+
rescue StandardError => e
|
11
|
+
raise "❌ Error: #{e}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute_click(element)
|
16
|
+
foundElement = find_object(element)
|
17
|
+
if foundElement != nil
|
18
|
+
begin
|
19
|
+
foundElement.click
|
20
|
+
rescue StandardError => e
|
21
|
+
raise "❌ Error: #{e}"
|
22
|
+
end
|
23
|
+
else
|
24
|
+
raise "❌ Error >> Not found object: #{element}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def execute_click_offset(element, x, y)
|
29
|
+
foundElement = find_object(element)
|
30
|
+
if foundElement != nil
|
31
|
+
begin
|
32
|
+
page.driver.browser.mouse.move_to(foundElement.native,x.to_i,y.to_i)
|
33
|
+
page.driver.browser.mouse.click()
|
34
|
+
rescue Exception => e
|
35
|
+
raise "❌ Error: #{e}"
|
36
|
+
end
|
37
|
+
else
|
38
|
+
raise "❌ Error: Not found object: #{element}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def double_click(element)
|
43
|
+
foundElement = find_object(element)
|
44
|
+
if foundElement != nil
|
45
|
+
begin
|
46
|
+
foundElement.double_click
|
47
|
+
rescue StandardError => e
|
48
|
+
raise "❌ Error: #{e}"
|
49
|
+
end
|
50
|
+
else
|
51
|
+
raise "❌ Error: Not found object: #{element}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def execute_settext(element, text)
|
56
|
+
foundElement = find_object(element)
|
57
|
+
if foundElement != nil
|
58
|
+
begin
|
59
|
+
foundElement.set(text)
|
60
|
+
rescue StandardError => e
|
61
|
+
raise "❌ Error: #{e}"
|
62
|
+
end
|
63
|
+
else
|
64
|
+
raise "❌ Error: Not found object: #{element}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def maximize_browser
|
69
|
+
begin
|
70
|
+
page.driver.browser.manage.window.maximize
|
71
|
+
rescue StandardError => e
|
72
|
+
raise "❌ Error: #{e}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def switch_to_window_by_title(window_title)
|
77
|
+
$previous_window = page.driver.browser.window_handle
|
78
|
+
@window_found = false
|
79
|
+
page.driver.browser.window_handles.each { |handle|
|
80
|
+
page.driver.browser.switch_to.window handle
|
81
|
+
if page.title == window_title
|
82
|
+
@window_found = true
|
83
|
+
break
|
84
|
+
end
|
85
|
+
}
|
86
|
+
if @window_found == false
|
87
|
+
raise "Window having title \"#{window_title}\" not found"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def scroll_to_end_page
|
92
|
+
begin
|
93
|
+
page.driver.execute_script('window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));')
|
94
|
+
rescue StandardError => e
|
95
|
+
raise "❌ Error: #{e}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def scroll_to_top_page
|
100
|
+
begin
|
101
|
+
page.driver.execute_script('window.scrollTo(Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight),0);')
|
102
|
+
rescue StandardError => e
|
103
|
+
raise "❌ Error: #{e}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def verify_title(expected_title)
|
108
|
+
begin
|
109
|
+
page_title = page.title
|
110
|
+
puts "Actual Page Title : #{page_title}, Expected Page Title : #{expected_title}"
|
111
|
+
expect(page_title).to eq expected_title
|
112
|
+
rescue StandardError => e
|
113
|
+
raise "❌ Error: #{e}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def verify_alert_text(text)
|
118
|
+
begin
|
119
|
+
alert = page.driver.browser.switch_to.alert.text
|
120
|
+
puts "Actual Page alert text : #{alert}, Expected value : #{text}"
|
121
|
+
expect(alert).to eq text
|
122
|
+
rescue StandardError => e
|
123
|
+
raise "❌ Error: #{e}"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def accept_alert
|
128
|
+
begin
|
129
|
+
page.driver.browser.switch_to.alert.accept
|
130
|
+
rescue Exception => e
|
131
|
+
raise "❌ ERROR: #{e}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def back
|
136
|
+
begin
|
137
|
+
page.execute_script('window.history.back()')
|
138
|
+
rescue Exception => e
|
139
|
+
raise "❌ ERROR: #{e}"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def refresh
|
144
|
+
begin
|
145
|
+
page.execute_script('window.location.reload()')
|
146
|
+
rescue Exception => e
|
147
|
+
raise "❌ ERROR: #{e}"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def clear_text(element)
|
152
|
+
foundElement = find_object(element)
|
153
|
+
if foundElement != nil?
|
154
|
+
begin
|
155
|
+
foundElement.native.clear
|
156
|
+
rescue Exception => e
|
157
|
+
raise "❌ ERROR: #{e}"
|
158
|
+
end
|
159
|
+
else
|
160
|
+
raise "❌ Error: Not found object: #{element}"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def execute_javascript(script)
|
165
|
+
begin
|
166
|
+
page.execute_script(script)
|
167
|
+
rescue Exception => e
|
168
|
+
puts "❌ Error: Not found object: #{element}"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def execute_select(element, text)
|
173
|
+
#select(text, :xpath => element)
|
174
|
+
foundElement = find_object(element)
|
175
|
+
if foundElement != nil
|
176
|
+
begin
|
177
|
+
option_value = page.evaluate_script("$(\"##{foundElement[:id]} option:contains('#{text}')\").val()")
|
178
|
+
page.execute_script("$('##{foundElement[:id]}').val('#{option_value}')")
|
179
|
+
page.execute_script("$('##{foundElement[:id]}').trigger('liszt:updated').trigger('change')")
|
180
|
+
rescue Exception => e
|
181
|
+
raise "❌ ERROR: #{e}"
|
182
|
+
end
|
183
|
+
else
|
184
|
+
raise "❌ Error: Not found object: #{element}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def execute_mouse_over(element)
|
189
|
+
foundElement = find_object(element)
|
190
|
+
if foundElement != nil
|
191
|
+
begin
|
192
|
+
page.driver.browser.action.move_to(foundElement.native, element).click.perform
|
193
|
+
sleep(1)
|
194
|
+
rescue StandardError => e
|
195
|
+
raise "❌ Error: #{e}"
|
196
|
+
end
|
197
|
+
else
|
198
|
+
raise "❌ Error: Not found object: #{element}"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def remove_element_attribute(element, attr)
|
203
|
+
foundElement = find_object(element)
|
204
|
+
if foundElement != nil
|
205
|
+
begin
|
206
|
+
page.driver.browser.execute_script("arguments[0].removeAttribute('#{attr}');", foundElement.native)
|
207
|
+
sleep(1)
|
208
|
+
rescue StandardError => e
|
209
|
+
raise "❌ Error: #{e}"
|
210
|
+
end
|
211
|
+
else
|
212
|
+
raise "❌ Error: Not found object: #{element}"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Set state
|
217
|
+
def execute_setstate(element, state)
|
218
|
+
foundElement = find_object(element)
|
219
|
+
if foundElement != nil
|
220
|
+
if state
|
221
|
+
foundElement.select_option
|
222
|
+
else
|
223
|
+
foundElement.unselect_option
|
224
|
+
end
|
225
|
+
else
|
226
|
+
raise "❌ Error: Not found object: #{element}"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def close_windows
|
231
|
+
begin
|
232
|
+
page.execute_script "window.close();"
|
233
|
+
rescue StandardError => e
|
234
|
+
raise "❌ Error: #{e}"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def resize_window_screen(x, y)
|
239
|
+
begin
|
240
|
+
page.driver.browser.manage.window.resize_to(x, y)
|
241
|
+
puts page.driver.browser.manage.window.size
|
242
|
+
rescue StandardError => e
|
243
|
+
raise "❌ Error: #{e}"
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def switch_to_frame(element)
|
248
|
+
begin
|
249
|
+
page.driver.browser.switch_to.frame element
|
250
|
+
rescue Exception => e
|
251
|
+
raise "❌ Error: #{e}"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def get_computed_style(element, style)
|
256
|
+
foundElement = get_object_value(element)
|
257
|
+
computedStyle = ""
|
258
|
+
if foundElement != nil
|
259
|
+
computedStyle = page.evaluate_script("window.getComputedStyle(document.querySelector('#{foundElement}')).#{style}")
|
260
|
+
else
|
261
|
+
raise "❌ Error: Not found object: #{element}"
|
262
|
+
end
|
263
|
+
puts "\nActual object style value is: #{computedStyle}"
|
264
|
+
computedStyle
|
265
|
+
end
|
266
|
+
|
267
|
+
def put_log str
|
268
|
+
p str if $print_log == true
|
269
|
+
end
|
270
|
+
|
271
|
+
def get_object_value(str_obj)
|
272
|
+
string_object = str_obj.gsub(/"/, "'")
|
273
|
+
hash_object = $OBJECT[string_object]
|
274
|
+
if hash_object == nil
|
275
|
+
raise ">>> OBJECT: #{str_obj} NAME MAYBE NOT FOUND!!!"
|
276
|
+
end
|
277
|
+
if hash_object.keys[0].to_s.upcase != "CSS_SELECTOR"
|
278
|
+
raise ">>> OBJECT: #{str_obj} should be formatted as Css Selector."
|
279
|
+
end
|
280
|
+
hash_object[hash_object.keys[0]]
|
281
|
+
end
|
282
|
+
|
283
|
+
def get_element_text(element)
|
284
|
+
foundElement = find_object(element)
|
285
|
+
if foundElement != nil
|
286
|
+
begin
|
287
|
+
result = foundElement.text()
|
288
|
+
puts "Text of #{element}: #{result}"
|
289
|
+
rescue StandardError => e
|
290
|
+
raise "❌ Error: #{e}"
|
291
|
+
end
|
292
|
+
else
|
293
|
+
raise "❌ Error: Not found object: #{element}"
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def get_element_attribute(element,value)
|
298
|
+
foundElement = find_object(element)
|
299
|
+
if foundElement != nil
|
300
|
+
begin
|
301
|
+
result = foundElement.value()
|
302
|
+
puts "Attribute of #{element}: #{result}"
|
303
|
+
rescue StandardError => e
|
304
|
+
raise "❌ Error: #{e}"
|
305
|
+
end
|
306
|
+
else
|
307
|
+
raise "❌ Error: Not found object: #{element}"
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
def verify_element_text(element,value)
|
312
|
+
foundElement = find_object(element)
|
313
|
+
if foundElement != nil
|
314
|
+
begin
|
315
|
+
actual_value = foundElement.text()
|
316
|
+
put_log "Actual result is: '#{actual_value}' -- Expected result is: '#{value}'"
|
317
|
+
expect(actual_value).to eq value
|
318
|
+
rescue Exception => e
|
319
|
+
raise "❌ ERROR: #{e} "
|
320
|
+
end
|
321
|
+
else
|
322
|
+
raise "❌ Error: Not found object: #{element}"
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def verify_element_not_has_text(element,value)
|
327
|
+
foundElement = find_object(element)
|
328
|
+
if foundElement != nil
|
329
|
+
begin
|
330
|
+
actual_value = foundElement.text()
|
331
|
+
put_log "Actual result is: '#{actual_value}' -- Expected result is: '#{value}'"
|
332
|
+
expect(actual_value).not_to eql value
|
333
|
+
rescue Exception => e
|
334
|
+
raise "❌ ERROR: #{e}"
|
335
|
+
end
|
336
|
+
|
337
|
+
else
|
338
|
+
raise "❌ Error: Not found object: #{element}"
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
def verify_element_value(element,value)
|
343
|
+
foundElement = find_object(element)
|
344
|
+
if foundElement != nil
|
345
|
+
begin
|
346
|
+
actual_value = foundElement.value()
|
347
|
+
put_log "Actual result is: '#{actual_value}' -- Expected result is: '#{value}'"
|
348
|
+
expect(actual_value).to eq value
|
349
|
+
rescue Exception => e
|
350
|
+
raise "❌ ERROR: #{e}"
|
351
|
+
end
|
352
|
+
else
|
353
|
+
raise "❌ Error: Not found object: #{element}"
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
def verify_element_not_has_value(element,value)
|
358
|
+
foundElement = find_object(element)
|
359
|
+
if foundElement != nil
|
360
|
+
begin
|
361
|
+
actual_value = foundElement.value()
|
362
|
+
put_log "Actual result is: '#{actual_value}' -- Expected result is: '#{value}'"
|
363
|
+
expect(actual_value).not_to eql value
|
364
|
+
rescue Exception => e
|
365
|
+
raise "❌ ERROR: #{e}"
|
366
|
+
end
|
367
|
+
else
|
368
|
+
raise "❌ Error: Not found object: #{element}"
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
def execute_checkproperty(element, property, negate, value, isSpecialChar=false)
|
373
|
+
validate_option_by(property)
|
374
|
+
Capybara.configure do |config|
|
375
|
+
config.ignore_hidden_elements = false
|
376
|
+
end
|
377
|
+
foundElement = find_object(element)
|
378
|
+
|
379
|
+
check = false
|
380
|
+
if foundElement == nil and value == ""
|
381
|
+
check = true
|
382
|
+
# check.should eq true
|
383
|
+
expect(check).to eq true
|
384
|
+
else
|
385
|
+
# put_log "\n\n\t>>> execute_checkproperty: finish to found element"
|
386
|
+
if foundElement != nil
|
387
|
+
|
388
|
+
if property.upcase == 'VALUE'
|
389
|
+
actual_value = foundElement.value()
|
390
|
+
|
391
|
+
elsif property.upcase == 'TEXT'
|
392
|
+
actual_value = foundElement.text()
|
393
|
+
|
394
|
+
else
|
395
|
+
actual_value = foundElement["#{property}"]
|
396
|
+
end
|
397
|
+
|
398
|
+
if actual_value == nil
|
399
|
+
actual_value = ''
|
400
|
+
end
|
401
|
+
else
|
402
|
+
put_log "❌ Error: Not found object: #{element}"
|
403
|
+
end
|
404
|
+
|
405
|
+
Capybara.configure do |config|
|
406
|
+
config.ignore_hidden_elements = true
|
407
|
+
end
|
408
|
+
|
409
|
+
# if IFD_Assertion.reg_compare(actual_value, value, isSpecialChar)
|
410
|
+
# check = true
|
411
|
+
# end
|
412
|
+
|
413
|
+
put_log "\n#{property} :: Actual result is: '#{actual_value}' -- Expected result is: '#{value}'"
|
414
|
+
|
415
|
+
if negate == " not"
|
416
|
+
actual_value.should_not eq value
|
417
|
+
expect(actual_value).not_to eql value
|
418
|
+
elsif actual_value.should eq value
|
419
|
+
expect(actual_value).to eq value
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
def check_valid_option_by?(option_by)
|
425
|
+
%w(text value).include? option_by
|
426
|
+
end
|
427
|
+
|
428
|
+
def validate_option_by(option_by)
|
429
|
+
raise "Please select valid option, invalid option - #{option_by}" unless check_valid_option_by? option_by
|
430
|
+
end
|
431
|
+
|
432
|
+
def check_valid_keys?(key)
|
433
|
+
%w(:cancel :help :backspace :tab :clear :return :enter :shift :control :alt :pause :escape :space :page_up :page_down :end :home :left :up :right :down :insert :delete :semicolon :equals).include? key
|
434
|
+
end
|
435
|
+
|
436
|
+
def validate_supported_keys(key)
|
437
|
+
raise "Please select valid keys, invalid key - #{key}" unless check_valid_option_by? key
|
438
|
+
end
|
439
|
+
|
440
|
+
def find_object string_object
|
441
|
+
startTime = Time.new.to_i
|
442
|
+
string_object = string_object.gsub(/"/, "'")
|
443
|
+
locator_matching = /(.*?)(\{.*?\})/.match(string_object)
|
444
|
+
dyn_pros = {}
|
445
|
+
if locator_matching != nil
|
446
|
+
string_object = locator_matching[1]
|
447
|
+
eval(locator_matching[2].gsub(/['][\s,\t]*?:[\s,\t]*?[']?/, "'=>'")).each { |k, v|
|
448
|
+
dyn_pros[k.to_s.upcase] = v
|
449
|
+
}
|
450
|
+
end
|
451
|
+
hash_object = $OBJECT[string_object]
|
452
|
+
if hash_object == nil
|
453
|
+
raise "❌ ERROR: >>> Object: #{string_object} is not found in Object Repository."
|
454
|
+
end
|
455
|
+
upcase_attrb = {}
|
456
|
+
if hash_object != nil
|
457
|
+
hash_object.each {|k,v|
|
458
|
+
k = k.to_s.upcase
|
459
|
+
if k =~ /ph_/i
|
460
|
+
if dyn_pros[k] != nil
|
461
|
+
if v =~ /<ph_value>/i
|
462
|
+
upcase_attrb[k[3..k.size-1]] = v.gsub(/<ph_value>/i, dyn_pros[k])
|
463
|
+
else
|
464
|
+
upcase_attrb[k[3..k.size-1]] = dyn_pros[k]
|
465
|
+
end
|
466
|
+
dyn_pros.delete(k)
|
467
|
+
end
|
468
|
+
else
|
469
|
+
upcase_attrb[k.to_s.upcase] = v
|
470
|
+
end
|
471
|
+
}
|
472
|
+
end
|
473
|
+
ph_attrs = {}
|
474
|
+
dyn_pros.each{|k,v|
|
475
|
+
if k =~ /ph_/i
|
476
|
+
ph_attrs[k] = v
|
477
|
+
else
|
478
|
+
upcase_attrb[k.to_s.upcase] = v
|
479
|
+
end
|
480
|
+
}
|
481
|
+
if upcase_attrb.size > 0
|
482
|
+
strId = ""
|
483
|
+
strClass = ""
|
484
|
+
strName = ""
|
485
|
+
strTagname = ""
|
486
|
+
strCssSelector = ""
|
487
|
+
strXpathSelector = ""
|
488
|
+
strText = ""
|
489
|
+
strRelated = ""
|
490
|
+
strRelatedType = ""
|
491
|
+
|
492
|
+
index = nil
|
493
|
+
minWidth = -1
|
494
|
+
maxWidth = -1
|
495
|
+
minHeight = -1
|
496
|
+
maxHeight = -1
|
497
|
+
|
498
|
+
ano_pros = {}
|
499
|
+
|
500
|
+
upcase_attrb.each{|key, value|
|
501
|
+
upcase_key = key.to_s.upcase
|
502
|
+
case upcase_key
|
503
|
+
when "XPATH_SELECTOR"
|
504
|
+
strXpathSelector = value
|
505
|
+
when "CSS_SELECTOR"
|
506
|
+
strCssSelector = value
|
507
|
+
when "ID"
|
508
|
+
strId = value
|
509
|
+
when "CLASS"
|
510
|
+
strClass = value
|
511
|
+
when "NAME"
|
512
|
+
strName = value
|
513
|
+
when "TAGNAME"
|
514
|
+
strTagname = value
|
515
|
+
when "TEXT"
|
516
|
+
strText = value
|
517
|
+
when "INDEX"
|
518
|
+
index = value
|
519
|
+
else
|
520
|
+
raise "ERROR: >>> Wrong format type: #{key.to_s} of object: #{string_object}. Available supported format are: XPATH_SELECTOR | CSS_SELECTOR | ID | NAME | CLASS | TEXT | TAGNAME | INDEX"
|
521
|
+
end
|
522
|
+
}
|
523
|
+
continue_run = true;
|
524
|
+
ref_object = nil;
|
525
|
+
|
526
|
+
if strRelated != nil and strRelated.length > 0
|
527
|
+
ref_object = find_object(strRelated)
|
528
|
+
if (ref_object == nil)
|
529
|
+
continue_run = false
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
if continue_run == true
|
534
|
+
begin
|
535
|
+
if strCssSelector != nil and strCssSelector.length > 0
|
536
|
+
foundElements = get_objects_by_css_selector(strCssSelector)
|
537
|
+
elsif strXpathSelector != nil and strXpathSelector.length > 0
|
538
|
+
foundElements = get_objects_by_xpath_selector(strXpathSelector)
|
539
|
+
else
|
540
|
+
strGenerateXpathSel = generate_xpath_selector(strId, strClass, strName, strTagname)
|
541
|
+
if strGenerateXpathSel.length > 0
|
542
|
+
foundElements = get_objects_by_xpath_selector(strGenerateXpathSel)
|
543
|
+
else
|
544
|
+
if (check_string_letters_only(strId))
|
545
|
+
foundElements = get_objects_by_Id(strId)
|
546
|
+
elsif (check_string_letters_only(strName))
|
547
|
+
foundElements = get_objects_by_Name(strName)
|
548
|
+
elsif (check_string_letters_only(strClass))
|
549
|
+
foundElements = get_objects_by_Class(strClass)
|
550
|
+
elsif (check_string_letters_only(strTagname))
|
551
|
+
foundElements = get_objects_by_Tagname(strTagname)
|
552
|
+
end
|
553
|
+
end
|
554
|
+
end
|
555
|
+
if foundElements == nil or foundElements.length == 0
|
556
|
+
currentTime = Time.new.to_i
|
557
|
+
else
|
558
|
+
break
|
559
|
+
end
|
560
|
+
test = currentTime - startTime
|
561
|
+
puts "\n Finding the object #{string_object}... TIME-OUT:: #{test} < #{$wait_time}"
|
562
|
+
sleep(0.5)
|
563
|
+
end while (currentTime - startTime) < $wait_time
|
564
|
+
|
565
|
+
if foundElements != nil or foundElements.length != 0
|
566
|
+
if index != nil and index.to_i >= 0
|
567
|
+
matched_index = 0;
|
568
|
+
return_element = nil
|
569
|
+
foundElements.each{|cur_element|
|
570
|
+
passCheck = find_object_check_object(cur_element, ref_object, strRelatedType, strId, strClass, strName, strTagname, strText, minWidth, maxWidth, minHeight, maxHeight, ano_pros)
|
571
|
+
if passCheck
|
572
|
+
if matched_index == index.to_i
|
573
|
+
return_element = cur_element
|
574
|
+
break
|
575
|
+
else
|
576
|
+
matched_index = matched_index + 1
|
577
|
+
end
|
578
|
+
end
|
579
|
+
}
|
580
|
+
return return_element
|
581
|
+
else
|
582
|
+
return_element = nil
|
583
|
+
foundElements.each{|cur_element|
|
584
|
+
passCheck = find_object_check_object(cur_element, ref_object, strRelatedType, strId, strClass, strName, strTagname, strText, minWidth, maxWidth, minHeight, maxHeight, ano_pros)
|
585
|
+
if passCheck
|
586
|
+
return_element = cur_element
|
587
|
+
break
|
588
|
+
end
|
589
|
+
}
|
590
|
+
return return_element
|
591
|
+
end # if index != nil and index.to_i >= 0
|
592
|
+
end #if foundElements != nil or foundElements.length != 0
|
593
|
+
end #if continue = true
|
594
|
+
end
|
595
|
+
return nil
|
596
|
+
end
|
597
|
+
|
598
|
+
def generate_xpath_selector(strId, strClass, strName, strTagname)
|
599
|
+
strGenerateXpathSel = ""
|
600
|
+
if strId != nil and strId.length > 0 and (strId =~ /^#/) == nil
|
601
|
+
strGenerateXpathSel = "[@id='#{strId}']"
|
602
|
+
end
|
603
|
+
if strClass != nil and strClass.length > 0 and (strClass =~ /^#/) == nil
|
604
|
+
strGenerateXpathSel = "#{strGenerateXpathSel}[@class='#{strClass}']"
|
605
|
+
end
|
606
|
+
if strName != nil and strName.length > 0 and (strName =~ /^#/) == nil
|
607
|
+
strGenerateXpathSel = "#{strGenerateXpathSel}[@name='#{strName}']"
|
608
|
+
end
|
609
|
+
|
610
|
+
if strGenerateXpathSel.length > 0
|
611
|
+
if strTagname != nil and strTagname.length > 0
|
612
|
+
strGenerateXpathSel = "//#{strTagname}#{strGenerateXpathSel}"
|
613
|
+
else
|
614
|
+
strGenerateXpathSel = "//*#{strGenerateXpathSel}"
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
return strGenerateXpathSel
|
619
|
+
end
|
620
|
+
|
621
|
+
def check_string_letters_only(strToCheck)
|
622
|
+
if strToCheck != nil and strToCheck.length > 0 and strToCheck =~ /^[a-zA-Z]+$/
|
623
|
+
return true
|
624
|
+
end
|
625
|
+
return false
|
626
|
+
end
|
627
|
+
|
628
|
+
def get_objects_by_Id(strId)
|
629
|
+
foundElements = nil
|
630
|
+
begin
|
631
|
+
foundElements = page.all("*[@id='#{strId}']")
|
632
|
+
rescue StandardError => e
|
633
|
+
raise "❌ Error: #{e}"
|
634
|
+
end
|
635
|
+
|
636
|
+
return foundElements
|
637
|
+
end
|
638
|
+
|
639
|
+
def get_objects_by_Class(strClass)
|
640
|
+
foundElements = nil
|
641
|
+
begin
|
642
|
+
foundElements = page.all("*[@class='#{strClass}']")
|
643
|
+
rescue StandardError => e
|
644
|
+
raise "❌ Error: #{e}"
|
645
|
+
end
|
646
|
+
|
647
|
+
return foundElements
|
648
|
+
end
|
649
|
+
|
650
|
+
def get_objects_by_Name(strName)
|
651
|
+
foundElements = nil
|
652
|
+
begin
|
653
|
+
foundElements = page.all("*[@name='#{strName}']")
|
654
|
+
rescue StandardError => e
|
655
|
+
raise "❌ Error: #{e}"
|
656
|
+
end
|
657
|
+
|
658
|
+
return foundElements
|
659
|
+
end
|
660
|
+
|
661
|
+
def get_objects_by_Tagname(strTagname)
|
662
|
+
foundElements = nil
|
663
|
+
begin
|
664
|
+
foundElements = page.all("#{strTagname}")
|
665
|
+
rescue StandardError => e
|
666
|
+
raise "❌ Error: #{e}"
|
667
|
+
end
|
668
|
+
|
669
|
+
return foundElements
|
670
|
+
end
|
671
|
+
|
672
|
+
def get_objects_by_css_selector(strCssSelector)
|
673
|
+
foundElements = nil
|
674
|
+
begin
|
675
|
+
foundElements = page.all(:css, strCssSelector)
|
676
|
+
rescue StandardError => e
|
677
|
+
raise "❌ Error: #{e}"
|
678
|
+
end
|
679
|
+
foundElements
|
680
|
+
end
|
681
|
+
|
682
|
+
def get_objects_by_xpath_selector(strXpathSelector)
|
683
|
+
foundElements = nil
|
684
|
+
begin
|
685
|
+
foundElements = page.all(:xpath, strXpathSelector)
|
686
|
+
rescue StandardError => e
|
687
|
+
raise "❌ Error: #{e}"
|
688
|
+
end
|
689
|
+
foundElements
|
690
|
+
end
|
691
|
+
|
692
|
+
def find_object_check_object(cur_element, ref_object, ref_object_type, strId, strClass, strName, strTagname, strText, minWidth, maxWidth, minHeight, maxHeight, ano_pros)
|
693
|
+
passCheck = true
|
694
|
+
if cur_element != nil
|
695
|
+
# Check ref_object
|
696
|
+
if (ref_object != nil)
|
697
|
+
if find_object_check_ref_object(ref_object, ref_object_type, cur_element) == false
|
698
|
+
passCheck = false
|
699
|
+
end
|
700
|
+
end
|
701
|
+
|
702
|
+
# Check ID
|
703
|
+
if strId != nil and strId.length > 0
|
704
|
+
if strId =~ /^#/
|
705
|
+
strId = strId[1..-1]
|
706
|
+
end
|
707
|
+
if find_object_check_Id(cur_element, strId) == false
|
708
|
+
passCheck = false
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
712
|
+
# Check Class
|
713
|
+
if passCheck and strClass != nil and strClass.length > 0
|
714
|
+
if strClass =~ /^#/
|
715
|
+
strClass = strClass[1..-1]
|
716
|
+
end
|
717
|
+
if find_object_check_Class(cur_element, strClass) == false
|
718
|
+
passCheck = false
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
722
|
+
# Check Name
|
723
|
+
if passCheck and strName != nil and strName.length > 0
|
724
|
+
if strName =~ /^#/
|
725
|
+
strName = strName[1..-1]
|
726
|
+
end
|
727
|
+
if find_object_check_Name(cur_element, strName) == false
|
728
|
+
passCheck = false
|
729
|
+
end
|
730
|
+
end
|
731
|
+
|
732
|
+
# Check Tag name
|
733
|
+
if passCheck and strTagname != nil and strTagname.length > 0
|
734
|
+
if find_object_check_Tagname(cur_element, strTagname) == false
|
735
|
+
passCheck = false
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
739
|
+
# Check Text
|
740
|
+
if passCheck and strText != nil and strText.length > 0
|
741
|
+
if (strText =~ /^#/)
|
742
|
+
strText = strText[1..-1]
|
743
|
+
end
|
744
|
+
|
745
|
+
if find_object_check_Text(cur_element, strText) == false
|
746
|
+
passCheck = false
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
750
|
+
# Check minWidth
|
751
|
+
if passCheck and minWidth > 0
|
752
|
+
if !find_object_check_minWidth(cur_element, minWidth)
|
753
|
+
passCheck = false
|
754
|
+
end
|
755
|
+
end
|
756
|
+
|
757
|
+
# Check maxWidth
|
758
|
+
if passCheck and maxWidth > 0
|
759
|
+
if !find_object_check_maxWidth(cur_element, maxWidth)
|
760
|
+
passCheck = false
|
761
|
+
end
|
762
|
+
end
|
763
|
+
|
764
|
+
# Check minHeight
|
765
|
+
if passCheck and minHeight > 0
|
766
|
+
if !find_object_check_minHeight(cur_element, minHeight)
|
767
|
+
passCheck = false
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
# Check maxHeight
|
772
|
+
if passCheck and maxHeight > 0
|
773
|
+
if !find_object_check_maxHeight(cur_element, maxHeight)
|
774
|
+
passCheck = false
|
775
|
+
end
|
776
|
+
end
|
777
|
+
|
778
|
+
# Check another properties
|
779
|
+
if passCheck and ano_pros.length > 0
|
780
|
+
ano_pros.each{|property, value|
|
781
|
+
if value =~ /^#/
|
782
|
+
value = value[1..-1]
|
783
|
+
end
|
784
|
+
if !find_object_check_property(cur_element, property, value)
|
785
|
+
passCheck = false
|
786
|
+
break
|
787
|
+
end
|
788
|
+
}
|
789
|
+
end
|
790
|
+
|
791
|
+
return passCheck
|
792
|
+
end
|
793
|
+
|
794
|
+
return false
|
795
|
+
end
|
796
|
+
|
797
|
+
def find_object_check_Id(element, strId)
|
798
|
+
actual_Id = element[:id]
|
799
|
+
if actual_Id != nil and actual_Id.length > 0
|
800
|
+
actual_Id = actual_Id.strip
|
801
|
+
if reg_compare(actual_Id, strId)
|
802
|
+
return true
|
803
|
+
end
|
804
|
+
end
|
805
|
+
|
806
|
+
return false
|
807
|
+
end
|
808
|
+
def find_object_check_Class(element, strClass)
|
809
|
+
actual_Class = element[:class]
|
810
|
+
if actual_Class != nil and actual_Class.length > 0
|
811
|
+
actual_Class = actual_Class.strip
|
812
|
+
if reg_compare(actual_Class, strClass)
|
813
|
+
return true
|
814
|
+
end
|
815
|
+
end
|
816
|
+
|
817
|
+
return false
|
818
|
+
end
|
819
|
+
def find_object_check_Name(element, strName)
|
820
|
+
actual_Name = element[:name]
|
821
|
+
if actual_Name != nil and actual_Name.length > 0
|
822
|
+
actual_Name = actual_Name.strip
|
823
|
+
if reg_compare(actual_Name, strName)
|
824
|
+
return true
|
825
|
+
end
|
826
|
+
end
|
827
|
+
|
828
|
+
return false
|
829
|
+
end
|
830
|
+
|
831
|
+
def find_object_check_Tagname(element, strTagname)
|
832
|
+
actual_Tagname = element.tag_name()
|
833
|
+
if actual_Tagname != nil and actual_Tagname.length > 0
|
834
|
+
actual_Tagname = actual_Tagname.strip
|
835
|
+
if reg_compare(actual_Tagname, strTagname)
|
836
|
+
return true
|
837
|
+
end
|
838
|
+
end
|
839
|
+
|
840
|
+
return false
|
841
|
+
end
|
842
|
+
def find_object_check_Xpath(element, strXpath)
|
843
|
+
|
844
|
+
end
|
845
|
+
def find_object_check_Text(element, strText)
|
846
|
+
actual_Text = element.text()
|
847
|
+
if actual_Text != nil and actual_Text.length > 0
|
848
|
+
actual_Text = actual_Text.strip
|
849
|
+
if reg_compare(actual_Text, strText)
|
850
|
+
return true
|
851
|
+
end
|
852
|
+
end
|
853
|
+
|
854
|
+
return false
|
855
|
+
end
|
856
|
+
def find_object_check_minWidth(element, minWidth)
|
857
|
+
width = element[:width]
|
858
|
+
if (width >= minWidth)
|
859
|
+
return true
|
860
|
+
end
|
861
|
+
|
862
|
+
return false
|
863
|
+
end
|
864
|
+
def find_object_check_maxWidth(element, maxWidth)
|
865
|
+
width = element[:width]
|
866
|
+
if (width <= maxWidth)
|
867
|
+
return true
|
868
|
+
end
|
869
|
+
|
870
|
+
return false
|
871
|
+
end
|
872
|
+
def find_object_check_minHeight(element, minHeight)
|
873
|
+
height = element[:height]
|
874
|
+
if (height <= minHeight)
|
875
|
+
return true
|
876
|
+
end
|
877
|
+
|
878
|
+
return false
|
879
|
+
end
|
880
|
+
def find_object_check_maxHeight(element, maxHeight)
|
881
|
+
height = element[:height]
|
882
|
+
if (height <= maxHeight)
|
883
|
+
return true
|
884
|
+
end
|
885
|
+
|
886
|
+
return false
|
887
|
+
end
|
888
|
+
|
889
|
+
def find_object_check_ref_object(ref_object, ref_type, target_element)
|
890
|
+
begin
|
891
|
+
ref = ref_object.native
|
892
|
+
target = target_element.native
|
893
|
+
if(ref_type == "up" or ref_type == "down")
|
894
|
+
ref_x1 = ref.location.x - 10
|
895
|
+
ref_x2 = ref.location.x + ref.size.width + 10
|
896
|
+
target_x1 = target.location.x
|
897
|
+
target_x2 = target_x1 + target.size.width
|
898
|
+
elsif(ref_type == "left" or ref_type == "right")
|
899
|
+
ref_y1 = ref.location.y - 10
|
900
|
+
ref_y2 = ref.location.y + ref_object.native.size.height + 10
|
901
|
+
target_y1 = target.location.y
|
902
|
+
target_y2 = target_y1 + target.size.height
|
903
|
+
elsif(ref_type == "child" or ref_type == "parent")
|
904
|
+
ref_W = ref.location.x + ref.size.width
|
905
|
+
ref_H = ref.location.y + ref.size.height
|
906
|
+
target_W = target.location.x + target.size.width
|
907
|
+
target_H = target.location.y + target.size.height
|
908
|
+
end
|
909
|
+
|
910
|
+
if(ref_type == "up" and
|
911
|
+
target_x1 > ref_x1 and target_x2 < ref_x2 and # has same column or X Position
|
912
|
+
target.location.y < ref.location.y) # at row or Y position, target is upper
|
913
|
+
return true
|
914
|
+
elsif(ref_type == "down" and
|
915
|
+
target_x1 > ref_x1 and target_x2 < ref_x2 and # has same column or X Position
|
916
|
+
target.location.y > ref.location.y) # at row or Y position, target is at down
|
917
|
+
return true
|
918
|
+
elsif(ref_type == "left" and
|
919
|
+
target.location.x < ref.location.x and # at column or X Position, target is at left
|
920
|
+
target_y1 > ref_y1 and target_y2 < ref_y2) # at row or Y position, target is same as ref object
|
921
|
+
return true
|
922
|
+
elsif(ref_type == "right" and
|
923
|
+
target.location.x > ref.location.x and # at column or X Position, target is at right
|
924
|
+
target_y1 > ref_y1 and target_y2 < ref_y2) # at row or Y position, target is same as ref object
|
925
|
+
return true
|
926
|
+
elsif(ref_type == "child" and
|
927
|
+
(target_W < ref_W) and (target_H < ref_H) and
|
928
|
+
(target.location.x > ref.location.x) and (target.location.y > ref.location.y))
|
929
|
+
return true
|
930
|
+
elsif(ref_type == "parent" and
|
931
|
+
(target_W > ref_W) and (target_H > ref_H) and
|
932
|
+
(target.location.x < ref.location.x) and (target.location.y < ref.location.y))
|
933
|
+
return true
|
934
|
+
end
|
935
|
+
rescue StandardError => e
|
936
|
+
puts "❌ Error: #{e}"
|
937
|
+
end
|
938
|
+
|
939
|
+
return false;
|
940
|
+
end
|
941
|
+
|
942
|
+
def get_object_and_store_as_string(object,string)
|
943
|
+
text = execute_gettext(object)
|
944
|
+
txt = "'" + text + "'"
|
945
|
+
set_var(string, txt)
|
946
|
+
end
|
947
|
+
|
948
|
+
|
949
|
+
def get_object_and_store_to_file(object,file_name)
|
950
|
+
$text = execute_gettext(object)
|
951
|
+
open($test_data_dir+file_name, 'a+') do |f|
|
952
|
+
f << $text + "\n"
|
953
|
+
end
|
954
|
+
end
|
955
|
+
|
956
|
+
def drag_and_drop_by_offset(element, x, y)
|
957
|
+
foundElement = find_object(element)
|
958
|
+
if foundElement != nil
|
959
|
+
begin
|
960
|
+
page.driver.browser.action.drag_and_drop_by(foundElement, x, y).perform
|
961
|
+
rescue Exception => e
|
962
|
+
raise "❌ ERROR: #{e}"
|
963
|
+
end
|
964
|
+
else
|
965
|
+
raise "❌ Error: Not found object: #{element}"
|
966
|
+
end
|
967
|
+
end
|
968
|
+
|
969
|
+
def drag_and_drop_to_object(from_element, element)
|
970
|
+
found_from_element = find_object(from_element)
|
971
|
+
foundElement = find_object(element)
|
972
|
+
if foundElement != nil and found_from_element != nil
|
973
|
+
found_from_element.drag_to(foundElement)
|
974
|
+
end
|
975
|
+
end
|
976
|
+
|
977
|
+
def execute_sendkeys(element, key)
|
978
|
+
validate_supported_keys(key)
|
979
|
+
foundElement = find_object(element)
|
980
|
+
if foundElement != nil
|
981
|
+
begin
|
982
|
+
foundElement.native.send_keys(key)
|
983
|
+
rescue Exception => e
|
984
|
+
raise "❌ ERROR: #{e}"
|
985
|
+
end
|
986
|
+
else
|
987
|
+
raise "❌ Error: Not found object: #{element}"
|
988
|
+
end
|
989
|
+
end
|
990
|
+
|
991
|
+
def movemouseandclick var, element
|
992
|
+
Selenium::WebDriver::Support::Select.new(page.driver.browser.find_element(:id, "#{var}")).select_by(:text, "#{element}")
|
993
|
+
page.driver.browser.find_element(:id, "#{var}").click
|
994
|
+
end
|