diff --git a/docs/api.md b/docs/api.md index eeea265e212d4..b9d8849365ca6 100644 --- a/docs/api.md +++ b/docs/api.md @@ -68,6 +68,7 @@ + [page.setCookie(...cookies)](#pagesetcookiecookies) + [page.setExtraHTTPHeaders(headers)](#pagesetextrahttpheadersheaders) + [page.setJavaScriptEnabled(enabled)](#pagesetjavascriptenabledenabled) + + [page.setOfflineMode(enabled)](#pagesetofflinemodeenabled) + [page.setRequestInterceptionEnabled(value)](#pagesetrequestinterceptionenabledvalue) + [page.setUserAgent(userAgent)](#pagesetuseragentuseragent) + [page.setViewport(viewport)](#pagesetviewportviewport) @@ -900,6 +901,10 @@ The extra HTTP headers will be sent with every request the page initiates. > **NOTE** changing this value won't affect scripts that have already been run. It will take full effect on the next [navigation](#pagegotourl-options). +#### page.setOfflineMode(enabled) +- `enabled` <[boolean]> When `true`, enables offline mode for the page. +- returns: <[Promise]> + #### page.setRequestInterceptionEnabled(value) - `value` <[boolean]> Whether to enable request interception. - returns: <[Promise]> diff --git a/lib/NetworkManager.js b/lib/NetworkManager.js index 85c107ae0c380..d53e154a171fe 100644 --- a/lib/NetworkManager.js +++ b/lib/NetworkManager.js @@ -32,6 +32,8 @@ class NetworkManager extends EventEmitter { /** @type {!Object} */ this._extraHTTPHeaders = {}; + this._offline = false; + /** @type {?{username: string, password: string}} */ this._credentials = null; /** @type {!Set} */ @@ -78,6 +80,22 @@ class NetworkManager extends EventEmitter { return Object.assign({}, this._extraHTTPHeaders); } + /** + * @param {boolean} value + */ + async setOfflineMode(value) { + if (this._offline === value) + return; + this._offline = value; + await this._client.send('Network.emulateNetworkConditions', { + offline: this._offline, + // values of 0 remove any active throttling. crbug.com/456324#c9 + latency: 0, + downloadThroughput: -1, + uploadThroughput: -1 + }); + } + /** * @param {string} userAgent */ diff --git a/lib/Page.js b/lib/Page.js index e054368442245..2cf650be2bdf7 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -149,6 +149,13 @@ class Page extends EventEmitter { return this._networkManager.setRequestInterceptionEnabled(value); } + /** + * @param {boolean} enabled + */ + setOfflineMode(enabled) { + return this._networkManager.setOfflineMode(enabled); + } + /** * @param {!Object} event */ diff --git a/test/test.js b/test/test.js index 5b15f2850233b..c27df75b8a39e 100644 --- a/test/test.js +++ b/test/test.js @@ -328,6 +328,25 @@ describe('Page', function() { })); }); + describe('Page.setOfflineMode', function() { + it('should work', SX(async function() { + await page.setOfflineMode(true); + let error = null; + await page.goto(EMPTY_PAGE).catch(e => error = e); + expect(error).toBeTruthy(); + await page.setOfflineMode(false); + const response = await page.reload(); + expect(response.status).toBe(200); + })); + it('should emulate navigator.onLine', SX(async function() { + expect(await page.evaluate(() => window.navigator.onLine)).toBe(true); + await page.setOfflineMode(true); + expect(await page.evaluate(() => window.navigator.onLine)).toBe(false); + await page.setOfflineMode(false); + expect(await page.evaluate(() => window.navigator.onLine)).toBe(true); + })); + }); + describe('Page.evaluateHandle', function() { it('should work', SX(async function() { const windowHandle = await page.evaluateHandle(() => window);