[Playwright]storageStateの読み込みがうまくいってるか確認する
- global-setupでログイン処理
- ログイン状態をstorageStateに保存
- テストを実行する前に読み込み
- テスト実行
という処理がどこかでうまくいっていないようで、
切り分けのためにどの時点でstorageStateの読み込みが確認できるのか調べてみました。
準備
セッションIDがCookieにセットされて、それをstorageStateに保存して読み込めるか確認したいので、以下を準備します。
- set-cookieしてくれるサーバー
- PlaywrightとglobalSetup
- テストケース
1. set-cookieしてくれるサーバーを準備
express,express-sessionを使って作ってみます。
dockerでnode:latestのイメージを取得して、VSCodeのDev Containersで作業しました。
$ node -v
v19.3.0
$ npm init -y
$ npm install --save express
$ npm install --save express-session
app.jsファイルを作って以下のようにサーバーを作ります。
const express = require('express')
const session = require('express-session')
const app = express()
app.use(session({
secret: 'kanikuriimukorokke',
cookie: { maxAge: 60000 },
resave: false,
saveUninitialized: true,
}))
app.get('/',(req,res) => {
req.session.count = req.session.count ? req.session.count + 1 : 1;
res.send('<p id="count">count: ' + req.session.count + '</p>')
})
app.listen('3000',() => {
console.log('Server running at http://127.0.0.1:8000/')
})
起動してみます。
$ node app.js
ブラウザでhttp://localhost:3000/
にアクセスするとcount: 1
と表示されるはずです。
chromeで検証 > アプリケーション > Cookie > http://localhost:3000/
を確認するとconnect.sidにセッションIDらしきものが入っていることが確認できます。
ページをリロードすると画面の表示がviews: 2
になり、connect.sid
は変化していないことを確認できます。
2. playwrightとグローバルセットアップを準備する
こちらは上記のdocker環境と要件が合わずブラウザのインストールができなかったのでローカルで実施してます
$ npm init playwright@latest
$ node -v
v18.12.1
$ npx playwright --version
Version 1.29.1
global-setupファイルを作成
import { chromium, FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('http://localhost:3000/');
await page.context().storageState({ path: 'storageState.json' });
await browser.close();
}
export default globalSetup;
playwright.config.ts
にglobalSetupを追加
ついでにprojectをchromeだけにしておきます。
const config: PlaywrightTestConfig = {
...
globalSetup: require.resolve('./global-setup'),
...
}
3. テストケースの準備
テストファイルを追加
import { test, expect } from '@playwright/test'
// これでテスト実行時にブラウザに同じcookieがセットされる
test.use({ storageState: 'storageState.json' })
test('同じセッションIDでアクセスできてるか', async ({page}) => {
await page.goto('http://localhost:3000/')
// ↓2回目のアクセスなのでcount: 2のはず
await expect(page.locator('#count')).toHaveText("count: 2")
})
実行してみる。成功しました。
$ npx playwright test
Running 1 test using 1 worker
1 passed (1s)
To open last HTML report run:
npx playwright show-report
cookieがどの時点で取得できるか調べる
--debugしてみる
$ npx playwright test --debug
テストケースの await page.goto('http://localhost:3000/');
の実行前で止まっているので
この時点でcookieを見てみると、セットされていないみたいです。
なんとなくブラウザ立ち上がった時点で読み込まれてるのかなと思ってたんですがそうではないみたいですね。
1つステップオーバーしてもう一度確認してみます。
セットされてました。
countも2になってるのでpage.goto()
が実行される前にセットされるみたいです。
普通にデバッグしてると、最初の時点でcookieがセットされていないから「storageStateの読み込み上手くいってなさそう」って勘違いしてしまいそうです...。
traceを見てみる
configでtraceをonにします。
const config: PlaywrightTestConfig = {
...
use: {
...
trace: 'on',
...
},
}
$ npx playwright test
$ npx playwright show-report
htmlレポートでテストケースを開いて下の方にあるtracesをクリックします。
cookie関連を確認できる項目はなく、見れないみたいですね...。
browserContext.cookies()で確認してみる
BrowserContext | Playwrightこれで確認してみます。
...
test('同じセッションIDでアクセスできてるか', async ({page}) => {
// 先頭でcookieを取得してconsole.log()する
const cookie = await page.context().cookies('http://localhost:3000/')
console.log(cookie)
await page.goto('http://localhost:3000/')
await expect(page.locator('#count')).toHaveText("count: 2")
})
$ npx playwright test
Running 1 test using 1 worker
[chromium] › session.spec.ts:5:5 › 同じセッションIDでアクセスできてるか
[
{
name: 'connect.sid',
value: 's%3Au7U67oWuIyxC_1bZFensbtkx-eHD4Lgu.kvyLufTuhV%2B675beYGe2TmhDtLhObu%2BMp7BijfoRfKs',
domain: 'localhost',
path: '/',
expires: 1671958463.919827,
httpOnly: true,
secure: false,
sameSite: 'Lax'
}
]
1 passed (1s)
...
取得できてますね!
結論
test.use({ storageState: 'storageState.json' })
が上手くいってるか確認するには、
テストの先頭にpage.context().cookies()
で中身を確認するのが手っ取り早くて確実そうです。
--debug
だと最初に確認できないので若干疑いの余地が残ります…。
Discussion