itms_automation 1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|