watir 7.1.0 → 7.2.0
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 +4 -4
- data/.github/workflows/chrome.yml +29 -16
- data/.github/workflows/edge.yml +19 -11
- data/.github/workflows/firefox.yml +28 -16
- data/.github/workflows/ie.yml +13 -7
- data/.github/workflows/safari.yml +22 -11
- data/.github/workflows/unit.yml +31 -23
- data/.rubocop.yml +14 -7
- data/.rubocop_todo.yml +0 -26
- data/CHANGES.md +16 -1
- data/Gemfile +6 -1
- data/README.md +15 -11
- data/Rakefile +9 -7
- data/lib/watir/adjacent.rb +3 -1
- data/lib/watir/after_hooks.rb +5 -3
- data/lib/watir/alert.rb +2 -0
- data/lib/watir/aliases.rb +2 -0
- data/lib/watir/attribute_helper.rb +4 -2
- data/lib/watir/browser.rb +10 -14
- data/lib/watir/capabilities.rb +56 -33
- data/lib/watir/cell_container.rb +2 -0
- data/lib/watir/container.rb +2 -0
- data/lib/watir/cookies.rb +5 -5
- data/lib/watir/element_collection.rb +3 -1
- data/lib/watir/elements/button.rb +2 -0
- data/lib/watir/elements/cell.rb +2 -0
- data/lib/watir/elements/checkbox.rb +2 -0
- data/lib/watir/elements/date_field.rb +2 -0
- data/lib/watir/elements/date_time_field.rb +2 -0
- data/lib/watir/elements/dlist.rb +3 -1
- data/lib/watir/elements/element.rb +29 -105
- data/lib/watir/elements/file_field.rb +2 -0
- data/lib/watir/elements/font.rb +2 -0
- data/lib/watir/elements/form.rb +2 -0
- data/lib/watir/elements/hidden.rb +2 -0
- data/lib/watir/elements/iframe.rb +2 -0
- data/lib/watir/elements/image.rb +2 -0
- data/lib/watir/elements/input.rb +2 -0
- data/lib/watir/elements/link.rb +2 -0
- data/lib/watir/elements/list.rb +2 -0
- data/lib/watir/elements/option.rb +2 -0
- data/lib/watir/elements/radio.rb +2 -0
- data/lib/watir/elements/row.rb +2 -0
- data/lib/watir/elements/select.rb +2 -0
- data/lib/watir/elements/table.rb +3 -1
- data/lib/watir/elements/table_cell.rb +2 -0
- data/lib/watir/elements/table_row.rb +2 -0
- data/lib/watir/elements/table_section.rb +2 -0
- data/lib/watir/elements/text_area.rb +2 -0
- data/lib/watir/elements/text_field.rb +2 -0
- data/lib/watir/exception.rb +2 -0
- data/lib/watir/extensions/nokogiri.rb +2 -0
- data/lib/watir/generator/base/generator.rb +2 -0
- data/lib/watir/generator/base/idl_sorter.rb +3 -1
- data/lib/watir/generator/base/spec_extractor.rb +6 -4
- data/lib/watir/generator/base/util.rb +2 -0
- data/lib/watir/generator/base/visitor.rb +5 -5
- data/lib/watir/generator/base.rb +2 -1
- data/lib/watir/generator/html/generator.rb +2 -0
- data/lib/watir/generator/html/spec_extractor.rb +2 -0
- data/lib/watir/generator/html/visitor.rb +2 -0
- data/lib/watir/generator/html.rb +2 -0
- data/lib/watir/generator/svg/generator.rb +2 -0
- data/lib/watir/generator/svg/spec_extractor.rb +2 -0
- data/lib/watir/generator/svg/visitor.rb +2 -0
- data/lib/watir/generator/svg.rb +2 -0
- data/lib/watir/generator.rb +2 -0
- data/lib/watir/has_window.rb +3 -1
- data/lib/watir/http_client.rb +2 -0
- data/lib/watir/js_execution.rb +2 -0
- data/lib/watir/js_snippets.rb +2 -0
- data/lib/watir/locators/anchor/selector_builder.rb +2 -0
- data/lib/watir/locators/button/matcher.rb +2 -0
- data/lib/watir/locators/button/selector_builder/xpath.rb +15 -19
- data/lib/watir/locators/button/selector_builder.rb +2 -0
- data/lib/watir/locators/cell/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/cell/selector_builder.rb +2 -0
- data/lib/watir/locators/element/locator.rb +2 -0
- data/lib/watir/locators/element/matcher.rb +2 -0
- data/lib/watir/locators/element/selector_builder/regexp_disassembler.rb +2 -0
- data/lib/watir/locators/element/selector_builder/xpath.rb +16 -15
- data/lib/watir/locators/element/selector_builder/xpath_support.rb +4 -2
- data/lib/watir/locators/element/selector_builder.rb +16 -6
- data/lib/watir/locators/option/matcher.rb +2 -0
- data/lib/watir/locators/option/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/option/selector_builder.rb +2 -0
- data/lib/watir/locators/row/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/row/selector_builder.rb +2 -0
- data/lib/watir/locators/text_area/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/text_area/selector_builder.rb +2 -0
- data/lib/watir/locators/text_field/matcher.rb +2 -0
- data/lib/watir/locators/text_field/selector_builder/xpath.rb +2 -0
- data/lib/watir/locators/text_field/selector_builder.rb +2 -0
- data/lib/watir/locators.rb +2 -0
- data/lib/watir/logger.rb +2 -0
- data/lib/watir/navigation.rb +3 -1
- data/lib/watir/radio_set.rb +2 -0
- data/lib/watir/row_container.rb +2 -0
- data/lib/watir/screenshot.rb +2 -0
- data/lib/watir/scroll.rb +27 -2
- data/lib/watir/search_context.rb +96 -0
- data/lib/watir/shadow_root.rb +60 -0
- data/lib/watir/user_editable.rb +3 -1
- data/lib/watir/version.rb +3 -1
- data/lib/watir/wait/timer.rb +3 -1
- data/lib/watir/wait.rb +5 -5
- data/lib/watir/window.rb +7 -3
- data/lib/watir/window_collection.rb +4 -1
- data/lib/watir.rb +4 -0
- data/lib/watirspec/guards.rb +2 -0
- data/lib/watirspec/implementation.rb +14 -10
- data/lib/watirspec/rake_tasks.rb +4 -4
- data/lib/watirspec/remote_server.rb +5 -3
- data/lib/watirspec/runner.rb +3 -1
- data/lib/watirspec/server/app.rb +2 -0
- data/lib/watirspec/server.rb +2 -0
- data/lib/watirspec.rb +7 -4
- data/spec/locator_spec_helper.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/capabilities_spec.rb +77 -58
- data/spec/unit/element_locator_spec.rb +2 -0
- data/spec/unit/match_elements/button_spec.rb +2 -0
- data/spec/unit/match_elements/element_spec.rb +10 -8
- data/spec/unit/match_elements/text_field_spec.rb +2 -0
- data/spec/unit/selector_builder/anchor_spec.rb +2 -0
- data/spec/unit/selector_builder/button_spec.rb +31 -28
- data/spec/unit/selector_builder/cell_spec.rb +3 -1
- data/spec/unit/selector_builder/element_spec.rb +61 -60
- data/spec/unit/selector_builder/row_spec.rb +21 -10
- data/spec/unit/selector_builder/text_field_spec.rb +29 -21
- data/spec/unit/selector_builder/textarea_spec.rb +2 -0
- data/spec/unit/unit_helper.rb +2 -0
- data/spec/unit/wait_spec.rb +2 -0
- data/spec/watirspec/adjacent_spec.rb +8 -6
- data/spec/watirspec/after_hooks_spec.rb +19 -21
- data/spec/watirspec/alert_spec.rb +2 -0
- data/spec/watirspec/attributes_spec.rb +2 -0
- data/spec/watirspec/browser_spec.rb +16 -12
- data/spec/watirspec/capabilities_spec.rb +569 -0
- data/spec/watirspec/cookies_spec.rb +4 -2
- data/spec/watirspec/drag_and_drop_spec.rb +2 -0
- data/spec/watirspec/element_hidden_spec.rb +2 -0
- data/spec/watirspec/elements/area_spec.rb +2 -0
- data/spec/watirspec/elements/areas_spec.rb +2 -0
- data/spec/watirspec/elements/button_spec.rb +2 -0
- data/spec/watirspec/elements/buttons_spec.rb +2 -0
- data/spec/watirspec/elements/checkbox_spec.rb +2 -0
- data/spec/watirspec/elements/checkboxes_spec.rb +2 -0
- data/spec/watirspec/elements/collections_spec.rb +5 -3
- data/spec/watirspec/elements/date_field_spec.rb +2 -0
- data/spec/watirspec/elements/date_fields_spec.rb +2 -0
- data/spec/watirspec/elements/date_time_field_spec.rb +2 -0
- data/spec/watirspec/elements/date_time_fields_spec.rb +2 -0
- data/spec/watirspec/elements/dd_spec.rb +2 -0
- data/spec/watirspec/elements/dds_spec.rb +2 -0
- data/spec/watirspec/elements/del_spec.rb +2 -0
- data/spec/watirspec/elements/dels_spec.rb +2 -0
- data/spec/watirspec/elements/div_spec.rb +2 -1
- data/spec/watirspec/elements/divs_spec.rb +2 -0
- data/spec/watirspec/elements/dl_spec.rb +6 -6
- data/spec/watirspec/elements/dls_spec.rb +2 -0
- data/spec/watirspec/elements/dt_spec.rb +2 -0
- data/spec/watirspec/elements/dts_spec.rb +2 -0
- data/spec/watirspec/elements/element_spec.rb +9 -1
- data/spec/watirspec/elements/elements_spec.rb +2 -0
- data/spec/watirspec/elements/em_spec.rb +2 -0
- data/spec/watirspec/elements/ems_spec.rb +2 -0
- data/spec/watirspec/elements/filefield_spec.rb +2 -0
- data/spec/watirspec/elements/filefields_spec.rb +2 -0
- data/spec/watirspec/elements/font_spec.rb +2 -0
- data/spec/watirspec/elements/form_spec.rb +2 -0
- data/spec/watirspec/elements/forms_spec.rb +2 -0
- data/spec/watirspec/elements/frame_spec.rb +2 -0
- data/spec/watirspec/elements/frames_spec.rb +2 -0
- data/spec/watirspec/elements/hidden_spec.rb +2 -0
- data/spec/watirspec/elements/hiddens_spec.rb +2 -0
- data/spec/watirspec/elements/hn_spec.rb +2 -0
- data/spec/watirspec/elements/hns_spec.rb +2 -0
- data/spec/watirspec/elements/iframe_spec.rb +3 -1
- data/spec/watirspec/elements/iframes_spec.rb +2 -0
- data/spec/watirspec/elements/image_spec.rb +2 -0
- data/spec/watirspec/elements/images_spec.rb +2 -0
- data/spec/watirspec/elements/input_spec.rb +2 -0
- data/spec/watirspec/elements/ins_spec.rb +2 -0
- data/spec/watirspec/elements/inses_spec.rb +2 -0
- data/spec/watirspec/elements/label_spec.rb +2 -0
- data/spec/watirspec/elements/labels_spec.rb +2 -0
- data/spec/watirspec/elements/li_spec.rb +2 -0
- data/spec/watirspec/elements/link_spec.rb +4 -4
- data/spec/watirspec/elements/links_spec.rb +2 -0
- data/spec/watirspec/elements/lis_spec.rb +2 -0
- data/spec/watirspec/elements/list_spec.rb +2 -0
- data/spec/watirspec/elements/map_spec.rb +2 -0
- data/spec/watirspec/elements/maps_spec.rb +2 -0
- data/spec/watirspec/elements/meta_spec.rb +2 -0
- data/spec/watirspec/elements/metas_spec.rb +2 -0
- data/spec/watirspec/elements/ol_spec.rb +2 -0
- data/spec/watirspec/elements/ols_spec.rb +2 -0
- data/spec/watirspec/elements/option_spec.rb +2 -0
- data/spec/watirspec/elements/p_spec.rb +2 -0
- data/spec/watirspec/elements/pre_spec.rb +2 -0
- data/spec/watirspec/elements/pres_spec.rb +2 -0
- data/spec/watirspec/elements/ps_spec.rb +2 -0
- data/spec/watirspec/elements/radio_spec.rb +2 -0
- data/spec/watirspec/elements/radios_spec.rb +2 -0
- data/spec/watirspec/elements/select_list_spec.rb +7 -1
- data/spec/watirspec/elements/select_lists_spec.rb +2 -0
- data/spec/watirspec/elements/span_spec.rb +2 -0
- data/spec/watirspec/elements/spans_spec.rb +2 -0
- data/spec/watirspec/elements/strong_spec.rb +2 -0
- data/spec/watirspec/elements/strongs_spec.rb +2 -0
- data/spec/watirspec/elements/table_nesting_spec.rb +2 -0
- data/spec/watirspec/elements/table_spec.rb +2 -0
- data/spec/watirspec/elements/tables_spec.rb +2 -0
- data/spec/watirspec/elements/tbody_spec.rb +2 -0
- data/spec/watirspec/elements/tbodys_spec.rb +2 -0
- data/spec/watirspec/elements/td_spec.rb +2 -0
- data/spec/watirspec/elements/tds_spec.rb +2 -0
- data/spec/watirspec/elements/text_field_spec.rb +2 -0
- data/spec/watirspec/elements/text_fields_spec.rb +2 -0
- data/spec/watirspec/elements/textarea_spec.rb +2 -0
- data/spec/watirspec/elements/textareas_spec.rb +2 -0
- data/spec/watirspec/elements/tfoot_spec.rb +2 -0
- data/spec/watirspec/elements/tfoots_spec.rb +2 -0
- data/spec/watirspec/elements/thead_spec.rb +2 -0
- data/spec/watirspec/elements/theads_spec.rb +2 -0
- data/spec/watirspec/elements/tr_spec.rb +2 -0
- data/spec/watirspec/elements/trs_spec.rb +2 -0
- data/spec/watirspec/elements/ul_spec.rb +2 -0
- data/spec/watirspec/elements/uls_spec.rb +2 -0
- data/spec/watirspec/html/child_frame.html +29 -0
- data/spec/watirspec/html/class_locator.html +2 -0
- data/spec/watirspec/html/scroll_nested.html +17 -0
- data/spec/watirspec/html/scroll_nested_offscreen.html +18 -0
- data/spec/watirspec/html/shadow_dom.html +28 -0
- data/spec/watirspec/radio_set_spec.rb +2 -0
- data/spec/watirspec/screenshot_spec.rb +4 -2
- data/spec/watirspec/scroll_spec.rb +75 -7
- data/spec/watirspec/shadow_root_spec.rb +103 -0
- data/spec/watirspec/special_chars_spec.rb +2 -0
- data/spec/watirspec/support/rspec_matchers.rb +35 -32
- data/spec/watirspec/user_editable_spec.rb +2 -0
- data/spec/watirspec/wait_spec.rb +2 -0
- data/spec/watirspec/window_switching_spec.rb +48 -38
- data/spec/watirspec_helper.rb +24 -18
- data/support/doctest_helper.rb +2 -0
- data/support/version_differ.rb +2 -0
- data/watir.gemspec +11 -8
- metadata +54 -215
- data/.github/actions/enable-safari/action.yml +0 -11
- data/.github/actions/install-chrome/action.yml +0 -12
- data/.github/actions/setup-linux/action.yml +0 -8
- data/lib/watir-webdriver.rb +0 -2
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Child frame</title>
|
|
5
|
+
<meta name="author" content="Software Freedom Conservancy">
|
|
6
|
+
<link rel="author" href="https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/common/src/web/scrolling_tests/frame_with_height_above_200.html">
|
|
7
|
+
<link rel="license" href="https://github.com/SeleniumHQ/selenium/blob/trunk/LICENSE">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<h1>This is a scrolling frame test</h1>
|
|
11
|
+
<div>
|
|
12
|
+
<table>
|
|
13
|
+
<tr height="50px">
|
|
14
|
+
<td>First row</td>
|
|
15
|
+
</tr>
|
|
16
|
+
<tr height="50px">
|
|
17
|
+
<td>Second row</td>
|
|
18
|
+
</tr>
|
|
19
|
+
<tr height="50px">
|
|
20
|
+
<td>Third row</td>
|
|
21
|
+
</tr>
|
|
22
|
+
<tr height="50px">
|
|
23
|
+
<td>Fourth row</td>
|
|
24
|
+
</tr>
|
|
25
|
+
</table>
|
|
26
|
+
</div>
|
|
27
|
+
<input type='checkbox' name='scroll_checkbox' />
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Welcome Page</title>
|
|
5
|
+
<meta name="author" content="Software Freedom Conservancy">
|
|
6
|
+
<link rel="author" href="https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/common/src/web/scrolling_tests/frame_with_height_above_200.html">
|
|
7
|
+
<link rel="license" href="https://github.com/SeleniumHQ/selenium/blob/trunk/LICENSE">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div>
|
|
11
|
+
<iframe name="nested_scrolling_frame" src="child_frame.html" width="800" height="200" ></iframe>
|
|
12
|
+
</div>
|
|
13
|
+
<div><a href="https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/common/src/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html">
|
|
14
|
+
© Software Freedom Conservancy
|
|
15
|
+
</a></div>
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Welcome Page</title>
|
|
5
|
+
<meta name="author" content="Software Freedom Conservancy">
|
|
6
|
+
<link rel="author" href="https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/common/src/web/scrolling_tests/frame_with_height_above_200.html">
|
|
7
|
+
<link rel="license" href="https://github.com/SeleniumHQ/selenium/blob/trunk/LICENSE">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div style="height: 5000px;"><a href="https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/common/src/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html">
|
|
11
|
+
HTML copyright Software Freedom Conservancy
|
|
12
|
+
</a></div>
|
|
13
|
+
<div>
|
|
14
|
+
<iframe name="nested_scrolling_frame" src="child_frame.html" width="800" height="200" ></iframe>
|
|
15
|
+
</div>
|
|
16
|
+
<footer>IFrame Above</footer>
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
5
|
+
<title>Shadow DOM</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<div id="non_host"></div>
|
|
9
|
+
<div id="shadow_host"></div>
|
|
10
|
+
<a href="scroll.html">scroll.html</a>
|
|
11
|
+
<script>
|
|
12
|
+
let shadowRoot = document.getElementById('shadow_host').attachShadow({mode: 'open'});
|
|
13
|
+
shadowRoot.innerHTML = `
|
|
14
|
+
<span class="wrapper" id="shadow_content"><span class="info">some text</span></span>
|
|
15
|
+
<div id="nested_shadow_host"></div>
|
|
16
|
+
<div id="chrome_workaround"><a href="scroll.html">scroll.html</a></div>
|
|
17
|
+
<input type="text" />
|
|
18
|
+
<input type="checkbox" />
|
|
19
|
+
<input type="file" />
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
let nestedShadowRoot = shadowRoot.getElementById('nested_shadow_host').attachShadow({mode: 'open'});
|
|
23
|
+
nestedShadowRoot.innerHTML = `
|
|
24
|
+
<div id="nested_shadow_content"><div>nested text</div></div>
|
|
25
|
+
`;
|
|
26
|
+
</script>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'base64'
|
|
2
4
|
require 'watirspec_helper'
|
|
3
5
|
|
|
4
6
|
describe 'Watir::Screenshot' do
|
|
5
|
-
let(:png_header) { "\211PNG".force_encoding('ASCII-8BIT') }
|
|
7
|
+
let(:png_header) { (+"\211PNG").force_encoding('ASCII-8BIT') }
|
|
6
8
|
|
|
7
9
|
describe '#png' do
|
|
8
10
|
it 'gets png representation of screenshot' do
|
|
@@ -23,7 +25,7 @@ describe 'Watir::Screenshot' do
|
|
|
23
25
|
expect(File).to_not exist(path)
|
|
24
26
|
browser.screenshot.save(path)
|
|
25
27
|
expect(File).to exist(path)
|
|
26
|
-
expect(File.
|
|
28
|
+
expect(File.binread(path)[0..3]).to eq png_header
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
end
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'watirspec_helper'
|
|
2
4
|
|
|
3
5
|
describe Watir::Scrolling do
|
|
4
6
|
before(:each) do
|
|
5
7
|
browser.goto(WatirSpec.url_for('scroll.html'))
|
|
8
|
+
pause
|
|
6
9
|
end
|
|
7
10
|
|
|
8
11
|
def top_centered_viewport
|
|
@@ -49,32 +52,56 @@ describe Watir::Scrolling do
|
|
|
49
52
|
|
|
50
53
|
describe '#by' do
|
|
51
54
|
before do
|
|
52
|
-
sleep(0.1)
|
|
53
55
|
browser.scroll.to :top
|
|
56
|
+
pause
|
|
54
57
|
end
|
|
55
58
|
|
|
56
59
|
it 'offset from top' do
|
|
57
60
|
initial_top = current_top
|
|
58
|
-
scroll_by = top_centered_viewport
|
|
61
|
+
scroll_by = top_centered_viewport.round
|
|
59
62
|
browser.scroll.by(0, -scroll_by)
|
|
60
|
-
|
|
63
|
+
pause
|
|
64
|
+
puts "scroll by #{scroll_by}"
|
|
65
|
+
puts "initial top #{initial_top}"
|
|
66
|
+
puts "current top #{current_top}"
|
|
61
67
|
expect(current_top).to be_within(1).of(scroll_by + initial_top)
|
|
62
68
|
end
|
|
63
69
|
|
|
64
70
|
it 'offset from bottom' do
|
|
65
|
-
browser.scroll.to :top
|
|
66
71
|
initial_top = current_top
|
|
67
72
|
browser.scroll.to :bottom
|
|
68
73
|
scroll_by = top_centered_viewport
|
|
69
74
|
browser.scroll.by(0, scroll_by)
|
|
70
|
-
|
|
75
|
+
pause
|
|
71
76
|
expect(current_top).to be_within(1).of(scroll_by + initial_top)
|
|
72
77
|
end
|
|
73
78
|
end
|
|
79
|
+
|
|
80
|
+
describe '#from' do
|
|
81
|
+
it 'scrolls by given amount with offset' do
|
|
82
|
+
browser.goto(WatirSpec.url_for('scroll_nested.html'))
|
|
83
|
+
|
|
84
|
+
browser.scroll.from(10, 10).by(0, 225)
|
|
85
|
+
|
|
86
|
+
expect(in_viewport?(browser.iframe.checkbox(name: 'scroll_checkbox'))).to eq true
|
|
87
|
+
end
|
|
88
|
+
end
|
|
74
89
|
end
|
|
75
90
|
|
|
76
91
|
context 'when scrolling Element' do
|
|
77
92
|
describe '#to' do
|
|
93
|
+
it 'scrolls element into view (viewport)',
|
|
94
|
+
except: {browser: %i[firefox safari], reason: 'incorrect MoveTargetOutOfBoundsError'} do
|
|
95
|
+
browser.goto(WatirSpec.url_for('scroll_nested_offscreen.html'))
|
|
96
|
+
iframe = browser.iframe
|
|
97
|
+
|
|
98
|
+
expect(in_viewport?(iframe)).to eq false
|
|
99
|
+
|
|
100
|
+
iframe.scroll.to(:viewport)
|
|
101
|
+
|
|
102
|
+
expect(in_viewport?(iframe)).to eq true
|
|
103
|
+
end
|
|
104
|
+
|
|
78
105
|
it 'scrolls to element (top) by default' do
|
|
79
106
|
element = browser.div(id: 'center')
|
|
80
107
|
element.scroll.to
|
|
@@ -120,17 +147,58 @@ describe Watir::Scrolling do
|
|
|
120
147
|
|
|
121
148
|
describe '#by' do
|
|
122
149
|
it 'offset' do
|
|
123
|
-
sleep 0.1
|
|
124
150
|
browser.scroll.to :top
|
|
151
|
+
pause
|
|
125
152
|
initial_top = current_top
|
|
126
153
|
browser.scroll.to :bottom
|
|
154
|
+
pause
|
|
127
155
|
scroll_by = top_centered_viewport
|
|
128
156
|
|
|
129
157
|
element = browser.div(id: 'bottom')
|
|
130
158
|
element.scroll.by(0, scroll_by)
|
|
131
|
-
|
|
159
|
+
pause
|
|
132
160
|
expect(current_top).to be_within(1).of(scroll_by + initial_top)
|
|
133
161
|
end
|
|
134
162
|
end
|
|
163
|
+
|
|
164
|
+
describe '#from',
|
|
165
|
+
except: {browser: %i[firefox safari], reason: 'incorrect MoveTargetOutOfBoundsError'} do
|
|
166
|
+
it 'scrolls from element by given amount' do
|
|
167
|
+
browser.goto(WatirSpec.url_for('scroll_nested_offscreen.html'))
|
|
168
|
+
iframe = browser.iframe
|
|
169
|
+
|
|
170
|
+
iframe.scroll.from.by(0, 200)
|
|
171
|
+
|
|
172
|
+
checkbox = iframe.checkbox(name: 'scroll_checkbox')
|
|
173
|
+
expect(in_viewport?(checkbox)).to eq true
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it 'scrolls from an element with an offset' do
|
|
177
|
+
browser.goto(WatirSpec.url_for('scroll_nested_offscreen.html'))
|
|
178
|
+
|
|
179
|
+
move_left = browser.execute_script('return arguments[0].getBoundingClientRect().width/2', browser.footer) -
|
|
180
|
+
browser.execute_script('return arguments[0].getBoundingClientRect().right/2', browser.iframe.we)
|
|
181
|
+
|
|
182
|
+
browser.footer.scroll.from(-move_left.round, -50).by(0, 200)
|
|
183
|
+
|
|
184
|
+
checkbox = browser.iframe.checkbox(name: 'scroll_checkbox')
|
|
185
|
+
expect(in_viewport?(checkbox)).to eq true
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def in_viewport?(element)
|
|
191
|
+
in_viewport = <<~IN_VIEWPORT
|
|
192
|
+
for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
|
|
193
|
+
e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
|
|
194
|
+
return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
|
|
195
|
+
window.pageYOffset&&t+o>window.pageXOffset
|
|
196
|
+
IN_VIEWPORT
|
|
197
|
+
|
|
198
|
+
element.browser.execute_script(in_viewport, element.we)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def pause
|
|
202
|
+
sleep 0.2
|
|
135
203
|
end
|
|
136
204
|
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'watirspec_helper'
|
|
4
|
+
|
|
5
|
+
describe 'ShadowRoot' do
|
|
6
|
+
before :each do
|
|
7
|
+
browser.goto(WatirSpec.url_for('shadow_dom.html'))
|
|
8
|
+
end
|
|
9
|
+
context 'with errors' do
|
|
10
|
+
it 'returns false when element does not exist' do
|
|
11
|
+
missing_shadow_root = browser.div(id: 'does_not_exist').shadow_root
|
|
12
|
+
expect(missing_shadow_root).not_to exist
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'raises ArgumentError when using :xpath to locate elements directly from the shadow root' do
|
|
16
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
17
|
+
expect { shadow_root.element(xpath: './/span').exists? }.to raise_exception(ArgumentError)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'returns false when locating element in shadow root that does not exist',
|
|
21
|
+
except: {browser: :safari, reason: 'shadow endpoint not recognized'} do
|
|
22
|
+
missing_shadow_root = browser.div(id: 'non_host').shadow_root
|
|
23
|
+
expect(missing_shadow_root.element).not_to exist
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'without errors', only: {browser: %i[firefox chrome edge]} do
|
|
28
|
+
describe '#exists?' do
|
|
29
|
+
it 'returns true when element has a shadow DOM' do
|
|
30
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
31
|
+
expect(shadow_root).to exist
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'returns false when element does not have a shadow DOM' do
|
|
35
|
+
missing_shadow_root = browser.div(id: 'non_host').shadow_root
|
|
36
|
+
expect(missing_shadow_root).not_to exist
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe 'locating', except: {browser: :firefox, reason: 'location not supported yet'} do
|
|
41
|
+
it 'locates a nested element' do
|
|
42
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
43
|
+
expect(shadow_root.element.id).to eq('shadow_content')
|
|
44
|
+
expect(shadow_root.element(id: 'nested_shadow_host').id).to eq('nested_shadow_host')
|
|
45
|
+
expect(shadow_root.element(id: /nested_shadow_.+/).id).to eq('nested_shadow_host')
|
|
46
|
+
expect(shadow_root.element(css: 'div').id).to eq('nested_shadow_host')
|
|
47
|
+
expect(shadow_root.div.id).to eq('nested_shadow_host')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'locates a collection of nested elements' do
|
|
51
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
52
|
+
expect(shadow_root.elements.count).to eq(8)
|
|
53
|
+
expect(shadow_root.elements(id: 'nested_shadow_host').map(&:id)).to eq(['nested_shadow_host'])
|
|
54
|
+
expect(shadow_root.elements(id: /nested_shadow_.+/).map(&:id)).to eq(['nested_shadow_host'])
|
|
55
|
+
expect(shadow_root.elements(css: 'div').map(&:id)).to eq(%w[nested_shadow_host chrome_workaround])
|
|
56
|
+
expect(shadow_root.divs.map(&:id)).to eq(%w[nested_shadow_host chrome_workaround])
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'locates a nested element within a nested shadow DOM' do
|
|
60
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
61
|
+
nested_shadow_root = shadow_root.element(id: 'nested_shadow_host').shadow_root
|
|
62
|
+
expect(nested_shadow_root.element.id).to eq('nested_shadow_content')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'locates a collection of nested elements within a nested shadow DOM' do
|
|
66
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
67
|
+
nested_shadow_root = shadow_root.element(id: 'nested_shadow_host').shadow_root
|
|
68
|
+
expect(nested_shadow_root.elements.count).to eq(2)
|
|
69
|
+
expect(nested_shadow_root.elements.map(&:id)).to include('nested_shadow_content')
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'allows using :xpath to locate elements with an element of a shadow root' do
|
|
73
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
74
|
+
expect(shadow_root.span.element(xpath: './/span')).to exist
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'click elements within the shadow dom' do
|
|
78
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
79
|
+
shadow_root.link.click
|
|
80
|
+
expect(browser.url).to include('scroll.html')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'click! elements within the shadow dom' do
|
|
84
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
85
|
+
shadow_root.link.click!
|
|
86
|
+
expect(browser.url).to include('scroll.html')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'inputs form elements within the shadow dom' do
|
|
90
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
91
|
+
|
|
92
|
+
shadow_root.text_field.set('abc')
|
|
93
|
+
expect(shadow_root.text_field.value).to eq('abc')
|
|
94
|
+
|
|
95
|
+
shadow_root.checkbox.set
|
|
96
|
+
expect(shadow_root.checkbox.set?).to eq(true)
|
|
97
|
+
|
|
98
|
+
shadow_root.file_field.set(File.expand_path(__FILE__))
|
|
99
|
+
expect(shadow_root.file_field.value).to include('shadow_root_spec.rb')
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -1,33 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
if defined?(RSpec)
|
|
2
|
-
|
|
4
|
+
RSpec::Matchers.define :have_deprecated do |deprecation|
|
|
5
|
+
match do |actual|
|
|
6
|
+
# Suppresses logging output to stdout while ensuring that it is still happening
|
|
7
|
+
default_output = Selenium::WebDriver.logger.io
|
|
8
|
+
io = StringIO.new
|
|
9
|
+
Watir.logger.output = io
|
|
3
10
|
|
|
4
|
-
|
|
5
|
-
RSpec::Matchers.define "have_deprecated_#{deprecation}" do
|
|
6
|
-
match do |actual|
|
|
7
|
-
return actual.call if ENV['IGNORE_DEPRECATIONS']
|
|
11
|
+
actual.call
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}.to output(warning).to_stdout_from_any_process
|
|
14
|
-
end
|
|
13
|
+
Watir.logger.output = default_output
|
|
14
|
+
@deprecations_found = (io.rewind && io.read).scan(/DEPRECATION\] \[:([^\]]*)\]/).flatten.map(&:to_sym)
|
|
15
|
+
expect(Array(deprecation).sort).to eq(@deprecations_found.sort)
|
|
16
|
+
end
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
end
|
|
25
|
-
"expected Warning message of \"#{deprecation}\" being deprecated, but #{but_message}"
|
|
26
|
-
end
|
|
18
|
+
failure_message do
|
|
19
|
+
but_message = if @deprecations_found.nil? || @deprecations_found.empty?
|
|
20
|
+
'no deprecations were found'
|
|
21
|
+
else
|
|
22
|
+
"instead these deprecations were found: [#{@deprecations_found.join(', ')}]"
|
|
23
|
+
end
|
|
24
|
+
"expected :#{deprecation} to have been deprecated, but #{but_message}"
|
|
25
|
+
end
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
failure_message_when_negated do
|
|
28
|
+
but_message = "it was found among these deprecations: [#{@deprecations_found.join(', ')}]"
|
|
29
|
+
"expected :#{deprecation} not to have been deprecated, but #{but_message}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def supports_block_expectations?
|
|
33
|
+
true
|
|
31
34
|
end
|
|
32
35
|
end
|
|
33
36
|
|
|
@@ -72,11 +75,11 @@ if defined?(RSpec)
|
|
|
72
75
|
original_timeout = Watir.default_timeout
|
|
73
76
|
Watir.default_timeout = timeout
|
|
74
77
|
begin
|
|
75
|
-
start_time =
|
|
78
|
+
start_time = Time.now
|
|
76
79
|
actual.call
|
|
77
80
|
false
|
|
78
81
|
rescue exception => e
|
|
79
|
-
finish_time =
|
|
82
|
+
finish_time = Time.now
|
|
80
83
|
unless message.nil? || e.message.match(message)
|
|
81
84
|
raise exception, "expected '#{message}' to be included in: '#{e.message}'"
|
|
82
85
|
end
|
|
@@ -91,7 +94,7 @@ if defined?(RSpec)
|
|
|
91
94
|
failure_message do
|
|
92
95
|
if @time_difference
|
|
93
96
|
"expected action to take more than provided timeout (#{timeout} seconds), " \
|
|
94
|
-
|
|
97
|
+
"instead it took #{@time_difference} seconds"
|
|
95
98
|
else
|
|
96
99
|
"expected #{exception} but nothing was raised"
|
|
97
100
|
end
|
|
@@ -109,9 +112,9 @@ if defined?(RSpec)
|
|
|
109
112
|
original_timeout = Watir.default_timeout
|
|
110
113
|
Watir.default_timeout = max
|
|
111
114
|
begin
|
|
112
|
-
start_time =
|
|
115
|
+
start_time = Time.now
|
|
113
116
|
actual.call
|
|
114
|
-
@time_difference =
|
|
117
|
+
@time_difference = Time.now - start_time
|
|
115
118
|
@time_difference > min && @time_difference < max
|
|
116
119
|
ensure
|
|
117
120
|
Watir.default_timeout = original_timeout
|
|
@@ -120,12 +123,12 @@ if defined?(RSpec)
|
|
|
120
123
|
|
|
121
124
|
failure_message_when_negated do
|
|
122
125
|
"expected action to take less than #{min} seconds or more than #{max} seconds, " \
|
|
123
|
-
|
|
126
|
+
"instead it took #{@time_difference} seconds"
|
|
124
127
|
end
|
|
125
128
|
|
|
126
129
|
failure_message do
|
|
127
130
|
"expected action to take more than #{min} seconds and less than #{max} seconds, " \
|
|
128
|
-
|
|
131
|
+
"instead it took #{@time_difference} seconds"
|
|
129
132
|
end
|
|
130
133
|
|
|
131
134
|
def supports_block_expectations?
|
data/spec/watirspec/wait_spec.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'watirspec_helper'
|
|
2
4
|
|
|
3
5
|
describe Watir::Browser do
|
|
@@ -400,13 +402,34 @@ describe Watir::Window do
|
|
|
400
402
|
end
|
|
401
403
|
|
|
402
404
|
context 'manipulating size and position', except: {headless: true} do
|
|
405
|
+
before(:all) do
|
|
406
|
+
maximized_size = browser.window.size
|
|
407
|
+
|
|
408
|
+
browser.window.resize_to(
|
|
409
|
+
maximized_size.width - 100,
|
|
410
|
+
maximized_size.height - 100
|
|
411
|
+
)
|
|
412
|
+
browser.wait_until { |b| b.window.size != maximized_size }
|
|
413
|
+
|
|
414
|
+
current_position = browser.window.position
|
|
415
|
+
|
|
416
|
+
browser.window.move_to(
|
|
417
|
+
current_position.x + 40,
|
|
418
|
+
current_position.y + 40
|
|
419
|
+
)
|
|
420
|
+
browser.wait_until { |b| b.window.position != current_position }
|
|
421
|
+
|
|
422
|
+
@initial_size = browser.window.size
|
|
423
|
+
@initial_position = browser.window.position
|
|
424
|
+
end
|
|
425
|
+
|
|
403
426
|
before do
|
|
404
427
|
browser.goto WatirSpec.url_for('window_switching.html')
|
|
405
|
-
@initial_size = browser.window.size
|
|
406
428
|
end
|
|
407
429
|
|
|
408
430
|
after do
|
|
409
431
|
browser.window.resize_to @initial_size.width, @initial_size.height
|
|
432
|
+
browser.window.move_to @initial_position.x, @initial_position.y
|
|
410
433
|
end
|
|
411
434
|
|
|
412
435
|
it 'should get the size of the current window' do
|
|
@@ -415,10 +438,8 @@ describe Watir::Window do
|
|
|
415
438
|
end
|
|
416
439
|
|
|
417
440
|
it 'should get the position of the current window' do
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
expect(pos.x).to eq browser.execute_script('return window.screenX;')
|
|
421
|
-
expect(pos.y).to eq browser.execute_script('return window.screenY;')
|
|
441
|
+
expect(@initial_position.x).to eq browser.execute_script('return window.screenX;')
|
|
442
|
+
expect(@initial_position.y).to eq browser.execute_script('return window.screenY;')
|
|
422
443
|
end
|
|
423
444
|
|
|
424
445
|
it 'should resize the window' do
|
|
@@ -427,57 +448,45 @@ describe Watir::Window do
|
|
|
427
448
|
@initial_size.height - 20
|
|
428
449
|
)
|
|
429
450
|
|
|
430
|
-
|
|
451
|
+
browser.wait_until { |b| b.window.size != @initial_size }
|
|
431
452
|
|
|
453
|
+
new_size = browser.window.size
|
|
432
454
|
expect(new_size.width).to eq @initial_size.width - 20
|
|
433
455
|
expect(new_size.height).to eq @initial_size.height - 20
|
|
434
456
|
end
|
|
435
457
|
|
|
436
458
|
it 'should move the window' do
|
|
437
|
-
initial_pos = browser.window.position
|
|
438
|
-
|
|
439
459
|
browser.window.move_to(
|
|
440
|
-
|
|
441
|
-
|
|
460
|
+
@initial_position.x + 5,
|
|
461
|
+
@initial_position.y + 5
|
|
442
462
|
)
|
|
443
463
|
|
|
444
|
-
|
|
445
|
-
expect(new_pos.x).to eq initial_pos.x + 2
|
|
446
|
-
expect(new_pos.y).to eq initial_pos.y + 2
|
|
447
|
-
end
|
|
464
|
+
browser.wait_until { |b| b.window.position != @initial_position }
|
|
448
465
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
)
|
|
454
|
-
browser.wait_until { |b| b.window.size != @initial_size }
|
|
455
|
-
new_size = browser.window.size
|
|
466
|
+
new_position = browser.window.position
|
|
467
|
+
expect(new_position.x).to eq @initial_position.x + 5
|
|
468
|
+
expect(new_position.y).to eq @initial_position.y + 5
|
|
469
|
+
end
|
|
456
470
|
|
|
471
|
+
it 'should maximize the window' do
|
|
457
472
|
browser.window.maximize
|
|
458
|
-
browser.wait_until { |b| b.window.size !=
|
|
459
|
-
|
|
460
|
-
final_size = browser.window.size
|
|
461
|
-
expect(final_size.width).to be >= new_size.width
|
|
462
|
-
expect(final_size.height).to be > new_size.height
|
|
463
|
-
end
|
|
473
|
+
browser.wait_until { |b| b.window.size != @initial_size }
|
|
464
474
|
|
|
465
|
-
it 'should make the window full screen', except: {browser: :firefox, window_manager: false} do
|
|
466
|
-
browser.window.resize_to(
|
|
467
|
-
@initial_size.width - 40,
|
|
468
|
-
@initial_size.height - 40
|
|
469
|
-
)
|
|
470
475
|
new_size = browser.window.size
|
|
476
|
+
expect(new_size.width).to be >= @initial_size.width
|
|
477
|
+
expect(new_size.height).to be > @initial_size.height
|
|
478
|
+
end
|
|
471
479
|
|
|
480
|
+
it 'should make the window full screen' do
|
|
472
481
|
browser.window.full_screen
|
|
473
|
-
browser.wait_until { |b| b.window.size !=
|
|
482
|
+
browser.wait_until { |b| b.window.size != @initial_size }
|
|
474
483
|
|
|
475
|
-
|
|
476
|
-
expect(
|
|
477
|
-
expect(
|
|
484
|
+
new_size = browser.window.size
|
|
485
|
+
expect(new_size.width).to be >= @initial_size.width
|
|
486
|
+
expect(new_size.height).to be > @initial_size.height
|
|
478
487
|
end
|
|
479
488
|
|
|
480
|
-
it 'should minimize the window'
|
|
489
|
+
it 'should minimize the window' do
|
|
481
490
|
expect(browser.execute_script('return document.visibilityState;')).to eq 'visible'
|
|
482
491
|
|
|
483
492
|
browser.window.minimize
|
|
@@ -485,6 +494,7 @@ describe Watir::Window do
|
|
|
485
494
|
browser.wait_until { |b| b.execute_script('return document.visibilityState;') != 'visible' }
|
|
486
495
|
|
|
487
496
|
expect(browser.execute_script('return document.visibilityState;')).to eq 'hidden'
|
|
497
|
+
browser.window.maximize
|
|
488
498
|
end
|
|
489
499
|
end
|
|
490
500
|
end
|
|
@@ -557,7 +567,7 @@ describe Watir::WindowCollection do
|
|
|
557
567
|
wins = browser.windows
|
|
558
568
|
expect(wins.size).to eq 2
|
|
559
569
|
wins.reset!
|
|
560
|
-
expect(wins.instance_variable_get(
|
|
570
|
+
expect(wins.instance_variable_get(:@window_list)).to be_nil
|
|
561
571
|
end
|
|
562
572
|
|
|
563
573
|
describe '#restore!' do
|