Fix Devii open-trigger race and close two flaky e2e waits
DeviiTerminal bound [data-devii-open] click listeners only after the async /devii/session fetch resolved, silently dropping early clicks. Switch to a single delegated document listener bound in the constructor, matching the ModalManager/dp-lightbox pattern. The steal-confirm and comment-vote e2e tests asserted DOM state right after a click with no wait for the triggering POST to land, racing the server under CI load. Wrap those clicks in page.expect_response. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
fa8751a4ca
commit
8db0efff29
@ -10,6 +10,7 @@ export class DeviiTerminal {
|
|||||||
this.avatar = null;
|
this.avatar = null;
|
||||||
this.bindEscapeTrigger();
|
this.bindEscapeTrigger();
|
||||||
this.bindDoubleClickTrigger();
|
this.bindDoubleClickTrigger();
|
||||||
|
this.bindOpenTrigger();
|
||||||
this.ready = this.init();
|
this.ready = this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,16 +30,19 @@ export class DeviiTerminal {
|
|||||||
this.element.setAttribute("avatar", "devii");
|
this.element.setAttribute("avatar", "devii");
|
||||||
document.body.appendChild(this.element);
|
document.body.appendChild(this.element);
|
||||||
|
|
||||||
this.bindTriggers();
|
this.maybeAutoOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
bindTriggers() {
|
bindOpenTrigger() {
|
||||||
document.querySelectorAll("[data-devii-open]").forEach((trigger) => {
|
document.addEventListener("click", (event) => {
|
||||||
trigger.addEventListener("click", (event) => {
|
const trigger = event.target.closest("[data-devii-open]");
|
||||||
event.preventDefault();
|
if (!trigger) return;
|
||||||
this.open(trigger.dataset.deviiPrompt || "");
|
event.preventDefault();
|
||||||
});
|
this.open(trigger.dataset.deviiPrompt || "");
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeAutoOpen() {
|
||||||
const stored = this.element && this.element.hasStoredState && this.element.hasStoredState();
|
const stored = this.element && this.element.hasStoredState && this.element.hasStoredState();
|
||||||
if (document.querySelector("[data-devii-autoopen]") && !stored) {
|
if (document.querySelector("[data-devii-autoopen]") && !stored) {
|
||||||
this.open();
|
this.open();
|
||||||
|
|||||||
@ -128,7 +128,8 @@ def test_steal_takes_build_and_pays_thief(bob):
|
|||||||
steal.click()
|
steal.click()
|
||||||
confirm_btn = page.locator(".dialog-confirm")
|
confirm_btn = page.locator(".dialog-confirm")
|
||||||
confirm_btn.wait_for(state="visible")
|
confirm_btn.wait_for(state="visible")
|
||||||
confirm_btn.click()
|
with page.expect_response(lambda r: "/steal" in r.url and r.request.method == "POST"):
|
||||||
|
confirm_btn.click()
|
||||||
expect(page.locator("form[data-game-action='steal']")).to_have_count(0)
|
expect(page.locator("form[data-game-action='steal']")).to_have_count(0)
|
||||||
page.wait_for_timeout(400)
|
page.wait_for_timeout(400)
|
||||||
assert _farm_coins("bob_test") == 18
|
assert _farm_coins("bob_test") == 18
|
||||||
@ -165,7 +166,8 @@ def test_victim_notification_names_the_raider_and_the_amount(bob):
|
|||||||
steal.click()
|
steal.click()
|
||||||
confirm_btn = page.locator(".dialog-confirm")
|
confirm_btn = page.locator(".dialog-confirm")
|
||||||
confirm_btn.wait_for(state="visible")
|
confirm_btn.wait_for(state="visible")
|
||||||
confirm_btn.click()
|
with page.expect_response(lambda r: "/steal" in r.url and r.request.method == "POST"):
|
||||||
|
confirm_btn.click()
|
||||||
expect(page.locator("form[data-game-action='steal']")).to_have_count(0)
|
expect(page.locator("form[data-game-action='steal']")).to_have_count(0)
|
||||||
page.wait_for_timeout(400)
|
page.wait_for_timeout(400)
|
||||||
note = get_table("notifications").find_one(
|
note = get_table("notifications").find_one(
|
||||||
|
|||||||
@ -114,7 +114,10 @@ def test_comment_voted_state_persists(alice):
|
|||||||
expect(
|
expect(
|
||||||
page.locator(".comment-text:has-text('Comment whose vote should persist')")
|
page.locator(".comment-text:has-text('Comment whose vote should persist')")
|
||||||
).to_be_visible()
|
).to_be_visible()
|
||||||
page.locator(".comment-vote-btn").first.click()
|
with page.expect_response(
|
||||||
|
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
||||||
|
):
|
||||||
|
page.locator(".comment-vote-btn").first.click()
|
||||||
expect(page.locator(".comment-vote-btn").first).to_have_class(
|
expect(page.locator(".comment-vote-btn").first).to_have_class(
|
||||||
re.compile(r"\bvoted\b")
|
re.compile(r"\bvoted\b")
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user