watir 6.16.5 → 6.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +32 -107
- data/.travis.yml +24 -21
- data/CHANGES.md +16 -0
- data/Gemfile +3 -1
- data/Rakefile +3 -3
- data/appveyor.yml +2 -1
- data/lib/watir-webdriver.rb +1 -1
- data/lib/watir.rb +0 -1
- data/lib/watir/adjacent.rb +8 -10
- data/lib/watir/after_hooks.rb +4 -4
- data/lib/watir/browser.rb +5 -1
- data/lib/watir/capabilities.rb +9 -6
- data/lib/watir/cookies.rb +1 -1
- data/lib/watir/elements/element.rb +59 -46
- data/lib/watir/elements/file_field.rb +1 -0
- data/lib/watir/elements/iframe.rb +2 -2
- data/lib/watir/elements/link.rb +0 -9
- data/lib/watir/elements/radio.rb +1 -1
- data/lib/watir/elements/select.rb +2 -2
- data/lib/watir/generator/base/spec_extractor.rb +4 -4
- data/lib/watir/js_execution.rb +1 -1
- data/lib/watir/legacy_wait.rb +1 -1
- data/lib/watir/locators/element/selector_builder.rb +11 -12
- data/lib/watir/locators/element/selector_builder/xpath.rb +40 -13
- data/lib/watir/locators/text_field/selector_builder/xpath.rb +3 -1
- data/lib/watir/logger.rb +5 -2
- data/lib/watir/version.rb +1 -1
- data/lib/watir/window.rb +1 -1
- data/lib/watirspec.rb +1 -1
- data/lib/watirspec/guards.rb +1 -1
- data/lib/watirspec/rake_tasks.rb +2 -0
- data/lib/watirspec/runner.rb +4 -0
- data/spec/unit/container_spec.rb +1 -1
- data/spec/unit/logger_spec.rb +5 -7
- data/spec/unit/selector_builder/button_spec.rb +16 -15
- data/spec/unit/selector_builder/element_spec.rb +58 -9
- data/spec/unit/selector_builder/text_field_spec.rb +14 -14
- data/spec/watirspec/after_hooks_spec.rb +64 -78
- data/spec/watirspec/alert_spec.rb +69 -79
- data/spec/watirspec/browser_spec.rb +48 -46
- data/spec/watirspec/cookies_spec.rb +52 -37
- data/spec/watirspec/drag_and_drop_spec.rb +14 -38
- data/spec/watirspec/elements/button_spec.rb +2 -0
- data/spec/watirspec/elements/buttons_spec.rb +1 -1
- data/spec/watirspec/elements/checkbox_spec.rb +8 -4
- data/spec/watirspec/elements/date_field_spec.rb +18 -9
- data/spec/watirspec/elements/date_time_field_spec.rb +3 -4
- data/spec/watirspec/elements/div_spec.rb +62 -54
- data/spec/watirspec/elements/element_spec.rb +60 -78
- data/spec/watirspec/elements/elements_spec.rb +12 -3
- data/spec/watirspec/elements/filefield_spec.rb +25 -50
- data/spec/watirspec/elements/form_spec.rb +6 -8
- data/spec/watirspec/elements/frame_spec.rb +10 -13
- data/spec/watirspec/elements/iframe_spec.rb +17 -12
- data/spec/watirspec/elements/iframes_spec.rb +2 -2
- data/spec/watirspec/elements/link_spec.rb +18 -9
- data/spec/watirspec/elements/links_spec.rb +11 -3
- data/spec/watirspec/elements/option_spec.rb +15 -17
- data/spec/watirspec/elements/select_list_spec.rb +66 -80
- data/spec/watirspec/elements/text_field_spec.rb +8 -4
- data/spec/watirspec/elements/tr_spec.rb +0 -9
- data/spec/watirspec/html/forms_with_input_elements.html +1 -0
- data/spec/watirspec/html/iframes.html +3 -0
- data/spec/watirspec/html/non_control_elements.html +4 -4
- data/spec/watirspec/html/right_click.html +12 -0
- data/spec/watirspec/html/wait.html +1 -1
- data/spec/watirspec/relaxed_locate_spec.rb +16 -20
- data/spec/watirspec/support/rspec_matchers.rb +7 -6
- data/spec/watirspec/user_editable_spec.rb +1 -1
- data/spec/watirspec/wait_spec.rb +13 -17
- data/spec/watirspec/window_switching_spec.rb +162 -163
- data/spec/watirspec_helper.rb +7 -5
- data/watir.gemspec +4 -5
- metadata +14 -16
- data/lib/watir/elements/area.rb +0 -10
@@ -1,110 +1,100 @@
|
|
1
1
|
require 'watirspec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
3
|
+
describe 'Alert API' do
|
4
|
+
before do
|
5
|
+
browser.goto WatirSpec.url_for('alerts.html')
|
6
|
+
end
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
after do
|
9
|
+
browser.alert.ok if browser.alert.exists?
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
12
|
+
compliant_on :relaxed_locate do
|
13
|
+
context 'Relaxed Waits' do
|
14
|
+
context 'when acting on an alert' do
|
15
|
+
it 'raises exception after timing out' do
|
16
|
+
expect { browser.alert.text }.to wait_and_raise_unknown_object_exception
|
19
17
|
end
|
20
18
|
end
|
21
19
|
end
|
20
|
+
end
|
22
21
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
22
|
+
context 'alert' do
|
23
|
+
describe '#text' do
|
24
|
+
it 'returns text of alert' do
|
25
|
+
browser.button(id: 'alert').click
|
26
|
+
expect(browser.alert.text).to include('ok')
|
29
27
|
end
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
describe '#exists?' do
|
31
|
+
it 'returns false if alert is not present' do
|
32
|
+
expect(browser.alert).to_not exist
|
33
|
+
end
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
browser.wait_until(timeout: 10) { browser.alert.exists? }
|
40
|
-
end
|
41
|
-
end
|
35
|
+
it 'returns true if alert is present' do
|
36
|
+
browser.button(id: 'alert').click
|
37
|
+
browser.wait_until(timeout: 10) { browser.alert.exists? }
|
42
38
|
end
|
39
|
+
end
|
43
40
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
expect(browser.alert).to_not exist
|
50
|
-
end
|
51
|
-
end
|
41
|
+
describe '#ok' do
|
42
|
+
it 'closes alert' do
|
43
|
+
browser.button(id: 'alert').click
|
44
|
+
browser.alert.ok
|
45
|
+
expect(browser.alert).to_not exist
|
52
46
|
end
|
47
|
+
end
|
53
48
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
browser.alert.close
|
60
|
-
expect(browser.alert).to_not exist
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
49
|
+
describe '#close' do
|
50
|
+
it 'closes alert' do
|
51
|
+
browser.button(id: 'alert').click
|
52
|
+
browser.alert.close
|
53
|
+
expect(browser.alert).to_not exist
|
64
54
|
end
|
55
|
+
end
|
65
56
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
57
|
+
not_compliant_on :relaxed_locate do
|
58
|
+
describe 'wait_until_present' do
|
59
|
+
it 'waits until alert is present and goes on' do
|
60
|
+
browser.button(id: 'timeout-alert').click
|
61
|
+
browser.alert.wait_until_present.ok
|
71
62
|
|
72
|
-
|
73
|
-
|
63
|
+
expect(browser.alert).to_not exist
|
64
|
+
end
|
74
65
|
|
75
|
-
|
76
|
-
|
77
|
-
end
|
66
|
+
it 'raises error if alert is not present after timeout' do
|
67
|
+
expect { browser.alert.wait_until_present.ok }.to raise_timeout_exception
|
78
68
|
end
|
79
69
|
end
|
80
70
|
end
|
71
|
+
end
|
81
72
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
73
|
+
context 'confirm' do
|
74
|
+
describe '#ok' do
|
75
|
+
it 'accepts confirm' do
|
76
|
+
browser.button(id: 'confirm').click
|
77
|
+
browser.alert.ok
|
78
|
+
expect(browser.button(id: 'confirm').value).to eq 'true'
|
89
79
|
end
|
80
|
+
end
|
90
81
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
82
|
+
describe '#close' do
|
83
|
+
it 'cancels confirm' do
|
84
|
+
browser.button(id: 'confirm').click
|
85
|
+
browser.alert.close
|
86
|
+
expect(browser.button(id: 'confirm').value).to eq 'false'
|
97
87
|
end
|
98
88
|
end
|
89
|
+
end
|
99
90
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
91
|
+
context 'prompt' do
|
92
|
+
describe '#set' do
|
93
|
+
it 'enters text to prompt' do
|
94
|
+
browser.button(id: 'prompt').click
|
95
|
+
browser.alert.set 'My Name'
|
96
|
+
browser.alert.ok
|
97
|
+
expect(browser.button(id: 'prompt').value).to eq 'My Name'
|
108
98
|
end
|
109
99
|
end
|
110
100
|
end
|
@@ -12,17 +12,15 @@ describe 'Browser' do
|
|
12
12
|
expect(browser).to exist
|
13
13
|
end
|
14
14
|
|
15
|
-
bug '
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
expect(browser.exists?).to be false
|
25
|
-
end
|
15
|
+
bug 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException', :safari do
|
16
|
+
it 'returns false if window is closed' do
|
17
|
+
browser.goto WatirSpec.url_for('window_switching.html')
|
18
|
+
browser.a(id: 'open').click
|
19
|
+
Watir::Wait.until { browser.windows.size == 2 }
|
20
|
+
browser.window(title: 'closeable window').use
|
21
|
+
browser.a(id: 'close').click
|
22
|
+
Watir::Wait.until { browser.windows.size == 1 }
|
23
|
+
expect(browser.exists?).to be false
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
@@ -74,7 +72,7 @@ describe 'Browser' do
|
|
74
72
|
end
|
75
73
|
end
|
76
74
|
|
77
|
-
bug 'Capitalization
|
75
|
+
bug 'Capitalization issue', :safari do
|
78
76
|
describe '#name' do
|
79
77
|
it 'returns browser name' do
|
80
78
|
expect(browser.name).to eq(WatirSpec.implementation.browser_args.first)
|
@@ -159,8 +157,8 @@ describe 'Browser' do
|
|
159
157
|
@original = WatirSpec.implementation.clone
|
160
158
|
|
161
159
|
require 'watirspec/remote_server'
|
162
|
-
args = ["-Dwebdriver.chrome.driver=#{Webdrivers::Chromedriver.
|
163
|
-
"-Dwebdriver.gecko.driver=#{Webdrivers::Geckodriver.
|
160
|
+
args = ["-Dwebdriver.chrome.driver=#{Webdrivers::Chromedriver.driver_path}",
|
161
|
+
"-Dwebdriver.gecko.driver=#{Webdrivers::Geckodriver.driver_path}"]
|
164
162
|
WatirSpec::RemoteServer.new.start(4544, args: args)
|
165
163
|
browser.close
|
166
164
|
end
|
@@ -287,13 +285,15 @@ describe 'Browser' do
|
|
287
285
|
|
288
286
|
compliant_on :chrome do
|
289
287
|
not_compliant_on :watigiri do
|
290
|
-
it 'takes
|
288
|
+
it 'takes service as argument' do
|
291
289
|
@original = WatirSpec.implementation.clone
|
292
290
|
browser.close
|
293
291
|
@opts = WatirSpec.implementation.browser_args.last
|
292
|
+
browser_name = WatirSpec.implementation.browser_args.first
|
293
|
+
|
294
|
+
service = Selenium::WebDriver::Service.send(browser_name, port: '2314', args: ['foo'])
|
294
295
|
|
295
|
-
@opts.merge!(
|
296
|
-
driver_opts: {args: ['foo']},
|
296
|
+
@opts.merge!(service: service,
|
297
297
|
listener: LocalConfig::SelectorListener.new)
|
298
298
|
|
299
299
|
@new_browser = WatirSpec.new_browser
|
@@ -373,16 +373,19 @@ describe 'Browser' do
|
|
373
373
|
end
|
374
374
|
end
|
375
375
|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
browser.refresh
|
383
|
-
browser.span(class: 'footer').wait_until(&:present?)
|
384
|
-
expect(browser.span(class: 'footer').text).to_not include('Javascript')
|
376
|
+
describe '#refresh' do
|
377
|
+
it 'refreshes the page' do
|
378
|
+
browser.goto(WatirSpec.url_for('non_control_elements.html'))
|
379
|
+
|
380
|
+
compliant_on :headless do
|
381
|
+
browser.div(id: 'best_language').scroll.to
|
385
382
|
end
|
383
|
+
|
384
|
+
browser.div(id: 'best_language').click
|
385
|
+
expect(browser.div(id: 'best_language').text).to include('Ruby!')
|
386
|
+
browser.refresh
|
387
|
+
browser.div(id: 'best_language').wait_until(&:present?)
|
388
|
+
expect(browser.div(id: 'best_language').text).to_not include('Ruby!')
|
386
389
|
end
|
387
390
|
end
|
388
391
|
|
@@ -509,27 +512,26 @@ describe 'Browser' do
|
|
509
512
|
|
510
513
|
describe '#wait' do
|
511
514
|
# The only way to get engage this method is with page load strategy set to "none"
|
512
|
-
# Chrome will be blocking on document ready state because it does not yet support page load strategy
|
513
515
|
# This spec is both mocking out the response and demonstrating the necessary settings for it to be meaningful
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
516
|
+
it 'waits for document ready state to be complete' do
|
517
|
+
@original = WatirSpec.implementation.clone
|
518
|
+
browser.close
|
519
|
+
@opts = WatirSpec.implementation.browser_args.last
|
520
|
+
|
521
|
+
@opts[:page_load_strategy] = 'none'
|
522
|
+
browser = WatirSpec.new_browser
|
523
|
+
|
524
|
+
start_time = Time.now
|
525
|
+
allow(browser).to receive(:ready_state) { Time.now < start_time + 3 ? 'loading' : 'complete' }
|
526
|
+
expect(browser.ready_state).to eq 'loading'
|
527
|
+
|
528
|
+
browser.wait(20)
|
529
|
+
expect(Time.now - start_time).to be > 3
|
530
|
+
expect(browser.ready_state).to eq 'complete'
|
531
|
+
|
532
|
+
browser.close
|
533
|
+
WatirSpec.implementation = @original.clone
|
534
|
+
$browser = WatirSpec.new_browser
|
533
535
|
end
|
534
536
|
end
|
535
537
|
|
@@ -42,7 +42,7 @@ describe 'Browser#cookies' do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
not_compliant_on :internet_explorer do
|
45
|
-
it 'adds a cookie' do
|
45
|
+
it 'adds a cookie without options' do
|
46
46
|
browser.goto set_cookie_url
|
47
47
|
verify_cookies_count 1
|
48
48
|
|
@@ -63,29 +63,49 @@ describe 'Browser#cookies' do
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
it 'adds a cookie with path' do
|
67
|
+
browser.goto set_cookie_url
|
68
|
+
|
69
|
+
options = {path: '/set_cookie'}
|
70
|
+
|
71
|
+
browser.cookies.add 'path', 'b', options
|
72
|
+
cookie = browser.cookies.to_a.find { |e| e[:name] == 'path' }
|
73
|
+
|
74
|
+
expect(cookie).to_not be_nil
|
75
|
+
expect(cookie[:name]).to eq 'path'
|
76
|
+
expect(cookie[:value]).to eq 'b'
|
77
|
+
expect(cookie[:path]).to eq '/set_cookie'
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'adds a cookie with expiration' do
|
81
|
+
browser.goto set_cookie_url
|
82
|
+
|
83
|
+
expires = Time.now + 10_000
|
84
|
+
options = {expires: expires}
|
85
|
+
|
86
|
+
browser.cookies.add 'expiration', 'b', options
|
87
|
+
cookie = browser.cookies.to_a.find { |e| e[:name] == 'expiration' }
|
88
|
+
|
89
|
+
expect(cookie).to_not be_nil
|
90
|
+
expect(cookie[:name]).to eq 'expiration'
|
91
|
+
expect(cookie[:value]).to eq 'b'
|
92
|
+
# a few ms slack
|
93
|
+
expect((cookie[:expires]).to_i).to be_within(2).of(expires.to_i)
|
94
|
+
end
|
95
|
+
|
96
|
+
bug 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=2727', :chrome, :safari do
|
97
|
+
it 'adds a cookie with security' do
|
69
98
|
browser.goto set_cookie_url
|
70
99
|
|
71
|
-
|
72
|
-
options = {path: '/set_cookie',
|
73
|
-
secure: true,
|
74
|
-
expires: expires}
|
100
|
+
options = {secure: true}
|
75
101
|
|
76
|
-
browser.cookies.add '
|
77
|
-
cookie = browser.cookies.to_a.find { |e| e[:name] == '
|
102
|
+
browser.cookies.add 'secure', 'b', options
|
103
|
+
cookie = browser.cookies.to_a.find { |e| e[:name] == 'secure' }
|
78
104
|
expect(cookie).to_not be_nil
|
79
105
|
|
80
|
-
expect(cookie[:name]).to eq '
|
106
|
+
expect(cookie[:name]).to eq 'secure'
|
81
107
|
expect(cookie[:value]).to eq 'b'
|
82
|
-
|
83
|
-
expect(cookie[:path]).to eq '/set_cookie'
|
84
108
|
expect(cookie[:secure]).to be true
|
85
|
-
|
86
|
-
expect(cookie[:expires]).to be_kind_of(Time)
|
87
|
-
# a few ms slack
|
88
|
-
expect((cookie[:expires]).to_i).to be_within(2).of(expires.to_i)
|
89
109
|
end
|
90
110
|
end
|
91
111
|
|
@@ -98,15 +118,13 @@ describe 'Browser#cookies' do
|
|
98
118
|
verify_cookies_count 0
|
99
119
|
end
|
100
120
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
verify_cookies_count 2
|
121
|
+
it 'clears all cookies' do
|
122
|
+
browser.goto set_cookie_url
|
123
|
+
browser.cookies.add 'foo', 'bar'
|
124
|
+
verify_cookies_count 2
|
106
125
|
|
107
|
-
|
108
|
-
|
109
|
-
end
|
126
|
+
browser.cookies.clear
|
127
|
+
verify_cookies_count 0
|
110
128
|
end
|
111
129
|
end
|
112
130
|
|
@@ -124,20 +142,17 @@ describe 'Browser#cookies' do
|
|
124
142
|
end
|
125
143
|
end
|
126
144
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
actual = YAML.safe_load(IO.read(file), [::Symbol])
|
145
|
+
describe '#load' do
|
146
|
+
it 'loads cookies from file' do
|
147
|
+
browser.cookies.clear
|
148
|
+
browser.cookies.load file
|
149
|
+
expected = browser.cookies.to_a
|
150
|
+
actual = YAML.safe_load(IO.read(file), [::Symbol])
|
134
151
|
|
135
|
-
|
136
|
-
|
137
|
-
actual.each { |cookie| cookie.delete(:expires) }
|
152
|
+
expected.each { |cookie| cookie.delete(:expires) }
|
153
|
+
actual.each { |cookie| cookie.delete(:expires) }
|
138
154
|
|
139
|
-
|
140
|
-
end
|
155
|
+
expect(actual).to eq(expected)
|
141
156
|
end
|
142
157
|
end
|
143
158
|
end
|
@@ -1,47 +1,23 @@
|
|
1
1
|
require 'watirspec_helper'
|
2
2
|
|
3
3
|
describe 'Element' do
|
4
|
-
|
5
|
-
|
6
|
-
context 'drag and drop' do
|
7
|
-
before { browser.goto WatirSpec.url_for('drag_and_drop.html') }
|
4
|
+
context 'drag and drop' do
|
5
|
+
before { browser.goto WatirSpec.url_for('drag_and_drop.html') }
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
let(:draggable) { browser.div id: 'draggable' }
|
8
|
+
let(:droppable) { browser.div id: 'droppable' }
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
not_compliant_on :headless, :firefox do
|
19
|
-
it 'can drag and drop an element onto another when draggable is out of viewport' do
|
20
|
-
reposition 'draggable'
|
21
|
-
perform_drag_and_drop_on_droppable
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'can drag and drop an element onto another when droppable is out of viewport' do
|
25
|
-
reposition 'droppable'
|
26
|
-
perform_drag_and_drop_on_droppable
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'can drag an element by the given offset' do
|
31
|
-
expect(droppable.text).to eq 'Drop here'
|
32
|
-
draggable.drag_and_drop_by 200, 50
|
33
|
-
expect(droppable.text).to eq 'Dropped!'
|
34
|
-
end
|
35
|
-
|
36
|
-
def reposition(what)
|
37
|
-
browser.button(id: "reposition#{what.capitalize}").click
|
38
|
-
end
|
10
|
+
it 'can drag and drop an element onto another' do
|
11
|
+
expect(droppable.text).to include 'Drop here'
|
12
|
+
draggable.drag_and_drop_on droppable
|
13
|
+
expect(droppable.text).to include 'Dropped!'
|
14
|
+
end
|
39
15
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
16
|
+
bug 'Element is getting moved to the wrong spot', :w3c do
|
17
|
+
it 'can drag an element by the given offset' do
|
18
|
+
expect(droppable.text).to include 'Drop here'
|
19
|
+
draggable.drag_and_drop_by 200, 50
|
20
|
+
expect(droppable.text).to include 'Dropped!'
|
45
21
|
end
|
46
22
|
end
|
47
23
|
end
|