-
-
Notifications
You must be signed in to change notification settings - Fork 132
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: add_target putting wrong target to pendings sometimes (#433)
* fix: add_target putting wrong target to pendings sometimes * chore: add CHANGELOG entry * ref: rename Client
- Loading branch information
Showing
14 changed files
with
180 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# frozen_string_literal: true | ||
|
||
require "forwardable" | ||
require "ferrum/client/subscriber" | ||
require "ferrum/client/web_socket" | ||
|
||
module Ferrum | ||
class Client | ||
extend Forwardable | ||
delegate %i[timeout timeout=] => :options | ||
|
||
attr_reader :options | ||
|
||
def initialize(ws_url, options) | ||
@command_id = 0 | ||
@options = options | ||
@pendings = Concurrent::Hash.new | ||
@ws = WebSocket.new(ws_url, options.ws_max_receive_size, options.logger) | ||
@subscriber = Subscriber.new | ||
|
||
start | ||
end | ||
|
||
def command(method, async: false, **params) | ||
message = build_message(method, params) | ||
|
||
if async | ||
@ws.send_message(message) | ||
true | ||
else | ||
pending = Concurrent::IVar.new | ||
@pendings[message[:id]] = pending | ||
@ws.send_message(message) | ||
data = pending.value!(timeout) | ||
@pendings.delete(message[:id]) | ||
|
||
raise DeadBrowserError if data.nil? && @ws.messages.closed? | ||
raise TimeoutError unless data | ||
|
||
error, response = data.values_at("error", "result") | ||
raise_browser_error(error) if error | ||
response | ||
end | ||
end | ||
|
||
def on(event, &block) | ||
@subscriber.on(event, &block) | ||
end | ||
|
||
def subscribed?(event) | ||
@subscriber.subscribed?(event) | ||
end | ||
|
||
def close | ||
@ws.close | ||
# Give a thread some time to handle a tail of messages | ||
@pendings.clear | ||
@thread.kill unless @thread.join(1) | ||
@subscriber.close | ||
end | ||
|
||
def inspect | ||
"#<#{self.class} " \ | ||
"@command_id=#{@command_id.inspect} " \ | ||
"@pendings=#{@pendings.inspect} " \ | ||
"@ws=#{@ws.inspect}>" | ||
end | ||
|
||
private | ||
|
||
def start | ||
@thread = Utils::Thread.spawn do | ||
loop do | ||
message = @ws.messages.pop | ||
break unless message | ||
|
||
if message.key?("method") | ||
@subscriber << message | ||
else | ||
@pendings[message["id"]]&.set(message) | ||
end | ||
end | ||
end | ||
end | ||
|
||
def build_message(method, params) | ||
{ method: method, params: params }.merge(id: next_command_id) | ||
end | ||
|
||
def next_command_id | ||
@command_id += 1 | ||
end | ||
|
||
def raise_browser_error(error) | ||
case error["message"] | ||
# Node has disappeared while we were trying to get it | ||
when "No node with given id found", | ||
"Could not find node with given id", | ||
"Inspected target navigated or closed" | ||
raise NodeNotFoundError, error | ||
# Context is lost, page is reloading | ||
when "Cannot find context with specified id" | ||
raise NoExecutionContextError, error | ||
when "No target with given id found" | ||
raise NoSuchPageError | ||
when /Could not compute content quads/ | ||
raise CoordinatesNotFoundError | ||
else | ||
raise BrowserError, error | ||
end | ||
end | ||
end | ||
end |
2 changes: 1 addition & 1 deletion
2
lib/ferrum/browser/subscriber.rb → lib/ferrum/client/subscriber.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.