👺
playwrightのsnapshotでmask以外の方法で要素を隠す
Playwrightのスクリーンショットのテストをする際、差分として考慮したくない部分に関してmaskを指定できる。
test('snapshot', async ({ page }) => {
await page.goto('https://playwright.dev/')
await expect(page).toHaveScreenshot({
mask: [
page.locator(".navbar__title.text--truncate"),
page.locator(".getStarted_Sjon"),
]
})
})
ある程度のランダムに発生する部分はこれで対処可能なのだが、トーストなどこれだけだと考慮しきれないケースがあり、消す方法を考えた
パターン1: removeで行う
要素を指定してremove()
で消すことを考えた
test('snapshot', async ({ page }) => {
await page.goto('https://playwright.dev/')
const target = [
".navbar__title.text--truncate",
".getStarted_Sjon"
]
await Promise.all(target.map(async (selector) => {
await page.$eval(selector, (element) => {
element.remove()
})
}))
await expect(page).toHaveScreenshot()
})
下記のように要素を消すことはできる。
ただ見て分かる通り、他の要素の位置がずれるなどが発生してしまう。positon:fixed
な要素などであればこれで十分対処できそうだったが、基本的にはあまり使えないケースが多いだろう
パターン2: style属性で非表示にする
次にstyle属性でopacity: 0
にする方法。
test('snapshot', async ({ page }) => {
await page.goto('https://playwright.dev/')
const target = [
".navbar__title.text--truncate",
".getStarted_Sjon"
]
await Promise.all(target.map(async (selector) => {
await page.$eval(selector, (elements) => {
elements.setAttribute("style", "opacity: 0")
})
}))
await expect(page).toHaveScreenshot()
})
これはこれでうまく行ったのだが、$eval
を実行してからsnapshotを取るまでの間に対象の要素が出てきてしまう場合があり、これもイマイチうまくいかなかった
パターン3: addStyleTagでCSSを追加する
上記で足りなかったので、addStyleTag
で追加する手段を取った。
test('snapshot', async ({ page }) => {
await page.goto('https://playwright.dev/')
const target = [
".navbar__title.text--truncate",
".getStarted_Sjon"
]
const hiddenCss = target.map(selector => `${selector} { opacity: 0 !important; }`).join("\n")
await page.addStyleTag({ content: hiddenCss })
await expect(page).toHaveScreenshot()
})
これであれば、後から要素が追加されても問題なかった。
スナップショット撮影後に戻す場合も下記のような形で行えた
test('snapshot', async ({ page }) => {
await page.goto('https://playwright.dev/')
const target = [
".navbar__title.text--truncate",
".getStarted_Sjon"
]
const hiddenCss = target.map(selector => `${selector} { opacity: 0 !important; }`).join("\n")
const styleHandle = await page.addStyleTag({ content: hiddenCss })
await expect(page).toHaveScreenshot()
// 追加した要素を消す
await styleHandle.evaluateHandle((el) => el.childNodes.forEach(el => el.remove()))
})
おまけ: blurでぼかす
発展型として、maskの代わりにblurにする事もできる。
test('snapshot', async ({ page }) => {
await page.goto('https://playwright.dev/')
const target = [
".navbar__title.text--truncate",
".getStarted_Sjon"
]
const hiddenCss = target.map(selector => `${selector} { filter: blur(5px); }`).join("\n")
await page.addStyleTag({ content: hiddenCss })
await expect(page).toHaveScreenshot()
})
少し分かりづらいがうっすらボケているのがわかる
「全部隠したくはないけどmaxDiffPixelsを調整してそれなりに近いと嬉しい」みたいな場合に使えるかもしれない
Discussion