Skip to content

Commit

Permalink
Fix setting execution context
Browse files Browse the repository at this point in the history
  • Loading branch information
route committed Dec 4, 2018
1 parent 79b2540 commit 37d5a68
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .rspec
@@ -0,0 +1,2 @@
--color
--format=doc
35 changes: 30 additions & 5 deletions lib/capybara/cuprite/browser/page.rb
Expand Up @@ -25,14 +25,16 @@ class Browser
class Page
extend Forwardable

delegate [:command, :wait, :subscribe] => :@client
delegate [:wait, :subscribe] => :@client
delegate targets: :@browser

attr_reader :target_id, :execution_context_id
attr_reader :target_id

def initialize(target_id, browser, logger)
@target_id = target_id
@browser, @logger = browser, logger
@query_root_node = false
@execution_context_mutex = Mutex.new

begin
@session_id = @browser.command("Target.attachToTarget", targetId: @target_id)["sessionId"]
Expand Down Expand Up @@ -84,6 +86,22 @@ def evaluate(node, expr)
)).dig("result", "value")
end

def execution_context_id
@execution_context_mutex.synchronize { @execution_context_id }
end

def command(*args)
if @query_root_node
begin
@client.command("DOM.getDocument", depth: 0)["root"]
ensure
@query_root_node = false
end
end

@client.command(*args)
end

private

def read(filename)
Expand All @@ -96,12 +114,20 @@ def subscribe_events
end
subscribe("Runtime.executionContextCreated") do |params|
@execution_context_id ||= params.dig("context", "id")
@execution_context_mutex.unlock if @execution_context_mutex.locked?
end
subscribe("Runtime.executionContextDestroyed") do |params|
if @execution_context_id == params["executionContextId"]
@execution_context_mutex.lock
@execution_context_id = nil
end
end
subscribe("Runtime.executionContextsCleared") do
# If we didn't have time to set context id at the beginning we have
# to set lock and release it when we set something.
@execution_context_id = nil
@execution_context_mutex.lock
end
subscribe("Page.windowOpen") { targets.refresh }
subscribe("Page.frameStartedLoading") do |params|
# Remember the first frame started loading since it's the main one
Expand All @@ -112,9 +138,8 @@ def subscribe_events
# It returns node with nodeId 1 and nodeType 9 from which descend the
# tree and we save it in a variable because if we call that again root
# node will change the id and all subsequent nodes have to change id too.
if params["frameId"] == @frame_id
command("DOM.getDocument", depth: 0)["root"]
end
# `command` is not allowed in the block as it will deadlock the process.
@query_root_node = true if params["frameId"] == @frame_id
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/capybara/cuprite/browser/web_socket.rb
Expand Up @@ -55,7 +55,7 @@ def on_message(event)
data = JSON.parse(event.data)

if block = @subscribed[data["method"]]
Thread.new { block.call(data["params"]) }
Thread.new { block.call(data["params"]) }.join
end

@messages << data
Expand Down

0 comments on commit 37d5a68

Please sign in to comment.