Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
window (browserless). That window lives in the browser's implicit context, which Chrome below 145
won't address by id. Ferrum now detects it and exposes as `Ferrum::Context#implicit?`. It's never
disposed, so `#reset` won't clear such a browser. [#578] [#627]
- `Browser.setDownloadBehavior` raised `Failed to find browser context for id` for a page in the browser's implicit
context, so connecting to a browser that came up with its own startup window and passing `:save_path` died on the
first page. `Ferrum::Target#context_id`, and with it `Ferrum::Page#context_id`, is now `nil` for that context,
which is how Chrome wants it addressed, by omitting `browserContextId` [#546]
- Connecting to a remote browser with `:url` drops query string when probing `/json/version`, endpoint might answer
401 and Ferrum died with `undefined method 'host' for nil`. in case of parse issues `Ferrum::NoWebSocketUrlError` is raised.
- Targets of a type `Ferrum::Contexts` doesn't track were left attached and paused by auto-attach for the lifetime
Expand Down
2 changes: 1 addition & 1 deletion lib/ferrum/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def create_target
#
# @return [Target]
def add_target(params:, session_id: nil)
new_target = Target.new(@client, session_id, params)
new_target = Target.new(@client, session_id, params, implicit: implicit?)
# `put_if_absent` returns nil if added a new value or existing if there was one already
target = @targets.put_if_absent(new_target.id, new_target) || new_target
# on first iteration session_id may be nil, then if session is present here we must set it to the target
Expand Down
3 changes: 2 additions & 1 deletion lib/ferrum/downloads.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ def set_behavior(save_path:, behavior: :allow)
raise ArgumentError unless VALID_BEHAVIOR.include?(behavior.to_sym)
raise Error, "supply absolute path for `:save_path` option" unless Pathname.new(save_path.to_s).absolute?

options = { browserContextId: @page.context_id } if @page.context_id
@page.command("Browser.setDownloadBehavior",
browserContextId: @page.context_id,
**Hash(options),
downloadPath: save_path,
behavior: behavior,
eventsEnabled: true)
Expand Down
10 changes: 7 additions & 3 deletions lib/ferrum/target.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ class Target
attr_reader :options
attr_accessor :session_id

def initialize(browser_client, session_id = nil, params = nil)
def initialize(browser_client, session_id = nil, params = nil, implicit: false)
@page = nil
@worker = nil
@session_id = session_id
@params = params
@implicit = implicit
@browser_client = browser_client
@options = browser_client.options
end
Expand Down Expand Up @@ -137,11 +138,14 @@ def parent_id
@params["parentId"]
end

# The id of the browser context this target belongs to.
# The id of the browser context this target belongs to, `nil` for the
# browser's implicit context, which Chrome doesn't let us address by id,
# see {Context#implicit?}. Commands scoped to a browser context target it
# by omitting `browserContextId`.
#
# @return [String, nil]
def context_id
@params["browserContextId"]
@params["browserContextId"] unless @implicit
end

# Whether this target is a window/tab, i.e. was opened via
Expand Down
6 changes: 3 additions & 3 deletions sig/ferrum/page.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module Ferrum
include Interceptable

attr_accessor referrer: String?
attr_reader context_id: String
attr_reader context_id: String?
attr_reader target_id: String
attr_reader event: Utils::Event
attr_reader tracing: Page::Tracing
Expand All @@ -26,7 +26,7 @@ module Ferrum
attr_reader client: (Client | SessionClient)

@client: (Client | SessionClient)
@context_id: String
@context_id: String?
@target_id: String
@options: Browser::Options
@frames: ::Concurrent::Map[String, Frame]
Expand All @@ -41,7 +41,7 @@ module Ferrum
@downloads: Downloads
@referrer: String?

def initialize: ((Client | SessionClient) client, context_id: String, target_id: String, ?proxy: { host: String, port: ::Integer, user: String?, password: String? }?) -> void
def initialize: ((Client | SessionClient) client, context_id: String?, target_id: String, ?proxy: { host: String, port: ::Integer, user: String?, password: String? }?) -> void

def context: () -> Context?

Expand Down
3 changes: 2 additions & 1 deletion sig/ferrum/target.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ module Ferrum
@worker: Worker?
@session_id: String?
@params: Hash[String, untyped]
@implicit: bool
@browser_client: Client
@options: Browser::Options
@client: (Client | SessionClient)?

def initialize: (Client browser_client, ?String? session_id, ?Hash[String, untyped]? params) -> void
def initialize: (Client browser_client, ?String? session_id, ?Hash[String, untyped]? params, ?implicit: bool) -> void

def update: (Hash[String, untyped] params) -> Hash[String, untyped]

Expand Down
18 changes: 18 additions & 0 deletions spec/downloads_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,24 @@
end
end

context "with the browser's implicit context" do
it "saves an attachment" do
with_external_browser(incognito: false) do |url|
remote = Ferrum::Browser.new(url: url, base_url: base_url, save_path: save_path)
remote_page = remote.create_page

expect(remote_page.context_id).to be_nil

remote_page.downloads.wait { remote_page.go_to("/#{filename}") }

expect(File.exist?("#{save_path}/#{filename}")).to be true
ensure
remote&.quit
FileUtils.rm_rf(save_path)
end
end
end

context "with local path" do
let(:save_path) { "spec/tmp" }

Expand Down
Loading