Path: blob/trunk/rb/spec/integration/selenium/webdriver/devtools_spec.rb
1864 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 'propagates errors in events' do48expect {49driver.devtools.page.enable50driver.devtools.page.on(:load_event_fired) { raise 'This is fine!' }51driver.navigate.to url_for('xhtmlTest.html')52sleep 0.553}.to raise_error(RuntimeError, 'This is fine!')54end5556describe '#target' do57it 'target type defaults to page' do58driver.devtools.page.navigate(url: url_for('xhtmlTest.html'))59expect(driver.devtools.target.get_target_info.dig('result', 'targetInfo', 'type')).to eq 'page'60end6162it 'target type is service_worker' do63driver.devtools.page.navigate(url: url_for('service_worker.html'))64sleep 0.5 # wait for service worker to register65target = 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::WebDriverError, "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) }102driver.navigate.to url_for('javascriptPage.html')103104driver.execute_script("console.log('I like cheese');")105sleep 0.5106driver.execute_script('console.log(true);')107sleep 0.5108driver.execute_script('console.log(null);')109sleep 0.5110driver.execute_script('console.log(undefined);')111sleep 0.5112driver.execute_script('console.log(document);')113sleep 0.5114115expect(logs).to include(116an_object_having_attributes(type: :log, args: ['I like cheese']),117an_object_having_attributes(type: :log, args: [true]),118an_object_having_attributes(type: :log, args: [nil]),119an_object_having_attributes(type: :log, args: [{'type' => 'undefined'}])120)121end122123it 'notifies about document log messages' do124logs = []125driver.on_log_event(:console) { |log| logs.push(log) }126driver.navigate.to url_for('javascriptPage.html')127128driver.execute_script('console.log(document);')129wait.until { !logs.empty? }130131expect(logs).to include(132an_object_having_attributes(type: :log, args: [hash_including('type' => 'object')])133)134end135136it 'notifies about exceptions' do137exceptions = []138driver.on_log_event(:exception) { |exception| exceptions.push(exception) }139driver.navigate.to url_for('javascriptPage.html')140141driver.find_element(id: 'throwing-mouseover').click142wait.until { exceptions.any? }143144exception = exceptions.first145expect(exception.description).to include('Error: I like cheese')146expect(exception.stacktrace).not_to be_empty147end148149it 'notifies about DOM mutations' do150mutations = []151driver.on_log_event(:mutation) { |mutation| mutations.push(mutation) }152driver.navigate.to url_for('dynamic.html')153154driver.find_element(id: 'reveal').click155wait.until { mutations.any? }156157mutation = mutations.first158expect(mutation.element).to eq(driver.find_element(id: 'revealed'))159expect(mutation.attribute_name).to eq('style')160expect(mutation.current_value).to eq('')161expect(mutation.old_value).to eq('display:none;')162end163164describe '#intercept' do165it 'continues requests' do166requests = []167driver.intercept do |request, &continue|168requests << request169continue.call(request)170end171driver.navigate.to url_for('html5Page.html')172expect(driver.title).to eq('HTML5')173expect(requests).not_to be_empty174end175176it 'changes requests' do177driver.intercept do |request, &continue|178uri = URI(request.url)179if uri.path.end_with?('one.js')180uri.path = '/devtools_request_interception_test/two.js'181request.url = uri.to_s182end183request.post_data = {foo: 'bar'}.to_json184continue.call(request)185end186driver.navigate.to url_for('devToolsRequestInterceptionTest.html')187driver.find_element(tag_name: 'button').click188expect(driver.find_element(id: 'result').text).to eq('two')189end190191it 'continues responses' do192responses = []193driver.intercept do |request, &continue|194continue.call(request) do |response|195responses << response196end197end198driver.navigate.to url_for('html5Page.html')199expect(driver.title).to eq('HTML5')200expect(responses).not_to be_empty201end202203it 'changes responses' do204driver.intercept do |request, &continue|205continue.call(request) do |response|206response.body << '<h4 id="appended">Appended!</h4>' if request.url.include?('html5Page.html')207end208end209driver.navigate.to url_for('html5Page.html')210expect(driver.find_elements(id: 'appended')).not_to be_empty211end212end213214describe '#pin_script', except: {browser: :firefox} do215before do216driver.navigate.to url_for('xhtmlTest.html')217end218219it 'allows to pin script' do220script = driver.pin_script('return document.title;')221expect(driver.pinned_scripts).to eq([script])222expect(driver.execute_script(script)).to eq('XHTML Test Page')223end224225it 'ensures pinned script is available on new pages' do226script = driver.pin_script('return document.title;')227driver.navigate.to url_for('formPage.html')228expect(driver.execute_script(script)).to eq('We Leave From Here')229end230231it 'allows to unpin script' do232script = driver.pin_script('return document.title;')233driver.unpin_script(script)234expect(driver.pinned_scripts).to be_empty235expect { driver.execute_script(script) }.to raise_error(Error::JavascriptError)236end237238it 'ensures unpinned scripts are not available on new pages' do239script = driver.pin_script('return document.title;')240driver.unpin_script(script)241driver.navigate.to url_for('formPage.html')242expect { driver.execute_script(script) }.to raise_error(Error::JavascriptError)243end244245it 'handles arguments in pinned script' do246script = driver.pin_script('return arguments;')247element = driver.find_element(id: 'id1')248expect(driver.execute_script(script, 1, true, element)).to eq([1, true, element])249end250251it 'supports async pinned scripts' do252script = driver.pin_script('arguments[0]()')253expect { driver.execute_async_script(script) }.not_to raise_error254end255end256end257end258end259260261