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

feat: allow handling other targets as pages internally #225

Merged
merged 1 commit into from Jun 28, 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
34 changes: 32 additions & 2 deletions lib/puppeteer/browser.rb
Expand Up @@ -13,14 +13,23 @@ class Puppeteer::Browser
# @param {?Puppeteer.Viewport} defaultViewport
# @param process [Puppeteer::BrowserRunner::BrowserProcess|NilClass]
# @param {function()=} closeCallback
def self.create(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:)
def self.create(connection:,
context_ids:,
ignore_https_errors:,
default_viewport:,
process:,
close_callback:,
target_filter_callback:,
is_page_target_callback:)
browser = Puppeteer::Browser.new(
connection: connection,
context_ids: context_ids,
ignore_https_errors: ignore_https_errors,
default_viewport: default_viewport,
process: process,
close_callback: close_callback,
target_filter_callback: target_filter_callback,
is_page_target_callback: is_page_target_callback,
)
connection.send_message('Target.setDiscoverTargets', discover: true)
browser
Expand All @@ -32,12 +41,21 @@ def self.create(connection:, context_ids:, ignore_https_errors:, default_viewpor
# @param {?Puppeteer.Viewport} defaultViewport
# @param {?Puppeteer.ChildProcess} process
# @param {(function():Promise)=} closeCallback
def initialize(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:)
def initialize(connection:,
context_ids:,
ignore_https_errors:,
default_viewport:,
process:,
close_callback:,
target_filter_callback:,
is_page_target_callback:)
@ignore_https_errors = ignore_https_errors
@default_viewport = default_viewport
@process = process
@connection = connection
@close_callback = close_callback
@target_filter_callback = target_filter_callback || method(:default_target_filter_callback)
@is_page_target_callback = is_page_target_callback || method(:default_is_page_target_callback)

@default_context = Puppeteer::BrowserContext.new(@connection, self, nil)
@contexts = {}
Expand All @@ -54,6 +72,14 @@ def initialize(connection:, context_ids:, ignore_https_errors:, default_viewport
@connection.on_event('Target.targetInfoChanged', &method(:handle_target_info_changed))
end

private def default_target_filter_callback(target_info)
true
end

private def default_is_page_target_callback(target_info)
['page', 'background_page', 'webview'].include?(target_info.type)
end

# @param event_name [Symbol] either of :disconnected, :targetcreated, :targetchanged, :targetdestroyed
def on(event_name, &block)
unless BrowserEmittedEvents.values.include?(event_name.to_s)
Expand Down Expand Up @@ -119,12 +145,16 @@ def handle_target_created(event)
if @targets[target_info.target_id]
raise TargetAlreadyExistError.new
end

return unless @target_filter_callback.call(target_info)

target = Puppeteer::Target.new(
target_info: target_info,
browser_context: context,
session_factory: -> { @connection.create_session(target_info) },
ignore_https_errors: @ignore_https_errors,
default_viewport: @default_viewport,
is_page_target_callback: @is_page_target_callback,
)
@targets[target_info.target_id] = target
if_present(@wait_for_creating_targets.delete(target_info.target_id)) do |promise|
Expand Down
13 changes: 12 additions & 1 deletion lib/puppeteer/launcher/browser_options.rb
Expand Up @@ -31,9 +31,20 @@ def initialize(options)
# `default_viewport: nil` must be respected here.
@default_viewport = options.key?(:default_viewport) ? options[:default_viewport] : Puppeteer::Viewport.new(width: 800, height: 600)
@slow_mo = options[:slow_mo] || 0

# only for Puppeteer.connect
@target_filter = options[:target_filter]
if @target_filter && !@target_filter.respond_to?(:call)
raise ArgumentError.new('target_filter must be a Proc (target_info => true/false)')
end

@is_page_target = options[:is_page_target]
if @is_page_target && !@is_page_target.respond_to?(:call)
raise ArgumentError.new('is_page_target must be a Proc (target_info => true/false)')
end
end

attr_reader :default_viewport, :slow_mo
attr_reader :default_viewport, :slow_mo, :target_filter, :is_page_target

def ignore_https_errors?
@ignore_https_errors
Expand Down
4 changes: 4 additions & 0 deletions lib/puppeteer/launcher/chrome.rb
Expand Up @@ -87,6 +87,8 @@ def launch(options = {})
default_viewport: @browser_options.default_viewport,
process: runner.proc,
close_callback: -> { runner.close },
target_filter_callback: nil,
is_page_target_callback: nil,
)
rescue
runner.kill
Expand Down Expand Up @@ -205,6 +207,8 @@ def connect(options = {})
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

Expand Down
4 changes: 4 additions & 0 deletions lib/puppeteer/launcher/firefox.rb
Expand Up @@ -85,6 +85,8 @@ def launch(options = {})
default_viewport: @browser_options.default_viewport,
process: runner.proc,
close_callback: -> { runner.close },
target_filter_callback: nil,
is_page_target_callback: nil,
)
rescue
runner.kill
Expand Down Expand Up @@ -132,6 +134,8 @@ def connect(options = {})
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

Expand Down
15 changes: 10 additions & 5 deletions lib/puppeteer/target.rb
Expand Up @@ -18,14 +18,19 @@ def initialize(options)
# @param {!function():!Promise<!Puppeteer.CDPSession>} sessionFactory
# @param {boolean} ignoreHTTPSErrors
# @param {?Puppeteer.Viewport} defaultViewport
def initialize(target_info:, browser_context:, session_factory:, ignore_https_errors:, default_viewport:)
def initialize(target_info:,
browser_context:,
session_factory:,
ignore_https_errors:,
default_viewport:,
is_page_target_callback:)
@target_info = target_info
@browser_context = browser_context
@target_id = target_info.target_id
@session_factory = session_factory
@ignore_https_errors = ignore_https_errors
@default_viewport = default_viewport

@is_page_target_callback = is_page_target_callback

# /** @type {?Promise<!Puppeteer.Page>} */
# this._pagePromise = null;
Expand All @@ -37,7 +42,7 @@ def initialize(target_info:, browser_context:, session_factory:, ignore_https_er
end
@is_closed_promise = resolvable_future

@is_initialized = @target_info.type != 'page' || !@target_info.url.empty?
@is_initialized = !@is_page_target_callback.call(@target_info) || !@target_info.url.empty?

if @is_initialized
@initialize_callback_promise.fulfill(true)
Expand Down Expand Up @@ -83,7 +88,7 @@ def create_cdp_session
end

def page
if ['page', 'background_page', 'webview'].include?(@target_info.type) && @page.nil?
if @is_page_target_callback.call(@target_info) && @page.nil?
client = @session_factory.call
@page = Puppeteer::Page.create(client, self, @ignore_https_errors, @default_viewport)
end
Expand Down Expand Up @@ -145,7 +150,7 @@ def opener
def handle_target_info_changed(target_info)
@target_info = target_info

if !@is_initialized && (@target_info.type != 'page' || !@target_info.url.empty?)
if !@is_initialized && (!@is_page_target_callback.call(@target_info) || !@target_info.url.empty?)
@is_initialized = true
@initialize_callback_promise.fulfill(true)
end
Expand Down