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 }