diff --git a/docs/api.md b/docs/api.md index 083e6b7934181..dfdbdfda84300 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1713,7 +1713,6 @@ await page.evaluate(() => matchMedia('print').matches); > **NOTE** This does not affect WebSockets and WebRTC PeerConnections (see https://crbug.com/563644). To set the page offline, you can use [page.setOfflineMode(enabled)](#pagesetofflinemodeenabled). - ```js const puppeteer = require('puppeteer'); const slow3G = puppeteer.networkConditions['Slow 3G']; @@ -2087,6 +2086,7 @@ Page is guaranteed to have a main frame which persists during navigations. - `left` <[string]|[number]> Left margin, accepts values labeled with units. - `preferCSSPageSize` <[boolean]> Give any CSS `@page` size declared in the page priority over what is declared in `width` and `height` or `format` options. Defaults to `false`, which will scale the content to fit the paper size. - `omitBackground` <[boolean]> Hides default white background and allows capturing screenshots with transparency. Defaults to `false`. + - `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. - returns: <[Promise]<[Buffer]>> Promise which resolves with PDF buffer. > **NOTE** Generating a pdf is currently only supported in Chrome headless. @@ -2329,7 +2329,7 @@ await page.setGeolocation({ latitude: 59.95, longitude: 30.31667 }); #### page.setOfflineMode(enabled) -- `enabled` <[boolean]> When `true`, enables offline mode for the page. +- `enabled` <[boolean]> When `true`, enables offline mode for the page. - returns: <[Promise]> > **NOTE** while this method sets the network connection to offline, it does not change the parameters used in [page.emulateNetworkConditions(networkConditions)](#pageemulatenetworkconditionsnetworkconditions). diff --git a/src/common/PDFOptions.ts b/src/common/PDFOptions.ts index 6c58300a02cb9..f05b040ab0f00 100644 --- a/src/common/PDFOptions.ts +++ b/src/common/PDFOptions.ts @@ -156,6 +156,11 @@ export interface PDFOptions { * @defaultValue false */ omitBackground?: boolean; + /** + * Timeout in milliseconds + * @defaultValue 30000 + */ + timeout?: number; } /** diff --git a/src/common/Page.ts b/src/common/Page.ts index 20d282e364388..6ca20aec4eb98 100644 --- a/src/common/Page.ts +++ b/src/common/Page.ts @@ -2748,6 +2748,7 @@ export class Page extends EventEmitter { preferCSSPageSize = false, margin = {}, omitBackground = false, + timeout = 30000, } = options; let paperWidth = 8.5; @@ -2772,7 +2773,7 @@ export class Page extends EventEmitter { await this._setTransparentBackgroundColor(); } - const result = await this._client.send('Page.printToPDF', { + const printCommandPromise = this._client.send('Page.printToPDF', { transferMode: 'ReturnAsStream', landscape, displayHeaderFooter, @@ -2790,6 +2791,12 @@ export class Page extends EventEmitter { preferCSSPageSize, }); + const result = await helper.waitWithTimeout( + printCommandPromise, + 'Page.printToPDF', + timeout + ); + if (omitBackground) { await this._resetDefaultBackgroundColor(); } diff --git a/test/assets/pdf.html b/test/assets/pdf.html new file mode 100644 index 0000000000000..987df27ebefda --- /dev/null +++ b/test/assets/pdf.html @@ -0,0 +1,11 @@ + + + + + + PDF + + +
PDF Content
+ + diff --git a/test/page.spec.ts b/test/page.spec.ts index ed2acb1c7a673..af5eea468fdfb 100644 --- a/test/page.spec.ts +++ b/test/page.spec.ts @@ -1646,6 +1646,17 @@ describe('Page', function () { } expect(size).toBeGreaterThan(0); }); + + it('should respect timeout', async () => { + const { isHeadless, page, server, puppeteer } = getTestState(); + if (!isHeadless) return; + + await page.goto(server.PREFIX + '/pdf.html'); + + let error = null; + await page.pdf({ timeout: 1 }).catch((_error) => (error = _error)); + expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError); + }); }); describe('Page.title', function () {