Skip to content

Commit 56a46cd

Browse files
authored
fix: browser.reset tries to dispose default implicit context #540 (#566)
Old Chrome doesn't even show implicit context. `Target.getBrowserContexts` returns `{"browserContextIds":[]}` `Target.setAutoAttach` doesn't send any `Target.attachedToTarget` events nor does `Target.setDiscoverTargets`. This context is not even registered in Ferrum. More recent Chrome < 145 still returns empty {"browserContextIds":[]} but starts to show target and context in `Target.attachedToTarget` and `Target.targetCreated`. Chrome >= 145 returns defaultBrowserContextId `{"browserContextIds":[],"defaultBrowserContextId":"7354CC1034D553EE803954E18CDEB447"}` and shows target and context as above. --no-startup-window flag tells Chrome not to open any browser window on startup thus affecting implicit context in a more recent Chrome. When flag is passed we create our own default context, and thus can dispose it. When flag is not passed we use implicit context and thus cannot dispose it.
1 parent 0c4d14b commit 56a46cd

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

lib/ferrum/contexts.rb

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def create(**options)
4848

4949
def dispose(context_id)
5050
context = @contexts[context_id]
51+
return unless context
52+
5153
context.close_targets_connection
5254
@client.command("Target.disposeBrowserContext", browserContextId: context.id)
5355
@contexts.delete(context_id)
@@ -59,8 +61,9 @@ def close_connections
5961
end
6062

6163
def reset
62-
@default_context = nil
63-
@contexts.each_key { |id| dispose(id) }
64+
context_ids = @client.command("Target.getBrowserContexts")["browserContextIds"]
65+
@default_context = nil if context_ids.include?(@default_context&.id)
66+
@contexts.each_key { |id| dispose(id) if context_ids.include?(id) }
6467
end
6568

6669
def size
@@ -69,18 +72,13 @@ def size
6972

7073
private
7174

72-
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
73-
def subscribe
75+
def subscribe # rubocop:disable Metrics/PerceivedComplexity
7476
@client.on("Target.attachedToTarget") do |params|
7577
info, session_id = params.values_at("targetInfo", "sessionId")
7678
next unless ALLOWED_TARGET_TYPES.include?(info["type"])
7779

7880
context_id = info["browserContextId"]
79-
unless @contexts[context_id]
80-
context = Context.new(@client, self, context_id)
81-
@contexts[context_id] = context
82-
@default_context ||= context
83-
end
81+
add_context(context_id)
8482

8583
@contexts[context_id]&.add_target(session_id: session_id, params: info)
8684
if params["waitingForDebugger"]
@@ -93,6 +91,7 @@ def subscribe
9391
next unless ALLOWED_TARGET_TYPES.include?(info["type"])
9492

9593
context_id = info["browserContextId"]
94+
add_context(context_id)
9695

9796
if info["type"] == "iframe" &&
9897
(target = @contexts[context_id].find_target { |t| t.connected? && t.page.frame_by(id: info["targetId"]) })
@@ -120,16 +119,21 @@ def subscribe
120119
context&.delete_target(params["targetId"])
121120
end
122121
end
123-
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
124122

125123
def discover
126124
@client.command("Target.setDiscoverTargets", discover: true)
127125
end
128126

129127
def auto_attach
130-
return unless @client.options.flatten
131-
132128
@client.command("Target.setAutoAttach", autoAttach: true, waitForDebuggerOnStart: true, flatten: true)
133129
end
130+
131+
def add_context(context_id)
132+
return if @contexts[context_id]
133+
134+
context = Context.new(@client, self, context_id)
135+
@contexts[context_id] = context
136+
@default_context ||= context # rubocop:disable Naming/MemoizedInstanceVariableName
137+
end
134138
end
135139
end

0 commit comments

Comments
 (0)