📝
【jest-puppeteer】要素を絞り込んでからさらに絞り込むにはどうすればよいのか?
背景
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;
}
}
最後に
リストからアイテムを絞り込み、アイテムから特定の要素を絞りこむことができました。アプリケーションでリストを使って表示するのはあるあるなので同様にブラウザテストの実装の時には必要になりそうな知識だと感じました。
Discussion