diff --git a/common/src/web/service-worker.js b/common/src/web/service-worker.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/common/src/web/service_worker.html b/common/src/web/service_worker.html new file mode 100644 index 0000000000000..1c3ade954ea27 --- /dev/null +++ b/common/src/web/service_worker.html @@ -0,0 +1,16 @@ + + + + Service Worker Test Page + + + +

This page loads a service worker

+ + diff --git a/rb/lib/selenium/webdriver/common/driver.rb b/rb/lib/selenium/webdriver/common/driver.rb index 9fe9b43444832..0d4944e326a8d 100644 --- a/rb/lib/selenium/webdriver/common/driver.rb +++ b/rb/lib/selenium/webdriver/common/driver.rb @@ -188,7 +188,7 @@ def quit bridge.quit ensure @service_manager&.stop - @devtools&.close + @devtools&.each_value(&:close) end # diff --git a/rb/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb b/rb/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb index 29aab394dfa6a..74fc6e80f6759 100644 --- a/rb/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +++ b/rb/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb @@ -27,12 +27,13 @@ module HasDevTools # @return [DevTools] # - def devtools - @devtools ||= begin + def devtools(target_type: 'page') + @devtools ||= {} + @devtools[target_type] ||= begin require 'selenium/devtools' Selenium::DevTools.version ||= devtools_version Selenium::DevTools.load_version - Selenium::WebDriver::DevTools.new(url: devtools_url) + Selenium::WebDriver::DevTools.new(url: devtools_url, target_type: target_type) end end end # HasDevTools diff --git a/rb/lib/selenium/webdriver/devtools.rb b/rb/lib/selenium/webdriver/devtools.rb index 4e1f321844163..fdc1a194ceee9 100644 --- a/rb/lib/selenium/webdriver/devtools.rb +++ b/rb/lib/selenium/webdriver/devtools.rb @@ -28,10 +28,10 @@ class DevTools autoload :Request, 'selenium/webdriver/devtools/request' autoload :Response, 'selenium/webdriver/devtools/response' - def initialize(url:) + def initialize(url:, target_type:) @ws = WebSocketConnection.new(url: url) @session_id = nil - start_session + start_session(target_type: target_type) end def close @@ -81,10 +81,12 @@ def respond_to_missing?(method, *_args) private - def start_session + def start_session(target_type:) targets = target.get_targets.dig('result', 'targetInfos') - page_target = targets.find { |target| target['type'] == 'page' } - session = target.attach_to_target(target_id: page_target['targetId'], flatten: true) + found_target = targets.find { |target| target['type'] == target_type } + raise Error::WebDriverError, "Target type '#{target_type}' not found" unless found_target + + session = target.attach_to_target(target_id: found_target['targetId'], flatten: true) @session_id = session.dig('result', 'sessionId') end diff --git a/rb/spec/integration/selenium/webdriver/devtools_spec.rb b/rb/spec/integration/selenium/webdriver/devtools_spec.rb index bf0245a538639..4506ecbbed5a1 100644 --- a/rb/spec/integration/selenium/webdriver/devtools_spec.rb +++ b/rb/spec/integration/selenium/webdriver/devtools_spec.rb @@ -54,6 +54,26 @@ module WebDriver }.to raise_error(RuntimeError, 'This is fine!') end + describe '#target' do + it 'target type defaults to page' do + driver.devtools.page.navigate(url: url_for('xhtmlTest.html')) + expect(driver.devtools.target.get_target_info.dig('result', 'targetInfo', 'type')).to eq 'page' + end + + it 'target type is service_worker' do + driver.devtools.page.navigate(url: url_for('service_worker.html')) + sleep 0.5 # wait for service worker to register + target = driver.devtools(target_type: 'service_worker').target + expect(target.get_target_info.dig('result', 'targetInfo', 'type')).to eq 'service_worker' + end + + it 'throws an error for unknown target type' do + driver.devtools.page.navigate(url: url_for('xhtmlTest.html')) + expect { driver.devtools(target_type: 'unknown') } + .to raise_error(Selenium::WebDriver::Error::WebDriverError, "Target type 'unknown' not found") + end + end + describe '#register' do let(:username) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.first } let(:password) { SpecSupport::RackServer::TestApp::BASIC_AUTH_CREDENTIALS.last }