Playwright
雑多
--grep=pattern, --project=project で対象フィルタ
--headed で頭アリにできる、普段は設定で headless するといいね
Assertion に Auto-retrying と Non-retrying がある
page.evaluate(...) で自分でページ内の要素を待ちながら探す、みたいなことをすると潜在的に race したり timeout 調整したりが発生しがちなので waitForFunction 等 Auto-retrying に任せるほうが大抵良い
page.on('request', ...) で Request を収集しておけば .response() メソッドで後で取得できる
npx run playwright --ui で UI つき
単にクローラとして使う
これぐらいで書き始められる
$ npm install playwright
$ npx playwright install chromium
code:simple.ts
import {chromium, Browser, BrowserContext, Page} from 'playwright';
(async () => {
const browser: Browser = await chromium.launch();
const context: BrowserContext = await browser.newContext();
const page: Page = await context.newPage();
console.log(await page.title());
console.log(await page.locator('h1').nth(0).textContent());
const firstListItems = page.locator('ul').nth(0).locator('li');
for (const el of await firstListeItems.all()) {
console.log(await el.textContent());
}
await browser.close();
})();
locator
.all() でマッチする要素に対してループ
locale
browser.newContext({locale: 'ja-JP'});
フォームに値を入れる
page.fill(selector, value)
動画取る
const page = await browser.newPage({ recordVideo: { dir: 'videos/' } });
画像のロードをスキップする
TBD
特定の条件を満たすまで操作する
あれ? 抽象度ちょっと上げたら playwright 関係なくなった
特定の要素が見えるまで左キーを押す、など
初期状態で既に達成しているかもしれないから チェック → action の順
code:repeatUntil.ts
export async function repeatUntil<T>(
action: () => Promise<T> | T,
condition: () => Promise<boolean> | boolean,
options: {
interval?: number
maxAttempts?: number
} = {}
): Promise<void> {
const { interval = 250, maxAttempts = 30 } = options
for (let attempts = 0; attempts < maxAttempts; attempts++) {
if (await Promise.resolve(condition())) return
await Promise.resolve(action())
await new Promise((resolve) => setTimeout(resolve, interval))
}
throw new Error(Max attempts (${maxAttempts}) reached)
}