diff --git a/docs/api.md b/docs/api.md index 6971497b33c..29a09cb8264 100644 --- a/docs/api.md +++ b/docs/api.md @@ -118,6 +118,7 @@ Next Release: **Sep 6, 2018** * [page.setCookie(...cookies)](#pagesetcookiecookies) * [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) * [page.setExtraHTTPHeaders(headers)](#pagesetextrahttpheadersheaders) + * [page.setGeolocation(options)](#pagesetgeolocationoptions) * [page.setJavaScriptEnabled(enabled)](#pagesetjavascriptenabledenabled) * [page.setOfflineMode(enabled)](#pagesetofflinemodeenabled) * [page.setRequestInterception(value)](#pagesetrequestinterceptionvalue) @@ -1556,6 +1557,21 @@ The extra HTTP headers will be sent with every request the page initiates. > **NOTE** page.setExtraHTTPHeaders does not guarantee the order of headers in the outgoing requests. +#### page.setGeolocation(options) +- `options` + - `latitude` <[number]> Latitude between -90 and 90. + - `longitude` <[number]> Longitude between -180 and 180. + - `accuracy` <[number]> Optional non-negative accuracy value. +- returns: <[Promise]> + +Sets the page's geolocation. + +```js +await page.setGeolocation({latitude: 59.95, longitude: 30.31667}); +``` + +> **NOTE** Consider using [browserContext.overridePermissions](#browsercontextoverridepermissionsorigin-permissions) to grant permissions for the page to read its geolocation. + #### page.setJavaScriptEnabled(enabled) - `enabled` <[boolean]> Whether or not to enable JavaScript on the page. - returns: <[Promise]> diff --git a/lib/Page.js b/lib/Page.js index 888d64ed835..4ba3ef840d0 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -144,6 +144,20 @@ class Page extends EventEmitter { }); } + /** + * @param {!{longitude: number, latitude: number, accuracy: (number|undefined)}} options + */ + async setGeolocation(options) { + const { longitude, latitude, accuracy = 0} = options; + if (longitude < -180 || longitude > 180) + throw new Error(`Invalid longitude "${longitude}": precondition -180 <= LONGITUDE <= 180 failed.`); + if (latitude < -90 || latitude > 90) + throw new Error(`Invalid latitude "${latitude}": precondition -90 <= LATITUDE <= 90 failed.`); + if (accuracy < 0) + throw new Error(`Invalid accuracy "${accuracy}": precondition 0 <= ACCURACY failed.`); + await this._client.send('Emulation.setGeolocationOverride', {longitude, latitude, accuracy}); + } + /** * @return {!Puppeteer.Target} */ diff --git a/test/page.spec.js b/test/page.spec.js index 50bb0e79123..0a4abf792a0 100644 --- a/test/page.spec.js +++ b/test/page.spec.js @@ -128,6 +128,30 @@ module.exports.addTests = function({testRunner, expect, headless}) { }); }); + describe('Page.setGeolocation', function() { + it('should work', async({page, server, context}) => { + await context.overridePermissions(server.PREFIX, ['geolocation']); + await page.goto(server.EMPTY_PAGE); + await page.setGeolocation({longitude: 10, latitude: 10}); + const geolocation = await page.evaluate(() => new Promise(resolve => navigator.geolocation.getCurrentPosition(position => { + resolve({latitude: position.coords.latitude, longitude: position.coords.longitude}); + }))); + expect(geolocation).toEqual({ + latitude: 10, + longitude: 10 + }); + }); + it('should throw when invalid longitude', async({page, server, context}) => { + let error = null; + try { + await page.setGeolocation({longitude: 200, latitude: 10}); + } catch (e) { + error = e; + } + expect(error.message).toContain('Invalid longitude "200"'); + }); + }); + describe('Page.evaluate', function() { it('should work', async({page, server}) => { const result = await page.evaluate(() => 7 * 3);