onlyoffice_documentserver_testing_framework 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +7 -0
  2. data/lib/onlyoffice_documentserver_testing_framework.rb +5 -0
  3. data/lib/onlyoffice_documentserver_testing_framework/name.rb +10 -0
  4. data/lib/onlyoffice_documentserver_testing_framework/selenium_wrapper.rb +141 -0
  5. data/lib/onlyoffice_documentserver_testing_framework/selenium_wrapper/selenium_wrapper_exceptions.rb +7 -0
  6. data/lib/onlyoffice_documentserver_testing_framework/selenium_wrapper/selenium_wrapper_js_errors.rb +46 -0
  7. data/lib/onlyoffice_documentserver_testing_framework/selenium_wrapper/selenium_wrapper_js_errors/ignored_errors.list +28 -0
  8. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs.rb +64 -0
  9. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/common_editor/editor_windows.rb +7 -0
  10. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_editor.rb +23 -0
  11. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_editor/doc_editor_top_toolbar.rb +17 -0
  12. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_editor/doc_editor_top_toolbar/top_toolbar_users.rb +32 -0
  13. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_editor/doc_editor_windows.rb +18 -0
  14. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_editor/doc_editor_windows/txt_options.rb +116 -0
  15. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_service_welcome.rb +35 -0
  16. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_test_site_functions.rb +235 -0
  17. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_test_site_functions/doc_test_file_list.rb +34 -0
  18. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_test_site_functions/doc_test_file_list/doc_test_site_file_list_entry.rb +101 -0
  19. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_test_site_functions/doc_test_site_server_helper.rb +25 -0
  20. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/doc_test_site_functions/healthcheck_page.rb +15 -0
  21. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/management.rb +206 -0
  22. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/management/loader_helper.rb +50 -0
  23. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/presentation_editor.rb +7 -0
  24. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/spreadsheet_editor.rb +13 -0
  25. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/spreadsheet_editor/spreadsheet_windows.rb +18 -0
  26. data/lib/onlyoffice_documentserver_testing_framework/test_instance_docs/spreadsheet_editor/spreadsheet_windows/csv_option.rb +58 -0
  27. data/lib/onlyoffice_documentserver_testing_framework/version.rb +9 -0
  28. metadata +229 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 44618864c88fe2bd26cbf33d3aec94e873a87e43b75c8d7d88af26747b3f0be1
4
+ data.tar.gz: c78a22c6e512edee73094216b6837cf72956a0ca2bd9cbea0c08258114543224
5
+ SHA512:
6
+ metadata.gz: fd93f2d21ed7bfe436c9f3772fe84da2c0563fa6d042d410415da4871a138e7db44d0e3038e1900ebb46578d92fbbc77fd2b16a7e86e93f30fa1b16e3add057c
7
+ data.tar.gz: d432c1af8e8481f48933dc114baabbd030427ff6f275b28aebffcac239690c02eae82b34ed5ad0f40a4a4b6d5e1c3200e096d63be204ed0617682f7541543701
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'onlyoffice_documentserver_testing_framework/selenium_wrapper'
4
+ require_relative 'onlyoffice_documentserver_testing_framework/test_instance_docs'
5
+ require_relative 'onlyoffice_documentserver_testing_framework/version'
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Namespace of project
4
+ module OnlyofficeDocumentserverTestingFramework
5
+ # Module to store gem name
6
+ module Name
7
+ # [String] name of gem
8
+ STRING = 'onlyoffice_documentserver_testing_framework'
9
+ end
10
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'selenium_wrapper/selenium_wrapper_exceptions'
4
+ require_relative 'selenium_wrapper/selenium_wrapper_js_errors'
5
+ module OnlyofficeDocumentserverTestingFramework
6
+ # Module for handle selenium with frames and some other methods
7
+ module SeleniumWrapper
8
+ include SeleniumWrapperJsErrors
9
+
10
+ # Main wrapper function
11
+ # @param name [Symbol] function to call
12
+ # @param arguments [Hash] list of arguments
13
+ # @return [Object] result of method
14
+ def selenium_functions(name, *arguments)
15
+ select_frame do
16
+ @instance.selenium.send name, *arguments
17
+ end
18
+ end
19
+
20
+ # Select actual frame of Editor
21
+ def select_frame
22
+ count_of_frame = @count_of_frame ? frame_count_addition : @instance.management.xpath_iframe_count
23
+ xpath_of_frame = @xpath_of_frame || @instance.management.xpath_iframe
24
+ @instance.selenium.select_frame xpath_of_frame, count_of_frame
25
+ value = yield
26
+ fail_if_console_error
27
+ @instance.selenium.select_top_frame
28
+ value
29
+ end
30
+
31
+ # @return [Integer] frame count with addition
32
+ def frame_count_addition
33
+ @count_of_frame + @instance.management.xpath_iframe_count - 1
34
+ end
35
+
36
+ # This method return true if xpath visible on the web page
37
+ # @param[String] xpath
38
+ # @return [Boolean]
39
+ def visible?(xpath)
40
+ selenium_functions :element_visible?, xpath
41
+ end
42
+
43
+ alias element_visible? visible?
44
+ alias element_present_and_visible? visible?
45
+
46
+ # This method click over button by xpath
47
+ # @param[String] xpath
48
+ def click_on_button(xpath)
49
+ selenium_functions :click_on_locator, xpath
50
+ end
51
+
52
+ # This method return true if button pressed
53
+ # @param[String] xpath
54
+ # @return [Boolean]
55
+ def button_pressed?(xpath)
56
+ selenium_functions(:get_attribute, xpath, 'class').include?('active')
57
+ end
58
+
59
+ alias button_active? button_pressed?
60
+
61
+ # This method return true if button disabled
62
+ # @param[String] xpath
63
+ # @return [Boolean]
64
+ def button_disabled?(xpath)
65
+ selenium_functions(:get_attribute, xpath, 'class').include?('disabled')
66
+ end
67
+
68
+ # @param xpath [String] xpath of menu
69
+ # @return [True, False] if menu active
70
+ def button_menu_active?(xpath)
71
+ selenium_functions(:get_attribute, xpath, 'class').include?('menu-active')
72
+ end
73
+
74
+ # This method return true if button menu open
75
+ # @param[String] xpath
76
+ # @return [Boolean]
77
+ def button_menu_open?(xpath)
78
+ element_visible = visible?(xpath)
79
+ element_visible = selenium_functions(:get_attribute, xpath, 'class').include?('open') if element_visible
80
+ element_visible
81
+ end
82
+
83
+ # Click on one of several displayed
84
+ # @param xpath [String] xpath to click
85
+ # @return [nil]
86
+ def click_on_of_several_by_display_button(xpath)
87
+ selenium_functions :click_on_one_of_several_by_display, xpath
88
+ end
89
+
90
+ # Wait to element to appear and click
91
+ # @param xpath [String] xpath to click
92
+ # @return [nil]
93
+ def click_on_displayed_button(xpath)
94
+ selenium_functions :wait_element, xpath
95
+ selenium_functions :click_on_displayed, xpath
96
+ end
97
+
98
+ # Is line enabled
99
+ # @param xpath [String] xpath to check
100
+ # @return [True, False]
101
+ def line_enabled?(xpath)
102
+ selenium_functions :element_visible?, xpath
103
+ end
104
+
105
+ # Is line checked
106
+ # @param xpath [String] xpath to check
107
+ # @return [True, False]
108
+ def line_checked?(xpath)
109
+ selenium_functions(:get_attribute, xpath, 'class').include?('checked')
110
+ end
111
+
112
+ # Is menu disabled
113
+ # @param xpath [String] xpath to check
114
+ # @return [True, False]
115
+ def menu_disabled?(xpath)
116
+ selenium_functions(:get_attribute, xpath, 'class').include?('disabled')
117
+ end
118
+
119
+ # Move to element
120
+ # @param xpath [String] xpath to move
121
+ # @return [nil]
122
+ def move_to_element(xpath)
123
+ selenium_functions :move_to_element_by_locator, xpath
124
+ end
125
+
126
+ # Remove element
127
+ # @param xpath [String] xpath to remove
128
+ # @return [nil]
129
+ def remove_element(xpath)
130
+ selenium_functions :remove_element, xpath
131
+ end
132
+
133
+ # Get attribute
134
+ # @param xpath [String] xpath to get attribute
135
+ # @param attribute [String] attribute to get
136
+ # @return [String] result of get attribute
137
+ def get_attribute(xpath, attribute)
138
+ selenium_functions :get_attribute, xpath, attribute
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnlyofficeDocumentserverTestingFramework
4
+ # Error that raised if element is not may be clicked
5
+ class ClickOnDisabledElement < StandardError
6
+ end
7
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module for working with selenium wrapper JavaScript Errors
4
+ module SeleniumWrapperJsErrors
5
+ # @return [Array<String>] list of errors should be ignored
6
+ def ignored_errors
7
+ return @ignored_errors if @ignored_errors
8
+
9
+ @ignored_errors = File.readlines("#{File.expand_path('..', __dir__)}"\
10
+ '/selenium_wrapper/selenium_wrapper_js_errors'\
11
+ '/ignored_errors.list')
12
+ .map(&:strip)
13
+ end
14
+
15
+ # Should current error be ignored
16
+ # @param error_message [String] current error
17
+ # @return [True, False] should be ignored?
18
+ def error_ignored?(error_message)
19
+ return true if ignored_errors.any? { |word| error_message.include?(word) }
20
+ return true if @instance.env_options['IgnoredJSErrors'].any? { |word| error_message.include?(word) }
21
+
22
+ false
23
+ end
24
+
25
+ # @return [Array<String>] list of current console errors
26
+ def console_errors
27
+ severe_error = []
28
+ @instance.webdriver.browser_logs.each do |log|
29
+ severe_error << log.message if log.level.include?('SEVERE') && !error_ignored?(log.message)
30
+ end
31
+ severe_error
32
+ end
33
+
34
+ alias get_console_errors console_errors
35
+ extend Gem::Deprecate
36
+ deprecate :get_console_errors, :console_errors, 2025, 1
37
+
38
+ # Fail if any JS error happened
39
+ def fail_if_console_error
40
+ errors = console_errors
41
+ return if errors.empty?
42
+
43
+ @instance.webdriver.webdriver_error(Selenium::WebDriver::Error::JavascriptError,
44
+ "There are some errors in the Web Console: #{errors}")
45
+ end
46
+ end
@@ -0,0 +1,28 @@
1
+ https://signalr.teamlab.info/signalr/negotiate
2
+ https://signalr.onlyoffice.com/signalr/negotiate
3
+ https://www.dropbox.com/
4
+ /bundle/
5
+ /socketio/
6
+ /discbundle/
7
+ /Contents.json
8
+ branding
9
+ favicon.ico
10
+ uservoice
11
+ js/third-party/jquery/jquery.core.js
12
+ js/asc/plugins/
13
+ /platform.twitter.com
14
+ googleads
15
+ pubmatic.com
16
+ rubiconproject.com
17
+ eventhandler
18
+ require.js
19
+ chrome-extension
20
+ Access-Control-Allow-Origin
21
+ SockJS has already been closed
22
+ Failed to load resource: the server responded with a status of 404 ()
23
+ AscFonts
24
+ yastatic.net
25
+ Blocked autofocusing on a form control in a cross-origin subframe.
26
+ /embed
27
+ ResponsiveVoice missing API key
28
+ /libfont/wasm/
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'onlyoffice_webdriver_wrapper'
4
+ require_relative 'test_instance_docs/common_editor/editor_windows'
5
+ require_relative 'test_instance_docs/doc_editor'
6
+ require_relative 'test_instance_docs/doc_service_welcome'
7
+ require_relative 'test_instance_docs/doc_test_site_functions'
8
+ require_relative 'test_instance_docs/presentation_editor'
9
+ require_relative 'test_instance_docs/spreadsheet_editor'
10
+ require_relative 'test_instance_docs/management'
11
+
12
+ module OnlyofficeDocumentserverTestingFramework
13
+ # Main class for browser instance
14
+ class TestInstanceDocs
15
+ attr_accessor :selenium
16
+ alias webdriver selenium
17
+
18
+ def initialize(webdriver: OnlyofficeWebdriverWrapper::WebDriver.new(:chrome))
19
+ @selenium = webdriver
20
+ end
21
+
22
+ # @return [DocServiceWelcome] welcome page of DocumentServer
23
+ def doc_service_welcome
24
+ @doc_service_welcome ||= DocServiceWelcome.new(self)
25
+ end
26
+
27
+ # @return [DocTestSiteFunctions] methods for test site
28
+ def doc_test_functions
29
+ # Do not cache methods since they use PageObject and cause all sort of troubles
30
+ # if test run several times with different webdriver
31
+ DocTestSiteFunctions.new(self)
32
+ end
33
+
34
+ # @return [DocEditor] Document Editor instance
35
+ def doc_editor
36
+ @doc_editor ||= DocEditor.new(self)
37
+ end
38
+
39
+ # @return [SpreadsheetEditor] Spreadsheet Editor instance
40
+ def spreadsheet_editor
41
+ @spreadsheet_editor ||= SpreadsheetEditor.new(self)
42
+ end
43
+
44
+ # @return [PresentationEditor] editor of presentations
45
+ def presentation_editor
46
+ @presentation_editor ||= PresentationEditor.new(self)
47
+ end
48
+
49
+ # @return [Management] management methods
50
+ def management
51
+ @management ||= Management.new(self)
52
+ end
53
+
54
+ # @return [Hash] Options read from environment variable
55
+ def env_options
56
+ return @env_options if @env_options
57
+
58
+ raw_options = ENV['ONLYOFFICE_DS_TESTING_OPTIONS'] || '{}'
59
+ @env_options = JSON.parse(raw_options)
60
+ @env_options['IgnoredJSErrors'] = [] unless @env_options['IgnoredJSErrors']
61
+ @env_options
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnlyofficeDocumentserverTestingFramework
4
+ # Place for storing common windows
5
+ class EditorWindows
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'doc_editor/doc_editor_top_toolbar'
4
+ require_relative 'doc_editor/doc_editor_windows'
5
+
6
+ module OnlyofficeDocumentserverTestingFramework
7
+ # Class for all Doc Editor actions
8
+ class DocEditor
9
+ def initialize(instance)
10
+ @instance = instance
11
+ end
12
+
13
+ # @return [DocEditorTopToolbar] top toolbar
14
+ def top_toolbar
15
+ @top_toolbar ||= DocEditorTopToolbar.new(@instance)
16
+ end
17
+
18
+ # @return [DocEditorWindows] windows of doc editor
19
+ def windows
20
+ @windows ||= DocEditorWindows.new(@instance)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'doc_editor_top_toolbar/top_toolbar_users'
4
+
5
+ module OnlyofficeDocumentserverTestingFramework
6
+ # Top Toolbar of Doc Editor
7
+ class DocEditorTopToolbar
8
+ def initialize(instance)
9
+ @instance = instance
10
+ end
11
+
12
+ # @return [TopToolbarUsers] icon for top toolbar users
13
+ def users
14
+ @users ||= TopToolbarUsers.new(@instance)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnlyofficeDocumentserverTestingFramework
4
+ # Class for getting info about share and users
5
+ # https://user-images.githubusercontent.com/668524/28920497-d444b674-785a-11e7-9254-2f46d4e95261.png
6
+ class TopToolbarUsers
7
+ include SeleniumWrapper
8
+
9
+ def initialize(instance)
10
+ @instance = instance
11
+ @xpath_button = '//*[@id="tlb-box-users"]'
12
+ @xpath_count = "#{@xpath_button}/div/label"
13
+ end
14
+
15
+ # @return [True, False] is button present
16
+ def present?
17
+ visible = visible?(@xpath_button)
18
+ OnlyofficeLoggerHelper.log("Button present: #{visible}")
19
+ visible
20
+ end
21
+
22
+ # @return [Integer] count of users
23
+ def count
24
+ return 1 unless present?
25
+
26
+ count = selenium_functions(:get_text, @xpath_count)
27
+ count = 1 if count == '+'
28
+ OnlyofficeLoggerHelper.log("User count: #{count}")
29
+ count.to_i
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'doc_editor_windows/txt_options'
4
+
5
+ module OnlyofficeDocumentserverTestingFramework
6
+ # Windows of Doc Editor
7
+ class DocEditorWindows < EditorWindows
8
+ def initialize(instance)
9
+ @instance = instance
10
+ super()
11
+ end
12
+
13
+ # @return [TxtOptions] widnow for txt options
14
+ def txt_options
15
+ @txt_options ||= TxtOptions.new(@instance)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnlyofficeDocumentserverTestingFramework
4
+ # Class for TXT export window
5
+ class TxtOptions
6
+ include SeleniumWrapper
7
+
8
+ def initialize(instance)
9
+ @instance = instance
10
+ @xpath_codepage_selector = '//*[contains(text(), "TXT")]/../..//div[@id="id-codepages-combo"]'
11
+ end
12
+
13
+ # region CVN Framework
14
+
15
+ # @return [True, False] is txt options dialog opened
16
+ def dialog_window_opened?
17
+ visible = visible? @xpath_codepage_selector
18
+ OnlyofficeLoggerHelper.log("Codepage option window is opened: #{visible}")
19
+ visible
20
+ end
21
+
22
+ # @return [True, False] is loose data warning visible
23
+ def loose_data_warning_present?
24
+ visible = visible? '//*[contains(@class, "asc-window modal alert")]'
25
+ OnlyofficeLoggerHelper.log("Codepage option window is opened: #{visible}")
26
+ visible
27
+ end
28
+
29
+ # Click on ok button
30
+ # @return [nil]
31
+ def click_on_ok
32
+ click_on_button '//button[@result="ok"]'
33
+ OnlyofficeLoggerHelper.log('Click on OK button')
34
+ end
35
+
36
+ # Click on cancel button
37
+ # @return [nil]
38
+ def click_on_cancel
39
+ click_on_button '//button[@result="cancel"]'
40
+ OnlyofficeLoggerHelper.log('Click on CANCEL button')
41
+ end
42
+
43
+ # Control to set encoding
44
+ # @return [BoundComboBoxUl]
45
+ def encoding
46
+ BoundComboBoxUl.new(@instance, @xpath_codepage_selector, nil, 'span')
47
+ end
48
+
49
+ # List encoding list to item number
50
+ # @param list_item_number [Integer] item to scroll
51
+ # @return [nil]
52
+ def scroll_encoding_list_to(list_item_number)
53
+ selenium_functions(:scroll_list_by_pixels,
54
+ "//*[@id='id-codepages-combo']/span/ul",
55
+ (list_item_number - 1) * 25)
56
+ OnlyofficeLoggerHelper.log("Scroll to #{list_item_number} element")
57
+ end
58
+
59
+ # endregion
60
+
61
+ # region Function
62
+
63
+ # Wait for loose data warning to show
64
+ # @return [nil]
65
+ def wait_warning
66
+ counter = 0
67
+ while !loose_data_warning_present? && counter < 30
68
+ sleep 1
69
+ counter += 1
70
+ end
71
+ @instance.webdriver.webdriver_error 'Wait for TXT warning failed' if counter == 30
72
+ end
73
+
74
+ # Wait for csv options to show
75
+ # @return [nil]
76
+ def wait_options
77
+ counter = 0
78
+ while !dialog_window_opened? && counter < 30
79
+ sleep 1
80
+ counter += 1
81
+ end
82
+ @instance.webdriver.webdriver_error 'Wait for TXT options failed' if counter == 30
83
+ end
84
+
85
+ # @param [String] encoding_name like as 'French Canadian (DOS)'
86
+ def encoding_select(encoding_name)
87
+ encoding.open
88
+ # TODO: Replace with correct include after find out https://github.com/ONLYOFFICE/testing-documentserver/pull/2006
89
+ list_item_number = encoding.items_text.index { |item| item.include?(encoding_name) } + 1
90
+ scroll_encoding_list_to list_item_number
91
+ encoding.select_by_number list_item_number
92
+ end
93
+
94
+ # Set options in txt window
95
+ # @param encoding_to_set [String] encoding to set
96
+ # @return [nil]
97
+ def txt_options=(encoding_to_set = nil)
98
+ return unless dialog_window_opened?
99
+
100
+ encoding_to_set = encoding.items_text.last if encoding_to_set.nil?
101
+ encoding_select encoding_to_set
102
+ click_on_ok
103
+ end
104
+
105
+ alias set_txt_options txt_options=
106
+ extend Gem::Deprecate
107
+ deprecate :set_txt_options, :txt_options=, 2025, 1
108
+
109
+ # Close warning about loose data
110
+ # @return [nil]
111
+ def close_warning_loose_data
112
+ click_on_ok if loose_data_warning_present?
113
+ end
114
+ # endregion
115
+ end
116
+ end