Repository navigation
[adr] Alert handling with async handlers and the synchronous Alert API - #18283
titusfortner wants to merge 5 commits into
Conversation
|
/agentic_describe |
PR Summary by QodoPropose BiDi alert handlers with classic Alert API compatibility
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can see how risky a PR is at a glance with blast radius labels |
|
Code review by qodo was updated up to the latest commit deff9ab |
| @@ -0,0 +1,116 @@ | |||
| # 18283. Allow alert handling with async handlers and the synchronous Alert API | |||
There was a problem hiding this comment.
We should update the PR name with the same ADR name.
| ## Decision | ||
|
|
||
| 1. **Alert handlers may be added or removed.** Two methods are made available directly on the driver object, and a registered handler applies to all contexts. | ||
| `addAlertHandler` returns a handle object; `removeAlertHandler` takes that handle and unregisters exactly that handler. |
There was a problem hiding this comment.
What happens when handlers are removed?
- If I add A, then B, then remove B, does A run again?
- If I remove the only handler, does the classic behavior from decisions 3 and 4 come back? Decision 5 hints at yes ("until it is removed").
Can we say it works like a stack?
| so it applies for a specific block of code. | ||
|
|
||
| 2. **A handler is a callable that acts on the alert object.** Inside the async handler the user has access to an alert object | ||
| that describes its type and can read text, send keys, accept or dismiss just like in the current Alert API. |
There was a problem hiding this comment.
What can a handler call while the alert is open? If it runs a non-alert command (e.g. find an element), that command may block or fail. Should we say only alert methods are allowed in the handler?
| all support for `unhandledPromptBehavior` values. Users need to manage alerts through their handler, and Alert API commands must error. | ||
|
|
||
| 6. **Only the most recently added handler is called.** Unlike Network handlers, events are not passed along a chain, | ||
| any previously registered handlers are ignored (including the default handler) so users can scope handlers to specific alert instances. |
There was a problem hiding this comment.
"The default handler" isn't defined anywhere. I assume it's the classic behavior from decisions 3 and 4 (Alert API plus unhandledPromptBehavior). Can we name it once and use that name everywhere?
|
|
||
| 7. **Non-default handlers must manage disposition and errors.** | ||
| An exception in the callable is not caught or logged on behalf of the user, it is always surfaced. | ||
| An alert must not be closed for the user after the callable is executed; a handler may pass the alert object to the main thread to act on later. |
There was a problem hiding this comment.
If a handler leaves the alert open, what does the next command do? The Alert API throws (decision 5), and falling back to unhandledPromptBehavior was rejected. So does it hang, or throw a specific error?
Also, if the handler passes the alert object to the main thread, does that object still work there while the Alert API throws? Both cases should be stated.
|
|
||
|
|
||
| ```ruby | ||
| handle = driver.add_alert_handler { |alert| alert.type == 'prompt' ? alert.accept : alert.dismiss } |
There was a problem hiding this comment.
With a handler registered, the default "accept beforeUnload" no longer applies. This example would dismiss a beforeUnload prompt and block navigation. Can we either update the example to handle it, or keep accepting beforeUnload when the handler doesn't act on it?
| - Enabling BiDi requires no code changes | ||
| - Current BiDi Users: | ||
| - If users updated `unhandledPromptBehavior` value to a map, they no longer need that and should remove it | ||
| - Sessions that completed only because BiDi has automatically dismissed alerts will now get the errors. |
There was a problem hiding this comment.
Agree this is the right behavior, since it matches classic.
| - Bindings must do a lot of work to compensate for what the remote end used to do | ||
| - Always set `unhandledPromptBehavior` to `{"default": "ignore"}` to allow client to handle all prompts | ||
| - Track open alerts and associated contexts | ||
| - Check for alerts before sending commands |
There was a problem hiding this comment.
The ADR seems to assume a mixed session: BiDi is on, but most commands still go over classic HTTP. It would help to say that explicitly in Context.
That leaves a timing gap. The BiDi "alert opened" event comes over the WebSocket, but classic commands go over HTTP, so a classic command can reach the browser before the binding gets the event. For example:
- A click opens an alert.
- The test sends
findElementright away. The binding hasn't received the event yet, so it sees no open alert and sends the command. - Since the remote end is set to
ignore, it returns a plain "unexpected alert open" error instead of applying the user's configured behavior.
So checking tracked alerts before each command isn't enough. Bindings also need to catch "unexpected alert open" errors from classic commands and apply the configured unhandledPromptBehavior then. Can we add that to this list?
|
/agentic_review |
|
Code review by qodo was updated up to the latest commit 011b6d3 |
📄 The decision, its rationale, considered options, and consequences are in the record file this PR adds; read it there. The sections below are proposal notes and review logistics.
🔗 Related
📝 Proposal notes
This proposal also includes updating the Selenium 5 plan to include it because without it existing alert handling user code can break without recourse.
This ADR is about how to handle alerts in general, but the biggest decision is going to be about how we want to manage Backwards compatibility (Decisions 3-5),
so I'm expounding on the options in the PR description here instead of blowing up the ADR.
Backwards Compatibility
There are 2 main backwards compatibility issues for working with Alerts in BiDi
Options
unhandledPromptBehaviorcapabilityunhandledPromptBehaviorcapability (we could add a new capability to accept/dismiss alerts when they open)The record proposes Option 3, but Option 2 might be better overall.
Implementation Considerations
Regardless of which option, Selenium must do these things:
unhandledPromptBehaviorso users can manage alerts at all (I'm pushing for this capability to go away entirely: unhandledPromptBehavior capability values break classic prompt handling w3c/webdriver-bidi#1187)Differences per option (assumes w3c/webdriver-bidi#1185 is merged)
unhandledPromptBehaviorin BiDi sessionsunhandledPromptBehavior🗣 Discussion
(TLC meeting notes linked here)
📌 Tracking
Tracking issue: (linked on acceptance)