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
3983 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 'logs errors in events' do
49
driver.devtools.page.enable
50
driver.devtools.page.on(:load_event_fired) { raise 'This is fine!' }
51
expect {
52
driver.navigate.to url_for('xhtmlTest.html')
53
}.to have_error(:ws, /This is fine!/)
54
end
55
56
describe '#target' do
57
it 'target type defaults to page' do
58
driver.devtools.page.navigate(url: url_for('xhtmlTest.html'))
59
expect(driver.devtools.target.get_target_info.dig('result', 'targetInfo', 'type')).to eq 'page'
60
end
61
62
it 'target type is service_worker' do
63
driver.devtools.page.navigate(url: url_for('service_worker.html'))
64
wait_for_devtools_target(target_type: 'service_worker')
65
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::NoSuchTargetError, "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.args[0]) }
103
driver.navigate.to url_for('javascriptPage.html')
104
105
driver.execute_script('console.log(true);')
106
driver.execute_script('console.log(null);')
107
driver.execute_script('console.log(undefined);')
108
driver.execute_script('console.log(document);')
109
driver.execute_script("console.log('I like cheese');")
110
111
wait.until { logs.include?('I like cheese') }
112
113
expect(logs).to include(true)
114
expect(logs).to include(nil)
115
expect(logs).to include({'type' => 'undefined'})
116
end
117
118
it 'notifies about document log messages' do
119
logs = []
120
driver.on_log_event(:console) { |log| logs.push(log) }
121
driver.navigate.to url_for('javascriptPage.html')
122
123
driver.execute_script('console.log(document);')
124
wait.until { !logs.empty? }
125
126
expect(logs).to include(
127
an_object_having_attributes(type: :log, args: [hash_including('type' => 'object')])
128
)
129
end
130
131
it 'notifies about exceptions' do
132
exceptions = []
133
driver.on_log_event(:exception) { |exception| exceptions.push(exception) }
134
driver.navigate.to url_for('javascriptPage.html')
135
136
driver.find_element(id: 'throwing-mouseover').click
137
wait.until { exceptions.any? }
138
139
exception = exceptions.first
140
expect(exception.description).to include('Error: I like cheese')
141
expect(exception.stacktrace).not_to be_empty
142
end
143
144
it 'notifies about DOM mutations' do
145
mutations = []
146
driver.on_log_event(:mutation) { |mutation| mutations.push(mutation) }
147
driver.navigate.to url_for('dynamic.html')
148
149
driver.find_element(id: 'reveal').click
150
wait.until { mutations.any? }
151
152
mutation = mutations.first
153
expect(mutation.element).to eq(driver.find_element(id: 'revealed'))
154
expect(mutation.attribute_name).to eq('style')
155
expect(mutation.current_value).to eq('')
156
expect(mutation.old_value).to eq('display:none;')
157
end
158
159
describe '#intercept' do
160
it 'continues requests' do
161
requests = []
162
driver.intercept do |request, &continue|
163
requests << request
164
continue.call(request)
165
end
166
driver.navigate.to url_for('html5Page.html')
167
expect(driver.title).to eq('HTML5')
168
expect(requests).not_to be_empty
169
end
170
171
it 'changes requests' do
172
driver.intercept do |request, &continue|
173
uri = URI(request.url)
174
if uri.path.end_with?('one.js')
175
uri.path = '/devtools_request_interception_test/two.js'
176
request.url = uri.to_s
177
end
178
request.post_data = {foo: 'bar'}.to_json
179
continue.call(request)
180
end
181
driver.navigate.to url_for('devToolsRequestInterceptionTest.html')
182
driver.find_element(tag_name: 'button').click
183
expect(driver.find_element(id: 'result').text).to eq('two')
184
end
185
186
it 'continues responses' do
187
responses = []
188
driver.intercept do |request, &continue|
189
continue.call(request) do |response|
190
responses << response
191
end
192
end
193
driver.navigate.to url_for('html5Page.html')
194
expect(driver.title).to eq('HTML5')
195
expect(responses).not_to be_empty
196
end
197
198
it 'changes responses' do
199
driver.intercept do |request, &continue|
200
continue.call(request) do |response|
201
response.body << '<h4 id="appended">Appended!</h4>' if request.url.include?('html5Page.html')
202
end
203
end
204
driver.navigate.to url_for('html5Page.html')
205
expect(driver.find_elements(id: 'appended')).not_to be_empty
206
end
207
end
208
209
describe '#pin_script', except: {browser: :firefox} do
210
before do
211
driver.navigate.to url_for('xhtmlTest.html')
212
end
213
214
it 'allows to pin script' do
215
script = driver.pin_script('return document.title;')
216
expect(driver.pinned_scripts).to eq([script])
217
expect(driver.execute_script(script)).to eq('XHTML Test Page')
218
end
219
220
it 'ensures pinned script is available on new pages' do
221
script = driver.pin_script('return document.title;')
222
driver.navigate.to url_for('formPage.html')
223
expect(driver.execute_script(script)).to eq('We Leave From Here')
224
end
225
226
it 'allows to unpin script' do
227
script = driver.pin_script('return document.title;')
228
driver.unpin_script(script)
229
expect(driver.pinned_scripts).to be_empty
230
expect { driver.execute_script(script) }.to raise_error(Error::JavascriptError)
231
end
232
233
it 'ensures unpinned scripts are not available on new pages' do
234
script = driver.pin_script('return document.title;')
235
driver.unpin_script(script)
236
driver.navigate.to url_for('formPage.html')
237
expect { driver.execute_script(script) }.to raise_error(Error::JavascriptError)
238
end
239
240
it 'handles arguments in pinned script' do
241
script = driver.pin_script('return arguments;')
242
element = driver.find_element(id: 'id1')
243
expect(driver.execute_script(script, 1, true, element)).to eq([1, true, element])
244
end
245
246
it 'supports async pinned scripts' do
247
script = driver.pin_script('arguments[0]()')
248
expect { driver.execute_async_script(script) }.not_to raise_error
249
end
250
end
251
end
252
end
253
end
254
255