class Capybara::Playwright::Browser
Responsibility of this class is:
-
Handling Capybara::Driver commands.
-
Managing
Playwright
browser contexts and pages.
Note that this class doesn't manage Playwright::Browser
. We should not use Playwright::Browser#close in this class.
Public Class Methods
new(driver:, playwright_browser:, page_options:, record_video: false)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 17 def initialize(driver:, playwright_browser:, page_options:, record_video: false) @driver = driver @playwright_browser = playwright_browser @page_options = page_options if record_video @page_options[:record_video_dir] ||= tmpdir end @playwright_page = create_page(create_browser_context) end
Public Instance Methods
accept_modal(dialog_type, **options, &block)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 296 def accept_modal(dialog_type, **options, &block) assert_page_alive @playwright_page.capybara_accept_modal(dialog_type, **options, &block) end
clear_browser_contexts()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 47 def clear_browser_contexts @playwright_browser.contexts.each(&:close) end
close_window(handle)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 255 def close_window(handle) on_window(handle) do |page| page.close if @playwright_page&.guid == handle @playwright_page = nil end end end
current_url()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 51 def current_url assert_page_alive @playwright_page.url end
current_window_handle()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 223 def current_window_handle @playwright_page&.guid end
dismiss_modal(dialog_type, **options, &block)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 302 def dismiss_modal(dialog_type, **options, &block) assert_page_alive @playwright_page.capybara_dismiss_modal(dialog_type, **options, &block) end
evaluate_async_script(script, *args)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 152 def evaluate_async_script(script, *args) assert_page_alive js = <<~JAVASCRIPT function(_arguments){ let args = Array.prototype.slice.call(_arguments); return new Promise((resolve, reject) => { args.push(resolve); (function(){ #{script} }).apply(this, args); }); } JAVASCRIPT result = @playwright_page.capybara_current_frame.evaluate_handle(js, arg: unwrap_node(args)) wrap_node(result) end
evaluate_script(script, *args)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 145 def evaluate_script(script, *args) assert_page_alive result = @playwright_page.capybara_current_frame.evaluate_handle("function (arguments) { return #{script} }", arg: unwrap_node(args)) wrap_node(result) end
execute_script(script, *args)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 138 def execute_script(script, *args) assert_page_alive @playwright_page.capybara_current_frame.evaluate("function (arguments) { #{script} }", arg: unwrap_node(args)) nil end
find_css(query, **options)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 86 def find_css(query, **options) assert_page_alive @playwright_page.capybara_current_frame.query_selector_all(query).map do |el| Node.new(@driver, @playwright_page, el) end end
find_xpath(query, **options)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 78 def find_xpath(query, **options) assert_page_alive @playwright_page.capybara_current_frame.query_selector_all("xpath=#{query}").map do |el| Node.new(@driver, @playwright_page, el) end end
fullscreen_window(handle)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 287 def fullscreen_window(handle) puts "[WARNING] fullscreen_window is not supported in Playwright driver" # incomplete in Playwright # ref: https://github.com/twalpole/apparition/blob/11aca464b38b77585191b7e302be2e062bdd369d/lib/capybara/apparition/page.rb#L341 on_window(handle) do |page| page.evaluate('() => document.body.requestFullscreen()') end end
go_back()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 126 def go_back assert_page_alive @playwright_page.go_back end
go_forward()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 132 def go_forward assert_page_alive @playwright_page.go_forward end
html()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 106 def html assert_page_alive js = <<~JAVASCRIPT () => { let html = ''; if (document.doctype) html += new XMLSerializer().serializeToString(document.doctype); if (document.documentElement) html += document.documentElement.outerHTML; return html; } JAVASCRIPT @playwright_page.capybara_current_frame.evaluate(js) end
maximize_window(handle)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 277 def maximize_window(handle) puts "[WARNING] maximize_window is not supported in Playwright driver" # incomplete in Playwright # ref: https://github.com/twalpole/apparition/blob/11aca464b38b77585191b7e302be2e062bdd369d/lib/capybara/apparition/page.rb#L346 on_window(handle) do |page| screen_size = page.evaluate('() => ({ width: window.screen.width, height: window.screen.height})') page.viewport_size = screen_size end end
open_new_window(kind = :tab)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 227 def open_new_window(kind = :tab) browser_context = if kind == :tab @playwright_page&.context || create_browser_context else create_browser_context end create_page(browser_context) end
raw_screenshot(**options)
click to toggle source
Not used by Capybara::Session. Intended to be directly called by user.
# File lib/capybara/playwright/browser.rb, line 178 def raw_screenshot(**options) return nil if !@playwright_page || @playwright_page.closed? @playwright_page.screenshot(**options) end
refresh()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 72 def refresh assert_page_alive @playwright_page.capybara_current_frame.evaluate('() => { location.reload(true) }') end
resize_window_to(handle, width, height)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 271 def resize_window_to(handle, width, height) on_window(handle) do |page| page.viewport_size = { width: width, height: height } end end
response_headers()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 94 def response_headers assert_page_alive @playwright_page.capybara_response_headers end
save_screenshot(path, **options)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 184 def save_screenshot(path, **options) assert_page_alive @playwright_page.screenshot(path: path) end
send_keys(*args)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 190 def send_keys(*args) Node::SendKeys.new(@playwright_page.keyboard, args).execute end
status_code()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 100 def status_code assert_page_alive @playwright_page.capybara_status_code end
switch_to_frame(frame)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 194 def switch_to_frame(frame) assert_page_alive case frame when :top @playwright_page.capybara_reset_frames when :parent @playwright_page.capybara_pop_frame else playwright_frame = frame.native.content_frame raise ArgumentError.new("Not a frame element: #{frame}") unless playwright_frame @playwright_page.capybara_push_frame(playwright_frame) end end
switch_to_window(handle)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 247 def switch_to_window(handle) if @playwright_page&.guid != handle on_window(handle) do |page| @playwright_page = page.tap(&:bring_to_front) end end end
title()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 120 def title assert_page_alive @playwright_page.title end
video_path()
click to toggle source
Not used by Capybara::Session. Intended to be directly called by user.
# File lib/capybara/playwright/browser.rb, line 170 def video_path return nil if !@playwright_page || @playwright_page.closed? @playwright_page.video&.path end
visit(path)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 57 def visit(path) assert_page_alive url = if Capybara.app_host URI(Capybara.app_host).merge(path) elsif Capybara.default_host URI(Capybara.default_host).merge(path) else path end @playwright_page.capybara_current_frame.goto(url) end
window_handles()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 219 def window_handles pages.map(&:guid) end
window_size(handle)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 265 def window_size(handle) on_window(handle) do |page| page.evaluate('() => [window.innerWidth, window.innerHeight]') end end
with_playwright_page(&block)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 354 def with_playwright_page(&block) assert_page_alive block.call(@playwright_page) end
Private Instance Methods
assert_page_alive()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 209 def assert_page_alive if !@playwright_page || @playwright_page.closed? raise NoSuchWindowError end end
create_browser_context()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 27 def create_browser_context @playwright_browser.new_context(**@page_options).tap do |browser_context| browser_context.on('page', ->(page) { unless @playwright_page @playwright_page = page end }) end end
create_page(browser_context)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 37 def create_page(browser_context) browser_context.new_page.tap do |page| page.on('close', -> { if @playwright_page @playwright_page = nil end }) end end
on_window(handle, &block)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 238 def on_window(handle, &block) page = pages.find { |page| page.guid == handle } if page block.call(page) else raise NoSuchWindowError end end
pages()
click to toggle source
# File lib/capybara/playwright/browser.rb, line 215 def pages @playwright_browser.contexts.flat_map(&:pages) end
unwrap_node(args)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 308 def unwrap_node(args) args.map do |arg| if arg.is_a?(Node) arg.send(:element) else arg end end end
wrap_node(arg)
click to toggle source
# File lib/capybara/playwright/browser.rb, line 318 def wrap_node(arg) case arg when Array arg.map do |item| wrap_node(item) end when Hash arg.map do |key, value| [key, wrap_node(value)] end.to_h when ::Playwright::ElementHandle Node.new(@driver, @playwright_page, arg) when ::Playwright::JSHandle obj_type, is_array = arg.evaluate('obj => [typeof obj, Array.isArray(obj)]') if obj_type == 'object' if is_array # Firefox often include 'toJSON' into properties. # https://github.com/microsoft/playwright/issues/7015 # # Get rid of non-numeric entries. arg.properties.select { |key, _| key.to_i.to_s == key.to_s }.map do |_, value| wrap_node(value) end else arg.properties.map do |key, value| [key, wrap_node(value)] end.to_h end else arg.json_value end else arg end end