Module: Capybara::Lightpanda::Browser::Modals

Included in:
Capybara::Lightpanda::Browser
Defined in:
lib/capybara/lightpanda/browser/modals.rb

Overview

JS dialog handling via Lightpanda's LP.handleJavaScriptDialog pre-arm model (PR #2261): accept/dismiss are sent BEFORE the triggering action; Page.javascriptDialogOpening supplies the text.

Instance Method Summary collapse

Instance Method Details

#accept_modal(_type, text: nil) ⇒ Object



45
46
47
48
49
50
# File 'lib/capybara/lightpanda/browser/modals.rb', line 45

def accept_modal(_type, text: nil)
  prepare_modals
  params = { accept: true }
  params[:promptText] = text if text
  arm_modal { page_command("LP.handleJavaScriptDialog", **params) }
end

#check_unhandled_modal!Object

Surface a dialog that opened with no pre-arm. Called from the main thread after every action that can open one (Browser#wait_for_idle, #go_to). Warns by default; raises when the driver was built with raise_on_unhandled_modal: true (Cuprite's option name). Either way the dialog is already gone — Lightpanda's default resolved it.



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/capybara/lightpanda/browser/modals.rb', line 62

def check_unhandled_modal!
  entry = @modal_messages_mutex.synchronize do
    e = @unhandled_modal
    @unhandled_modal = nil
    e
  end
  return unless entry

  message = unhandled_modal_message(entry)
  raise UnhandledModalError, message if @options.raise_on_unhandled_modal

  warn "[capybara-lightpanda] #{message}"
end

#dismiss_modal(_type) ⇒ Object



52
53
54
55
# File 'lib/capybara/lightpanda/browser/modals.rb', line 52

def dismiss_modal(_type)
  prepare_modals
  arm_modal { page_command("LP.handleJavaScriptDialog", accept: false) }
end

#find_modal(type, text: nil, wait: options.timeout) ⇒ Object

type is accepted for the error message only: like Selenium (where alert/confirm are indistinguishable) and Cuprite (whose dialog handler accepts whatever fires), we deliberately do NOT reject a dialog whose reported type differs from the one Capybara asked for. Real suites wrap data-confirm deletes in accept_alert (e.g. solidus admin) and expect it to work; only the message text is matched.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/capybara/lightpanda/browser/modals.rb', line 82

def find_modal(type, text: nil, wait: options.timeout)
  regexp = text.is_a?(Regexp) ? text : (text && Regexp.new(Regexp.escape(text.to_s)))
  last_seen_message = nil
  claimed = nil
  Utils::Wait.until(timeout: wait, interval: 0.05) do
    claimed = pop_modal_message(regexp)
    next true if claimed

    last_seen_message = peek_last_modal_message || last_seen_message
    false
  end
  claimed[:message]
rescue TimeoutError
  raise_modal_not_found(type, text, last_seen_message)
end