Playwrightチートシート

# Playwrightチートシート

:::note info
TypeScript 5.1.3
Playwright 1.34.3
:::

# Browser関連

## ヘッドフルで起動する

実際のブラウザを見ながら挙動を確認したい場合は、
ブラウザ起動時に`{ headless: false }`をオプションで渡してChroniumを起動します。

```typescript:ヘッドフルで起動する
import { chromium } from 'playwright';

const browser = await chronium.launch({ headless: false });
```

参考：[Playwright - BrowserType - headless](https://playwright.dev/docs/api/class-browsertype#browser-type-launch-option-headless)

## Cookieを取得

Cookieの取得は`browserContext.cookies()`を利用します。

なお、引数にURLとして`string`または`string[]`が渡せます。
指定した場合は指定したURLのCookieを、
指定しない場合はブラウザが保持するすべてのCookieを取得できます。

```typescript:Cookieの取得
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('www.hogehoge.com');
const cookies = page.context().cookies();
```

参考：[Playwright - BrowserContext - cookies](https://playwright.dev/docs/api/class-browsercontext#browser-context-cookies)

# Page関連

## 指定したURLへ遷移

`page.goto(url)`を利用します。

```typescript:指定したURLへ遷移
await page.goto('https://qiita.com/');
```

参考：[Playwright - Page - goto](https://playwright.dev/docs/api/class-page#page-goto)

## URLを取得

URLは`page.url()`で取得できます。

```typescript:URLを取得
await page.goto('https://qiita.com/');
const url = page.url();
```

## スクリーンショット撮影とPDF生成

閲覧ページのスクリーンショットを撮影する時は`page.screenshot()`を利用します。
オプションが色々用意されているので利用する際は是非公式を確認してください。
下記はフルスクリーンで`./tmp/hoge.png`に書き出すサンプルです。

```typescript:スクリーンショット撮影
await page.screenshot({ './tmp/hoge.png', fullPage: true });
```

閲覧ページをPDF化するには`page.pdf()`を利用します。
スクリーンショットと同様に多彩なオプションが用意されています。
また、`screenshot()`も`pdf()`も返り値は`Promise<Buffer>`となっており、オプションのパスを渡さない限りディスクへの保存はされません。

```typescript:PDF生成
// Bufferとして受け取れる
const pdf = await page.pdf();
```

参考：
- [Playwright - Page - screenshot](https://playwright.dev/docs/api/class-page#page-screenshot)
- [Playwright - Page - pdf](https://playwright.dev/docs/api/class-page#page-pdf)

## ダイアログを操作する

JavaScriptによるダイアログを操作するには`page.on('dialog')`のリスナーを利用します。
リスナーを利用する際は必ず`dialog.accept()`か`dialog.dismiss()`を利用するようにしてください。

```typescript:ダイアログを操作する
page.on('dialog', (dialog) => dialog.accept())
```

参考：[Playwright - Page - on('dialog')](https://playwright.dev/docs/api/class-page#page-event-dialog)

## 色々な待機処理

### load, DOMContentLoaded, networkidle

loadやDOMContentLoadedの待機はおそらく最も利用することになると思います。
これらの待機には`page.waitForLoadState(state)`を利用します。

```typescript:load, DOMContentLoaded, networkidleの待機
await page.waitForLoadState('load')
await page.waitForLoadState('domcontentloaded')
await page.waitForLoadState('networkidle')
```

なお、NetworkIdleは非推奨となっているので可能な限り利用を避けたほうが良さそうです。

参考：[Playwright - Page - waitForLoadState](https://playwright.dev/docs/api/class-page#page-wait-for-load-state)

### 別タブページ、ポップアップページ、ダウンロードを待機待機

リンクをクリックした際に、別タブやポップアップでページが開かれるケースや、ダウンロードが始まる際の待機処理です。
これらの待機には`page.context().waitForEvent(event)`を用います。
指定した`event`によって返り値が変わることに気を付けてください。

```typescript:別タブページ、ポップアップページ、ダウンロード待機
// 別タブ（タブをPageとして受け取れる）
const tab = await page.context().waitForEvent('page');
// ポップアップ（ポップアップをPageとして受け取れる）
const popup = await page.context().waitForEvent('popup');
// ダウンロード（Downloadのオブジェクトを受け取れる）
const download = await page.context().waitForEvent('download');
```

参考：[Playwright - BrowserContext - waitForEvent](https://playwright.dev/docs/api/class-browsercontext#browser-context-wait-for-event)

### レスポンスを待機

レスポンスを待機する時は`page.waitForResponse(urlOrPredicate)`を利用します。
クリック後に画面遷移はしたけどAPIの通信はまだ完了してなくて、とかって時に有用かもしれません。
下記は指定したURLでメソッドがPOSTでステータスが200であることを待機するサンプルです。

```typescript:レスポンスを待機
await page.waitForResponse(async (response) => {
  await response.finished();
  return (
    response.url() === 'www.hogehoge.com'
    && response.request().method() === 'POSE'
    && response.status() === 200
  );
})
```

参考：[Playwright - Page - waitForResponse](https://playwright.dev/docs/api/class-page#page-wait-for-response)

# Locator関連

※Locatorの操作は直感的なものが多いので表形式で列挙させてもらいます。

参考：[Playwright - Locator](https://playwright.dev/docs/api/class-locator)

## 操作系

|操作|メソッド|備考|
|:--|:--|:--|
|クリック|`click()`||
|入力|`fill(value)`|似た挙動をするメソッドに`type(text)`がありますが、`type`はキーイベントを発火します。|
|チェック|`check()`||
|オプション選択|`selectOption(value)`|引数はstringまたはstring[]で配列を渡せば複数選択が可能です。|
|フォーカス|`focus()`||

## 取得系

|取得対象|メソッド|備考|
|:--|:--|:--|
|テキスト|`innerText()`||
|HTML|`innerHTML()`||
|属性|`getAttribute(name)`|classやaltなどを取得する場合に利用します。|
|n個目|`nth(index)`|indexは0始まりのため、3個目の要素を取得する場合は`nth(2)`となります。|

# その他

## ローカルファイルを読み込む

別記事https://qiita.com/rokumura7/items/d708c2cec6a7997556e7をご参照ください。

# 最後に

ザッとよく使うあたりを列挙してみました。
「こんな処理はどうするの？」という質問も、
「これはこうした方がいいのでは？」というマサカリも、
大歓迎です。