onlyoffice_webdriver_wrapper 0.19.0 → 0.22.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.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/lib/onlyoffice_webdriver_wrapper/dimensions.rb +1 -0
  3. data/lib/onlyoffice_webdriver_wrapper/helpers/chrome_helper/chromedriver_bin/chromedriver_mac +0 -0
  4. data/lib/onlyoffice_webdriver_wrapper/helpers/chrome_helper.rb +2 -0
  5. data/lib/onlyoffice_webdriver_wrapper/helpers/firefox_helper.rb +1 -0
  6. data/lib/onlyoffice_webdriver_wrapper/helpers/headless_helper/headless_screenshot_patch.rb +5 -0
  7. data/lib/onlyoffice_webdriver_wrapper/helpers/headless_helper/headless_video_recorder.rb +1 -1
  8. data/lib/onlyoffice_webdriver_wrapper/helpers/headless_helper/real_display_tools.rb +3 -0
  9. data/lib/onlyoffice_webdriver_wrapper/helpers/headless_helper/ruby_helper.rb +2 -1
  10. data/lib/onlyoffice_webdriver_wrapper/helpers/headless_helper.rb +9 -0
  11. data/lib/onlyoffice_webdriver_wrapper/name.rb +2 -0
  12. data/lib/onlyoffice_webdriver_wrapper/version.rb +3 -1
  13. data/lib/onlyoffice_webdriver_wrapper/webdriver/click_methods.rb +1 -1
  14. data/lib/onlyoffice_webdriver_wrapper/webdriver/wait_until_methods.rb +10 -0
  15. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_alert_helper.rb +3 -1
  16. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_attributes_helper.rb +18 -2
  17. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_browser_log_helper.rb +1 -0
  18. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_exceptions.rb +1 -0
  19. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_frame_methods.rb +2 -2
  20. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_helper.rb +4 -0
  21. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_js_methods.rb +6 -1
  22. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_navigation_methods.rb +18 -0
  23. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_screenshot_helper.rb +26 -3
  24. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_style_helper.rb +8 -0
  25. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_tab_helper.rb +24 -3
  26. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_type_helper.rb +46 -0
  27. data/lib/onlyoffice_webdriver_wrapper/webdriver/webdriver_user_agent_helper.rb +6 -2
  28. data/lib/onlyoffice_webdriver_wrapper/webdriver.rb +69 -3
  29. metadata +31 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c2c0b6a752ec508710b4642c516b0d33ae43660cc6b0c8918528541cef29d74
4
- data.tar.gz: bb62666d6e3285139c0ec3c283408b8418ab3475d85a902b5c46e2d6e74e0e3a
3
+ metadata.gz: fe12b63e804baec935bd02d7c762665dc42ae2ffaaa6b22e9f87b8897f7094fe
4
+ data.tar.gz: aac62666386193b8afe23e973d61cfb79654cbc9697cbf6984919608cfa9cb04
5
5
  SHA512:
6
- metadata.gz: e5b9aeae0da9acb8f6cfd7d45cf374df888365001e5afee68f6fec5bf86e8cc6afb27c02a62411b01b2cf83175f779fda3f7a58c126d6c85ddb7b8a0d749d484
7
- data.tar.gz: 3796e30526b01c3f96104ba418828d93e96adfd33f95862c9958941141068cc802e6f73951071869cb020061308075d4781dda5f1113a92a8d97b1b86454c207
6
+ metadata.gz: 43b653341d3b50c0c5f16b691eb293a284ade5b3287bcebe5bd88a6a131daae6d3a52117fe2eef75c3d66002421c7ed8df8ae3930fded89fdcf248fe8c7d7e11
7
+ data.tar.gz: 5bd9fee614e98c0a825cd09f5eb5bb4aab8a17b935bc2dd4651e5436f3111608956ee8ba271bee6af64d62e09671631b08e4d9b14d2aa4cb5ff8a9f853bab2f2
@@ -15,6 +15,7 @@ module OnlyofficeWebdriverWrapper
15
15
  alias x left
16
16
  alias y top
17
17
 
18
+ # @return [String] String representation of Dimensions
18
19
  def to_s
19
20
  "Dimensions(left: #{@left}, top: #{@top})"
20
21
  end
@@ -7,6 +7,7 @@ module OnlyofficeWebdriverWrapper
7
7
  module ChromeHelper
8
8
  include ChromeVersionHelper
9
9
 
10
+ # @return [String] list of default Chrome command line switches
10
11
  DEFAULT_CHROME_SWITCHES = %w[--kiosk-printing
11
12
  --disable-gpu
12
13
  --disable-popup-blocking
@@ -14,6 +15,7 @@ module OnlyofficeWebdriverWrapper
14
15
  --no-sandbox
15
16
  test-type].freeze
16
17
 
18
+ # @return [Selenium::WebDriver::Chrome::Service] Instance of Chrome Service object
17
19
  def chrome_service
18
20
  @chrome_service ||= Selenium::WebDriver::Chrome::Service.new(path: chromedriver_path)
19
21
  end
@@ -3,6 +3,7 @@
3
3
  module OnlyofficeWebdriverWrapper
4
4
  # Module for working with firefox
5
5
  module FirefoxHelper
6
+ # @return [Selenium::WebDriver::Firefox::Service] Instance of Firefox Service object
6
7
  def firefox_service
7
8
  geckodriver = File.join(File.dirname(__FILE__), 'bin/geckodriver')
8
9
  @firefox_service ||= Selenium::WebDriver::Firefox::Service.new(path: geckodriver)
@@ -1,4 +1,9 @@
1
+ # Monkey-patching class from `headless` gem
1
2
  class Headless
3
+ # Fix incorrect taking of screenshots
4
+ # @param [String] file_path Path to store screenshot
5
+ # @param [Hash] options Different options
6
+ # @return [void]
2
7
  def take_screenshot(file_path, options={})
3
8
  using = options.fetch(:using, :imagemagick)
4
9
  case using
@@ -22,7 +22,7 @@ module OnlyofficeWebdriverWrapper
22
22
  @record_video = false
23
23
  end
24
24
 
25
- # @return [nil] stop catpure of file
25
+ # @return [nil] stop capture of file
26
26
  def stop_capture
27
27
  return unless record_video
28
28
 
@@ -3,12 +3,15 @@
3
3
  module OnlyofficeWebdriverWrapper
4
4
  # module for getting info about real display
5
5
  module RealDisplayTools
6
+ # @return [String] result of `xrandr` command output
6
7
  def xrandr_result
7
8
  result = `xrandr 2>&1`
8
9
  OnlyofficeLoggerHelper.log("xrandr answer: #{result}".delete("\n"))
9
10
  result
10
11
  end
11
12
 
13
+ # Check if any real display connected to system
14
+ # @return [Boolean] result of this check
12
15
  def real_display_connected?
13
16
  return true if OSHelper.mac?
14
17
 
@@ -3,12 +3,13 @@
3
3
  module OnlyofficeWebdriverWrapper
4
4
  # Module for check ruby info
5
5
  module RubyHelper
6
+ # @return [Boolean] If current ruby instance run in debug mode
6
7
  def debug?
7
8
  ENV['RUBYLIB'].to_s.include?('ruby-debug')
8
9
  end
9
10
 
10
11
  # Check if current os is 64 bit
11
- # @return [True, False] result of comparision
12
+ # @return [True, False] result of check
12
13
  def os_64_bit?
13
14
  RUBY_PLATFORM.include?('_64')
14
15
  end
@@ -38,6 +38,8 @@ module OnlyofficeWebdriverWrapper
38
38
  true
39
39
  end
40
40
 
41
+ # Start headless session
42
+ # @return [void]
41
43
  def start
42
44
  create_session = if real_display_connected?
43
45
  should_start?
@@ -64,6 +66,8 @@ module OnlyofficeWebdriverWrapper
64
66
  start_capture
65
67
  end
66
68
 
69
+ # Stop current headless session
70
+ # @return [void]
67
71
  def stop
68
72
  return unless running?
69
73
 
@@ -72,10 +76,15 @@ module OnlyofficeWebdriverWrapper
72
76
  headless_instance.destroy
73
77
  end
74
78
 
79
+ # Check if headless session currently running
80
+ # @return [Boolean] result of this check
75
81
  def running?
76
82
  !headless_instance.nil?
77
83
  end
78
84
 
85
+ # Take a screenshot of current headless session
86
+ # @param [String] scr_path Path to store screenshot
87
+ # @return [void]
79
88
  def take_screenshot(scr_path = '/tmp/screenshot.png')
80
89
  return unless running?
81
90
 
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OnlyofficeWebdriverWrapper
4
+ # Module to store name of this gem
4
5
  module Name
6
+ # @return [String] name of this gem
5
7
  STRING = 'onlyoffice_webdriver_wrapper'
6
8
  end
7
9
  end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OnlyofficeWebdriverWrapper
4
+ # Module for storing version data
4
5
  module Version
5
- STRING = '0.19.0'
6
+ # @return [String] Current stable version of gem
7
+ STRING = '0.22.1'
6
8
  end
7
9
  end
@@ -19,7 +19,7 @@ module OnlyofficeWebdriverWrapper
19
19
  return webdriver_error("Element with xpath: #{xpath_name} not found") if element.nil?
20
20
 
21
21
  if by_javascript
22
- execute_javascript("document.evaluate(\"#{xpath_name}\", document, null, XPathResult.ANY_TYPE, null).iterateNext().click();")
22
+ execute_javascript("#{dom_element_by_xpath(xpath_name)}.click();")
23
23
  else
24
24
  begin
25
25
  count.times { element.click }
@@ -6,6 +6,11 @@ module OnlyofficeWebdriverWrapper
6
6
  # @return [Integer] default timeout for wait element
7
7
  TIMEOUT_WAIT_ELEMENT = 15
8
8
 
9
+ # Wait until something happens
10
+ # @param [String] timeout How much to wait
11
+ # @param [String] message which message show if something happens
12
+ # @param [Boolean] wait_js should we wait for JavaScript actions
13
+ # @return [void]
9
14
  def wait_until(timeout = ::PageObject.default_page_wait, message = nil, wait_js: true, &block)
10
15
  tries ||= 3
11
16
  wait = Object::Selenium::WebDriver::Wait.new(timeout: timeout, message: message)
@@ -22,6 +27,11 @@ module OnlyofficeWebdriverWrapper
22
27
  webdriver_error('Wait until: rescuing from Stale Element error failed after 3 tries')
23
28
  end
24
29
 
30
+ # Wait until element is visible
31
+ # @param [String] xpath_name to find object
32
+ # @param [Integer] timeout How much to wait
33
+ # @raise [StandardError] error if element not found for timeout
34
+ # @return [void]
25
35
  def wait_until_element_visible(xpath_name, timeout = 15)
26
36
  wait_until_element_present(xpath_name)
27
37
  time = 0
@@ -3,12 +3,14 @@
3
3
  module OnlyofficeWebdriverWrapper
4
4
  # Methods for working with alerts
5
5
  module WebdriverAlertHelper
6
+ # Confirm current alert
7
+ # @return [void]
6
8
  def alert_confirm
7
9
  @driver.switch_to.alert.accept if alert_exists?
8
10
  end
9
11
 
10
12
  # Check if alert exists
11
- # @return [True, false]
13
+ # @return [Boolean]
12
14
  def alert_exists?
13
15
  @driver.switch_to.alert.text
14
16
  true
@@ -3,9 +3,11 @@
3
3
  module OnlyofficeWebdriverWrapper
4
4
  # Module with methods to work with attributes
5
5
  module WebdriverAttributesHelper
6
+ # Check if attribute of xpath is exists
7
+ # @param [String] xpath_name to find object
8
+ # @param [String] attribute name to check
9
+ # @return [Boolean] result of check
6
10
  def attribute_exist?(xpath_name, attribute)
7
- exist = false
8
-
9
11
  element = xpath_name.is_a?(String) ? get_element(xpath_name) : xpath_name
10
12
  begin
11
13
  attribute_value = element.attribute(attribute)
@@ -16,6 +18,10 @@ module OnlyofficeWebdriverWrapper
16
18
  exist
17
19
  end
18
20
 
21
+ # Get attribute of element
22
+ # @param [String] xpath_name to find object
23
+ # @param [String] attribute to get
24
+ # @return [String] value of attribute
19
25
  def get_attribute(xpath_name, attribute)
20
26
  element = xpath_name.is_a?(Selenium::WebDriver::Element) ? xpath_name : get_element(xpath_name)
21
27
 
@@ -26,6 +32,10 @@ module OnlyofficeWebdriverWrapper
26
32
  end
27
33
  end
28
34
 
35
+ # Get attributes of several elements
36
+ # @param [String] xpath_several_elements to find objects
37
+ # @param [String] attribute to get
38
+ # @return [Array<String>] list of attributes
29
39
  def get_attributes_of_several_elements(xpath_several_elements, attribute)
30
40
  elements = @driver.find_elements(:xpath, xpath_several_elements)
31
41
 
@@ -34,6 +44,12 @@ module OnlyofficeWebdriverWrapper
34
44
  end
35
45
  end
36
46
 
47
+ # Get index of element from array with attribute value
48
+ # @param [String] xpath to find objects
49
+ # @param [String] attribute to check
50
+ # @param [String] value to compare
51
+ # @param [Boolean] only_visible ignore invisible elements unless only_visible
52
+ # @return [Integer] index of element or `0` if not found
37
53
  def get_index_of_elements_with_attribute(xpath, attribute, value, only_visible = true)
38
54
  get_elements(xpath, only_visible).each_with_index do |element, index|
39
55
  return (index + 1) if get_attribute(element, attribute).include?(value)
@@ -3,6 +3,7 @@
3
3
  module OnlyofficeWebdriverWrapper
4
4
  # Methods for working with browser console logs
5
5
  module WebdriverBrowserLogHelper
6
+ # @return [Array] list of browser logs
6
7
  def browser_logs
7
8
  return [] if browser == :firefox # not implemented, see https://github.com/mozilla/geckodriver/issues/284
8
9
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OnlyofficeWebdriverWrapper
4
+ # Exception class if system is not supported
4
5
  class WebdriverSystemNotSupported < StandardError; end
5
6
  end
@@ -14,11 +14,11 @@ module OnlyofficeWebdriverWrapper
14
14
  rescue Selenium::WebDriver::Error::NoSuchElementError
15
15
  OnlyofficeLoggerHelper.log('Raise NoSuchElementError in the select_frame method')
16
16
  rescue Exception => e
17
- webdriver_error("Raise unkwnown exception: #{e}")
17
+ webdriver_error("Raise unknown exception: #{e}")
18
18
  end
19
19
  end
20
20
 
21
- # Select top frame of browser (even if several subframes exists)
21
+ # Select top frame of browser (even if several sub-frames exists)
22
22
  # @return [nil]
23
23
  def select_top_frame
24
24
  @driver.switch_to.default_content
@@ -6,6 +6,10 @@ require 'tempfile'
6
6
  module OnlyofficeWebdriverWrapper
7
7
  # Some additional methods for webdriver
8
8
  module WebdriverHelper
9
+ # Make screenshot by system methods
10
+ # Works only on Linux
11
+ # @param [String] file_name to export screenshot
12
+ # @return [String] result of screenshot command execution
9
13
  def system_screenshot(file_name)
10
14
  `import -window root #{file_name}`
11
15
  end
@@ -29,6 +29,10 @@ module OnlyofficeWebdriverWrapper
29
29
  "document.evaluate(\"#{escaped_xpath}\", document, null, XPathResult.ANY_TYPE, null).iterateNext()"
30
30
  end
31
31
 
32
+ # Type to locator by javascript
33
+ # @param [String] xpath_name to find object where to type
34
+ # @param [String] text to type
35
+ # @return [void]
32
36
  def type_to_locator_by_javascript(xpath_name, text)
33
37
  escaped_text = text.gsub('\\', '\\\\\\\\').gsub('"', '\\"').gsub("\n", '\\n')
34
38
  execute_javascript("document.evaluate('#{xpath_name}', document, null, XPathResult.ANY_TYPE, null).iterateNext().value=\"#{escaped_text}\";")
@@ -52,7 +56,7 @@ module OnlyofficeWebdriverWrapper
52
56
  Dimensions.new(width, height)
53
57
  end
54
58
 
55
- # Get object absolute postion from top left edge of screen
59
+ # Get object absolute position from top left edge of screen
56
60
  # @param xpath [Sting] xpath of object
57
61
  # @return [CursorPoint] position of element
58
62
  def object_absolute_position(xpath)
@@ -76,6 +80,7 @@ module OnlyofficeWebdriverWrapper
76
80
  execute_javascript('return window.jQuery.active;').zero?
77
81
  end
78
82
 
83
+ # @return [Boolean] Is document is ready, finished to be loading
79
84
  def document_ready?
80
85
  execute_javascript('return document.readyState;') == 'complete'
81
86
  end
@@ -8,6 +8,7 @@ module OnlyofficeWebdriverWrapper
8
8
  # @return [nil]
9
9
  def open(url)
10
10
  url = "http://#{url}" unless url.include?('http') || url.include?('file://')
11
+ ensure_url_available(url)
11
12
  @driver.navigate.to url
12
13
  sleep(1) # Correct wait for Page to init focus
13
14
  OnlyofficeLoggerHelper.log("Opened page: #{url}")
@@ -59,5 +60,22 @@ module OnlyofficeWebdriverWrapper
59
60
  cleanup_download_folder
60
61
  @browser_running = false
61
62
  end
63
+
64
+ private
65
+
66
+ # Fast check if url available
67
+ # @param [String] url to check
68
+ # @param [Integer] timeout for wait for page to load
69
+ # @raise [Net::ReadTimeout] exception if timeout happened
70
+ # @return [nil]
71
+ def ensure_url_available(url, timeout: 5)
72
+ return true unless url.start_with?('http://')
73
+
74
+ URI.parse(url).open(read_timeout: timeout,
75
+ open_timeout: timeout).read
76
+ rescue StandardError => e
77
+ OnlyofficeLoggerHelper.log("Url: #{url} is not available with error `#{e}`")
78
+ raise Net::ReadTimeout, e
79
+ end
62
80
  end
63
81
  end
@@ -4,6 +4,9 @@ require 'onlyoffice_s3_wrapper'
4
4
  module OnlyofficeWebdriverWrapper
5
5
  # Working with screenshots
6
6
  module WebdriverScreenshotHelper
7
+ # @return [String] content type of png image
8
+ SCREENSHOT_CONTENT_TYPE = 'image/png'
9
+
7
10
  # @return [OnlyofficeS3Wrapper::AmazonS3Wrapper] s3 wrapper
8
11
  def amazon_s3_wrapper
9
12
  @amazon_s3_wrapper ||= OnlyofficeS3Wrapper::AmazonS3Wrapper.new(bucket_name: 'webdriver-wrapper-screenshots',
@@ -15,10 +18,13 @@ module OnlyofficeWebdriverWrapper
15
18
  '/tmp/screenshot/WebdriverError'
16
19
  end
17
20
 
21
+ # Get screenshot of current windows and upload it to cloud storage
22
+ # @param [String] path_to_screenshot place to store local screenshot
23
+ # @return [String] url of public screenshot
18
24
  def get_screenshot_and_upload(path_to_screenshot = "#{screenshot_folder}/#{StringHelper.generate_random_string}.png")
19
25
  begin
20
26
  get_screenshot(path_to_screenshot)
21
- cloud_screenshot = amazon_s3_wrapper.upload_file_and_make_public(path_to_screenshot)
27
+ cloud_screenshot = publish_screenshot(path_to_screenshot)
22
28
  File.delete(path_to_screenshot) if File.exist?(path_to_screenshot)
23
29
  OnlyofficeLoggerHelper.log("upload screenshot: #{cloud_screenshot}")
24
30
  return cloud_screenshot
@@ -34,6 +40,9 @@ module OnlyofficeWebdriverWrapper
34
40
  path_to_screenshot
35
41
  end
36
42
 
43
+ # Get screenshot of current window
44
+ # @param [String] path_to_screenshot place to store local screenshot
45
+ # @return [void]
37
46
  def get_screenshot(path_to_screenshot = "#{screenshot_folder}/#{StringHelper.generate_random_string}.png")
38
47
  screenshot_folder = File.dirname(path_to_screenshot)
39
48
  FileUtils.mkdir_p(screenshot_folder) unless File.directory?(screenshot_folder)
@@ -41,6 +50,9 @@ module OnlyofficeWebdriverWrapper
41
50
  OnlyofficeLoggerHelper.log("get_screenshot(#{path_to_screenshot})")
42
51
  end
43
52
 
53
+ # Make a screenshot by webdriver methods
54
+ # @param [String] screenshot_name random name for file
55
+ # @return [String] text string with screenshot file location
44
56
  def webdriver_screenshot(screenshot_name = SecureRandom.uuid)
45
57
  begin
46
58
  link = get_screenshot_and_upload("#{screenshot_folder}/#{screenshot_name}.png")
@@ -49,14 +61,14 @@ module OnlyofficeWebdriverWrapper
49
61
  if @headless.headless_instance.nil?
50
62
  system_screenshot("/tmp/#{screenshot_name}.png")
51
63
  begin
52
- link = amazon_s3_wrapper.upload_file_and_make_public("/tmp/#{screenshot_name}.png")
64
+ link = publish_screenshot("/tmp/#{screenshot_name}.png")
53
65
  rescue Exception => e
54
66
  OnlyofficeLoggerHelper.log("Error in get screenshot: #{e}. System screenshot #{link}")
55
67
  end
56
68
  else
57
69
  @headless.take_screenshot("/tmp/#{screenshot_name}.png")
58
70
  begin
59
- link = amazon_s3_wrapper.upload_file_and_make_public("/tmp/#{screenshot_name}.png")
71
+ link = publish_screenshot("/tmp/#{screenshot_name}.png")
60
72
  rescue Exception => e
61
73
  OnlyofficeLoggerHelper.log("Error in get screenshot: #{e}. Headless screenshot #{link}")
62
74
  end
@@ -64,5 +76,16 @@ module OnlyofficeWebdriverWrapper
64
76
  end
65
77
  "screenshot: #{link}"
66
78
  end
79
+
80
+ private
81
+
82
+ # Publish screenshot
83
+ # @param [String] path to file
84
+ # @return [String] public internet link to file
85
+ def publish_screenshot(path)
86
+ amazon_s3_wrapper.upload_file_and_make_public(path,
87
+ nil,
88
+ SCREENSHOT_CONTENT_TYPE)
89
+ end
67
90
  end
68
91
  end
@@ -3,6 +3,10 @@
3
3
  module OnlyofficeWebdriverWrapper
4
4
  # Webdriver style helper
5
5
  module WebdriverStyleHelper
6
+ # Get style parameter of object
7
+ # @param [String] xpath to find object
8
+ # @param [String] parameter_name which parameter to get
9
+ # @return [String, nil] nil if there is no such param
6
10
  def get_style_parameter(xpath, parameter_name)
7
11
  get_attribute(xpath, 'style').split(';').each do |current_param|
8
12
  return /:\s(.*);?$/.match(current_param)[1] if current_param.include?(parameter_name)
@@ -21,6 +25,10 @@ module OnlyofficeWebdriverWrapper
21
25
 
22
26
  alias set_style_parameter set_style_attribute
23
27
 
28
+ # Show element by changing it css style
29
+ # @param [String] xpath to find object
30
+ # @param [Boolean] move_to_center should object be moved to center of screen
31
+ # @return [void]
24
32
  def set_style_show_by_xpath(xpath, move_to_center = false)
25
33
  execute_javascript("#{dom_element_by_xpath(xpath)}.style.display = 'block';")
26
34
  return unless move_to_center
@@ -3,19 +3,28 @@
3
3
  module OnlyofficeWebdriverWrapper
4
4
  # Module for work with tabs
5
5
  module WebdriverTabHelper
6
+ # @return [Integer] Default timeout for waiting for element
6
7
  TIMEOUT_WAIT_ELEMENT = 15
7
8
 
9
+ # Create new tab
10
+ # @return [void]
8
11
  def new_tab
9
12
  execute_javascript('window.open()')
10
13
  end
11
14
 
15
+ # Resize current tab to specific size
16
+ # @param [Integer] width to set
17
+ # @param [Integer] height to set
18
+ # @return [void]
12
19
  def resize_tab(width, height)
13
20
  @driver.manage.window.resize_to(width, height)
14
21
  OnlyofficeLoggerHelper.log("Resize current window to #{width}x#{height}")
15
22
  end
16
23
 
24
+ # Switch to popup window
17
25
  # @param after_switch_timeout [Integer] wait after switch to window
18
26
  # non-zero to workaround bug with page load hanging up after switch
27
+ # @return [void]
19
28
  def switch_to_popup(after_switch_timeout: 3)
20
29
  counter = 0
21
30
  while tab_count < 2 && counter < 30
@@ -37,32 +46,44 @@ module OnlyofficeWebdriverWrapper
37
46
  tab_count
38
47
  end
39
48
 
40
- def choose_tab(tab_number)
49
+ # Choose tab by it's number
50
+ # @param [Integer] tab_number to choose
51
+ # @param [Integer] timeout how much for this tab
52
+ # @raise [RuntimeError] error if tab not found
53
+ # @return [void]
54
+ def choose_tab(tab_number, timeout: TIMEOUT_WAIT_ELEMENT)
41
55
  counter = 0
42
- while tab_count < 2 && counter < TIMEOUT_WAIT_ELEMENT
56
+ while tab_count < tab_number && counter < timeout
43
57
  sleep 1
44
58
  counter += 1
45
59
  end
46
- webdriver_error("choose_tab: Tab number = #{tab_number} not found") if counter >= TIMEOUT_WAIT_ELEMENT
60
+ webdriver_error("choose_tab: Tab number = #{tab_number} not found") if counter >= timeout
47
61
  @driver.switch_to.window(@driver.window_handles[tab_number - 1])
48
62
  end
49
63
 
64
+ # Switch to first tab of chrome
65
+ # @return [void]
50
66
  def switch_to_main_tab
51
67
  @driver.switch_to.window(@driver.window_handles.first)
52
68
  end
53
69
 
70
+ # Close current active tab and switch to first one
71
+ # @return [void]
54
72
  def close_tab
55
73
  @driver.close
56
74
  sleep 1
57
75
  switch_to_main_tab
58
76
  end
59
77
 
78
+ # Wait for popup window, close it and return to first tab
79
+ # @return [void]
60
80
  def close_popup_and_switch_to_main_tab
61
81
  switch_to_popup
62
82
  close_tab
63
83
  switch_to_main_tab
64
84
  end
65
85
 
86
+ # @return [String] title of current tab
66
87
  def get_title_of_current_tab
67
88
  @driver.title
68
89
  end
@@ -3,17 +3,35 @@
3
3
  module OnlyofficeWebdriverWrapper
4
4
  # Class for helping with type stuff
5
5
  module WebdriverTypeHelper
6
+ # Type text to element
7
+ # @param [String] element to find object
8
+ # @param [String] text_to_send text to type
9
+ # @param [Boolean] clear_area should area be cleared
10
+ # @return [void]
6
11
  def type_text(element, text_to_send, clear_area = false)
7
12
  element = get_element(element)
8
13
  element.clear if clear_area
9
14
  element.send_keys(text_to_send)
10
15
  end
11
16
 
17
+ # Type text to element and select it
18
+ # @param [String] element to find object
19
+ # @param [String] text_to_send text to type
20
+ # @param [Boolean] clear_area should area be cleared
21
+ # @return [void]
12
22
  def type_text_and_select_it(element, text_to_send, clear_area = false)
13
23
  type_text(element, text_to_send, clear_area)
14
24
  text_to_send.length.times { element.send_keys %i[shift left] }
15
25
  end
16
26
 
27
+ # Type text to object
28
+ # @param [String] xpath_name to find object
29
+ # @param [String] text_to_send text to type
30
+ # @param [Boolean] clear_content should content be cleared
31
+ # @param [Boolean] click_on_it should object be clicked
32
+ # @param [Boolean] by_action type by `@driver.action` if true
33
+ # @param [Boolean] by_element_send_key use `element.send_keys` if true
34
+ # @return [void]
17
35
  def type_to_locator(xpath_name, text_to_send, clear_content = true, click_on_it = false, by_action = false, by_element_send_key = false)
18
36
  element = get_element(xpath_name)
19
37
  if clear_content
@@ -45,6 +63,12 @@ module OnlyofficeWebdriverWrapper
45
63
  end
46
64
  end
47
65
 
66
+ # Type text to input
67
+ # @param [String] xpath_name to find object
68
+ # @param [String] text_to_send text to type
69
+ # @param [Boolean] clear_content should content be cleared
70
+ # @param [Boolean] click_on_it should object be clicked
71
+ # @return [void]
48
72
  def type_to_input(xpath_name, text_to_send, clear_content = false, click_on_it = true)
49
73
  element = get_element(xpath_name)
50
74
  if element.nil?
@@ -65,6 +89,11 @@ module OnlyofficeWebdriverWrapper
65
89
  element.send_keys text_to_send
66
90
  end
67
91
 
92
+ # Send keys to object
93
+ # @param [String] xpath_name to find object
94
+ # @param [String] text_to_send text to type
95
+ # @param [Boolean] by_action type by `@driver.action` if true
96
+ # @return [void]
68
97
  def send_keys(xpath_name, text_to_send, by_action = true)
69
98
  element = get_element(xpath_name)
70
99
  @driver.action.click(element).perform if @browser == :firefox
@@ -75,21 +104,36 @@ module OnlyofficeWebdriverWrapper
75
104
  end
76
105
  end
77
106
 
107
+ # Type text to currently focused element
108
+ # @param [Array<String, Symbol>, String, Symbol] keys to send
109
+ # @param [Integer] count_of_times how much times to repeat
110
+ # @return [void]
78
111
  def send_keys_to_focused_elements(keys, count_of_times = 1)
79
112
  command = @driver.action.send_keys(keys)
80
113
  (count_of_times - 1).times { command = command.send_keys(keys) }
81
114
  command.perform
82
115
  end
83
116
 
117
+ # Press some specific key
118
+ # @param [String, Symbol] key to press
119
+ # @return [void]
84
120
  def press_key(key)
85
121
  @driver.action.send_keys(key).perform
86
122
  end
87
123
 
124
+ # Simulate pressed down key on object
125
+ # @param [String] xpath to find object
126
+ # @param [String, Symbol] key to press
127
+ # @return [void]
88
128
  def key_down(xpath, key)
89
129
  @driver.action.key_down(get_element(xpath), key).perform
90
130
  sleep(1) # for some reason quick key_down select text in control
91
131
  end
92
132
 
133
+ # Release pressed key from object
134
+ # @param [String] xpath to find object
135
+ # @param [String, Symbol] key to release
136
+ # @return [void]
93
137
  def key_up(xpath, key)
94
138
  @driver.action.key_up(get_element(xpath), key).perform
95
139
  end
@@ -99,6 +143,8 @@ module OnlyofficeWebdriverWrapper
99
143
  # Workaround for bug with typing with :control
100
144
  # See https://github.com/SeleniumHQ/selenium/issues/8179
101
145
  # for more details
146
+ # @param [String] text_to_send text to type
147
+ # @return [void]
102
148
  def webdriver_bug_8179_workaround(text_to_send)
103
149
  text_to_send = [text_to_send].flatten
104
150
 
@@ -1,22 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OnlyofficeWebdriverWrapper
4
- # Module for wokring with webdriver useragent
4
+ # Module for working with webdriver useragent
5
5
  module WebdriverUserAgentHelper
6
+ # @return [String] useragent for Android phone browser
6
7
  USERAGENT_ANDROID_PHONE = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MDB08M) '\
7
8
  'AppleWebKit/537.36 (KHTML, like Gecko) '\
8
9
  'Chrome/51.0.2704.81 Mobile Safari/537.36'
10
+ # @return [String] useragent for iPhone browser
9
11
  USERAGENT_IPHONE = 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_2 like Mac OS X) '\
10
12
  'AppleWebKit/601.1.46 (KHTML, like Gecko) '\
11
13
  'Version/9.0 Mobile/13F69 Safari/601.1'
14
+ # @return [String] useragent for iPad Air 2 Safari browser
12
15
  USERAGENT_IPAD_AIR_2_SAFARI = 'Mozilla/5.0 (iPad; CPU OS 10_0 like Mac OS X) '\
13
16
  'AppleWebKit/602.1.50 (KHTML, like Gecko) '\
14
17
  'Version/10.0 Mobile/14A5346a Safari/602.1'
18
+ # @return [String] useragent for Nexus 10 Chrome browser
15
19
  USERAGENT_NEXUS_10_CHROME = 'Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) '\
16
20
  'AppleWebKit/537.36 (KHTML, like Gecko) '\
17
21
  'Chrome/48.0.2564.23 Safari/537.36'
18
22
 
19
- # @return [String] user agent string for current device
23
+ # @return [String, nil] user agent string for current device
20
24
  def user_agent_for_device
21
25
  case @device
22
26
  when :desktop_linux
@@ -25,6 +25,7 @@ require_relative 'webdriver/webdriver_tab_helper'
25
25
  require_relative 'webdriver/webdriver_user_agent_helper'
26
26
  require_relative 'webdriver/webdriver_browser_log_helper'
27
27
 
28
+ # Namespace of this gem
28
29
  module OnlyofficeWebdriverWrapper
29
30
  # noinspection RubyTooManyMethodsInspection, RubyInstanceMethodNamingConvention, RubyParameterNamingConvention
30
31
  class WebDriver
@@ -47,6 +48,7 @@ module OnlyofficeWebdriverWrapper
47
48
  include WebdriverTabHelper
48
49
  include WebdriverUserAgentHelper
49
50
  include WebdriverBrowserLogHelper
51
+ # @return [Integer] Default timeout for waiting to file to download
50
52
  TIMEOUT_FILE_DOWNLOAD = 100
51
53
  # @return [Array, String] default switches for chrome
52
54
  attr_accessor :driver
@@ -89,6 +91,9 @@ module OnlyofficeWebdriverWrapper
89
91
  @browser_running = true
90
92
  end
91
93
 
94
+ # Get element by it's xpath
95
+ # @param [String] object_identification xpath of object to find
96
+ # @return [Object, nil] nil if nothing found
92
97
  def get_element(object_identification)
93
98
  return object_identification unless object_identification.is_a?(String)
94
99
 
@@ -104,11 +109,19 @@ module OnlyofficeWebdriverWrapper
104
109
  get_elements(array_elements).map { |current_element| get_text(current_element) }
105
110
  end
106
111
 
112
+ # Select from list elements
113
+ # @param [String] value value to find object
114
+ # @param [Array<Object>] elements_value elements to check
115
+ # @return [void]
107
116
  def select_from_list_elements(value, elements_value)
108
117
  index = get_element_index(value, elements_value)
109
118
  elements_value[index].click
110
119
  end
111
120
 
121
+ # Get index of element by it's text
122
+ # @param [String] title to compare text
123
+ # @param [Array<Objects>] list_elements to find in which
124
+ # @return [Object, nil] nil if nothing found
112
125
  def get_element_index(title, list_elements)
113
126
  list_elements.each_with_index do |current, i|
114
127
  return i if get_text(current) == title
@@ -116,22 +129,36 @@ module OnlyofficeWebdriverWrapper
116
129
  nil
117
130
  end
118
131
 
132
+ # Get all options for combo box
133
+ # @param [String] xpath_name to find combobox
134
+ # @return [Array<String>] values
119
135
  def get_all_combo_box_values(xpath_name)
120
136
  @driver.find_element(:xpath, xpath_name).find_elements(tag_name: 'option').map { |el| el.attribute('value') }
121
137
  end
122
138
 
139
+ # Scroll list to specific element
140
+ # @param [String] list_xpath how to find this list
141
+ # @param [String] element_xpath to which we should scrolled
142
+ # @return [void]
123
143
  def scroll_list_to_element(list_xpath, element_xpath)
124
144
  execute_javascript("$(document.evaluate(\"#{list_xpath}\", document, null, XPathResult.ANY_TYPE, null).
125
145
  iterateNext()).jScrollPane().data('jsp').scrollToElement(document.evaluate(\"#{element_xpath}\",
126
146
  document, null, XPathResult.ANY_TYPE, null).iterateNext());")
127
147
  end
128
148
 
149
+ # Scroll list by pixel count
150
+ # @param [String] list_xpath how to detect this list
151
+ # @param [Integer] pixels how much to scroll
152
+ # @return [void]
129
153
  def scroll_list_by_pixels(list_xpath, pixels)
130
154
  execute_javascript("$(document.evaluate(\"#{list_xpath.tr('"', "'")}\", document, null, XPathResult.ANY_TYPE, null).iterateNext()).scrollTop(#{pixels})")
131
155
  end
132
156
 
133
157
  # Open dropdown selector, like 'Color Selector', which has no element id
134
158
  # @param [String] xpath_name name of dropdown list
159
+ # @param [Integer] horizontal_shift x value
160
+ # @param [Integer] vertical_shift y value
161
+ # @return [void]
135
162
  def open_dropdown_selector(xpath_name, horizontal_shift = 30, vertical_shift = 0)
136
163
  element = get_element(xpath_name)
137
164
  if @browser == :firefox || @browser == :safari
@@ -145,12 +172,22 @@ module OnlyofficeWebdriverWrapper
145
172
  end
146
173
  end
147
174
 
175
+ # Perform an action on coordinate
176
+ # @param [String] xpath_name to find element
177
+ # @param [Integer] right_by x coordinate
178
+ # @param [Integer] down_by y coordinate
179
+ # @param [Symbol] action to perform
180
+ # @param [Integer] times how much times to repeat
181
+ # @return [void]
148
182
  def action_on_locator_coordinates(xpath_name, right_by, down_by, action = :click, times = 1)
149
183
  wait_until_element_visible(xpath_name)
150
184
  element = @driver.find_element(:xpath, xpath_name)
151
185
  (0...times).inject(@driver.action.move_to(element, right_by.to_i, down_by.to_i)) { |acc, _elem| acc.send(action) }.perform
152
186
  end
153
187
 
188
+ # Check if element present on page
189
+ # @param [String] xpath_name to find element
190
+ # @return [Boolean] result of check
154
191
  def element_present?(xpath_name)
155
192
  case xpath_name
156
193
  when PageObject::Elements::Element
@@ -165,6 +202,9 @@ module OnlyofficeWebdriverWrapper
165
202
  false
166
203
  end
167
204
 
205
+ # Get first visible element from several
206
+ # @param [String] xpath_name to find several objects
207
+ # @return [Object] first visible element
168
208
  def get_element_by_display(xpath_name)
169
209
  @driver.find_elements(:xpath, xpath_name).each do |element|
170
210
  return element if element.displayed?
@@ -186,6 +226,10 @@ module OnlyofficeWebdriverWrapper
186
226
  end
187
227
  end
188
228
 
229
+ # Get array of webdriver object by xpath
230
+ # @param [String] objects_identification object to find
231
+ # @param [Boolean] only_visible return invisible if true
232
+ # @return [Array, Object] list of objects
189
233
  def get_elements(objects_identification, only_visible = true)
190
234
  return objects_identification if objects_identification.is_a?(Array)
191
235
 
@@ -198,6 +242,9 @@ module OnlyofficeWebdriverWrapper
198
242
  elements
199
243
  end
200
244
 
245
+ # Check if element visible on page
246
+ # @param [String] xpath_name element to find
247
+ # @return [Boolean] result of check
201
248
  def element_visible?(xpath_name)
202
249
  if xpath_name.is_a?(PageObject::Elements::Element) # PageObject always visible
203
250
  true
@@ -225,12 +272,13 @@ module OnlyofficeWebdriverWrapper
225
272
  end
226
273
  false
227
274
  rescue Exception => e
228
- webdriver_error("Raise unkwnown exception: #{e}")
275
+ webdriver_error("Raise unknown exception: #{e}")
229
276
  end
230
277
 
231
278
  # Get text of current element
232
279
  # @param [String] xpath_name name of xpath
233
- # @param [true, false] wait_until_visible wait until element visible [@default = true]
280
+ # @param [Boolean] wait_until_visible wait until element visible
281
+ # @return [String] result string
234
282
  def get_text(xpath_name, wait_until_visible = true)
235
283
  wait_until_element_visible(xpath_name) if wait_until_visible
236
284
 
@@ -243,10 +291,18 @@ module OnlyofficeWebdriverWrapper
243
291
  end
244
292
  end
245
293
 
294
+ # Get text from several elements
295
+ # @param [String] xpath_several_elements to find objects
296
+ # @return [Array<String>] text of those elements
246
297
  def get_text_of_several_elements(xpath_several_elements)
247
298
  @driver.find_elements(:xpath, xpath_several_elements).map { |element| element.text unless element.text == '' }.compact
248
299
  end
249
300
 
301
+ # Select value of combo box
302
+ # @param [String] xpath_name to find combobox
303
+ # @param [String] select_value to select
304
+ # @param [Symbol] select_by select type
305
+ # @return [void]
250
306
  def select_combo_box(xpath_name, select_value, select_by = :value)
251
307
  wait_until_element_visible(xpath_name)
252
308
  option = Selenium::WebDriver::Support::Select.new(get_element(xpath_name))
@@ -263,6 +319,11 @@ module OnlyofficeWebdriverWrapper
263
319
  @driver.execute_script('return document.documentElement.innerHTML;')
264
320
  end
265
321
 
322
+ # Raise an error, making a screenshot before it
323
+ # @param [String, Object] exception class to raise
324
+ # @param [String] error_message to raise
325
+ # @raise [Object] specified exception
326
+ # @return [void]
266
327
  def webdriver_error(exception, error_message = nil)
267
328
  if exception.is_a?(String) # If there is no error_message
268
329
  error_message = exception
@@ -273,6 +334,11 @@ module OnlyofficeWebdriverWrapper
273
334
  raise exception, "#{error_message}\n\nPage address: #{current_url}\n\nError #{webdriver_screenshot}"
274
335
  end
275
336
 
337
+ # Wait for file to be downloaded
338
+ # @param [String] file_name to wait for download
339
+ # @param [Integer] timeout to wait for file to download
340
+ # @raise [StandardError] error if something happened and file not downloaded
341
+ # @return [String] full file name of downloaded file
276
342
  def wait_file_for_download(file_name, timeout = TIMEOUT_FILE_DOWNLOAD)
277
343
  full_file_name = "#{@download_directory}/#{file_name}"
278
344
  full_file_name = file_name if file_name[0] == '/'
@@ -291,7 +357,7 @@ module OnlyofficeWebdriverWrapper
291
357
  def self.clean_up(forced = false)
292
358
  return unless OnlyofficeFileHelper::LinuxHelper.user_name.include?('nct-at') ||
293
359
  OnlyofficeFileHelper::LinuxHelper.user_name.include?('ubuntu') ||
294
- forced == true
360
+ forced
295
361
 
296
362
  OnlyofficeFileHelper::LinuxHelper.kill_all('chromedriver')
297
363
  OnlyofficeFileHelper::LinuxHelper.kill_all('geckodriver')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: onlyoffice_webdriver_wrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.22.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ONLYOFFICE
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2021-11-15 00:00:00.000000000 Z
14
+ date: 2021-12-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: headless
@@ -62,6 +62,9 @@ dependencies:
62
62
  - - "~>"
63
63
  - !ruby/object:Gem::Version
64
64
  version: '0'
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 0.5.0
65
68
  type: :runtime
66
69
  prerelease: false
67
70
  version_requirements: !ruby/object:Gem::Requirement
@@ -69,6 +72,9 @@ dependencies:
69
72
  - - "~>"
70
73
  - !ruby/object:Gem::Version
71
74
  version: '0'
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 0.5.0
72
78
  - !ruby/object:Gem::Dependency
73
79
  name: page-object
74
80
  requirement: !ruby/object:Gem::Requirement
@@ -229,14 +235,34 @@ dependencies:
229
235
  requirements:
230
236
  - - "~>"
231
237
  - !ruby/object:Gem::Version
232
- version: '1'
238
+ version: '2'
233
239
  type: :development
234
240
  prerelease: false
235
241
  version_requirements: !ruby/object:Gem::Requirement
236
242
  requirements:
237
243
  - - "~>"
238
244
  - !ruby/object:Gem::Version
239
- version: '1'
245
+ version: '2'
246
+ - !ruby/object:Gem::Dependency
247
+ name: yard
248
+ requirement: !ruby/object:Gem::Requirement
249
+ requirements:
250
+ - - "~>"
251
+ - !ruby/object:Gem::Version
252
+ version: '0'
253
+ - - ">="
254
+ - !ruby/object:Gem::Version
255
+ version: 0.9.20
256
+ type: :development
257
+ prerelease: false
258
+ version_requirements: !ruby/object:Gem::Requirement
259
+ requirements:
260
+ - - "~>"
261
+ - !ruby/object:Gem::Version
262
+ version: '0'
263
+ - - ">="
264
+ - !ruby/object:Gem::Version
265
+ version: 0.9.20
240
266
  description: ONLYOFFICE Webdriver Wrapper Gem. Used in QA
241
267
  email:
242
268
  - shockwavenn@gmail.com
@@ -306,7 +332,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
306
332
  - !ruby/object:Gem::Version
307
333
  version: '0'
308
334
  requirements: []
309
- rubygems_version: 3.2.29
335
+ rubygems_version: 3.2.32
310
336
  signing_key:
311
337
  specification_version: 4
312
338
  summary: ONLYOFFICE Webdriver Wrapper Gem