Class: Ferrum::Page
- Inherits:
-
Object
- Object
- Ferrum::Page
- Extended by:
- Forwardable
- Includes:
- Interceptable, Animation, Frames, Screencast, Screenshot, Stream
- Defined in:
- lib/ferrum/page.rb,
lib/ferrum/page/frames.rb,
lib/ferrum/page/stream.rb,
lib/ferrum/page/tracing.rb,
lib/ferrum/page/animation.rb,
lib/ferrum/page/screencast.rb,
lib/ferrum/page/screenshot.rb
Overview
Represents a single browser tab (a CDP target of type page). Owns the
tab's Mouse, Keyboard, Network, Cookies, Headers, Downloads
and Accessibility helpers, as well as its frame tree (see the included
Frames module), and is the object that navigation, DOM search and
JavaScript evaluation methods are ultimately delegated to from Browser.
Defined Under Namespace
Modules: Animation, Frames, Screencast, Screenshot, Stream Classes: Tracing
Constant Summary collapse
- GOTO_WAIT =
ENV.fetch("FERRUM_GOTO_WAIT", 0.1).to_f
Constants included from Stream
Constants included from Screenshot
Screenshot::AREA_WARNING, Screenshot::DEFAULT_PDF_OPTIONS, Screenshot::DEFAULT_RENDER_TIMEOUT, Screenshot::DEFAULT_SCREENSHOT_FORMAT, Screenshot::FULL_WARNING, Screenshot::PAPER_FORMATS, Screenshot::SUPPORTED_SCREENSHOT_FORMAT
Constants included from Screencast
Screencast::START_SCREENCAST_KEY_CONV
Instance Attribute Summary collapse
-
#accessibility ⇒ Accessibility
readonly
Accessibility object.
-
#client ⇒ Client
readonly
Client connection.
-
#context_id ⇒ Object
readonly
Returns the value of attribute context_id.
-
#cookies ⇒ Cookies
readonly
Cookie store.
-
#downloads ⇒ Downloads
readonly
Downloads object.
-
#event ⇒ Object
readonly
Returns the value of attribute event.
-
#headers ⇒ Headers
readonly
Headers object.
-
#keyboard ⇒ Keyboard
readonly
Keyboard object.
-
#mouse ⇒ Mouse
readonly
Mouse object.
-
#network ⇒ Network
readonly
Network object.
-
#referrer ⇒ Object
Returns the value of attribute referrer.
-
#target_id ⇒ Object
readonly
Returns the value of attribute target_id.
-
#tracing ⇒ Object
readonly
Returns the value of attribute tracing.
Attributes included from Frames
Instance Method Summary collapse
-
#activate ⇒ Boolean
Activates (focuses) the target for the given page.
-
#back ⇒ Object
Navigates to the previous URL in the history.
-
#bypass_csp(enabled: true) ⇒ Boolean
Enables/disables CSP bypass.
-
#close ⇒ Boolean
Closes the page's target and its underlying client connection.
-
#close_connection ⇒ Object
Closes the underlying client connection only, without closing the target itself.
-
#command(method, wait: 0, slowmoable: false, timeout: nil, **params) ⇒ Hash{String => Object}
Sends a CDP command to the browser and optionally waits for network activity on the main frame to settle before returning.
-
#disable_javascript ⇒ Object
Disables JavaScript execution from the HTML source for the page.
-
#document_node_id(async: false) ⇒ Integer, Boolean
Returns the node id of the document's root element.
-
#forward ⇒ Object
Navigates to the next URL in the history.
-
#go_to(url = nil) ⇒ Object
(also: #goto, #go)
Navigates the page to a URL.
-
#initialize(client, context_id:, target_id:, proxy: nil) ⇒ Page
constructor
A new instance of Page.
-
#off(name, id) ⇒ void
Unsubscribes a listener previously registered via #on.
-
#on(name, &block) ⇒ Integer
Subscribes to a CDP event, or to
:dialog,:request,:auth(the latter two handled by Interceptable). -
#position ⇒ (Integer, Integer)
The current position of the window.
-
#position=(options) ⇒ Object
Sets the position of the window.
-
#refresh ⇒ Object
(also: #reload)
Reloads the current page.
-
#resize(width: nil, height: nil, fullscreen: false) ⇒ Hash{String => Object}
Resizes the window and emulates the viewport accordingly, optionally switching to fullscreen.
-
#set_viewport(width:, height:, scale_factor: 0, mobile: false) ⇒ Object
Overrides device screen dimensions and emulates viewport according to parameters.
-
#stop ⇒ Object
Stop all navigations and loading pending resources on the page.
-
#use_authorized_proxy? ⇒ Boolean
Whether the page is configured to use a proxy that requires authentication.
-
#use_proxy? ⇒ Boolean
Whether the page is configured to use a proxy.
-
#wait_for_reload(timeout = 1) ⇒ Object
Blocks until the page reloads or the timeout is reached.
-
#window_bounds ⇒ Hash{String => (Integer, String)}
Current window bounds.
-
#window_bounds=(bounds) ⇒ Object
Sets the position of the window.
-
#window_id ⇒ Integer
Current window id.
Methods included from Interceptable
Methods included from Stream
#stream, #stream_to, #stream_to_file, #stream_to_memory
Methods included from Frames
Methods included from Screenshot
#device_pixel_ratio, #document_size, #mhtml, #pdf, #screenshot, #viewport_size
Methods included from Screencast
#start_screencast, #stop_screencast
Methods included from Animation
#playback_rate, #playback_rate=
Constructor Details
#initialize(client, context_id:, target_id:, proxy: nil) ⇒ Page
Returns a new instance of Page.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/ferrum/page.rb', line 90 def initialize(client, context_id:, target_id:, proxy: nil) @client = client @context_id = context_id @target_id = target_id @options = client. @frames = Concurrent::Map.new @main_frame = Frame.new(nil, self) @event = Utils::Event.new.tap(&:set) self.proxy = proxy @mouse = Mouse.new(self) @keyboard = Keyboard.new(self) @headers = Headers.new(self) @cookies = Cookies.new(self) @network = Network.new(self) @accessibility = Accessibility.new(self) @tracing = Tracing.new(self) @downloads = Downloads.new(self) subscribe prepare_page end |
Instance Attribute Details
#accessibility ⇒ Accessibility (readonly)
Accessibility object.
73 74 75 |
# File 'lib/ferrum/page.rb', line 73 def accessibility @accessibility end |
#client ⇒ Client (readonly)
Client connection.
53 54 55 |
# File 'lib/ferrum/page.rb', line 53 def client @client end |
#context_id ⇒ Object (readonly)
Returns the value of attribute context_id.
48 49 50 |
# File 'lib/ferrum/page.rb', line 48 def context_id @context_id end |
#cookies ⇒ Cookies (readonly)
Cookie store.
83 84 85 |
# File 'lib/ferrum/page.rb', line 83 def @cookies end |
#downloads ⇒ Downloads (readonly)
Downloads object.
88 89 90 |
# File 'lib/ferrum/page.rb', line 88 def downloads @downloads end |
#event ⇒ Object (readonly)
Returns the value of attribute event.
48 49 50 |
# File 'lib/ferrum/page.rb', line 48 def event @event end |
#headers ⇒ Headers (readonly)
Headers object.
78 79 80 |
# File 'lib/ferrum/page.rb', line 78 def headers @headers end |
#keyboard ⇒ Keyboard (readonly)
Keyboard object.
63 64 65 |
# File 'lib/ferrum/page.rb', line 63 def keyboard @keyboard end |
#mouse ⇒ Mouse (readonly)
Mouse object.
58 59 60 |
# File 'lib/ferrum/page.rb', line 58 def mouse @mouse end |
#network ⇒ Network (readonly)
Network object.
68 69 70 |
# File 'lib/ferrum/page.rb', line 68 def network @network end |
#referrer ⇒ Object
Returns the value of attribute referrer.
47 48 49 |
# File 'lib/ferrum/page.rb', line 47 def referrer @referrer end |
#target_id ⇒ Object (readonly)
Returns the value of attribute target_id.
48 49 50 |
# File 'lib/ferrum/page.rb', line 48 def target_id @target_id end |
#tracing ⇒ Object (readonly)
Returns the value of attribute tracing.
48 49 50 |
# File 'lib/ferrum/page.rb', line 48 def tracing @tracing end |
Instance Method Details
#activate ⇒ Boolean
Activates (focuses) the target for the given page. When you have multiple tabs you work with, and you need to switch a given one.
409 410 411 412 |
# File 'lib/ferrum/page.rb', line 409 def activate command("Target.activateTarget", targetId: target_id) true end |
#back ⇒ Object
Navigates to the previous URL in the history.
349 350 351 |
# File 'lib/ferrum/page.rb', line 349 def back history_navigate(delta: -1) end |
#bypass_csp(enabled: true) ⇒ Boolean
Enables/disables CSP bypass.
395 396 397 398 |
# File 'lib/ferrum/page.rb', line 395 def bypass_csp(enabled: true) command("Page.setBypassCSP", enabled: enabled) enabled end |
#close ⇒ Boolean
Closes the page's target and its underlying client connection.
151 152 153 154 155 156 157 |
# File 'lib/ferrum/page.rb', line 151 def close @headers.clear client.command("Target.closeTarget", async: true, targetId: @target_id) close_connection true end |
#close_connection ⇒ Object
Closes the underlying client connection only, without closing the target itself. Useful when you want to detach from a page without ending the browser tab it represents.
164 165 166 |
# File 'lib/ferrum/page.rb', line 164 def close_connection client&.close end |
#command(method, wait: 0, slowmoable: false, timeout: nil, **params) ⇒ Hash{String => Object}
Sends a CDP command to the browser and optionally waits for network activity on the main frame to settle before returning.
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 |
# File 'lib/ferrum/page.rb', line 439 def command(method, wait: 0, slowmoable: false, timeout: nil, **params) iteration = @event.reset if wait.positive? sleep(@options.slowmo) if slowmoable && @options.slowmo.positive? result = client.command(method, timeout: timeout || self.timeout, **params) if wait.positive? # Wait a bit after command and check if iteration has # changed, which means there was some network event for # the main frame, and it started to load new content. @event.wait(wait) if iteration != @event.iteration set = @event.wait(self.timeout) raise TimeoutError unless set end end result end |
#disable_javascript ⇒ Object
Disables JavaScript execution from the HTML source for the page.
This doesn't prevent users evaluate JavaScript with Ferrum.
229 230 231 |
# File 'lib/ferrum/page.rb', line 229 def disable_javascript command("Emulation.setScriptExecutionDisabled", value: true) end |
#document_node_id(async: false) ⇒ Integer, Boolean
Returns the node id of the document's root element.
510 511 512 513 514 |
# File 'lib/ferrum/page.rb', line 510 def document_node_id(async: false) return client.command("DOM.getDocument", async: true, depth: 0) if async command("DOM.getDocument", depth: 0).dig("root", "nodeId") end |
#forward ⇒ Object
Navigates to the next URL in the history.
362 363 364 |
# File 'lib/ferrum/page.rb', line 362 def forward history_navigate(delta: 1) end |
#go_to(url = nil) ⇒ Object Also known as: goto, go
Navigates the page to a URL.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/ferrum/page.rb', line 124 def go_to(url = nil) = { url: combine_url!(url) } .merge!(referrer: referrer) if referrer response = command("Page.navigate", wait: GOTO_WAIT, **) error_text = response["errorText"] # https://cs.chromium.org/chromium/src/net/base/net_error_list.h if error_text && error_text != "net::ERR_ABORTED" # Request aborted due to user action or download raise StatusError.new([:url], "Request to #{[:url]} failed (#{error_text})") end response["frameId"] rescue TimeoutError if @options.pending_connection_errors pendings = network.traffic.select(&:pending?).map(&:url).compact raise PendingConnectionsError.new([:url], Array(pendings)) end end |
#off(name, id) ⇒ void
This method returns an undefined value.
Unsubscribes a listener previously registered via #on.
481 482 483 484 485 |
# File 'lib/ferrum/page.rb', line 481 def off(name, id) return super unless name == :dialog client.off("Page.javascriptDialogOpening", id) end |
#on(name, &block) ⇒ Integer
Subscribes to a CDP event, or to :dialog, :request, :auth (the
latter two handled by Interceptable).
464 465 466 467 468 469 470 471 |
# File 'lib/ferrum/page.rb', line 464 def on(name, &block) return super unless name == :dialog client.on("Page.javascriptDialogOpening") do |params, index, total| dialog = Dialog.new(self, params) block.call(dialog, index, total) end end |
#position ⇒ (Integer, Integer)
The current position of the window.
242 243 244 |
# File 'lib/ferrum/page.rb', line 242 def position window_bounds.values_at("left", "top") end |
#position=(options) ⇒ Object
Sets the position of the window.
260 261 262 |
# File 'lib/ferrum/page.rb', line 260 def position=() self.window_bounds = { left: [:left], top: [:top] } end |
#refresh ⇒ Object Also known as: reload
Reloads the current page.
325 326 327 |
# File 'lib/ferrum/page.rb', line 325 def refresh command("Page.reload", wait: timeout, slowmoable: true) end |
#resize(width: nil, height: nil, fullscreen: false) ⇒ Hash{String => Object}
Resizes the window and emulates the viewport accordingly, optionally switching to fullscreen.
212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/ferrum/page.rb', line 212 def resize(width: nil, height: nil, fullscreen: false) if fullscreen width, height = document_size self.window_bounds = { window_state: "fullscreen" } else self.window_bounds = { window_state: "normal" } self.window_bounds = { width: width, height: height } end (width: width, height: height) end |
#set_viewport(width:, height:, scale_factor: 0, mobile: false) ⇒ Object
Overrides device screen dimensions and emulates viewport according to parameters
Read more here.
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/ferrum/page.rb', line 181 def (width:, height:, scale_factor: 0, mobile: false) command( "Emulation.setDeviceMetricsOverride", slowmoable: true, width: width, height: height, deviceScaleFactor: scale_factor, mobile: mobile ) end |
#stop ⇒ Object
Stop all navigations and loading pending resources on the page.
337 338 339 |
# File 'lib/ferrum/page.rb', line 337 def stop command("Page.stopLoading", slowmoable: true) end |
#use_authorized_proxy? ⇒ Boolean
Whether the page is configured to use a proxy that requires authentication.
497 498 499 |
# File 'lib/ferrum/page.rb', line 497 def use_proxy? && @proxy_user && @proxy_password end |
#use_proxy? ⇒ Boolean
Whether the page is configured to use a proxy.
490 491 492 |
# File 'lib/ferrum/page.rb', line 490 def use_proxy? @proxy_host && @proxy_port end |
#wait_for_reload(timeout = 1) ⇒ Object
Blocks until the page reloads or the timeout is reached.
375 376 377 378 379 |
# File 'lib/ferrum/page.rb', line 375 def wait_for_reload(timeout = 1) @event.reset if @event.set? @event.wait(timeout) @event.set end |
#window_bounds ⇒ Hash{String => (Integer, String)}
Current window bounds.
302 303 304 |
# File 'lib/ferrum/page.rb', line 302 def window_bounds client.command("Browser.getWindowBounds", windowId: window_id).fetch("bounds") end |
#window_bounds=(bounds) ⇒ Object
Sets the position of the window.
286 287 288 289 290 291 292 |
# File 'lib/ferrum/page.rb', line 286 def window_bounds=(bounds) = bounds.dup window_state = .delete(:window_state) bounds = { windowState: window_state, ** }.compact client.command("Browser.setWindowBounds", windowId: window_id, bounds: bounds) end |
#window_id ⇒ Integer
Current window id.
314 315 316 |
# File 'lib/ferrum/page.rb', line 314 def window_id client.command("Browser.getWindowForTarget", targetId: target_id)["windowId"] end |