From f6e27a9429addeb80dc864f3e1764d3a52694b9c Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Mon, 23 Oct 2017 21:13:38 -0700 Subject: [PATCH] feat(Page): teach Page.setContent to wait for resources to load This patch adds "options" parameter to the `page.setContent` method. The parameter is the same as a navigation parameter and allows to specify maximum timeout to wait for resources to be loaded, as well as to describe events that should be emitted before the setContent operation would be considered successful. Fixes #728. --- docs/api.md | 11 +++++++++-- lib/Page.js | 16 ++++++++++------ test/test.js | 11 +++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/docs/api.md b/docs/api.md index 8bdbe3206d7e0..d536fffb21540 100644 --- a/docs/api.md +++ b/docs/api.md @@ -937,9 +937,16 @@ page.select('select#colors', 'blue'); // single selection page.select('select#colors', 'red', 'green', 'blue'); // multiple selections ``` -#### page.setContent(html) +#### page.setContent(html, options) - `html` <[string]> HTML markup to assign to the page. -- returns: <[Promise]> +- `options` <[Object]> Navigation parameters which might have the following properties: + - `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. + - `waitUntil` <[string]|[Array]<[string]>> When to consider setting content complete, defaults to `load`. Given an array of event strings, setting content is considered to be successful after all events have been fired. Events Can be either: + - `load` - consider setting content to be finished when the `load` event is fired. + - `domcontentloaded` - consider setting content to be finished when the `DOMContentLoaded` event is fired. + - `networkidle0` - consider setting content to be finished when there are no more then 0 network connections for at least `500` ms. + - `networkidle2` - consider setting content to be finished when there are no more then 2 network connections for at least `500` ms. +- returns: <[Promise]> Promise which resolves when content is set and all events are triggered. #### page.setCookie(...cookies) - `...cookies` <...[Object]> diff --git a/lib/Page.js b/lib/Page.js index dea00d9b7502c..9b0b7ae1537a5 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -437,13 +437,17 @@ class Page extends EventEmitter { /** * @param {string} html + * @param {!Object=} options */ - async setContent(html) { - await this.evaluate(html => { - document.open(); - document.write(html); - document.close(); - }, html); + async setContent(html, options) { + await Promise.all([ + this.evaluate(html => { + document.open(); + document.write(html); + document.close(); + }, html), + this.waitForNavigation(options), + ]); } /** diff --git a/test/test.js b/test/test.js index 767b51eab0d70..d6804623fe94a 100644 --- a/test/test.js +++ b/test/test.js @@ -2174,6 +2174,17 @@ describe('Page', function() { const result = await page.content(); expect(result).toBe(`${doctype}${expectedOutput}`); })); + it('should await resources to load', SX(async function() { + const imgPath = '/img.png'; + let imgResponse = null; + server.setRoute(imgPath, (req, res) => imgResponse = res); + let loaded = false; + let contentPromise = page.setContent(``).then(() => loaded = true); + await server.waitForRequest(imgPath); + expect(loaded).toBe(false); + imgResponse.end(); + await contentPromise; + })); }); describe('Network Events', function() {