Class: Capybara::Lightpanda::Driver
- Inherits:
-
Driver::Base
- Object
- Driver::Base
- Capybara::Lightpanda::Driver
- Extended by:
- Forwardable
- Defined in:
- lib/capybara/lightpanda/driver.rb
Instance Attribute Summary collapse
-
#app ⇒ Object
readonly
Returns the value of attribute app.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Instance Method Summary collapse
-
#accept_modal(type, **options, &block) ⇒ Object
– Modal/Dialog Support –.
- #active_element ⇒ Object
- #browser ⇒ Object
- #browser_alive? ⇒ Boolean
- #clear_cookies ⇒ Object
- #dismiss_modal(type, **options, &block) ⇒ Object
- #evaluate_async_script(script, *args) ⇒ Object
- #evaluate_script(script, *args) ⇒ Object
- #execute_script(script, *args) ⇒ Object
- #find_css(selector) ⇒ Object
- #find_xpath(selector) ⇒ Object
- #frame_title ⇒ Object
-
#frame_url ⇒ Object
Capybara::Driver::Base falls back to running these via the top execution context, which always reports the parent document.
- #go_back ⇒ Object
- #go_forward ⇒ Object
- #html ⇒ Object (also: #body)
-
#initialize(app, options = {}) ⇒ Driver
constructor
A new instance of Driver.
-
#invalid_element_errors ⇒ Object
Expanded error list for Capybara retry logic (Cuprite pattern).
- #needs_server? ⇒ Boolean
-
#network ⇒ Object
Network tracker (lazily auto-enabled).
-
#pause ⇒ Object
Pause execution for interactive debugging.
- #quit ⇒ Object
- #refresh ⇒ Object
- #remove_cookie(name) ⇒ Object
-
#reset! ⇒ Object
– Lifecycle –.
-
#save_screenshot(path, **_options) ⇒ Object
– Screenshots – Lightpanda has no rendering engine so screenshots are blank, but we handle the call gracefully so Rails’ before_teardown (screenshot on failure) doesn’t raise NotSupportedByDriverError.
-
#send_keys(*keys) ⇒ Object
Capybara’s Session#send_keys routes to Driver#send_keys; Cuprite’s pattern is to fan that out to whatever element currently has focus.
-
#set_cookie(name, value, **options) ⇒ Object
– Cookie Management –.
-
#switch_to_frame(frame) ⇒ Object
– Frame Support – Passes Node objects (with remote_object_id) to Browser’s frame stack.
- #visit(url) ⇒ Object
- #wait? ⇒ Boolean
-
#wait_for_network_idle(timeout: 5, connections: 0) ⇒ Object
Block until in-flight HTTP traffic settles.
Constructor Details
#initialize(app, options = {}) ⇒ Driver
Returns a new instance of Driver.
15 16 17 18 19 20 21 |
# File 'lib/capybara/lightpanda/driver.rb', line 15 def initialize(app, = {}) super() @app = app @options = @browser = nil @started = false end |
Instance Attribute Details
#app ⇒ Object (readonly)
Returns the value of attribute app.
11 12 13 |
# File 'lib/capybara/lightpanda/driver.rb', line 11 def app @app end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
11 12 13 |
# File 'lib/capybara/lightpanda/driver.rb', line 11 def @options end |
Instance Method Details
#accept_modal(type, **options, &block) ⇒ Object
– Modal/Dialog Support –
169 170 171 172 173 174 175 |
# File 'lib/capybara/lightpanda/driver.rb', line 169 def accept_modal(type, **, &block) browser.accept_modal(type, text: [:with]) block&.call browser.find_modal(type, text: [:text], wait: .fetch(:wait, browser..timeout)) end |
#active_element ⇒ Object
56 57 58 59 |
# File 'lib/capybara/lightpanda/driver.rb', line 56 def active_element oid = browser.active_element oid && Node.new(self, oid) end |
#browser ⇒ Object
23 24 25 26 |
# File 'lib/capybara/lightpanda/driver.rb', line 23 def browser @browser = nil if @browser && !browser_alive? @browser ||= Browser.new(@options) end |
#browser_alive? ⇒ Boolean
28 29 30 31 32 |
# File 'lib/capybara/lightpanda/driver.rb', line 28 def browser_alive? @browser.client && !@browser.client.closed? rescue StandardError false end |
#clear_cookies ⇒ Object
121 122 123 |
# File 'lib/capybara/lightpanda/driver.rb', line 121 def browser..clear end |
#dismiss_modal(type, **options, &block) ⇒ Object
177 178 179 180 181 182 183 |
# File 'lib/capybara/lightpanda/driver.rb', line 177 def dismiss_modal(type, **, &block) browser.dismiss_modal(type) block&.call browser.find_modal(type, text: [:text], wait: .fetch(:wait, browser..timeout)) end |
#evaluate_async_script(script, *args) ⇒ Object
86 87 88 |
# File 'lib/capybara/lightpanda/driver.rb', line 86 def evaluate_async_script(script, *args) unwrap_script_result(browser.evaluate_async(script.strip, *native_args(args))) end |
#evaluate_script(script, *args) ⇒ Object
77 78 79 |
# File 'lib/capybara/lightpanda/driver.rb', line 77 def evaluate_script(script, *args) unwrap_script_result(browser.evaluate(script.strip, *native_args(args))) end |
#execute_script(script, *args) ⇒ Object
81 82 83 84 |
# File 'lib/capybara/lightpanda/driver.rb', line 81 def execute_script(script, *args) browser.execute(script.strip, *native_args(args)) nil end |
#find_css(selector) ⇒ Object
72 73 74 75 |
# File 'lib/capybara/lightpanda/driver.rb', line 72 def find_css(selector) object_ids = browser.find("css", selector) object_ids.map { |oid| Node.new(self, oid) } end |
#find_xpath(selector) ⇒ Object
67 68 69 70 |
# File 'lib/capybara/lightpanda/driver.rb', line 67 def find_xpath(selector) object_ids = browser.find("xpath", selector) object_ids.map { |oid| Node.new(self, oid) } end |
#frame_title ⇒ Object
159 160 161 162 163 164 165 |
# File 'lib/capybara/lightpanda/driver.rb', line 159 def frame_title frame = browser.frame_stack.last return browser.title unless frame browser.call_function_on(frame.remote_object_id, "function() { return this.contentDocument.title }") end |
#frame_url ⇒ Object
Capybara::Driver::Base falls back to running these via the top execution context, which always reports the parent document. Resolve them through the iframe element’s contentWindow / contentDocument so they reflect the active frame.
151 152 153 154 155 156 157 |
# File 'lib/capybara/lightpanda/driver.rb', line 151 def frame_url frame = browser.frame_stack.last return browser.current_url unless frame browser.call_function_on(frame.remote_object_id, "function() { return this.contentWindow.location.href }") end |
#go_back ⇒ Object
39 40 41 |
# File 'lib/capybara/lightpanda/driver.rb', line 39 def go_back browser.back end |
#go_forward ⇒ Object
43 44 45 |
# File 'lib/capybara/lightpanda/driver.rb', line 43 def go_forward browser.forward end |
#html ⇒ Object Also known as: body
51 52 53 |
# File 'lib/capybara/lightpanda/driver.rb', line 51 def html browser.body end |
#invalid_element_errors ⇒ Object
Expanded error list for Capybara retry logic (Cuprite pattern).
224 225 226 227 228 229 230 231 |
# File 'lib/capybara/lightpanda/driver.rb', line 224 def invalid_element_errors [ NodeNotFoundError, NoExecutionContextError, ObsoleteNode, MouseEventFailed, ] end |
#needs_server? ⇒ Boolean
215 216 217 |
# File 'lib/capybara/lightpanda/driver.rb', line 215 def needs_server? true end |
#network ⇒ Object
Network tracker (lazily auto-enabled). Exposes ‘traffic`, `clear`, `wait_for_idle`, header overrides, etc. Cuprite parity.
94 95 96 |
# File 'lib/capybara/lightpanda/driver.rb', line 94 def network browser.network end |
#pause ⇒ Object
Pause execution for interactive debugging.
234 235 236 237 238 239 240 241 242 243 |
# File 'lib/capybara/lightpanda/driver.rb', line 234 def pause if $stdin.tty? warn "\nPaused. Press Enter to continue." $stdin.gets else warn "\nPaused. Send SIGCONT (kill -CONT #{::Process.pid}) to continue." trap("CONT") {} # rubocop:disable Lint/EmptyBlock ::Process.kill("STOP", ::Process.pid) end end |
#quit ⇒ Object
210 211 212 213 |
# File 'lib/capybara/lightpanda/driver.rb', line 210 def quit @browser&.quit @browser = nil end |
#refresh ⇒ Object
47 48 49 |
# File 'lib/capybara/lightpanda/driver.rb', line 47 def refresh browser.refresh end |
#remove_cookie(name) ⇒ Object
125 126 127 |
# File 'lib/capybara/lightpanda/driver.rb', line 125 def (name, **) browser..remove(name: name, **) end |
#reset! ⇒ Object
– Lifecycle –
199 200 201 202 203 204 205 206 207 208 |
# File 'lib/capybara/lightpanda/driver.rb', line 199 def reset! browser.clear_frames browser.reset_modals browser..clear browser.network.clear browser.go_to("about:blank") rescue StandardError @browser&.quit @browser = nil end |
#save_screenshot(path, **_options) ⇒ Object
– Screenshots – Lightpanda has no rendering engine so screenshots are blank, but we handle the call gracefully so Rails’ before_teardown (screenshot on failure) doesn’t raise NotSupportedByDriverError.
190 191 192 193 194 195 |
# File 'lib/capybara/lightpanda/driver.rb', line 190 def save_screenshot(path, **) browser.screenshot(path: path) rescue BinaryError, BinaryNotFoundError # Browser can't start (e.g., version too old) — don't crash teardown nil end |
#send_keys(*keys) ⇒ Object
Capybara’s Session#send_keys routes to Driver#send_keys; Cuprite’s pattern is to fan that out to whatever element currently has focus.
63 64 65 |
# File 'lib/capybara/lightpanda/driver.rb', line 63 def send_keys(*keys) active_element&.send_keys(*keys) end |
#set_cookie(name, value, **options) ⇒ Object
– Cookie Management –
108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/capybara/lightpanda/driver.rb', line 108 def (name, value, **) = { domain: [:domain] || default_domain } [:path] = [:path] if [:path] [:secure] = [:secure] if .key?(:secure) if .key?(:httpOnly) || .key?(:http_only) [:http_only] = [:httpOnly] || [:http_only] end [:expires] = [:expires] if [:expires] browser..set(name: name, value: value, **) end |
#switch_to_frame(frame) ⇒ Object
– Frame Support – Passes Node objects (with remote_object_id) to Browser’s frame stack. callFunctionOn on the iframe element scopes finding to its contentDocument.
133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/capybara/lightpanda/driver.rb', line 133 def switch_to_frame(frame) case frame when :top browser.clear_frames when :parent browser.pop_frame when Node browser.push_frame(frame) else # Capybara passes a Capybara::Node::Element; extract our driver Node browser.push_frame(frame.base) end end |
#visit(url) ⇒ Object
34 35 36 37 |
# File 'lib/capybara/lightpanda/driver.rb', line 34 def visit(url) @started = true browser.go_to(url) end |
#wait? ⇒ Boolean
219 220 221 |
# File 'lib/capybara/lightpanda/driver.rb', line 219 def wait? true end |
#wait_for_network_idle(timeout: 5, connections: 0) ⇒ Object
Block until in-flight HTTP traffic settles. Auto-enables the tracker on first call so callers don’t have to remember to flip it on. Returns true on success, false on timeout.
101 102 103 104 |
# File 'lib/capybara/lightpanda/driver.rb', line 101 def wait_for_network_idle(timeout: 5, connections: 0) network.enable network.wait_for_idle(timeout: timeout, connections: connections) end |