Playwrightで非同期でボタンを複数押そうとしたら安定しなかった

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();
});