diff --git a/packages/playwright-core/src/server/screenshotter.ts b/packages/playwright-core/src/server/screenshotter.ts index 3fd4f9eb60..464d95bdc0 100644 --- a/packages/playwright-core/src/server/screenshotter.ts +++ b/packages/playwright-core/src/server/screenshotter.ts @@ -240,6 +240,13 @@ export class Screenshotter { await Promise.all(this._page.frames().map(async frame => { await frame.nonStallingEvaluateInExistingContext('(' + inPagePrepareForScreenshots.toString() + `)(${hideCaret}, ${disableAnimations})`, false, 'utility').catch(() => {}); })); + if (!process.env.PW_TEST_SCREENSHOT_NO_FONTS_READY) { + progress.log('waiting for fonts to load...'); + await Promise.all(this._page.frames().map(async frame => { + await frame.nonStallingEvaluateInExistingContext('document.fonts.ready', false, 'utility').catch(() => {}); + })); + progress.log('fonts loaded'); + } progress.cleanupWhenAborted(() => this._restorePageAfterScreenshot()); } diff --git a/tests/page/page-screenshot.spec.ts b/tests/page/page-screenshot.spec.ts index 1b4bb17169..ecb876cd15 100644 --- a/tests/page/page-screenshot.spec.ts +++ b/tests/page/page-screenshot.spec.ts @@ -824,6 +824,32 @@ it.describe('page screenshot animations', () => { 'onfinish', 'animationend' ]); }); + + it('should wait for fonts to load', async ({ page, server, isWindows, browserName, isLinux }) => { + it.fixme(isWindows, 'This requires a windows-specific test expectations. https://github.com/microsoft/playwright/issues/12707'); + await page.setViewportSize({ width: 500, height: 500 }); + const fontRequestPromise = new Promise(resolve => { + // Stall font loading. + server.setRoute('/webfont/iconfont.woff2', (request, response) => { + resolve({ request, response }); + }); + }); + await page.goto(server.PREFIX + '/webfont/webfont.html', { + waitUntil: 'domcontentloaded', // 'load' will not happen if webfont is pending + }); + + // Make sure screenshot times out while webfont is stalled. + const error = await page.screenshot({ timeout: 200, }).catch(e => e); + expect(error.message).toContain('waiting for fonts to load...'); + expect(error.message).toContain('Timeout 200ms exceeded'); + + const fontRequest = await fontRequestPromise; + server.serveFile(fontRequest.request, fontRequest.response); + const iconsScreenshot = await page.screenshot(); + expect(iconsScreenshot).toMatchSnapshot('screenshot-web-font.png', { + maxDiffPixels: 50, + }); + }); }); it('should throw if screenshot size is too large', async ({ page, browserName, isMac }) => {