onlyoffice_webdriver_wrapper 0.0.1
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/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
|