The element is there, and the click does nothing
The selector matches the button. The click reports success, and nothing moves. Two escalation levels, in the order to try them.
The symptom. The selector matches a real, visible element. You click it,
you get succes: true — and the page does not move. Or you get a timeout on
an element you can confirm exists via --a11y.
Why a real element can be unclickable
Playwright refuses to click what a person could not click. Before acting it checks that the element is visible, stable, and not covered by something else. That check is a feature: it stops you from clicking a spinner overlay and believing you hit the button behind it.
It also fires on things a person can click. A toggle styled with a custom
CSS skin, a button inside a <dialog> opened by showModal(), an element
under a decorative layer with no pointer events — all real, all interactive,
all rejected.
Two levels, in this order
1 — Plain click. Always start here. If it works, nothing else matters.
{"type": "cliquer", "selecteur": "#confirm"}
2 — force: true. Skips Playwright’s interactability check and clicks
anyway. This is the right answer for an element that is genuinely there but
fails the check.
{"type": "cliquer", "selecteur": "#confirm", "force": true}
3 — repli_js: true. A second level, not a replacement for the first.
Dinoer retries with a JavaScript click on the element itself — the same
el.click() you would otherwise write by hand in an evaluer action, built
into cliquer.
{"type": "cliquer", "selecteur": "#dialog-confirm button[type=submit]",
"force": true, "repli_js": true}
It only runs after a native click has actually failed. Setting the flag does not force JS on every click.
How to know which level did the work
The compass tells you, and only when the escalation really happened:
"boussole": {"repli_js_utilise": true}
The field appears when the fallback ran, never merely because the flag was set. So you learn whether your target genuinely needs level 3 — worth knowing before you copy that flag onto every action in the scenario.
One incompatibility, and it fails loudly
repli_js executes JavaScript, which –no-evaluer
forbids for the whole run. A scenario combining both is rejected at
validation (exit 2) before any browser starts — never a silent no-op.
The case that looks the same and is not
If the click fails on an element inside a dialog you opened in a previous
call, no escalation level will save you. The dialog is gone: resuming a
session reloads the page, and a showModal() dialog does not survive a
reload.
That is a different problem with a different fix. The session does not survive between two calls →
In short
- Try plain, then
force: true, thenrepli_js: true. In that order. repli_jsneeds a real failure to trigger — it is not a JS click on demand.- Check
repli_js_utiliseto learn what your target actually requires. - A click that fails on an element from a previous call is a session problem, not a click problem.