From 6072b668ffae308b800316b9af46e807e2930960 Mon Sep 17 00:00:00 2001 From: Mathias Bynens Date: Tue, 17 Sep 2019 15:00:59 +0200 Subject: [PATCH 1/3] feat(api): add page.emulateTimezone(timezoneId) This enables dynamically changing the timezone of the page. --- docs/api.md | 5 +++++ lib/Page.js | 13 +++++++++++++ test/emulation.spec.js | 25 +++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/docs/api.md b/docs/api.md index aa78657c39865..1d318429358a7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -109,6 +109,7 @@ * [page.deleteCookie(...cookies)](#pagedeletecookiecookies) * [page.emulate(options)](#pageemulateoptions) * [page.emulateMedia(mediaType)](#pageemulatemediamediatype) + * [page.emulateTimezone(timezoneId)](#pageemulatetimezonetimezoneid) * [page.evaluate(pageFunction[, ...args])](#pageevaluatepagefunction-args) * [page.evaluateHandle(pageFunction[, ...args])](#pageevaluatehandlepagefunction-args) * [page.evaluateOnNewDocument(pageFunction[, ...args])](#pageevaluateonnewdocumentpagefunction-args) @@ -1280,6 +1281,10 @@ List of all available devices is available in the source code: [DeviceDescriptor - `mediaType` Changes the CSS media type of the page. The only allowed values are `'screen'`, `'print'` and `null`. Passing `null` disables media emulation. - returns: <[Promise]> +#### page.emulateTimezone(timezoneId) +- `timezoneId` Changes the timezone of the page. See [ICU’s `metaZones.txt`](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1) for a list of supported timezone IDs. Passing `null` disables timezone emulation. +- returns: <[Promise]> + #### page.evaluate(pageFunction[, ...args]) - `pageFunction` <[function]|[string]> Function to be evaluated in the page context - `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction` diff --git a/lib/Page.js b/lib/Page.js index 0bdd217c8291f..cb2266a2a8879 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -808,6 +808,19 @@ class Page extends EventEmitter { await this._client.send('Emulation.setEmulatedMedia', {media: mediaType || ''}); } + /** + * @param {?string} timezoneId + */ + async emulateTimezone(timezoneId) { + try { + await this._client.send('Emulation.setTimezoneOverride', {timezoneId: timezoneId || ''}); + } catch (exception) { + if (exception.message.includes('Invalid timezone')) + throw new Error(`Invalid timezone ID: ${timezoneId}`); + throw exception; + } + } + /** * @param {!Puppeteer.Viewport} viewport */ diff --git a/test/emulation.spec.js b/test/emulation.spec.js index 485394cc89251..81c77c3e01010 100644 --- a/test/emulation.spec.js +++ b/test/emulation.spec.js @@ -114,4 +114,29 @@ module.exports.addTests = function({testRunner, expect, puppeteer}) { expect(error.message).toBe('Unsupported media type: bad'); }); }); + + describe('Page.emulateTimezone', function() { + it('should work', async({page, server}) => { + const date = new Date(1479579154987); + await page.emulateTimezone('America/Jamaica'); + expect(await page.evaluate(() => date.toString())).toBe('Sat Nov 19 2016 13:12:34 GMT-0500 (Eastern Standard Time)'); + + await page.emulateTimezone('Pacific/Honolulu'); + expect(await page.evaluate(() => date.toString())).toBe('Sat Nov 19 2016 08:12:34 GMT-1000 (Hawaii-Aleutian Standard Time)'); + + await page.emulateTimezone('America/Buenos_Aires'); + expect(await page.evaluate(() => date.toString())).toBe('Sat Nov 19 2016 15:12:34 GMT-0300 (Argentina Standard Time)'); + + await page.emulateTimezone('Europe/Berlin'); + expect(await page.evaluate(() => date.toString())).toBe('Sat Nov 19 2016 19:12:34 GMT+0100 (Central European Standard Time)'); + }); + + fit('should throw for invalid timezone IDs', async({page, server}) => { + let error = null; + await page.emulateTimezone('Foo/Bar').catch(e => error = e); + expect(error.message).toBe('Invalid timezone ID: Foo/Bar'); + await page.emulateTimezone('Baz/Qux').catch(e => error = e); + expect(error.message).toBe('Invalid timezone ID: Baz/Qux'); + }); + }); }; From c2fff690eac2f0810181ca076fa2be0ecc662301 Mon Sep 17 00:00:00 2001 From: Mathias Bynens Date: Wed, 23 Oct 2019 15:07:29 +0200 Subject: [PATCH 2/3] Update test/emulation.spec.js Co-Authored-By: Simon --- test/emulation.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/emulation.spec.js b/test/emulation.spec.js index e118868b6a57e..60e7fc3366b0d 100644 --- a/test/emulation.spec.js +++ b/test/emulation.spec.js @@ -173,7 +173,7 @@ module.exports.addTests = function({testRunner, expect, puppeteer}) { expect(await page.evaluate(() => date.toString())).toBe('Sat Nov 19 2016 19:12:34 GMT+0100 (Central European Standard Time)'); }); - fit('should throw for invalid timezone IDs', async({page, server}) => { + it('should throw for invalid timezone IDs', async({page, server}) => { let error = null; await page.emulateTimezone('Foo/Bar').catch(e => error = e); expect(error.message).toBe('Invalid timezone ID: Foo/Bar'); From 33e12a8a95cdf66400cf064e03b3faad518a998f Mon Sep 17 00:00:00 2001 From: Mathias Bynens Date: Wed, 23 Oct 2019 15:16:11 +0200 Subject: [PATCH 3/3] Expose test date object globally --- test/emulation.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/emulation.spec.js b/test/emulation.spec.js index 60e7fc3366b0d..c196a392a5a77 100644 --- a/test/emulation.spec.js +++ b/test/emulation.spec.js @@ -159,7 +159,9 @@ module.exports.addTests = function({testRunner, expect, puppeteer}) { describe_fails_ffox('Page.emulateTimezone', function() { it('should work', async({page, server}) => { - const date = new Date(1479579154987); + page.evaluate(() => { + globalThis.date = new Date(1479579154987); + }); await page.emulateTimezone('America/Jamaica'); expect(await page.evaluate(() => date.toString())).toBe('Sat Nov 19 2016 13:12:34 GMT-0500 (Eastern Standard Time)');