onlyoffice_webdriver_wrapper 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/onlyoffice_webdriver_wrapper.rb +5 -0
- data/lib/onlyoffice_webdriver_wrapper/dimensions.rb +16 -0
- data/lib/onlyoffice_webdriver_wrapper/helpers/bin/chromedriver +0 -0
- data/lib/onlyoffice_webdriver_wrapper/helpers/bin/chromedriver_mac +0 -0
- data/lib/onlyoffice_webdriver_wrapper/helpers/bin/geckodriver +0 -0
- data/lib/onlyoffice_webdriver_wrapper/helpers/chrome_helper.rb +62 -0
- data/lib/onlyoffice_webdriver_wrapper/helpers/firefox_helper.rb +26 -0
- data/lib/onlyoffice_webdriver_wrapper/helpers/headless_helper.rb +65 -0
- data/lib/onlyoffice_webdriver_wrapper/helpers/headless_helper/real_display_tools.rb +22 -0
- data/lib/onlyoffice_webdriver_wrapper/helpers/headless_helper/ruby_helper.rb +14 -0
- data/lib/onlyoffice_webdriver_wrapper/helpers/os_helper.rb +9 -0
- data/lib/onlyoffice_webdriver_wrapper/version.rb +5 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver.rb +713 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_alert_helper.rb +25 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_attributes_helper.rb +53 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_browser_info_helper.rb +20 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_browser_log_helper.rb +9 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_exceptions.rb +3 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_extension.rb +2 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_helper.rb +22 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_js_methods.rb +56 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_screenshot_helper.rb +60 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_style_helper.rb +41 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_tab_helper.rb +74 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_type_helper.rb +104 -0
- data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_user_agent_helper.rb +40 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f5c77f8a1e5352b76bd894aa9039fe4e3094ba5f9c66818e5ea5ba556fff4c8f
|
4
|
+
data.tar.gz: 935c4aaa607da023aa5cd59e5335c84d7cbc87becd1afc12252b1faecdd58e8b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2abcee5172ae2629bfea3610dc88d767db299a609d6de8c3c37ce05461ee78c10679f6af5be453799658ab2898999bdbe1845dc79a07e2607b7c7e845a582855
|
7
|
+
data.tar.gz: 4952374aa06647c64e94a7ade41e107f636cd40ab2144017118d44861bc7652b2af6ba392026fe591ddb9622d7da1bb47d1d2f889913cbf3d5aaa97e2d56ec0d
|
@@ -0,0 +1,5 @@
|
|
1
|
+
require 'onlyoffice_logger_helper'
|
2
|
+
require_relative 'onlyoffice_webdriver_wrapper/helpers/headless_helper'
|
3
|
+
require_relative 'onlyoffice_webdriver_wrapper/helpers/os_helper'
|
4
|
+
require_relative 'onlyoffice_webdriver_wrapper/dimensions'
|
5
|
+
require_relative 'onlyoffice_webdriver_wrapper/webdriver'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module OnlyofficeWebdriverWrapper
|
2
|
+
# Class for working with cursor coordinates
|
3
|
+
class Dimensions
|
4
|
+
attr_accessor :left, :top
|
5
|
+
|
6
|
+
def initialize(left, top)
|
7
|
+
@left = left
|
8
|
+
@top = top
|
9
|
+
end
|
10
|
+
|
11
|
+
alias width left
|
12
|
+
alias height top
|
13
|
+
alias x left
|
14
|
+
alias y top
|
15
|
+
end
|
16
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module OnlyofficeWebdriverWrapper
|
2
|
+
# Class for working with Chrome
|
3
|
+
module ChromeHelper
|
4
|
+
DEFAULT_CHROME_SWITCHES = %w[--kiosk-printing
|
5
|
+
--start-maximized
|
6
|
+
--disable-popup-blocking
|
7
|
+
--disable-infobars
|
8
|
+
--no-sandbox
|
9
|
+
test-type].freeze
|
10
|
+
|
11
|
+
# @return [String] path to chromedriver
|
12
|
+
def chromedriver_path
|
13
|
+
driver_name = 'bin/chromedriver'
|
14
|
+
driver_name = 'bin/chromedriver_mac' if OSHelper.mac?
|
15
|
+
File.join(File.dirname(__FILE__), driver_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Webdriver::Chrome] Chrome webdriver
|
19
|
+
def start_chrome_driver
|
20
|
+
prefs = {
|
21
|
+
download: {
|
22
|
+
prompt_for_download: false,
|
23
|
+
default_directory: download_directory
|
24
|
+
},
|
25
|
+
profile: {
|
26
|
+
default_content_settings: {
|
27
|
+
'multiple-automatic-downloads' => 1
|
28
|
+
}
|
29
|
+
},
|
30
|
+
credentials_enable_service: false
|
31
|
+
}
|
32
|
+
caps = Selenium::WebDriver::Remote::Capabilities.chrome
|
33
|
+
caps[:logging_prefs] = { browser: 'ALL' }
|
34
|
+
caps[:proxy] = Selenium::WebDriver::Proxy.new(ssl: "#{@proxy.proxy_address}:#{@proxy.proxy_port}") if @proxy
|
35
|
+
if ip_of_remote_server.nil?
|
36
|
+
switches = add_useragent_to_switches(DEFAULT_CHROME_SWITCHES)
|
37
|
+
options = Selenium::WebDriver::Chrome::Options.new(args: switches,
|
38
|
+
prefs: prefs)
|
39
|
+
webdriver_options = { options: options,
|
40
|
+
desired_capabilities: caps,
|
41
|
+
driver_path: chromedriver_path }
|
42
|
+
begin
|
43
|
+
driver = Selenium::WebDriver.for :chrome, webdriver_options
|
44
|
+
rescue Selenium::WebDriver::Error::WebDriverError,
|
45
|
+
Net::ReadTimeout,
|
46
|
+
Errno::ECONNREFUSED => e
|
47
|
+
OnlyofficeLoggerHelper.log("Starting chrome failed with error: #{e.backtrace}")
|
48
|
+
sleep 10
|
49
|
+
driver = Selenium::WebDriver.for :chrome, webdriver_options
|
50
|
+
end
|
51
|
+
driver.manage.window.size = Selenium::WebDriver::Dimension.new(headless.resolution_x, headless.resolution_y) if headless.running?
|
52
|
+
driver
|
53
|
+
else
|
54
|
+
caps['chromeOptions'] = {
|
55
|
+
profile: data['zip'],
|
56
|
+
extensions: data['extensions']
|
57
|
+
}
|
58
|
+
Selenium::WebDriver.for(:remote, url: 'http://' + remote_server + ':4444/wd/hub', desired_capabilities: caps)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module OnlyofficeWebdriverWrapper
|
2
|
+
# Module for working with firefox
|
3
|
+
module FirefoxHelper
|
4
|
+
# @return [Webdriver::Firefox] firefox webdriver
|
5
|
+
def start_firefox_driver
|
6
|
+
geckodriver = File.join(File.dirname(__FILE__), 'bin/geckodriver')
|
7
|
+
profile = Selenium::WebDriver::Firefox::Profile.new
|
8
|
+
profile['browser.download.folderList'] = 2
|
9
|
+
profile['browser.helperApps.neverAsk.saveToDisk'] = 'application/doct, application/mspowerpoint, application/msword, application/octet-stream, application/oleobject, application/pdf, application/powerpoint, application/pptt, application/rtf, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/vnd.oasis.opendocument.spreadsheet, application/vnd.oasis.opendocument.text, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/x-compressed, application/x-excel, application/xlst, application/x-msexcel, application/x-mspowerpoint, application/x-rtf, application/x-zip-compressed, application/zip, image/jpeg, image/pjpeg, image/pjpeg, image/x-jps, message/rfc822, multipart/x-zip, text/csv, text/html, text/html, text/plain, text/richtext'
|
10
|
+
profile['browser.download.dir'] = @download_directory
|
11
|
+
profile['browser.download.manager.showWhenStarting'] = false
|
12
|
+
profile['dom.disable_window_move_resize'] = false
|
13
|
+
options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
|
14
|
+
caps = Selenium::WebDriver::Remote::Capabilities.firefox
|
15
|
+
caps[:proxy] = Selenium::WebDriver::Proxy.new(ssl: "#{@proxy.proxy_address}:#{@proxy.proxy_port}") if @proxy
|
16
|
+
if ip_of_remote_server.nil?
|
17
|
+
driver = Selenium::WebDriver.for :firefox, options: options, driver_path: geckodriver, desired_capabilities: caps
|
18
|
+
driver.manage.window.size = Selenium::WebDriver::Dimension.new(headless.resolution_x, headless.resolution_y) if headless.running?
|
19
|
+
driver
|
20
|
+
else
|
21
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.firefox(firefox_profile: profile, desired_capabilities: caps)
|
22
|
+
Selenium::WebDriver.for :remote, desired_capabilities: capabilities, url: 'http://' + ip_of_remote_server + ':4444/wd/hub'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require_relative 'headless_helper/real_display_tools'
|
2
|
+
require_relative 'headless_helper/ruby_helper'
|
3
|
+
require 'headless'
|
4
|
+
|
5
|
+
module OnlyofficeWebdriverWrapper
|
6
|
+
# Class for using headless gem
|
7
|
+
class HeadlessHelper
|
8
|
+
include RealDisplayTools
|
9
|
+
include RubyHelper
|
10
|
+
attr_accessor :headless_instance
|
11
|
+
attr_accessor :resolution_x
|
12
|
+
attr_accessor :resolution_y
|
13
|
+
|
14
|
+
def initialize(resolution_x = 1680, resolution_y = 1050)
|
15
|
+
@resolution_x = resolution_x
|
16
|
+
@resolution_y = resolution_y
|
17
|
+
end
|
18
|
+
|
19
|
+
# Check if should start headless
|
20
|
+
# @return [True, False] result
|
21
|
+
def should_start?
|
22
|
+
return false if debug?
|
23
|
+
return false if OSHelper.mac?
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def start
|
28
|
+
create_session = if real_display_connected?
|
29
|
+
should_start?
|
30
|
+
else
|
31
|
+
true
|
32
|
+
end
|
33
|
+
return unless create_session
|
34
|
+
OnlyofficeLoggerHelper.log('Starting Headless Session')
|
35
|
+
begin
|
36
|
+
@headless_instance = Headless.new(reuse: false,
|
37
|
+
destroy_at_exit: true,
|
38
|
+
dimensions: "#{@resolution_x + 1}x#{@resolution_y + 1}x24")
|
39
|
+
rescue Exception => e
|
40
|
+
OnlyofficeLoggerHelper.log("xvfb not started with problem #{e}")
|
41
|
+
RspecHelper.clean_up(true)
|
42
|
+
@headless_instance = Headless.new(reuse: false,
|
43
|
+
destroy_at_exit: true,
|
44
|
+
dimensions: "#{@resolution_x + 1}x#{@resolution_y + 1}x24")
|
45
|
+
end
|
46
|
+
headless_instance.start
|
47
|
+
end
|
48
|
+
|
49
|
+
def stop
|
50
|
+
return unless running?
|
51
|
+
OnlyofficeLoggerHelper.log('Stopping Headless Session')
|
52
|
+
headless_instance.destroy
|
53
|
+
end
|
54
|
+
|
55
|
+
def running?
|
56
|
+
!headless_instance.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
def take_screenshot(scr_path = '/tmp/screenshot.png')
|
60
|
+
return unless running?
|
61
|
+
headless_instance.take_screenshot(scr_path)
|
62
|
+
OnlyofficeLoggerHelper.log("Took Screenshot to file: #{scr_path}")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module OnlyofficeWebdriverWrapper
|
2
|
+
# module for getting info about real display
|
3
|
+
module RealDisplayTools
|
4
|
+
def xrandr_result
|
5
|
+
begin
|
6
|
+
result = `xrandr 2>&1`
|
7
|
+
rescue Exception
|
8
|
+
result = 'xrandr throw an exception'
|
9
|
+
end
|
10
|
+
OnlyofficeLoggerHelper.log("xrandr answer: #{result}".delete("\n"))
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
def real_display_connected?
|
15
|
+
return true if OSHelper.mac?
|
16
|
+
result = xrandr_result
|
17
|
+
exists = result.include?(' connected') && !result.include?('Failed')
|
18
|
+
OnlyofficeLoggerHelper.log("Real Display Exists: #{exists}")
|
19
|
+
exists
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module OnlyofficeWebdriverWrapper
|
2
|
+
# Module for check ruby info
|
3
|
+
module RubyHelper
|
4
|
+
def debug?
|
5
|
+
ENV['RUBYLIB'].to_s.include?('ruby-debug')
|
6
|
+
end
|
7
|
+
|
8
|
+
# Check if current os is 64 bit
|
9
|
+
# @return [True, False] result of comparision
|
10
|
+
def os_64_bit?
|
11
|
+
RUBY_PLATFORM.include?('_64')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,713 @@
|
|
1
|
+
require 'onlyoffice_file_helper'
|
2
|
+
require 'page-object'
|
3
|
+
require 'securerandom'
|
4
|
+
require 'selenium-webdriver'
|
5
|
+
require 'uri'
|
6
|
+
require_relative 'helpers/chrome_helper'
|
7
|
+
require_relative 'helpers/firefox_helper'
|
8
|
+
require_relative 'webdriver/webdriver_alert_helper'
|
9
|
+
require_relative 'webdriver/webdriver_attributes_helper'
|
10
|
+
require_relative 'webdriver/webdriver_browser_info_helper'
|
11
|
+
require_relative 'webdriver/webdriver_type_helper'
|
12
|
+
require_relative 'webdriver/webdriver_exceptions'
|
13
|
+
require_relative 'webdriver/webdriver_extension'
|
14
|
+
require_relative 'webdriver/webdriver_helper'
|
15
|
+
require_relative 'webdriver/webdriver_js_methods'
|
16
|
+
require_relative 'webdriver/webdriver_screenshot_helper'
|
17
|
+
require_relative 'webdriver/webdriver_style_helper'
|
18
|
+
require_relative 'webdriver/webdriver_tab_helper'
|
19
|
+
require_relative 'webdriver/webdriver_user_agent_helper'
|
20
|
+
require_relative 'webdriver/webdriver_browser_log_helper'
|
21
|
+
|
22
|
+
module OnlyofficeWebdriverWrapper
|
23
|
+
# noinspection RubyTooManyMethodsInspection, RubyInstanceMethodNamingConvention, RubyParameterNamingConvention
|
24
|
+
class WebDriver
|
25
|
+
include ChromeHelper
|
26
|
+
include FirefoxHelper
|
27
|
+
include RubyHelper
|
28
|
+
include WebdriverAlertHelper
|
29
|
+
include WebdriverAttributesHelper
|
30
|
+
include WebdriverBrowserInfo
|
31
|
+
include WebdriverTypeHelper
|
32
|
+
include WebdriverHelper
|
33
|
+
include WebdriverJsMethods
|
34
|
+
include WebdriverScreenshotHelper
|
35
|
+
include WebdriverStyleHelper
|
36
|
+
include WebdriverTabHelper
|
37
|
+
include WebdriverUserAgentHelper
|
38
|
+
include WebdriverBrowserLogHelper
|
39
|
+
TIMEOUT_WAIT_ELEMENT = 15
|
40
|
+
TIMEOUT_FILE_DOWNLOAD = 100
|
41
|
+
# @return [Array, String] default switches for chrome
|
42
|
+
attr_accessor :driver
|
43
|
+
attr_accessor :browser
|
44
|
+
# @return [Symbol] device of which we try to simulate, default - :desktop_linux
|
45
|
+
attr_accessor :device
|
46
|
+
attr_accessor :ip_of_remote_server
|
47
|
+
attr_accessor :download_directory
|
48
|
+
attr_accessor :server_address
|
49
|
+
attr_accessor :headless
|
50
|
+
# @return [Net::HTTP::Proxy] connection proxy
|
51
|
+
attr_accessor :proxy
|
52
|
+
|
53
|
+
singleton_class.class_eval { attr_accessor :web_console_error }
|
54
|
+
|
55
|
+
def initialize(browser = :firefox,
|
56
|
+
remote_server = nil,
|
57
|
+
device: :desktop_linux,
|
58
|
+
proxy: nil)
|
59
|
+
raise WebdriverSystemNotSupported, 'Your OS is not 64 bit. It is not supported' unless os_64_bit?
|
60
|
+
@device = device
|
61
|
+
@headless = HeadlessHelper.new
|
62
|
+
@headless.start
|
63
|
+
|
64
|
+
@download_directory = Dir.mktmpdir('webdriver-download')
|
65
|
+
@browser = browser
|
66
|
+
@ip_of_remote_server = remote_server
|
67
|
+
@proxy = proxy
|
68
|
+
case browser
|
69
|
+
when :firefox
|
70
|
+
@driver = start_firefox_driver
|
71
|
+
when :chrome
|
72
|
+
@driver = start_chrome_driver
|
73
|
+
else
|
74
|
+
raise 'Unknown Browser: ' + browser.to_s
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def add_web_console_error(log)
|
79
|
+
WebDriver.web_console_error = log
|
80
|
+
end
|
81
|
+
|
82
|
+
def open(url)
|
83
|
+
url = 'http://' + url unless url.include?('http') || url.include?('file://')
|
84
|
+
loop do
|
85
|
+
begin
|
86
|
+
@driver.navigate.to url
|
87
|
+
break
|
88
|
+
rescue Timeout::Error
|
89
|
+
@driver.navigate.refresh
|
90
|
+
end
|
91
|
+
end
|
92
|
+
OnlyofficeLoggerHelper.log("Opened page: #{url}")
|
93
|
+
end
|
94
|
+
|
95
|
+
def quit
|
96
|
+
begin
|
97
|
+
@driver.execute_script('window.onbeforeunload = null') # off popup window
|
98
|
+
rescue StandardError
|
99
|
+
Exception
|
100
|
+
end
|
101
|
+
begin
|
102
|
+
@driver.quit
|
103
|
+
rescue Exception => e
|
104
|
+
OnlyofficeLoggerHelper.log("Some error happened on webdriver.quit #{e.backtrace}")
|
105
|
+
end
|
106
|
+
alert_confirm
|
107
|
+
@headless.stop
|
108
|
+
FileUtils.remove_dir(@download_directory) if Dir.exist?(@download_directory)
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_element(object_identification)
|
112
|
+
return object_identification unless object_identification.is_a?(String)
|
113
|
+
@driver.find_element(:xpath, object_identification)
|
114
|
+
rescue StandardError
|
115
|
+
nil
|
116
|
+
end
|
117
|
+
|
118
|
+
def set_text_to_iframe(element, text)
|
119
|
+
element.click
|
120
|
+
@driver.action.send_keys(text).perform
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_text_array(array_elements)
|
124
|
+
get_elements(array_elements).map { |current_element| get_text(current_element) }
|
125
|
+
end
|
126
|
+
|
127
|
+
def click(element)
|
128
|
+
element.click
|
129
|
+
end
|
130
|
+
|
131
|
+
def click_and_wait(element_to_click, element_to_wait)
|
132
|
+
element_to_click.click
|
133
|
+
count = 0
|
134
|
+
while !element_to_wait.visible? && count < 30
|
135
|
+
sleep 1
|
136
|
+
count += 1
|
137
|
+
end
|
138
|
+
webdriver_error("click_and_wait: Wait for element: #{element_to_click} for 30 seconds") if count == 30
|
139
|
+
end
|
140
|
+
|
141
|
+
def select_from_list(xpath_value, value)
|
142
|
+
@driver.find_element(:xpath, xpath_value).find_elements(tag_name: 'li').each do |element|
|
143
|
+
next unless element.text == value.to_s
|
144
|
+
element.click
|
145
|
+
return true
|
146
|
+
end
|
147
|
+
|
148
|
+
webdriver_error("select_from_list: Option #{value} in list #{xpath_value} not found")
|
149
|
+
end
|
150
|
+
|
151
|
+
def select_from_list_elements(value, elements_value)
|
152
|
+
index = get_element_index(value, elements_value)
|
153
|
+
elements_value[index].click
|
154
|
+
end
|
155
|
+
|
156
|
+
def get_element_index(title, list_elements)
|
157
|
+
list_elements.each_with_index do |current, i|
|
158
|
+
return i if get_text(current) == title
|
159
|
+
end
|
160
|
+
nil
|
161
|
+
end
|
162
|
+
|
163
|
+
def get_all_combo_box_values(xpath_name)
|
164
|
+
@driver.find_element(:xpath, xpath_name).find_elements(tag_name: 'option').map { |el| el.attribute('value') }
|
165
|
+
end
|
166
|
+
|
167
|
+
# @return [String] url of current frame, or browser url if
|
168
|
+
# it is a root frame
|
169
|
+
def get_url
|
170
|
+
execute_javascript('return window.location.href')
|
171
|
+
rescue Selenium::WebDriver::Error::NoSuchDriverError
|
172
|
+
raise 'Browser is crushed or hangup'
|
173
|
+
end
|
174
|
+
|
175
|
+
def refresh
|
176
|
+
@driver.navigate.refresh
|
177
|
+
OnlyofficeLoggerHelper.log('Refresh page')
|
178
|
+
end
|
179
|
+
|
180
|
+
def go_back
|
181
|
+
@driver.navigate.back
|
182
|
+
OnlyofficeLoggerHelper.log('Go back to previous page')
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.host_name_by_full_url(full_url)
|
186
|
+
uri = URI(full_url)
|
187
|
+
uri.port == 80 || uri.port == 443 ? "#{uri.scheme}://#{uri.host}" : "#{uri.scheme}://#{uri.host}:#{uri.port}"
|
188
|
+
end
|
189
|
+
|
190
|
+
def get_host_name
|
191
|
+
WebDriver.host_name_by_full_url(get_url)
|
192
|
+
end
|
193
|
+
|
194
|
+
def remove_event(event_name)
|
195
|
+
execute_javascript("jQuery(document).unbind('#{event_name}');")
|
196
|
+
end
|
197
|
+
|
198
|
+
def remove_class_by_jquery(selector, class_name)
|
199
|
+
execute_javascript('cd(window.frames[0])')
|
200
|
+
execute_javascript("$('#{selector}').removeClass('#{class_name}');")
|
201
|
+
end
|
202
|
+
|
203
|
+
def add_class_by_jquery(selector, class_name)
|
204
|
+
execute_javascript("$('#{selector}').addClass('#{class_name}');")
|
205
|
+
end
|
206
|
+
|
207
|
+
# Perform drag'n'drop action in one element (for example on big canvas area)
|
208
|
+
# for drag'n'drop one whole element use 'drag_and_drop_by'
|
209
|
+
# ==== Attributes
|
210
|
+
#
|
211
|
+
# * +xpath+ - xpath of element on which drag and drop performed
|
212
|
+
# * +x1+ - x coordinate on element to start drag'n'drop
|
213
|
+
# * +y1+ - y coordinate on element to start drag'n'drop
|
214
|
+
# * +x2+ - shift vector x coordinate
|
215
|
+
# * +y2+ - shift vector y coordinate
|
216
|
+
# * +mouse_release+ - release mouse after move
|
217
|
+
def drag_and_drop(xpath, x1, y1, x2, y2, mouse_release: true)
|
218
|
+
canvas = get_element(xpath)
|
219
|
+
if mouse_release
|
220
|
+
@driver.action.move_to(canvas, x1.to_i, y1.to_i).click_and_hold.move_by(x2, y2).release.perform
|
221
|
+
else
|
222
|
+
@driver.action.move_to(canvas, x1.to_i, y1.to_i).click_and_hold.move_by(x2, y2).perform
|
223
|
+
end
|
224
|
+
rescue ArgumentError
|
225
|
+
raise "Replace 'click_and_hold(element)' to 'click_and_hold(element = nil)' in action_builder.rb"
|
226
|
+
rescue TypeError => e
|
227
|
+
webdriver_error("drag_and_drop(#{xpath}, #{x1}, #{y1}, #{x2}, #{y2}) TypeError: #{e.message}")
|
228
|
+
end
|
229
|
+
|
230
|
+
# Perform drag'n'drop one whole element
|
231
|
+
# for drag'n'drop inside one element (f.e. canvas) use drag_and_drop
|
232
|
+
# ==== Attributes
|
233
|
+
#
|
234
|
+
# * +source+ - xpath of element on which drag and drop performed
|
235
|
+
# * +right_by+ - shift vector x coordinate
|
236
|
+
# * +down_by+ - shift vector y coordinate
|
237
|
+
def drag_and_drop_by(source, right_by, down_by = 0)
|
238
|
+
@driver.action.drag_and_drop_by(get_element(source), right_by, down_by).perform
|
239
|
+
end
|
240
|
+
|
241
|
+
def scroll_list_to_element(list_xpath, element_xpath)
|
242
|
+
execute_javascript("$(document.evaluate(\"#{list_xpath}\", document, null, XPathResult.ANY_TYPE, null).
|
243
|
+
iterateNext()).jScrollPane().data('jsp').scrollToElement(document.evaluate(\"#{element_xpath}\",
|
244
|
+
document, null, XPathResult.ANY_TYPE, null).iterateNext());")
|
245
|
+
end
|
246
|
+
|
247
|
+
def scroll_list_by_pixels(list_xpath, pixels)
|
248
|
+
execute_javascript("$(document.evaluate(\"#{list_xpath.tr('"', "'")}\", document, null, XPathResult.ANY_TYPE, null).iterateNext()).scrollTop(#{pixels})")
|
249
|
+
end
|
250
|
+
|
251
|
+
# Open dropdown selector, like 'Color Selector', which has no element id
|
252
|
+
# @param [String] xpath_name name of dropdown list
|
253
|
+
def open_dropdown_selector(xpath_name, horizontal_shift = 30, vertical_shift = 0)
|
254
|
+
element = get_element(xpath_name)
|
255
|
+
if @browser == :firefox || @browser == :safari
|
256
|
+
set_style_attribute(xpath_name + '/button', 'display', 'none')
|
257
|
+
set_style_attribute(xpath_name, 'display', 'inline')
|
258
|
+
element.click
|
259
|
+
set_style_attribute(xpath_name + '/button', 'display', 'inline-block')
|
260
|
+
set_style_attribute(xpath_name, 'display', 'block')
|
261
|
+
else
|
262
|
+
@driver.action.move_to(element, horizontal_shift, vertical_shift).click.perform
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
# Click on locator
|
267
|
+
# @param count [Integer] count of clicks
|
268
|
+
def click_on_locator(xpath_name, by_javascript = false, count: 1)
|
269
|
+
element = get_element(xpath_name)
|
270
|
+
return webdriver_error("Element with xpath: #{xpath_name} not found") if element.nil?
|
271
|
+
if by_javascript
|
272
|
+
execute_javascript("document.evaluate(\"#{xpath_name}\", document, null, XPathResult.ANY_TYPE, null).iterateNext().click();")
|
273
|
+
else
|
274
|
+
begin
|
275
|
+
count.times { element.click }
|
276
|
+
rescue Selenium::WebDriver::Error::ElementNotVisibleError
|
277
|
+
webdriver_error("Selenium::WebDriver::Error::ElementNotVisibleError: element not visible for xpath: #{xpath_name}")
|
278
|
+
rescue Exception => e
|
279
|
+
webdriver_error(e.class, "UnknownError #{e.message} #{xpath_name}")
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def left_mouse_click(xpath, x_coord, y_coord)
|
285
|
+
@driver.action.move_to(get_element(xpath), x_coord.to_i, y_coord.to_i).click.perform
|
286
|
+
end
|
287
|
+
|
288
|
+
# Context click on locator
|
289
|
+
# @param [String] xpath_name name of xpath to click
|
290
|
+
def context_click_on_locator(xpath_name)
|
291
|
+
wait_until_element_visible(xpath_name)
|
292
|
+
|
293
|
+
element = @driver.find_element(:xpath, xpath_name)
|
294
|
+
@driver.action.context_click(element).perform
|
295
|
+
end
|
296
|
+
|
297
|
+
def right_click(xpath_name)
|
298
|
+
@driver.action.context_click(@driver.find_element(:xpath, xpath_name)).perform
|
299
|
+
end
|
300
|
+
|
301
|
+
def context_click(xpath, x_coord, y_coord)
|
302
|
+
element = get_element(xpath)
|
303
|
+
if browser == :firefox
|
304
|
+
element.send_keys %i[shift f10]
|
305
|
+
else
|
306
|
+
@driver.action.move_to(element, x_coord.to_i, y_coord.to_i).context_click.perform
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
def click_on_displayed(xpath_name)
|
311
|
+
element = get_element_by_display(xpath_name)
|
312
|
+
begin
|
313
|
+
element.is_a?(Array) ? element.first.click : element.click
|
314
|
+
rescue Exception => e
|
315
|
+
webdriver_error("Exception #{e} in click_on_displayed(#{xpath_name})")
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def click_on_locator_by_action(xpath)
|
320
|
+
@driver.action.move_to(get_element(xpath)).click.perform
|
321
|
+
end
|
322
|
+
|
323
|
+
def click_on_locator_coordinates(xpath_name, right_by, down_by)
|
324
|
+
wait_until_element_visible(xpath_name)
|
325
|
+
element = @driver.find_element(:xpath, xpath_name)
|
326
|
+
@driver.action.move_to(element, right_by.to_i, down_by.to_i).perform
|
327
|
+
@driver.action.move_to(element, right_by.to_i, down_by.to_i).click.perform
|
328
|
+
end
|
329
|
+
|
330
|
+
def right_click_on_locator_coordinates(xpath_name, right_by = nil, down_by = nil)
|
331
|
+
wait_until_element_visible(xpath_name)
|
332
|
+
element = @driver.find_element(:xpath, xpath_name)
|
333
|
+
@driver.action.move_to(element, right_by.to_i, down_by.to_i).perform
|
334
|
+
@driver.action.move_to(element, right_by.to_i, down_by.to_i).context_click.perform
|
335
|
+
end
|
336
|
+
|
337
|
+
def double_click(xpath_name)
|
338
|
+
wait_until_element_visible(xpath_name)
|
339
|
+
@driver.action.move_to(@driver.find_element(:xpath, xpath_name)).double_click.perform
|
340
|
+
end
|
341
|
+
|
342
|
+
def double_click_on_locator_coordinates(xpath_name, right_by, down_by)
|
343
|
+
wait_until_element_visible(xpath_name)
|
344
|
+
@driver.action.move_to(@driver.find_element(:xpath, xpath_name), right_by.to_i, down_by.to_i).double_click.perform
|
345
|
+
end
|
346
|
+
|
347
|
+
def action_on_locator_coordinates(xpath_name, right_by, down_by, action = :click, times = 1)
|
348
|
+
wait_until_element_visible(xpath_name)
|
349
|
+
element = @driver.find_element(:xpath, xpath_name)
|
350
|
+
(0...times).inject(@driver.action.move_to(element, right_by.to_i, down_by.to_i)) { |acc, _elem| acc.send(action) }.perform
|
351
|
+
end
|
352
|
+
|
353
|
+
def click_on_one_of_several_by_text(xpath_several_elements, text_to_click)
|
354
|
+
@driver.find_elements(:xpath, xpath_several_elements).each do |current_element|
|
355
|
+
next unless text_to_click.to_s == current_element.attribute('innerHTML')
|
356
|
+
begin
|
357
|
+
current_element.click
|
358
|
+
rescue Exception => e
|
359
|
+
webdriver_error("Error in click_on_one_of_several_by_text(#{xpath_several_elements}, #{text_to_click}): #{e.message}")
|
360
|
+
end
|
361
|
+
return true
|
362
|
+
end
|
363
|
+
false
|
364
|
+
end
|
365
|
+
|
366
|
+
def click_on_one_of_several_by_display(xpath_several_elements)
|
367
|
+
@driver.find_elements(:xpath, xpath_several_elements).each do |current_element|
|
368
|
+
if current_element.displayed?
|
369
|
+
current_element.click
|
370
|
+
return true
|
371
|
+
end
|
372
|
+
end
|
373
|
+
false
|
374
|
+
end
|
375
|
+
|
376
|
+
def click_on_one_of_several_with_display_by_text(xpath_several_elements, text_to_click)
|
377
|
+
@driver.find_elements(:xpath, xpath_several_elements).each do |current_element|
|
378
|
+
if current_element.displayed? && text_to_click == current_element.text
|
379
|
+
current_element.click
|
380
|
+
return true
|
381
|
+
end
|
382
|
+
end
|
383
|
+
false
|
384
|
+
end
|
385
|
+
|
386
|
+
def right_click_on_one_of_several_by_text(xpath_several_elements, text_to_click)
|
387
|
+
@driver.find_elements(:xpath, xpath_several_elements).each do |current_element|
|
388
|
+
if text_to_click == current_element.text
|
389
|
+
@driver.action.context_click(current_element).perform
|
390
|
+
return true
|
391
|
+
end
|
392
|
+
end
|
393
|
+
false
|
394
|
+
end
|
395
|
+
|
396
|
+
def click_on_one_of_several_with_display_by_number(xpath_several_elements, number)
|
397
|
+
@driver.find_elements(:xpath, "#{xpath_several_elements}[#{number}]").each do |current_element|
|
398
|
+
if current_element.displayed?
|
399
|
+
current_element.click
|
400
|
+
return true
|
401
|
+
end
|
402
|
+
end
|
403
|
+
false
|
404
|
+
end
|
405
|
+
|
406
|
+
def click_on_one_of_several_by_parameter(xpath_several_elements, parameter_name, parameter_value)
|
407
|
+
@driver.find_elements(:xpath, xpath_several_elements).each do |current_element|
|
408
|
+
if current_element.attribute(parameter_name).include? parameter_value
|
409
|
+
current_element.click
|
410
|
+
return true
|
411
|
+
end
|
412
|
+
end
|
413
|
+
false
|
414
|
+
end
|
415
|
+
|
416
|
+
def click_on_one_of_several_by_parameter_and_text(xpath_several_elements, parameter_name, parameter_value, text_to_click)
|
417
|
+
@driver.find_elements(:xpath, xpath_several_elements).each do |current_element|
|
418
|
+
if current_element.attribute(parameter_name).include?(parameter_value) && text_to_click == current_element.text
|
419
|
+
current_element.click
|
420
|
+
return true
|
421
|
+
end
|
422
|
+
end
|
423
|
+
false
|
424
|
+
end
|
425
|
+
|
426
|
+
def click_on_one_of_several_xpath_by_number(xpath, number_of_element)
|
427
|
+
click_on_locator("(#{xpath})[#{number_of_element}]")
|
428
|
+
end
|
429
|
+
|
430
|
+
def move_to_element(element)
|
431
|
+
element = get_element(element) if element.is_a?(String)
|
432
|
+
@driver.action.move_to(element).perform
|
433
|
+
end
|
434
|
+
|
435
|
+
def move_to_element_by_locator(xpath_name)
|
436
|
+
element = get_element(xpath_name)
|
437
|
+
@driver.action.move_to(element).perform
|
438
|
+
OnlyofficeLoggerHelper.log("Moved mouse to element: #{xpath_name}")
|
439
|
+
end
|
440
|
+
|
441
|
+
def move_to_one_of_several_displayed_element(xpath_several_elements)
|
442
|
+
get_elements(xpath_several_elements).each do |current_element|
|
443
|
+
if current_element.displayed?
|
444
|
+
move_to_element(current_element)
|
445
|
+
return true
|
446
|
+
end
|
447
|
+
end
|
448
|
+
false
|
449
|
+
end
|
450
|
+
|
451
|
+
def mouse_over(xpath_name, x_coordinate = 0, y_coordinate = 0)
|
452
|
+
wait_until_element_present(xpath_name)
|
453
|
+
@driver.action.move_to(@driver.find_element(:xpath, xpath_name), x_coordinate.to_i, y_coordinate.to_i).perform
|
454
|
+
end
|
455
|
+
|
456
|
+
def element_present?(xpath_name)
|
457
|
+
if xpath_name.is_a?(PageObject::Elements::Element)
|
458
|
+
xpath_name.visible?
|
459
|
+
elsif xpath_name.is_a?(Selenium::WebDriver::Element)
|
460
|
+
xpath_name.displayed?
|
461
|
+
else
|
462
|
+
@driver.find_element(:xpath, xpath_name)
|
463
|
+
true
|
464
|
+
end
|
465
|
+
rescue Exception
|
466
|
+
false
|
467
|
+
end
|
468
|
+
|
469
|
+
def wait_until_element_present(xpath_name)
|
470
|
+
wait = Selenium::WebDriver::Wait.new(timeout: TIMEOUT_WAIT_ELEMENT) # seconds
|
471
|
+
begin
|
472
|
+
wait.until { get_element(xpath_name) }
|
473
|
+
rescue Selenium::WebDriver::Error::TimeOutError
|
474
|
+
webdriver_error("wait_until_element_present(#{xpath_name}) Selenium::WebDriver::Error::TimeOutError: timed out after 15 seconds")
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
def wait_until_element_disappear(xpath_name)
|
479
|
+
wait = Selenium::WebDriver::Wait.new(timeout: TIMEOUT_WAIT_ELEMENT) # seconds
|
480
|
+
begin
|
481
|
+
wait.until { get_element(xpath_name) ? false : true }
|
482
|
+
rescue Selenium::WebDriver::Error::TimeOutError
|
483
|
+
webdriver_error("wait_until_element_present(#{xpath_name}) Selenium::WebDriver::Error::TimeOutError: timed out after 15 seconds")
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
def get_elements_from_array_before_some(xpath_several_elements, xpath_for_some)
|
488
|
+
elements = get_elements(xpath_several_elements)
|
489
|
+
result = []
|
490
|
+
some_element = get_element(xpath_for_some)
|
491
|
+
return result if some_element.nil?
|
492
|
+
elements.each do |current|
|
493
|
+
break if current == some_element
|
494
|
+
result << current
|
495
|
+
end
|
496
|
+
result
|
497
|
+
end
|
498
|
+
|
499
|
+
def get_elements_from_array_after_some(xpath_several_elements, xpath_for_some)
|
500
|
+
elements = get_elements(xpath_several_elements)
|
501
|
+
some_element = get_element(xpath_for_some)
|
502
|
+
return elements if some_element.nil?
|
503
|
+
elements.each do |current|
|
504
|
+
elements.delete(current)
|
505
|
+
break if current == some_element
|
506
|
+
end
|
507
|
+
elements
|
508
|
+
end
|
509
|
+
|
510
|
+
def get_element_by_display(xpath_name)
|
511
|
+
@driver.find_elements(:xpath, xpath_name).each do |element|
|
512
|
+
return element if element.displayed?
|
513
|
+
end
|
514
|
+
rescue Selenium::WebDriver::Error::InvalidSelectorError
|
515
|
+
webdriver_error("get_element_by_display(#{xpath_name}): invalid selector: Unable to locate an element with the xpath expression")
|
516
|
+
end
|
517
|
+
|
518
|
+
def get_element_count(xpath_name, only_visible = true)
|
519
|
+
if element_present?(xpath_name)
|
520
|
+
elements = @driver.find_elements(:xpath, xpath_name)
|
521
|
+
only_visible ? elements.delete_if { |element| @browser == :firefox && !element.displayed? }.length : elements.length
|
522
|
+
else
|
523
|
+
0
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
def get_elements(objects_identification, only_visible = true)
|
528
|
+
return objects_identification if objects_identification.is_a?(Array)
|
529
|
+
elements = @driver.find_elements(:xpath, objects_identification)
|
530
|
+
if only_visible
|
531
|
+
elements.each do |current|
|
532
|
+
elements.delete(current) unless @browser == :firefox || current.displayed?
|
533
|
+
end
|
534
|
+
end
|
535
|
+
elements
|
536
|
+
end
|
537
|
+
|
538
|
+
def element_visible?(xpath_name)
|
539
|
+
if xpath_name.is_a?(PageObject::Elements::Element) # PageObject always visible
|
540
|
+
true
|
541
|
+
elsif element_present?(xpath_name)
|
542
|
+
element = get_element(xpath_name)
|
543
|
+
return false if element.nil?
|
544
|
+
begin
|
545
|
+
visible = element.displayed?
|
546
|
+
rescue Exception
|
547
|
+
visible = false
|
548
|
+
end
|
549
|
+
visible
|
550
|
+
else
|
551
|
+
false
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
def wait_until_element_visible(xpath_name, timeout = 15)
|
556
|
+
wait_until_element_present(xpath_name)
|
557
|
+
time = 0
|
558
|
+
while !element_visible?(xpath_name) && time < timeout
|
559
|
+
sleep(1)
|
560
|
+
time += 1
|
561
|
+
end
|
562
|
+
return unless time >= timeout
|
563
|
+
webdriver_error("Element #{xpath_name} not visible for #{timeout} seconds")
|
564
|
+
end
|
565
|
+
|
566
|
+
def one_of_several_elements_displayed?(xpath_several_elements)
|
567
|
+
@driver.find_elements(:xpath, xpath_several_elements).each do |current_element|
|
568
|
+
return true if current_element.displayed?
|
569
|
+
end
|
570
|
+
false
|
571
|
+
rescue Exception => e
|
572
|
+
webdriver_error("Raise unkwnown exception: #{e}")
|
573
|
+
end
|
574
|
+
|
575
|
+
def wait_element(xpath_name, period_of_wait = 1, critical_time = 3)
|
576
|
+
wait_until_element_present(xpath_name)
|
577
|
+
time = 0
|
578
|
+
until element_visible?(xpath_name)
|
579
|
+
sleep(period_of_wait)
|
580
|
+
time += 1
|
581
|
+
return if time == critical_time
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
def remove_element(xpath)
|
586
|
+
execute_javascript("element = document.evaluate(\"#{xpath}\", document, null, XPathResult.ANY_TYPE, null).iterateNext();if (element !== null) {element.parentNode.removeChild(element);};")
|
587
|
+
end
|
588
|
+
|
589
|
+
# Select frame as current
|
590
|
+
# @param [String] xpath_name name of current xpath
|
591
|
+
def select_frame(xpath_name = '//iframe', count_of_frames = 1)
|
592
|
+
(0...count_of_frames).each do
|
593
|
+
begin
|
594
|
+
frame = @driver.find_element(:xpath, xpath_name)
|
595
|
+
@driver.switch_to.frame frame
|
596
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError
|
597
|
+
OnlyofficeLoggerHelper.log('Raise NoSuchElementError in the select_frame method')
|
598
|
+
rescue Exception => e
|
599
|
+
webdriver_error("Raise unkwnown exception: #{e}")
|
600
|
+
end
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
604
|
+
# Select top frame of browser (even if several subframes exists)
|
605
|
+
def select_top_frame
|
606
|
+
@driver.switch_to.default_content
|
607
|
+
rescue Timeout::Error
|
608
|
+
OnlyofficeLoggerHelper.log('Raise TimeoutError in the select_top_frame method')
|
609
|
+
rescue Exception => e
|
610
|
+
raise "Browser is crushed or hangup with error: #{e}"
|
611
|
+
end
|
612
|
+
|
613
|
+
# Get text of current element
|
614
|
+
# @param [String] xpath_name name of xpath
|
615
|
+
# @param [true, false] wait_until_visible wait until element visible [@default = true]
|
616
|
+
def get_text(xpath_name, wait_until_visible = true)
|
617
|
+
wait_until_element_visible(xpath_name) if wait_until_visible
|
618
|
+
|
619
|
+
element = get_element(xpath_name)
|
620
|
+
webdriver_error("get_text(#{xpath_name}, #{wait_until_visible}) not found element by xpath") if element.nil?
|
621
|
+
if element.tag_name == 'input' || element.tag_name == 'textarea'
|
622
|
+
element.attribute('value')
|
623
|
+
else
|
624
|
+
element.text
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
def get_text_of_several_elements(xpath_several_elements)
|
629
|
+
@driver.find_elements(:xpath, xpath_several_elements).map { |element| element.text unless element.text == '' }.compact
|
630
|
+
end
|
631
|
+
|
632
|
+
def set_parameter(xpath, attribute, attribute_value)
|
633
|
+
execute_javascript("document.evaluate(\"#{xpath.tr('"', "'")}\",document, null, XPathResult.ANY_TYPE, null ).iterateNext()." \
|
634
|
+
"#{attribute}=\"#{attribute_value}\";")
|
635
|
+
end
|
636
|
+
|
637
|
+
def remove_attribute(xpath, attribute)
|
638
|
+
execute_javascript("document.evaluate(\"#{xpath}\",document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)." \
|
639
|
+
"singleNodeValue.removeAttribute('#{attribute}');")
|
640
|
+
end
|
641
|
+
|
642
|
+
def select_text_from_page(xpath_name)
|
643
|
+
wait_until_element_visible(xpath_name)
|
644
|
+
elem = get_element xpath_name
|
645
|
+
@driver.action.key_down(:control).click(elem).send_keys('a').key_up(:control).perform
|
646
|
+
end
|
647
|
+
|
648
|
+
def select_combo_box(xpath_name, select_value, select_by = :value)
|
649
|
+
wait_until_element_visible(xpath_name)
|
650
|
+
option = Selenium::WebDriver::Support::Select.new(get_element(xpath_name))
|
651
|
+
begin
|
652
|
+
option.select_by(select_by, select_value)
|
653
|
+
rescue StandardError
|
654
|
+
option.select_by(:text, select_value)
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
def get_element_number_by_text(xpath_list, element_text)
|
659
|
+
@driver.find_elements(:xpath, xpath_list).each_with_index do |current_element, index|
|
660
|
+
return index if element_text == current_element.attribute('innerHTML')
|
661
|
+
end
|
662
|
+
nil
|
663
|
+
end
|
664
|
+
|
665
|
+
def get_page_source
|
666
|
+
@driver.execute_script('return document.documentElement.innerHTML;')
|
667
|
+
end
|
668
|
+
|
669
|
+
def webdriver_error(exception, error_message = nil)
|
670
|
+
if exception.is_a?(String) # If there is no error_message
|
671
|
+
error_message = exception
|
672
|
+
exception = RuntimeError
|
673
|
+
end
|
674
|
+
select_top_frame
|
675
|
+
current_url = get_url
|
676
|
+
raise exception, "#{error_message}\n\nPage address: #{current_url}\n\nError #{webdriver_screenshot}"
|
677
|
+
end
|
678
|
+
|
679
|
+
def wait_until(timeout = ::PageObject.default_page_wait, message = nil, wait_js: true, &block)
|
680
|
+
tries ||= 3
|
681
|
+
wait = Object::Selenium::WebDriver::Wait.new(timeout: timeout, message: message)
|
682
|
+
wait.until(&block)
|
683
|
+
if wait_js
|
684
|
+
wait.until { document_ready? }
|
685
|
+
wait.until { jquery_finished? }
|
686
|
+
end
|
687
|
+
rescue Selenium::WebDriver::Error::TimeOutError
|
688
|
+
webdriver_error("Wait until timeout: #{timeout} seconds in")
|
689
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
690
|
+
OnlyofficeLoggerHelper.log("Wait until: rescuing from Stale Element error, #{tries} attempts remaining")
|
691
|
+
retry unless (tries -= 1).zero?
|
692
|
+
webdriver_error('Wait until: rescuing from Stale Element error failed after 3 tries')
|
693
|
+
end
|
694
|
+
|
695
|
+
def wait_file_for_download(file_name, timeout = TIMEOUT_FILE_DOWNLOAD)
|
696
|
+
full_file_name = "#{@download_directory}/#{file_name}"
|
697
|
+
full_file_name = file_name if file_name[0] == '/'
|
698
|
+
counter = 0
|
699
|
+
while !File.exist?(full_file_name) && counter < timeout
|
700
|
+
OnlyofficeLoggerHelper.log("Waiting for download file #{full_file_name} for #{counter} of #{timeout}")
|
701
|
+
sleep 1
|
702
|
+
counter += 1
|
703
|
+
end
|
704
|
+
webdriver_error("File #{full_file_name} not download for #{timeout} seconds") if counter >= timeout
|
705
|
+
full_file_name
|
706
|
+
end
|
707
|
+
|
708
|
+
def service_unavailable?
|
709
|
+
source = get_page_source
|
710
|
+
source.include?('Error 503')
|
711
|
+
end
|
712
|
+
end
|
713
|
+
end
|