Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/rb/spec/integration/selenium/webdriver/devtools_spec.rb
1864 views
1
# frozen_string_literal: true
2
3
# Licensed to the Software Freedom Conservancy (SFC) under one
4
# or more contributor license agreements. See the NOTICE file
5
# distributed with this work for additional information
6
# regarding copyright ownership. The SFC licenses this file
7
# to you under the Apache License, Version 2.0 (the
8
# "License"); you may not use this file except in compliance
9
# with the License. You may obtain a copy of the License at
10
#
11
# http://www.apache.org/licenses/LICENSE-2.0
12
#
13
# Unless required by applicable law or agreed to in writing,
14
# software distributed under the License is distributed on an
15
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
# KIND, either express or implied. See the License for the
17
# specific language governing permissions and limitations
18
# under the License.
19
20
require_relative 'spec_helper'
21
22
module Selenium
23
module WebDriver
24
describe DevTools, exclusive: [{bidi: false, reason: 'Not yet implemented with BiDi'},
25
{browser: %i[chrome edge]}] do
26
after { |example| reset_driver!(example: example) }
27
28
it 'sends commands' do
29
driver.devtools.page.navigate(url: url_for('xhtmlTest.html'))
30
expect(driver.title).to eq('XHTML Test Page')
31
end
32
33
it 'maps methods to classes' do
34
expect(driver.devtools.css).not_to be_nil
35
expect(driver.devtools.dom).not_to be_nil
36
expect(driver.devtools.dom_debugger).not_to be_nil
37
end
38
39
it 'supports events' do
40
expect { |block|
41
driver.devtools.page.enable
42
driver.devtools.page.on(:load_event_fired, &block)
43
driver.navigate.to url_for('xhtmlTest.html')
44
sleep 0.5
45
}.to yield_control
46
end
47
48
it 'propagates errors in events' do
49
expect {
50
driver.devtools.page.enable
51
driver.devtools.page.on(:load_event_fired) { raise 'This is fine!' }
52
driver.navigate.to url_for('xhtmlTest.html')
53
sleep 0.5
54
}.to raise_error(RuntimeError, 'This is fine!')
55
end
56
57
describe '#target' do
58
it 'target type defaults to page' do
59
driver.devtools.page.navigate(url: url_for('xhtmlTest.html'))
60
expect(driver.devtools.target.get_target_info.dig('result', 'targetInfo', 'type')).to eq 'page'
61
end
62
63
it 'target type is service_worker' do
64
driver.devtools.page.navigate(url: url_for('service_worker.html'))
65
sleep 0.5 # wait for service worker to register
66
target = driver.devtools(target_type: 'service_worker').target
67
expect(target.get_target_info.dig('result', 'targetInfo', 'type')).to eq 'service_worker'
68
end
69
70
it 'throws an error for unknown target type' do
71
driver.devtools.page.navigate(url: url_for('xhtmlTest.html'))
72
expect { driver.devtools(target_type: 'unknown') }
73
.to raise_error(Selenium::WebDriver::Error::WebDriverError, "Target type 'unknown' not found")
74
end
75
end
76
77
describe '#register' do
78
let(:username) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.first }
79
let(:password) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.last }
80
81
it 'on any request' do
82
driver.register(username: username, password: password)
83
84
driver.navigate.to url_for('basicAuth')
85
expect(driver.find_element(tag_name: 'h1').text).to eq('authorized')
86
end
87
88
it 'based on URL' do
89
auth_url = url_for('basicAuth')
90
driver.register(username: username, password: password, uri: /localhost/)
91
92
driver.navigate.to auth_url.sub('localhost', '127.0.0.1')
93
expect { driver.find_element(tag_name: 'h1') }.to raise_error(Error::NoSuchElementError)
94
95
driver.navigate.to auth_url
96
expect(driver.find_element(tag_name: 'h1').text).to eq('authorized')
97
end
98
end
99
100
it 'notifies about log messages' do
101
logs = []
102
driver.on_log_event(:console) { |log| logs.push(log) }
103
driver.navigate.to url_for('javascriptPage.html')
104
105
driver.execute_script("console.log('I like cheese');")
106
sleep 0.5
107
driver.execute_script('console.log(true);')
108
sleep 0.5
109
driver.execute_script('console.log(null);')
110
sleep 0.5
111
driver.execute_script('console.log(undefined);')
112
sleep 0.5
113
driver.execute_script('console.log(document);')
114
sleep 0.5
115
116
expect(logs).to include(
117
an_object_having_attributes(type: :log, args: ['I like cheese']),
118
an_object_having_attributes(type: :log, args: [true]),
119
an_object_having_attributes(type: :log, args: [nil]),
120
an_object_having_attributes(type: :log, args: [{'type' => 'undefined'}])
121
)
122
end
123
124
it 'notifies about document log messages' do
125
logs = []
126
driver.on_log_event(:console) { |log| logs.push(log) }
127
driver.navigate.to url_for('javascriptPage.html')
128
129
driver.execute_script('console.log(document);')
130
wait.until { !logs.empty? }
131
132
expect(logs).to include(
133
an_object_having_attributes(type: :log, args: [hash_including('type' => 'object')])
134
)
135
end
136
137
it 'notifies about exceptions' do
138
exceptions = []
139
driver.on_log_event(:exception) { |exception| exceptions.push(exception) }
140
driver.navigate.to url_for('javascriptPage.html')
141
142
driver.find_element(id: 'throwing-mouseover').click
143
wait.until { exceptions.any? }
144
145
exception = exceptions.first
146
expect(exception.description).to include('Error: I like cheese')
147
expect(exception.stacktrace).not_to be_empty
148
end
149
150
it 'notifies about DOM mutations' do
151
mutations = []
152
driver.on_log_event(:mutation) { |mutation| mutations.push(mutation) }
153
driver.navigate.to url_for('dynamic.html')
154
155
driver.find_element(id: 'reveal').click
156
wait.until { mutations.any? }
157
158
mutation = mutations.first
159
expect(mutation.element).to eq(driver.find_element(id: 'revealed'))
160
expect(mutation.attribute_name).to eq('style')
161
expect(mutation.current_value).to eq('')
162
expect(mutation.old_value).to eq('display:none;')
163
end
164
165
describe '#intercept' do
166
it 'continues requests' do
167
requests = []
168
driver.intercept do |request, &continue|
169
requests << request
170
continue.call(request)
171
end
172
driver.navigate.to url_for('html5Page.html')
173
expect(driver.title).to eq('HTML5')
174
expect(requests).not_to be_empty
175
end
176
177
it 'changes requests' do
178
driver.intercept do |request, &continue|
179
uri = URI(request.url)
180
if uri.path.end_with?('one.js')
181
uri.path = '/devtools_request_interception_test/two.js'
182
request.url = uri.to_s
183
end
184
request.post_data = {foo: 'bar'}.to_json
185
continue.call(request)
186
end
187
driver.navigate.to url_for('devToolsRequestInterceptionTest.html')
188
driver.find_element(tag_name: 'button').click
189
expect(driver.find_element(id: 'result').text).to eq('two')
190
end
191
192
it 'continues responses' do
193
responses = []
194
driver.intercept do |request, &continue|
195
continue.call(request) do |response|
196
responses << response
197
end
198
end
199
driver.navigate.to url_for('html5Page.html')
200
expect(driver.title).to eq('HTML5')
201
expect(responses).not_to be_empty
202
end
203
204
it 'changes responses' do
205
driver.intercept do |request, &continue|
206
continue.call(request) do |response|
207
response.body << '<h4 id="appended">Appended!</h4>' if request.url.include?('html5Page.html')
208
end
209
end
210
driver.navigate.to url_for('html5Page.html')
211
expect(driver.find_elements(id: 'appended')).not_to be_empty
212
end
213
end
214
215
describe '#pin_script', except: {browser: :firefox} do
216
before do
217
driver.navigate.to url_for('xhtmlTest.html')
218
end
219
220
it 'allows to pin script' do
221
script = driver.pin_script('return document.title;')
222
expect(driver.pinned_scripts).to eq([script])
223
expect(driver.execute_script(script)).to eq('XHTML Test Page')
224
end
225
226
it 'ensures pinned script is available on new pages' do
227
script = driver.pin_script('return document.title;')
228
driver.navigate.to url_for('formPage.html')
229
expect(driver.execute_script(script)).to eq('We Leave From Here')
230
end
231
232
it 'allows to unpin script' do
233
script = driver.pin_script('return document.title;')
234
driver.unpin_script(script)
235
expect(driver.pinned_scripts).to be_empty
236
expect { driver.execute_script(script) }.to raise_error(Error::JavascriptError)
237
end
238
239
it 'ensures unpinned scripts are not available on new pages' do
240
script = driver.pin_script('return document.title;')
241
driver.unpin_script(script)
242
driver.navigate.to url_for('formPage.html')
243
expect { driver.execute_script(script) }.to raise_error(Error::JavascriptError)
244
end
245
246
it 'handles arguments in pinned script' do
247
script = driver.pin_script('return arguments;')
248
element = driver.find_element(id: 'id1')
249
expect(driver.execute_script(script, 1, true, element)).to eq([1, true, element])
250
end
251
252
it 'supports async pinned scripts' do
253
script = driver.pin_script('arguments[0]()')
254
expect { driver.execute_async_script(script) }.not_to raise_error
255
end
256
end
257
end
258
end
259
end
260
261