version情報
"@playwright/test": "1.22.2"
起こったこと
Webアプリケーション内にあるボタンを二つ押すと遷移できるページで、非同期で二つのボタンを押そうとしたけど出来なかった。
例
前提
例えば、ボタン1とボタン2を押すと下の要素に「二つのフラグが立ちました」と表示されるWebアプリケーションがあるとする。
(ごちゃごちゃして申し訳ない)
コードではこう書いた
test("ボタンを非同期で二つ押す", async ({ page }) => { await page.goto("/"); const btn1 = page.locator(`text="ボタン1"`); const btn2 = page.locator(`text="ボタン2"`); const btns = [btn1, btn2]; await Promise.all(btns.map(async (b) => await b.click())); await expect(page.locator(".flager")).toHaveText(/二つのフラグが立ちました/); });
数回このコードで実行してみたが、Chromiumeだけ成功するパターン、firefoxだけ成功するパターンなど、いろいろと不思議なことが起きた。
こうした
test("ボタンを順繰りで二つ押す", async ({ page }) => { await page.goto("/"); const btn1 = page.locator(`text="ボタン1"`); const btn2 = page.locator(`text="ボタン2"`); const btns = [btn1, btn2]; for (let btn of btns) { await btn.click(); } await expect(page.locator(".flager")).toHaveText(/二つのフラグが立ちました/); });
こう書いたら安定した。
アプリ側の実装はこのような感じ
let flag1 = false; let flag2 = false; const btn1 = document.getElementById("button1"); const btn2 = document.getElementById("button2"); const flag1AndFlag2 = () => { if (flag1 && flag2) { const p = document.querySelector(".flager") as HTMLParagraphElement; p.innerText = "二つのフラグが立ちました"; } }; btn1?.addEventListener("click", () => { flag1 = true; flag1AndFlag2(); }); btn2?.addEventListener("click", () => { flag2 = true; flag1AndFlag2(); });