Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce BrowserConnector #252

Merged
merged 2 commits into from Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/puppeteer.rb
Expand Up @@ -22,6 +22,7 @@ module Puppeteer; end
require 'puppeteer/browser'
require 'puppeteer/browser_context'
require 'puppeteer/browser_runner'
require 'puppeteer/browser_connector'
require 'puppeteer/cdp_session'
require 'puppeteer/chrome_target_manager'
require 'puppeteer/connection'
Expand Down
12 changes: 6 additions & 6 deletions lib/puppeteer/browser.rb
Expand Up @@ -326,12 +326,12 @@ def pages

# @return [String]
def version
get_version.product
Version.fetch(@connection).product
end

# @return [String]
def user_agent
get_version.user_agent
Version.fetch(@connection).user_agent
end

def close
Expand All @@ -349,6 +349,10 @@ def connected?
end

class Version
def self.fetch(connection)
new(connection.send_message('Browser.getVersion'))
end

def initialize(hash)
@protocol_version = hash['protocolVersion']
@product = hash['product']
Expand All @@ -359,8 +363,4 @@ def initialize(hash)

attr_reader :protocol_version, :product, :revision, :user_agent, :js_version
end

private def get_version
Version.new(@connection.send_message('Browser.getVersion'))
end
end
67 changes: 67 additions & 0 deletions lib/puppeteer/browser_connector.rb
@@ -0,0 +1,67 @@
require_relative './browser'
require_relative './launcher/browser_options'

class Puppeteer::BrowserConnector
def initialize(options)
@browser_options = Puppeteer::Launcher::BrowserOptions.new(options)
@browser_ws_endpoint = options[:browser_ws_endpoint]
@browser_url = options[:browser_url]
@transport = options[:transport]
end

# @return [Puppeteer::Browser]
def connect_to_browser
version = Puppeteer::Browser::Version.fetch(connection)
product = version.product.downcase.include?('firefox') ? 'firefox' : 'chrome'

result = connection.send_message('Target.getBrowserContexts')
browser_context_ids = result['browserContextIds']

Puppeteer::Browser.create(
product: product,
connection: connection,
context_ids: browser_context_ids,
ignore_https_errors: @browser_options.ignore_https_errors?,
default_viewport: @browser_options.default_viewport,
process: nil,
close_callback: -> { connection.send_message('Browser.close') },
target_filter_callback: @browser_options.target_filter,
is_page_target_callback: @browser_options.is_page_target,
)
end

private def connection
@connection ||=
if @browser_ws_endpoint && @browser_url.nil? && @transport.nil?
connect_with_browser_ws_endpoint(@browser_ws_endpoint)
elsif @browser_ws_endpoint.nil? && @browser_url && @transport.nil?
connect_with_browser_url(@browser_url)
elsif @browser_ws_endpoint.nil? && @browser_url.nil? && @transport
connect_with_transport(@transport)
else
raise ArgumentError.new("Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect")
end
end

# @return [Puppeteer::Connection]
private def connect_with_browser_ws_endpoint(browser_ws_endpoint)
transport = Puppeteer::WebSocketTransport.create(browser_ws_endpoint)
Puppeteer::Connection.new(browser_ws_endpoint, transport, @browser_options.slow_mo)
end

# @return [Puppeteer::Connection]
private def connect_with_browser_url(browser_url)
require 'net/http'
uri = URI(browser_url)
uri.path = '/json/version'
response_body = Net::HTTP.get(uri)
json = JSON.parse(response_body)
connection_url = json['webSocketDebuggerUrl']
connect_with_browser_ws_endpoint(connection_url)
end

# @return [Puppeteer::Connection]
private def connect_with_transport(transport)
Puppeteer::Connection.new('', transport, @browser_options.slow_mo)
end
end
56 changes: 0 additions & 56 deletions lib/puppeteer/launcher/chrome.rb
Expand Up @@ -182,62 +182,6 @@ def default_args(options = nil)
DefaultArgs.new(ChromeArgOptions.new(options || {}))
end

# @return [Puppeteer::Browser]
def connect(options = {})
@browser_options = BrowserOptions.new(options)
browser_ws_endpoint = options[:browser_ws_endpoint]
browser_url = options[:browser_url]
transport = options[:transport]

connection =
if browser_ws_endpoint && browser_url.nil? && transport.nil?
connect_with_browser_ws_endpoint(browser_ws_endpoint)
elsif browser_ws_endpoint.nil? && browser_url && transport.nil?
connect_with_browser_url(browser_url)
elsif browser_ws_endpoint.nil? && browser_url.nil? && transport
connect_with_transport(transport)
else
raise ArgumentError.new("Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect")
end

result = connection.send_message('Target.getBrowserContexts')
browser_context_ids = result['browserContextIds']

Puppeteer::Browser.create(
product: product,
connection: connection,
context_ids: browser_context_ids,
ignore_https_errors: @browser_options.ignore_https_errors?,
default_viewport: @browser_options.default_viewport,
process: nil,
close_callback: -> { connection.send_message('Browser.close') },
target_filter_callback: @browser_options.target_filter,
is_page_target_callback: @browser_options.is_page_target,
).tap(&:pages)
end

# @return [Puppeteer::Connection]
private def connect_with_browser_ws_endpoint(browser_ws_endpoint)
transport = Puppeteer::WebSocketTransport.create(browser_ws_endpoint)
Puppeteer::Connection.new(browser_ws_endpoint, transport, @browser_options.slow_mo)
end

# @return [Puppeteer::Connection]
private def connect_with_browser_url(browser_url)
require 'net/http'
uri = URI(browser_url)
uri.path = '/json/version'
response_body = Net::HTTP.get(uri)
json = JSON.parse(response_body)
connection_url = json['webSocketDebuggerUrl']
connect_with_browser_ws_endpoint(connection_url)
end

# @return [Puppeteer::Connection]
private def connect_with_transport(transport)
Puppeteer::Connection.new('', transport, @browser_options.slow_mo)
end

# @return {string}
def executable_path(channel: nil)
if channel
Expand Down
56 changes: 0 additions & 56 deletions lib/puppeteer/launcher/firefox.rb
Expand Up @@ -107,62 +107,6 @@ def launch(options = {})
browser
end

# @return [Puppeteer::Browser]
def connect(options = {})
@browser_options = BrowserOptions.new(options)
browser_ws_endpoint = options[:browser_ws_endpoint]
browser_url = options[:browser_url]
transport = options[:transport]

connection =
if browser_ws_endpoint && browser_url.nil? && transport.nil?
connect_with_browser_ws_endpoint(browser_ws_endpoint)
elsif browser_ws_endpoint.nil? && browser_url && transport.nil?
connect_with_browser_url(browser_url)
elsif browser_ws_endpoint.nil? && browser_url.nil? && transport
connect_with_transport(transport)
else
raise ArgumentError.new("Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect")
end

result = connection.send_message('Target.getBrowserContexts')
browser_context_ids = result['browserContextIds']

Puppeteer::Browser.create(
product: product,
connection: connection,
context_ids: browser_context_ids,
ignore_https_errors: @browser_options.ignore_https_errors?,
default_viewport: @browser_options.default_viewport,
process: nil,
close_callback: -> { connection.send_message('Browser.close') },
target_filter_callback: nil,
is_page_target_callback: nil,
)
end

# @return [Puppeteer::Connection]
private def connect_with_browser_ws_endpoint(browser_ws_endpoint)
transport = Puppeteer::WebSocketTransport.create(browser_ws_endpoint)
Puppeteer::Connection.new(browser_ws_endpoint, transport, @browser_options.slow_mo)
end

# @return [Puppeteer::Connection]
private def connect_with_browser_url(browser_url)
require 'net/http'
uri = URI(browser_url)
uri.path = '/json/version'
response_body = Net::HTTP.get(uri)
json = JSON.parse(response_body)
connection_url = json['webSocketDebuggerUrl']
connect_with_browser_ws_endpoint(connection_url)
end

# @return [Puppeteer::Connection]
private def connect_with_transport(transport)
Puppeteer::Connection.new('', transport, @browser_options.slow_mo)
end

# @return {string}
def executable_path(channel: nil)
if channel
Expand Down
2 changes: 1 addition & 1 deletion lib/puppeteer/puppeteer.rb
Expand Up @@ -110,7 +110,7 @@ def connect(
default_viewport: default_viewport,
slow_mo: slow_mo,
}.compact
browser = launcher.connect(options)
browser = Puppeteer::BrowserConnector.new(options).connect_to_browser
if block_given?
begin
yield(browser)
Expand Down