複数のページからスクリーンショットを撮ろうとしていますが、後で比較するために完全にロードする必要があります(遅延ロードしたイメージを含む)。
lazyimages_without_scroll_events.jsの例 が見つかりました。これは非常に役立ちます。
次のコードでは、スクリーンショットは正常に見えますが、いくつかの大きな問題があります。
_async function takeScreenshot(browser, viewport, route) {
return browser.newPage().then(async (page) => {
const fileName = `${viewport.directory}/${getFilename(route)}`;
await page.setViewport({
width: viewport.width,
height: 500,
});
await page.goto(
`${config.server.master}${route}.html`,
{
waitUntil: 'networkidle0',
}
);
await page.evaluate(() => {
/* global document,requestAnimationFrame */
let lastScrollTop = document.scrollingElement.scrollTop;
// Scroll to bottom of page until we can't scroll anymore.
const scroll = () => {
document.scrollingElement.scrollTop += 100;
if (document.scrollingElement.scrollTop !== lastScrollTop) {
lastScrollTop = document.scrollingElement.scrollTop;
requestAnimationFrame(scroll);
}
};
scroll();
});
await page.waitFor(5000);
await page.screenshot({
path: `screenshots/master/${fileName}.png`,
fullPage: true,
});
await page.close();
console.log(`Viewport "${viewport.name}", Route "${route}"`);
});
}
_
Issue:page.waitFor()
(タイムアウト)の値が大きくても、ページ上のフロントエンドに関連するJavaScriptのすべてが完全ではない場合がありました実行されました。
JavaScriptがフロントエンドを変更する可能性のある古いページの場合。 F.e.レガシーの場合、_jQuery.matchHeight
_。
ベストケース:理想的な世界では、操り人形師はすべてのJavaScriptが評価および実行されるまで待機します。 このようなことは可能ですか?
[〜#〜] edit [〜#〜]
_cody-g
_の助けを借りて、スクリプトを少し改善できました。
_function jQueryMatchHeightIsProcessed() {
return Array.from($('.match-height')).every((element) => {
return element.style.height !== '';
});
}
// Within takeScreenshot() after page.waitFor()
await page.waitForFunction(jQueryMatchHeightIsProcessed, {timeout: 0});
_
...しかし、完璧にはほど遠い。ターゲットページで発生するすべてのことを実際に考慮するには、異なるフロントエンドスクリプトに対して同様のソリューションを見つける必要があるようです。
私の場合の_jQuery.matchHeight
_の主な問題は、異なる実行で異なる高さを処理することです。画像の遅延読み込みが原因である可能性があります。 Flexboxに交換できるようになるまで待つ必要があるようです。 (^ _ ^)°
修正するその他の問題:
アニメーションを無効にします。
_await page.addStyleTag({
content: `
* {
transition: none !important;
animation: none !important;
}
`,
});
_
スライドショーの処理:
_function handleSwiperSlideshows() {
Array.from($('.swiper-container')).forEach((element) => {
if (typeof element.swiper !== 'undefined') {
if (element.swiper.autoplaying) {
element.swiper.stopAutoplay();
element.swiper.slideTo(0);
}
}
});
}
// Within takeScreenshot() after page.waitFor()
await page.evaluate(handleSwiperSlideshows);
_
しかし、まだ十分ではありません。これらのレガシーページを視覚的にテストすることは不可能だと思います。
次の waitForFunction が役立つ場合があります。これを使用して、任意の関数がtrueと評価されるのを待つことができます。ページのコードにアクセスできる場合は、ウィンドウのステータスを設定し、それを使用して、人形が安全に続行できることを通知するか、他の準備完了状態に依存することができます。 注:この関数はポーリング関数であり、指定可能な間隔で再評価されます。
const watchDog = page.waitForFunction('<your function to evaluate to true>');
例えば。、
const watchDog = page.waitForFunction('window.status === "ready"');
await watchDog;
ページのコードでは、単にwindow.status
からready
複数の非同期ファイルで複数のウォッチドッグを利用するには、次のようなことができます
index.js
...import/require file1.js;
...import/require file2.js;
...code...
file1.js:
var file1Flag=false; // global
...code...
file1Flag=true;
file2.js:
var file2Flag=false; // global
...code...
file2Flag=true;
main.js:
const watchDog = page.waitForFunction('file1Flag && file2Flag');
await watchDog;