Class: Ask::WebFetch::Backends::AttachedBrowser::Page
- Inherits:
-
Object
- Object
- Ask::WebFetch::Backends::AttachedBrowser::Page
- Defined in:
- lib/ask/web_fetch/backends/attached_browser.rb
Overview
One tab in the attached browser, closed with #close. Speaks just enough CDP for the Browser backend: navigate, read title/URL/HTML, and report the main-document HTTP status.
Defined Under Namespace
Classes: Network
Instance Method Summary collapse
- #body ⇒ Object
- #close ⇒ Object
- #evaluate(expression) ⇒ Object
-
#go_to(url) ⇒ Object
Navigates and does not return until the document has actually loaded — Page.navigate only starts the navigation, and reading the page before it commits yields an empty document (the very failure mode this class exists to avoid).
-
#initialize(client, timeout:, restore_focus_to: nil) ⇒ Page
constructor
A new instance of Page.
-
#network ⇒ Object
Minimal network facade for the Browser backend: status from the Navigation Timing API, idle from CDP Network events (subscribed in the constructor, before navigation).
- #title ⇒ Object
- #url ⇒ Object
Constructor Details
#initialize(client, timeout:, restore_focus_to: nil) ⇒ Page
Returns a new instance of Page.
50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/ask/web_fetch/backends/attached_browser.rb', line 50 def initialize(client, timeout:, restore_focus_to: nil) @client = client @timeout = timeout @restore_focus_to = restore_focus_to @target_id = @client.command('Target.createTarget', url: 'about:blank')['targetId'] @session = @client.session( @client.command('Target.attachToTarget', targetId: @target_id, flatten: true)['sessionId'] ) # Subscribed BEFORE any navigation so the idle wait sees the # page's real load traffic (lazy SPAs render in waves). @network = Network.new(self) end |
Instance Method Details
#body ⇒ Object
84 85 86 |
# File 'lib/ask/web_fetch/backends/attached_browser.rb', line 84 def body evaluate('document.documentElement.outerHTML') || '' end |
#close ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/ask/web_fetch/backends/attached_browser.rb', line 95 def close @client.command('Target.closeTarget', targetId: @target_id) rescue Ferrum::Error nil ensure # The attached dev Chrome window steals focus when a tab is # created; give it back once the tab is gone — but only to an # app that ISN'T Chrome, so a fetch while the user is already # looking at Chrome doesn't ping-pong. FocusRestorer.restore_frontmost(@restore_focus_to) end |
#evaluate(expression) ⇒ Object
107 108 109 110 111 112 |
# File 'lib/ask/web_fetch/backends/attached_browser.rb', line 107 def evaluate(expression) response = @session.command('Runtime.evaluate', expression: expression, returnByValue: true) # Ferrum's command() unwraps CDP's outer "result", leaving # { "result" => RemoteObject, "exceptionDetails" => ... }. response.dig('result', 'value') end |
#go_to(url) ⇒ Object
Navigates and does not return until the document has actually loaded — Page.navigate only starts the navigation, and reading the page before it commits yields an empty document (the very failure mode this class exists to avoid).
67 68 69 70 71 72 73 74 75 |
# File 'lib/ask/web_fetch/backends/attached_browser.rb', line 67 def go_to(url) result = @session.command('Page.navigate', url: url) error = result['errorText'] if error && error != 'net::ERR_ABORTED' raise Ferrum::StatusError, "Request to #{url} failed (#{error})" end wait_for_load end |
#network ⇒ Object
Minimal network facade for the Browser backend: status from the Navigation Timing API, idle from CDP Network events (subscribed in the constructor, before navigation).
91 92 93 |
# File 'lib/ask/web_fetch/backends/attached_browser.rb', line 91 def network @network end |
#title ⇒ Object
76 77 78 |
# File 'lib/ask/web_fetch/backends/attached_browser.rb', line 76 def title evaluate('document.title') end |
#url ⇒ Object
80 81 82 |
# File 'lib/ask/web_fetch/backends/attached_browser.rb', line 80 def url evaluate('location.href') end |