【jest-puppeteer】要素を絞り込んでからさらに絞り込むにはどうすればよいのか?

15293 ワード

背景

Vue.jsでのブラウザテストとしてjest-puppeteerを採用しています。

下記のリストの中から該当するアイテムを押下し詳細画面へ遷移する処理を実装したかったのですが「要素を絞り込んでからさらに絞り込む」実装に時間がかかってしまったのと意外とこのロジックを別のテストで使い回すことが多かったのでメモします。

具体的には下記のようなリストからアイテムを全て取得しlist.status === "無効"の場合押下させlist.status === "有効"の際はスルーさせます。

<template>
  <div class="list-box">
    <a
      v-for="(item, index) in list"
      :key="index"
      href="#"
      data-jp="move-detail-link"
      class="item"
    >
      <div class="name">
        <div class="item-container">
          <p class="text -bold">{{ item.full_name }}</p>
          <p class="text -small">{{ item.full_name_kana }}</p>
        </div>
      </div>
      <div class="status">
        <div class="item-container">
          <p class="label" data-jp="item-status">{{ item.status }}</p>
        </div>
      </div>
    </a>
  </div>
</template>

実装したコード

test("ステータス「無効」アイテムの詳細画面へ遷移する", async () => {
  const moveDetailLinks = await page.$$('[data-jp="move-detail-link"]');
  for (const link of moveDetailLinks) {
    const itemStatus = await link.$('[data-jp="item-status"]');
    const itemStatusText = await (
      await itemStatus.getProperty("textContent")
    ).jsonValue();
    if (itemStatusText.trim() === "無効") {
      await link.click();
      break;
    }
  }
  await page.waitForNavigation();
  const detailTitle = await getTextContent('[data-jp="detail-title"]');
  expect(detailTitle).toEqual("詳細");
});

今回の味噌

move-detail-linkというカスタム属性を持つ要素を全て取得しmoveDetailLinksに格納します。

const moveDetailLinks = await page.$$('[data-jp="move-detail-link"]');

次にfor文で一つ一つのmove-detail-linkの要素(テンプレートでいうとitem)からさらにitem-statusというカスタム属性を持つ要素にアクセスします。

getTextContentでtextContentを抽出しテキストが無効の場合はクリックしループを解除します。breakを宣言しないと詳細画面へ遷移した後でもループ処理が実行され続けタイムアウトエラーになるので注意してください。

getTextContentはカスタムフックです。

for (const link of moveDetailLinks) {
    const itemStatus = await link.$('[data-jp="item-status"]');
    const itemStatusText = await (
      await itemStatus.getProperty("textContent")
    ).jsonValue();
    if (itemStatusText.trim() === "無効") {
      await link.click();
      break;
    }
  }

最後に

リストからアイテムを絞り込み、アイテムから特定の要素を絞りこむことができました。アプリケーションでリストを使って表示するのはあるあるなので同様にブラウザテストの実装の時には必要になりそうな知識だと感じました。

参考記事