Path: blob/trunk/rb/spec/integration/selenium/webdriver/devtools_spec.rb
3983 views
# frozen_string_literal: true12# Licensed to the Software Freedom Conservancy (SFC) under one3# or more contributor license agreements. See the NOTICE file4# distributed with this work for additional information5# regarding copyright ownership. The SFC licenses this file6# to you under the Apache License, Version 2.0 (the7# "License"); you may not use this file except in compliance8# with the License. You may obtain a copy of the License at9#10# http://www.apache.org/licenses/LICENSE-2.011#12# Unless required by applicable law or agreed to in writing,13# software distributed under the License is distributed on an14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY15# KIND, either express or implied. See the License for the16# specific language governing permissions and limitations17# under the License.1819require_relative 'spec_helper'2021module Selenium22module WebDriver23describe DevTools, exclusive: [{bidi: false, reason: 'Not yet implemented with BiDi'},24{browser: %i[chrome edge]}] do25after { |example| reset_driver!(example: example) }2627it 'sends commands' do28driver.devtools.page.navigate(url: url_for('xhtmlTest.html'))29expect(driver.title).to eq('XHTML Test Page')30end3132it 'maps methods to classes' do33expect(driver.devtools.css).not_to be_nil34expect(driver.devtools.dom).not_to be_nil35expect(driver.devtools.dom_debugger).not_to be_nil36end3738it 'supports events' do39expect { |block|40driver.devtools.page.enable41driver.devtools.page.on(:load_event_fired, &block)42driver.navigate.to url_for('xhtmlTest.html')43sleep 0.544}.to yield_control45end4647it 'logs errors in events' do48driver.devtools.page.enable49driver.devtools.page.on(:load_event_fired) { raise 'This is fine!' }50expect {51driver.navigate.to url_for('xhtmlTest.html')52}.to have_error(:ws, /This is fine!/)53end5455describe '#target' do56it 'target type defaults to page' do57driver.devtools.page.navigate(url: url_for('xhtmlTest.html'))58expect(driver.devtools.target.get_target_info.dig('result', 'targetInfo', 'type')).to eq 'page'59end6061it 'target type is service_worker' do62driver.devtools.page.navigate(url: url_for('service_worker.html'))63wait_for_devtools_target(target_type: 'service_worker')6465target = driver.devtools(target_type: 'service_worker').target66expect(target.get_target_info.dig('result', 'targetInfo', 'type')).to eq 'service_worker'67end6869it 'throws an error for unknown target type' do70driver.devtools.page.navigate(url: url_for('xhtmlTest.html'))71expect { driver.devtools(target_type: 'unknown') }72.to raise_error(Selenium::WebDriver::Error::NoSuchTargetError, "Target type 'unknown' not found")73end74end7576describe '#register' do77let(:username) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.first }78let(:password) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.last }7980it 'on any request' do81driver.register(username: username, password: password)8283driver.navigate.to url_for('basicAuth')84expect(driver.find_element(tag_name: 'h1').text).to eq('authorized')85end8687it 'based on URL' do88auth_url = url_for('basicAuth')89driver.register(username: username, password: password, uri: /localhost/)9091driver.navigate.to auth_url.sub('localhost', '127.0.0.1')92expect { driver.find_element(tag_name: 'h1') }.to raise_error(Error::NoSuchElementError)9394driver.navigate.to auth_url95expect(driver.find_element(tag_name: 'h1').text).to eq('authorized')96end97end9899it 'notifies about log messages' do100logs = []101driver.on_log_event(:console) { |log| logs.push(log.args[0]) }102driver.navigate.to url_for('javascriptPage.html')103104driver.execute_script('console.log(true);')105driver.execute_script('console.log(null);')106driver.execute_script('console.log(undefined);')107driver.execute_script('console.log(document);')108driver.execute_script("console.log('I like cheese');")109110wait.until { logs.include?('I like cheese') }111112expect(logs).to include(true)113expect(logs).to include(nil)114expect(logs).to include({'type' => 'undefined'})115end116117it 'notifies about document log messages' do118logs = []119driver.on_log_event(:console) { |log| logs.push(log) }120driver.navigate.to url_for('javascriptPage.html')121122driver.execute_script('console.log(document);')123wait.until { !logs.empty? }124125expect(logs).to include(126an_object_having_attributes(type: :log, args: [hash_including('type' => 'object')])127)128end129130it 'notifies about exceptions' do131exceptions = []132driver.on_log_event(:exception) { |exception| exceptions.push(exception) }133driver.navigate.to url_for('javascriptPage.html')134135driver.find_element(id: 'throwing-mouseover').click136wait.until { exceptions.any? }137138exception = exceptions.first139expect(exception.description).to include('Error: I like cheese')140expect(exception.stacktrace).not_to be_empty141end142143it 'notifies about DOM mutations' do144mutations = []145driver.on_log_event(:mutation) { |mutation| mutations.push(mutation) }146driver.navigate.to url_for('dynamic.html')147148driver.find_element(id: 'reveal').click149wait.until { mutations.any? }150151mutation = mutations.first152expect(mutation.element).to eq(driver.find_element(id: 'revealed'))153expect(mutation.attribute_name).to eq('style')154expect(mutation.current_value).to eq('')155expect(mutation.old_value).to eq('display:none;')156end157158describe '#intercept' do159it 'continues requests' do160requests = []161driver.intercept do |request, &continue|162requests << request163continue.call(request)164end165driver.navigate.to url_for('html5Page.html')166expect(driver.title).to eq('HTML5')167expect(requests).not_to be_empty168end169170it 'changes requests' do171driver.intercept do |request, &continue|172uri = URI(request.url)173if uri.path.end_with?('one.js')174uri.path = '/devtools_request_interception_test/two.js'175request.url = uri.to_s176end177request.post_data = {foo: 'bar'}.to_json178continue.call(request)179end180driver.navigate.to url_for('devToolsRequestInterceptionTest.html')181driver.find_element(tag_name: 'button').click182expect(driver.find_element(id: 'result').text).to eq('two')183end184185it 'continues responses' do186responses = []187driver.intercept do |request, &continue|188continue.call(request) do |response|189responses << response190end191end192driver.navigate.to url_for('html5Page.html')193expect(driver.title).to eq('HTML5')194expect(responses).not_to be_empty195end196197it 'changes responses' do198driver.intercept do |request, &continue|199continue.call(request) do |response|200response.body << '<h4 id="appended">Appended!</h4>' if request.url.include?('html5Page.html')201end202end203driver.navigate.to url_for('html5Page.html')204expect(driver.find_elements(id: 'appended')).not_to be_empty205end206end207208describe '#pin_script', except: {browser: :firefox} do209before do210driver.navigate.to url_for('xhtmlTest.html')211end212213it 'allows to pin script' do214script = driver.pin_script('return document.title;')215expect(driver.pinned_scripts).to eq([script])216expect(driver.execute_script(script)).to eq('XHTML Test Page')217end218219it 'ensures pinned script is available on new pages' do220script = driver.pin_script('return document.title;')221driver.navigate.to url_for('formPage.html')222expect(driver.execute_script(script)).to eq('We Leave From Here')223end224225it 'allows to unpin script' do226script = driver.pin_script('return document.title;')227driver.unpin_script(script)228expect(driver.pinned_scripts).to be_empty229expect { driver.execute_script(script) }.to raise_error(Error::JavascriptError)230end231232it 'ensures unpinned scripts are not available on new pages' do233script = driver.pin_script('return document.title;')234driver.unpin_script(script)235driver.navigate.to url_for('formPage.html')236expect { driver.execute_script(script) }.to raise_error(Error::JavascriptError)237end238239it 'handles arguments in pinned script' do240script = driver.pin_script('return arguments;')241element = driver.find_element(id: 'id1')242expect(driver.execute_script(script, 1, true, element)).to eq([1, true, element])243end244245it 'supports async pinned scripts' do246script = driver.pin_script('arguments[0]()')247expect { driver.execute_async_script(script) }.not_to raise_error248end249end250end251end252end253254255