📚

【Playwright】E2EツールのPlaywrightについて~関数編2~

2024/07/03に公開

それでは、今回は「関数編2」として、各関数を掘り下げていきたいと思います。
公式のドキュメントに書いてあるのですが、必要な部分だけまとめます。

事前準備

↓の記事を参考にサンプルを作成するか、Githubからソースを取得してください。

公式locators

https://playwright.dev/docs/locators

推奨されている関数

Playwrightでは、公式で要素取得する際に推奨している関数たちがあります。
それが↓の通りです。
関数名が明示的で用途がわかりやすいですね。

関数 説明
getByRole() getByRoleは、WAI-ARIAロール*1で定義されているheadingなどを指定し要素を取得します。
getByText() ページ内にあるテキストで要素を取得します。
getByLabel() Labelタグのテキストから要素を取得します。
getByPlaceholder() テキストボックスにあるプレースホルダに入力されているテキストをもとに要素を取得します。
getByAltText() 画像のaltのテキストをもとに要素を取得する。
getByTitle() title属性にあるテキストで要素を取得する。
getByTestId() data-testid属性に基づいて要素を取得する。

*1
https://developer.mozilla.org/ja/docs/Web/Accessibility/ARIA/Roles#mdn_で定義されているロール

使用例

  • getByRole()
sample html
<h3>Sign up</h3>
<label>
  <input type="checkbox" /> Subscribe
</label>
<br/>
<button>Submit</button>
使用例
await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();

await page.getByRole('checkbox', { name: 'Subscribe' }).check();

await page.getByRole('button', { name: /submit/i }).click();
  • getByText()
sample html
<span>Welcome, John</span>
使用例
// テキストのみ
await expect(page.getByText('Welcome, John')).toBeVisible();
// 完全一致オプション
await expect(page.getByText('Welcome, John', { exact: true })).toBeVisible();
// 正規表現
await expect(page.getByText(/welcome, [A-Za-z]+$/i)).toBeVisible();
  • getByLabel()
sample html
<label>Password <input type="password" /></label>
使用例
await page.getByLabel('Password').fill('secret');
  • getByPlaceholder()
sample html
<input type="email" placeholder="name@example.com" />
使用例
await page
    .getByPlaceholder('name@example.com')
    .fill('playwright@microsoft.com');
  • getByAltText()
sample html
<img alt="playwright logo" src="/img/playwright-logo.svg" width="100" />
使用例
await page.getByAltText('playwright logo').click();
  • getByTitle()
sample html
<span title='Issues count'>25 issues</span>
使用例
await expect(page.getByTitle('Issues count')).toHaveText('25 issues');
  • getByTestId()
sample html
<button data-testid="directions">Itinéraire</button>
使用例
await page.getByTestId('directions').click();

locator関数

非推奨というわけではないみたいです。
公式によると、CSSXPathで要素を取得したい場合に使用するようです。

使用例
// プレフィックス(冒頭)にcss / xpathをつける
await page.locator('css=button').click();
await page.locator('xpath=//button').click();

// プレフィックスを省略すると自動判定
await page.locator('button').click();
await page.locator('//button').click();

また、公式では「長い CSS や XPath チェーンは、不安定なテストにつながる」bad practiceとして以下は注意を促しています。

原文

XPath and CSS selectors can be tied to the DOM structure or implementation. These selectors can break when the DOM structure changes. Long CSS or XPath chains below are an example of a bad practice that leads to unstable tests:

翻訳

XPathとCSSのセレクタは、DOM構造や実装に縛られることがある。これらのセレクタは、DOM 構造が変わると壊れる可能性があります。以下のような長い CSS や XPath チェーンは、不安定なテストにつながる悪い習慣の一例です:

避けた方がいいとされる例
await page.locator(
    '#tsf > div:nth-child(2) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input'
).click();

await page
    .locator('//*[@id="tsf"]/div[2]/div[1]/div[1]/div/div[2]/input')
    .click();

あとがき

今回の記事作ってみて、知識として不足していたWAI-ARIAロールとか、「あー、確かに」と思ったlocatorの指定の仕方とか非常に勉強になりました。
実際DOM構造が変わるってなると、デザインが変わりやすいサイトとかのE2Eには向かないかもしれませんね。
そして、ちょっと別のところにもフィードバックせねば・・・(笑

関連記事

Github

記事に合わせたサンプルコード
https://github.com/beeeegle/playwrightSample

Discussion