diff --git a/docs/api.md b/docs/api.md index a13e8161ee..287cf76643 100644 --- a/docs/api.md +++ b/docs/api.md @@ -23,7 +23,7 @@ * [browserContext.clearPermissions()](#browsercontextclearpermissions) * [browserContext.close()](#browsercontextclose) * [browserContext.cookies([...urls])](#browsercontextcookiesurls) - * [browserContext.newPage()](#browsercontextnewpage) + * [browserContext.newPage(url)](#browsercontextnewpageurl) * [browserContext.pages()](#browsercontextpages) * [browserContext.setCookies(cookies)](#browsercontextsetcookiescookies) * [browserContext.setGeolocation(geolocation)](#browsercontextsetgeolocationgeolocation) @@ -305,8 +305,7 @@ const playwright = require('playwright')('chromium'); // Or 'firefox' or 'webki (async () => { const browser = await playwright.launch(); const context = await browser.newContext(); - const page = await context.newPage(); - await page.goto('http://example.com'); + const page = await context.newPage('http://example.com'); // other actions... await browser.close(); })(); @@ -335,10 +334,11 @@ const iPhone = playwright.devices['iPhone 6']; (async () => { const browser = await playwright.launch(); - const context = await browser.newContext(); - const page = await context.newPage(); - await page.emulate(iPhone); - await page.goto('http://example.com'); + const context = await browser.newContext({ + viewport: iPhone.viewport, + userAgent: iPhone.userAgent; + }); + const page = await context.newPage('http://example.com'); // other actions... await browser.close(); })(); @@ -381,8 +381,7 @@ const playwright = require('playwright'); (async () => { const browser = await playwright.launch(); const context = await browser.newContext(); - const page = await context.newPage(); - await page.goto('https://example.com'); + const page = await context.newPage('https://example.com'); await browser.close(); })(); ``` @@ -441,8 +440,6 @@ Indicates that the browser is connected. - `height` <[number]> page height in pixels. - `deviceScaleFactor` <[number]> Specify device scale factor (can be thought of as dpr). Defaults to `1`. - `isMobile` <[boolean]> Whether the `meta viewport` tag is taken into account. Defaults to `false`. - - `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false` - - `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`. - `userAgent` Specific user agent to use in this page - `javaScriptEnabled` Whether or not to enable or disable JavaScript in the page. Defaults to true. - `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. @@ -450,6 +447,7 @@ Indicates that the browser is connected. - `latitude` <[number]> Latitude between -90 and 90. - `longitude` <[number]> Longitude between -180 and 180. - `accuracy` <[number]> Optional non-negative accuracy value. + - `permissions` <[Object]> A map from origin keys to permissions values. See [browserContext.setPermissions]((#browsercontextsetpermissionsorigin-permissions)) for more details. - returns: <[Promise]<[BrowserContext]>> Creates a new browser context. It won't share cookies/cache with other browser contexts. @@ -460,9 +458,7 @@ Creates a new browser context. It won't share cookies/cache with other browser c // Create a new incognito browser context. const context = await browser.newContext(); // Create a new page in a pristine context. - const page = await context.newPage(); - // Do stuff - await page.goto('https://example.com'); + const page = await context.newPage('https://example.com'); })(); ``` @@ -482,9 +478,7 @@ Playwright allows creation of "incognito" browser contexts with `browser.newCont // Create a new incognito browser context const context = await browser.newContext(); // Create a new page inside context. -const page = await context.newPage(); -// ... do stuff with page ... -await page.goto('https://example.com'); +const page = await context.newPage('https://example.com'); // Dispose context once it's no longer needed. await context.close(); ``` @@ -533,10 +527,11 @@ If URLs are specified, only cookies that affect those URLs are returned. > **NOTE** the default browser context cannot be closed. -#### browserContext.newPage() +#### browserContext.newPage(url) +- `url` Optional url to navigate the page to. - returns: <[Promise]<[Page]>> -Creates a new page in the browser context. +Creates a new page in the browser context and optionally navigates it to the specified URL. #### browserContext.pages() - returns: <[Promise]<[Array]<[Page]>>> Promise which resolves to an array of all open pages. Non visible pages, such as `"background_page"`, will not be listed here. You can find them using [target.page()](#targetpage). @@ -725,8 +720,7 @@ const playwright = require('playwright'); (async () => { const browser = await playwright.launch(); const context = await browser.newContext(); - const page = await context.newPage(); - await page.goto('https://example.com'); + const page = await context.newPage('https://example.com'); const hrefElement = await page.$('a'); await hrefElement.click(); // ... @@ -993,8 +987,7 @@ const playwright = require('playwright'); (async () => { const browser = await playwright.launch(); const context = await browser.newContext(); - const page = await context.newPage(); - await page.goto('https://www.google.com/chrome/browser/canary.html'); + const page = await context.newPage('https://www.google.com/chrome/browser/canary.html'); dumpFrameTree(page.mainFrame(), ''); await browser.close(); @@ -1782,8 +1775,7 @@ const playwright = require('playwright'); (async () => { const browser = await playwright.launch(); const context = await browser.newContext(); - const page = await context.newPage(); - await page.goto('https://example.com'); + const page = await context.newPage('https://example.com'); await page.screenshot({path: 'screenshot.png'}); await browser.close(); })(); @@ -2629,11 +2621,9 @@ await browser.close(); - `height` <[number]> page height in pixels. **required** - `deviceScaleFactor` <[number]> Specify device scale factor (can be thought of as dpr). Defaults to `1`. - `isMobile` <[boolean]> Whether the `meta viewport` tag is taken into account. Defaults to `false`. - - `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false` - - `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`. - returns: <[Promise]> -> **NOTE** in certain cases, setting viewport will reload the page in order to set the `isMobile` or `hasTouch` properties. +> **NOTE** in certain cases, setting viewport will reload the page in order to set the `isMobile` property. In the case of multiple pages in a single browser, each page can have its own viewport size. @@ -2707,8 +2697,6 @@ This is a shortcut for [page.mainFrame().url()](#frameurl) - `height` <[number]> page height in pixels. - `deviceScaleFactor` <[number]> Specify device scale factor (can be though of as dpr). Defaults to `1`. - `isMobile` <[boolean]> Whether the `meta viewport` tag is taken into account. Defaults to `false`. - - `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false` - - `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`. #### page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]]) - `selectorOrFunctionOrTimeout` <[string]|[number]|[function]> A [selector], predicate or timeout to wait for diff --git a/src/browserContext.ts b/src/browserContext.ts index 067f77dc24..b077d725e4 100644 --- a/src/browserContext.ts +++ b/src/browserContext.ts @@ -41,7 +41,8 @@ export type BrowserContextOptions = { bypassCSP?: boolean, userAgent?: string, timezoneId?: string, - geolocation?: types.Geolocation + geolocation?: types.Geolocation, + permissions?: { [key: string]: string[] }; }; export class BrowserContext { @@ -60,12 +61,22 @@ export class BrowserContext { this._options.geolocation = { ...this._options.geolocation }; } + async _initialize() { + const entries = Object.entries(this._options.permissions || {}); + await Promise.all(entries.map(entry => this.setPermissions(entry[0], entry[1]))); + if (this._options.geolocation) + await this.setGeolocation(this._options.geolocation); + } + async pages(): Promise { return this._delegate.pages(); } - async newPage(): Promise { - return this._delegate.newPage(); + async newPage(url?: string): Promise { + const page = await this._delegate.newPage(); + if (url) + await page.goto(url); + return page; } async cookies(...urls: string[]): Promise { diff --git a/src/chromium/crBrowser.ts b/src/chromium/crBrowser.ts index 3c1e5fcf36..50199e55b2 100644 --- a/src/chromium/crBrowser.ts +++ b/src/chromium/crBrowser.ts @@ -156,6 +156,7 @@ export class CRBrowser extends platform.EventEmitter implements Browser { async newContext(options: BrowserContextOptions = {}): Promise { const { browserContextId } = await this._client.send('Target.createBrowserContext'); const context = this._createBrowserContext(browserContextId, options); + await context._initialize(); this._contexts.set(browserContextId, context); return context; } diff --git a/src/chromium/crPage.ts b/src/chromium/crPage.ts index 89cdb01dc0..eb5f919912 100644 --- a/src/chromium/crPage.ts +++ b/src/chromium/crPage.ts @@ -299,15 +299,12 @@ export class CRPage implements PageDelegate { height, isMobile = false, deviceScaleFactor = 1, - hasTouch = false, - isLandscape = false, } = viewport; + const isLandscape = width > height; const screenOrientation: Protocol.Emulation.ScreenOrientation = isLandscape ? { angle: 90, type: 'landscapePrimary' } : { angle: 0, type: 'portraitPrimary' }; await Promise.all([ this._client.send('Emulation.setDeviceMetricsOverride', { mobile: isMobile, width, height, deviceScaleFactor, screenOrientation }), - this._client.send('Emulation.setTouchEmulationEnabled', { - enabled: hasTouch - }) + this._client.send('Emulation.setTouchEmulationEnabled', { enabled: isMobile }) ]); } diff --git a/src/deviceDescriptors.ts b/src/deviceDescriptors.ts index 0697a0cbc2..63efe2a899 100644 --- a/src/deviceDescriptors.ts +++ b/src/deviceDescriptors.ts @@ -25,9 +25,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 600, 'height': 1024, 'deviceScaleFactor': 1, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -37,9 +35,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 1024, 'height': 600, 'deviceScaleFactor': 1, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -49,9 +45,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 360, 'height': 640, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -61,9 +55,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 360, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -73,9 +65,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 360, 'height': 640, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -85,9 +75,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 360, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -97,9 +85,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 360, 'height': 640, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -109,9 +95,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 360, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -121,9 +105,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 360, 'height': 640, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -133,9 +115,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 360, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -145,9 +125,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 360, 'height': 640, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -157,129 +135,87 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 360, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { - 'name': 'iPad', - 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1', + 'name': 'iPad (gen 6)', + 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', 'viewport': { 'width': 768, 'height': 1024, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { - 'name': 'iPad landscape', - 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1', + 'name': 'iPad (gen 6) landscape', + 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', 'viewport': { 'width': 1024, 'height': 768, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true + } + }, + { + 'name': 'iPad (gen 7)', + 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', + 'viewport': { + 'width': 810, + 'height': 1080, + 'deviceScaleFactor': 2, + 'isMobile': true + } + }, + { + 'name': 'iPad (gen 7) landscape', + 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', + 'viewport': { + 'width': 1080, + 'height': 810, + 'deviceScaleFactor': 2, + 'isMobile': true } }, { 'name': 'iPad Mini', - 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1', + 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', 'viewport': { 'width': 768, 'height': 1024, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { 'name': 'iPad Mini landscape', - 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1', + 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', 'viewport': { 'width': 1024, 'height': 768, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { - 'name': 'iPad Pro', - 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1', + 'name': 'iPad Pro 11', + 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', 'viewport': { - 'width': 1024, - 'height': 1366, + 'width': 834, + 'height': 1194, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { - 'name': 'iPad Pro landscape', - 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1', + 'name': 'iPad Pro 11 landscape', + 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', 'viewport': { - 'width': 1366, - 'height': 1024, + 'width': 1194, + 'height': 834, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true - } - }, - { - 'name': 'iPhone 4', - 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53', - 'viewport': { - 'width': 320, - 'height': 480, - 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false - } - }, - { - 'name': 'iPhone 4 landscape', - 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53', - 'viewport': { - 'width': 480, - 'height': 320, - 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true - } - }, - { - 'name': 'iPhone 5', - 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1', - 'viewport': { - 'width': 320, - 'height': 568, - 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false - } - }, - { - 'name': 'iPhone 5 landscape', - 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1', - 'viewport': { - 'width': 568, - 'height': 320, - 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -289,9 +225,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 375, 'height': 667, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -301,9 +235,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 667, 'height': 375, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -313,9 +245,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 414, 'height': 736, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -325,9 +255,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 736, 'height': 414, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -337,9 +265,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 375, 'height': 667, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -349,9 +275,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 667, 'height': 375, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -361,9 +285,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 414, 'height': 736, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -373,9 +295,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 736, 'height': 414, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -385,9 +305,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 375, 'height': 667, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -397,9 +315,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 667, 'height': 375, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -409,9 +325,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 414, 'height': 736, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -421,9 +335,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 736, 'height': 414, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -433,9 +345,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 320, 'height': 568, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -445,9 +355,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 568, 'height': 320, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -457,9 +365,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 375, 'height': 812, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -469,9 +375,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 812, 'height': 375, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -481,9 +385,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 414, 'height': 896, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -493,9 +395,37 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 896, 'height': 414, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true + } + }, + { + 'name': 'iPhone 11', + 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', + 'viewport': { + 'width': 414, + 'height': 896, + 'deviceScaleFactor': 2, + 'isMobile': true + } + }, + { + 'name': 'iPhone 11 Pro', + 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', + 'viewport': { + 'width': 375, + 'height': 812, + 'deviceScaleFactor': 3, + 'isMobile': true + } + }, + { + 'name': 'iPhone 11 Pro Max', + 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1', + 'viewport': { + 'width': 414, + 'height': 896, + 'deviceScaleFactor': 3, + 'isMobile': true } }, { @@ -505,9 +435,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 240, 'height': 320, 'deviceScaleFactor': 1, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -517,9 +445,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 320, 'height': 240, 'deviceScaleFactor': 1, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -529,9 +455,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 800, 'height': 1280, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -541,9 +465,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 1280, 'height': 800, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -553,9 +475,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 384, 'height': 640, 'deviceScaleFactor': 1.25, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -565,9 +485,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 384, 'deviceScaleFactor': 1.25, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -577,9 +495,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 360, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -589,9 +505,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 360, 'height': 640, 'deviceScaleFactor': 4, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -601,9 +515,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 360, 'deviceScaleFactor': 4, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -613,9 +525,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 800, 'height': 1280, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -625,9 +535,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 1280, 'height': 800, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -637,9 +545,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 384, 'height': 640, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -649,9 +555,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 384, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -661,9 +565,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 360, 'height': 640, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -673,9 +575,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 640, 'height': 360, 'deviceScaleFactor': 3, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -685,9 +585,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 412, 'height': 732, 'deviceScaleFactor': 2.625, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -697,9 +595,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 732, 'height': 412, 'deviceScaleFactor': 2.625, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -709,9 +605,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 412, 'height': 732, 'deviceScaleFactor': 3.5, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -721,9 +615,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 732, 'height': 412, 'deviceScaleFactor': 3.5, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -733,9 +625,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 412, 'height': 732, 'deviceScaleFactor': 3.5, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -745,9 +635,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 732, 'height': 412, 'deviceScaleFactor': 3.5, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -757,9 +645,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 600, 'height': 960, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -769,9 +655,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 960, 'height': 600, 'deviceScaleFactor': 2, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -781,9 +665,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 320, 'height': 533, 'deviceScaleFactor': 1.5, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -793,9 +675,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 533, 'height': 320, 'deviceScaleFactor': 1.5, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -805,9 +685,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 480, 'height': 854, 'deviceScaleFactor': 1, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -817,9 +695,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 854, 'height': 480, 'deviceScaleFactor': 1, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -829,9 +705,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 411, 'height': 731, 'deviceScaleFactor': 2.625, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -841,9 +715,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 731, 'height': 411, 'deviceScaleFactor': 2.625, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } }, { @@ -853,9 +725,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 411, 'height': 823, 'deviceScaleFactor': 3.5, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': false + 'isMobile': true } }, { @@ -865,9 +735,7 @@ const descriptors: types.DeviceDescriptor[] = [ 'width': 823, 'height': 411, 'deviceScaleFactor': 3.5, - 'isMobile': true, - 'hasTouch': true, - 'isLandscape': true + 'isMobile': true } } ]; diff --git a/src/firefox/ffBrowser.ts b/src/firefox/ffBrowser.ts index 7a5c3036d1..21636fdd27 100644 --- a/src/firefox/ffBrowser.ts +++ b/src/firefox/ffBrowser.ts @@ -83,6 +83,7 @@ export class FFBrowser extends platform.EventEmitter implements Browser { if (options.ignoreHTTPSErrors) await this._connection.send('Browser.setIgnoreHTTPSErrors', { enabled: true }); const context = this._createBrowserContext(browserContextId, options); + await context._initialize(); this._contexts.set(browserContextId, context); return context; } diff --git a/src/firefox/ffPage.ts b/src/firefox/ffPage.ts index cf1adc5ff8..eae4e7cc52 100644 --- a/src/firefox/ffPage.ts +++ b/src/firefox/ffPage.ts @@ -204,11 +204,9 @@ export class FFPage implements PageDelegate { height, isMobile = false, deviceScaleFactor = 1, - hasTouch = false, - isLandscape = false, } = viewport; await this._session.send('Page.setViewport', { - viewport: { width, height, isMobile, deviceScaleFactor, hasTouch, isLandscape }, + viewport: { width, height, isMobile, deviceScaleFactor, hasTouch: isMobile, isLandscape: width > height }, }); } diff --git a/src/page.ts b/src/page.ts index 5aaeb12c35..97ea5de1b3 100644 --- a/src/page.ts +++ b/src/page.ts @@ -393,12 +393,10 @@ export class Page extends platform.EventEmitter { async setViewport(viewport: types.Viewport) { const oldIsMobile = this._state.viewport ? !!this._state.viewport.isMobile : false; - const oldHasTouch = this._state.viewport ? !!this._state.viewport.hasTouch : false; const newIsMobile = !!viewport.isMobile; - const newHasTouch = !!viewport.hasTouch; this._state.viewport = { ...viewport }; await this._delegate.setViewport(viewport); - if (oldIsMobile !== newIsMobile || oldHasTouch !== newHasTouch) + if (oldIsMobile !== newIsMobile) await this.reload(); } diff --git a/src/types.ts b/src/types.ts index 9b77ff0108..f45f10b0b1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -58,8 +58,6 @@ export type Viewport = { height: number; deviceScaleFactor?: number; isMobile?: boolean; - isLandscape?: boolean; - hasTouch?: boolean; }; export type URLMatch = string | RegExp | ((url: URL) => boolean); diff --git a/src/webkit/wkBrowser.ts b/src/webkit/wkBrowser.ts index 7823764354..cee74a6445 100644 --- a/src/webkit/wkBrowser.ts +++ b/src/webkit/wkBrowser.ts @@ -80,6 +80,7 @@ export class WKBrowser extends platform.EventEmitter implements Browser { const context = this._createBrowserContext(browserContextId, options); if (options.ignoreHTTPSErrors) await this._browserSession.send('Browser.setIgnoreCertificateErrors', { browserContextId, ignore: true }); + await context._initialize(); this._contexts.set(browserContextId, context); return context; } diff --git a/src/webkit/wkPage.ts b/src/webkit/wkPage.ts index 8d97009af8..d3468020be 100644 --- a/src/webkit/wkPage.ts +++ b/src/webkit/wkPage.ts @@ -322,10 +322,10 @@ export class WKPage implements PageDelegate { const height = viewport.height; const fixedLayout = !!viewport.isMobile; const deviceScaleFactor = viewport.deviceScaleFactor || 1; - this._page._state.hasTouch = !!viewport.hasTouch; + this._page._state.hasTouch = !!viewport.isMobile; await Promise.all([ this._pageProxySession.send('Emulation.setDeviceMetricsOverride', {width, height, fixedLayout, deviceScaleFactor }), - this._session.send('Page.setTouchEmulationEnabled', { enabled: !!viewport.hasTouch }), + this._session.send('Page.setTouchEmulationEnabled', { enabled: !!viewport.isMobile }), ]); } diff --git a/test/emulation.spec.js b/test/emulation.spec.js index b4ff63138e..898225e526 100644 --- a/test/emulation.spec.js +++ b/test/emulation.spec.js @@ -66,7 +66,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI expect(await page.evaluate(() => document.body.textContent.trim())).toBe('YES'); }); it('should detect touch when applying viewport with touches', async({page, server}) => { - await page.setViewport({ width: 800, height: 600, hasTouch: true }); + await page.setViewport({ width: 800, height: 600, isMobile: true }); await page.addScriptTag({url: server.PREFIX + '/modernizr.js'}); expect(await page.evaluate(() => Modernizr.touchevents)).toBe(true); }); diff --git a/test/geolocation.spec.js b/test/geolocation.spec.js index 96889dbed5..327aa63e79 100644 --- a/test/geolocation.spec.js +++ b/test/geolocation.spec.js @@ -49,5 +49,20 @@ module.exports.describe = function ({ testRunner, expect, FFOX, WEBKIT }) { await context.setGeolocation({ longitude: 20, latitude: 20 }); expect(options.geolocation).toBe(geolocation); }); + it('should use context options', async({newContext, server}) => { + const options = { geolocation: { longitude: 10, latitude: 10 }, permissions: {} }; + options.permissions[server.PREFIX] = ['geolocation']; + const context = await newContext(options); + const page = await context.newPage(); + await page.goto(server.EMPTY_PAGE); + + 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 + }); + }); }); };