diff --git a/docs/api.md b/docs/api.md
index 95176e466f7..24631e17c19 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -29,7 +29,7 @@
* [page.addScriptTag(url)](#pageaddscripttagurl)
* [page.click(selector)](#pageclickselector)
* [page.close()](#pageclose)
- * [page.emulate(name, options)](#pageemulatename-options)
+ * [page.emulate(name)](#pageemulatename)
* [page.emulatedDevices()](#pageemulateddevices)
* [page.evaluate(pageFunction, ...args)](#pageevaluatepagefunction-args)
* [page.evaluateOnInitialized(pageFunction, ...args)](#pageevaluateoninitializedpagefunction-args)
@@ -316,10 +316,8 @@ Adds a `` tag to the page with the desired url. Alternatively,
#### page.close()
- returns: <[Promise]> Returns promise which resolves when page gets closed.
-#### page.emulate(name, options)
+#### page.emulate(name)
- `name` <[string]> A name of the device to be emulated. Get the full list of emulated devices via `page.emulatedDevices()`.
-- `options` <[Object]> Emulation parameters which might have the following properties:
- - `landscape` <[boolean]> Emulates device in the landscape mode, defaults to `false`.
- returns: <[Promise]> Returns promise which resolves when device is emulated. Can reload the page if switching between mobile and desktop devices.
#### page.emulatedDevices()
diff --git a/lib/DeviceDescriptors.js b/lib/DeviceDescriptors.js
index f39da5f6fea..d9f6934d33c 100644
--- a/lib/DeviceDescriptors.js
+++ b/lib/DeviceDescriptors.js
@@ -14,1136 +14,619 @@
* limitations under the License.
*/
-module.exports =
-[
+module.exports = [
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'iPhone 4' ,
- 'screen': {
- 'horizontal': {
- 'width': 480,
- 'height': 320
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 320,
- 'height': 480
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Blackberry PlayBook',
+ 'userAgent': 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+',
+ 'viewport': {
+ 'width': 600,
+ 'height': 1024,
+ 'deviceScaleFactor': 1,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'order': 40,
- 'device': {
- 'show-by-default': true,
- 'title': 'iPhone 5',
- 'screen': {
- 'horizontal': {
- 'outline' : {
- 'image': '@url(iPhone5-landscape.svg)',
- 'insets' : { 'left': 115, 'top': 25, 'right': 115, 'bottom': 28 }
- },
- 'width': 568,
- 'height': 320
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'outline' : {
- 'image': '@url(iPhone5-portrait.svg)',
- 'insets' : { 'left': 29, 'top': 105, 'right': 25, 'bottom': 111 }
- },
- 'width': 320,
- 'height': 568
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Blackberry PlayBook landscape',
+ 'userAgent': 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+',
+ 'viewport': {
+ 'width': 1024,
+ 'height': 600,
+ 'deviceScaleFactor': 1,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'order': 50,
- 'device': {
- 'show-by-default': true,
- 'title': 'iPhone 6',
- 'screen': {
- 'horizontal': {
- 'outline' : {
- 'image': '@url(iPhone6-landscape.svg)',
- 'insets' : { 'left': 106, 'top': 28, 'right': 106, 'bottom': 28 }
- },
- 'width': 667,
- 'height': 375
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'outline' : {
- 'image': '@url(iPhone6-portrait.svg)',
- 'insets' : { 'left': 28, 'top': 105, 'right': 28, 'bottom': 105 }
- },
- 'width': 375,
- 'height': 667
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'BlackBerry Z30',
+ 'userAgent': 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+',
+ 'viewport': {
+ 'width': 360,
+ 'height': 640,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'order': 60,
- 'device': {
- 'show-by-default': true,
- 'title': 'iPhone 6 Plus',
- 'screen': {
- 'horizontal': {
- 'outline' : {
- 'image': '@url(iPhone6Plus-landscape.svg)',
- 'insets' : { 'left': 109, 'top': 29, 'right': 109, 'bottom': 27 }
- },
- 'width': 736,
- 'height': 414
- },
- 'device-pixel-ratio': 3,
- 'vertical': {
- 'outline' : {
- 'image': '@url(iPhone6Plus-portrait.svg)',
- 'insets' : { 'left': 26, 'top': 107, 'right': 30, 'bottom': 111 }
- },
- 'width': 414,
- 'height': 736
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'BlackBerry Z30 landscape',
+ 'userAgent': 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+',
+ 'viewport': {
+ 'width': 640,
+ 'height': 360,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'BlackBerry Z30',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 360
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 360,
- 'height': 640
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Galaxy Note 3',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
+ 'viewport': {
+ 'width': 360,
+ 'height': 640,
+ 'deviceScaleFactor': 3,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Nexus 4',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 384
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 384,
- 'height': 640
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Mobile Safari/537.36',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Galaxy Note 3 landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
+ 'viewport': {
+ 'width': 640,
+ 'height': 360,
+ 'deviceScaleFactor': 3,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'title': 'Nexus 5',
- 'type': 'phone',
- 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Mobile Safari/537.36',
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'show-by-default': false,
- 'screen': {
- 'device-pixel-ratio': 3,
- 'vertical': {
- 'width': 360,
- 'height': 640
- },
- 'horizontal': {
- 'width': 640,
- 'height': 360
- }
- },
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 25, 'right': 0, 'bottom': 48 },
- 'image': '@url(google-nexus-5-vertical-default-1x.png) 1x, @url(google-nexus-5-vertical-default-2x.png) 2x'
- },
- {
- 'title': 'navigation bar',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 80, 'right': 0, 'bottom': 48 },
- 'image': '@url(google-nexus-5-vertical-navigation-1x.png) 1x, @url(google-nexus-5-vertical-navigation-2x.png) 2x'
- },
- {
- 'title': 'keyboard',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 80, 'right': 0, 'bottom': 312 },
- 'image': '@url(google-nexus-5-vertical-keyboard-1x.png) 1x, @url(google-nexus-5-vertical-keyboard-2x.png) 2x'
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 25, 'right': 42, 'bottom': 0 },
- 'image': '@url(google-nexus-5-horizontal-default-1x.png) 1x, @url(google-nexus-5-horizontal-default-2x.png) 2x'
- },
- {
- 'title': 'navigation bar',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 80, 'right': 42, 'bottom': 0 },
- 'image': '@url(google-nexus-5-horizontal-navigation-1x.png) 1x, @url(google-nexus-5-horizontal-navigation-2x.png) 2x'
- },
- {
- 'title': 'keyboard',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 80, 'right': 42, 'bottom': 202 },
- 'image': '@url(google-nexus-5-horizontal-keyboard-1x.png) 1x, @url(google-nexus-5-horizontal-keyboard-2x.png) 2x'
- }
- ]
+ 'name': 'Galaxy Note II',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
+ 'viewport': {
+ 'width': 360,
+ 'height': 640,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'order': 20,
- 'device': {
- 'title': 'Nexus 5X',
- 'type': 'phone',
- 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Mobile Safari/537.36',
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'show-by-default': true,
- 'screen': {
- 'device-pixel-ratio': 2.625,
- 'vertical': {
- 'outline' : {
- 'image': '@url(Nexus5X-portrait.svg)',
- 'insets' : { 'left': 18, 'top': 88, 'right': 22, 'bottom': 98 }
- },
- 'width': 412,
- 'height': 732
- },
- 'horizontal': {
- 'outline' : {
- 'image': '@url(Nexus5X-landscape.svg)',
- 'insets' : { 'left': 88, 'top': 21, 'right': 98, 'bottom': 19 }
- },
- 'width': 732,
- 'height': 412
- }
- },
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 24, 'right': 0, 'bottom': 48 },
- 'image': '@url(google-nexus-5x-vertical-default-1x.png) 1x, @url(google-nexus-5x-vertical-default-2x.png) 2x'
- },
- {
- 'title': 'navigation bar',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 80, 'right': 0, 'bottom': 48 },
- 'image': '@url(google-nexus-5x-vertical-navigation-1x.png) 1x, @url(google-nexus-5x-vertical-navigation-2x.png) 2x'
- },
- {
- 'title': 'keyboard',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 80, 'right': 0, 'bottom': 342 },
- 'image': '@url(google-nexus-5x-vertical-keyboard-1x.png) 1x, @url(google-nexus-5x-vertical-keyboard-2x.png) 2x'
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 24, 'right': 48, 'bottom': 0 },
- 'image': '@url(google-nexus-5x-horizontal-default-1x.png) 1x, @url(google-nexus-5x-horizontal-default-2x.png) 2x'
- },
- {
- 'title': 'navigation bar',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 80, 'right': 48, 'bottom': 0 },
- 'image': '@url(google-nexus-5x-horizontal-navigation-1x.png) 1x, @url(google-nexus-5x-horizontal-navigation-2x.png) 2x'
- },
- {
- 'title': 'keyboard',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 80, 'right': 48, 'bottom': 222 },
- 'image': '@url(google-nexus-5x-horizontal-keyboard-1x.png) 1x, @url(google-nexus-5x-horizontal-keyboard-2x.png) 2x'
- }
- ]
+ 'name': 'Galaxy Note II landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
+ 'viewport': {
+ 'width': 640,
+ 'height': 360,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Nexus 6',
- 'screen': {
- 'horizontal': {
- 'width': 732,
- 'height': 412
- },
- 'device-pixel-ratio': 3.5,
- 'vertical': {
- 'width': 412,
- 'height': 732
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Mobile Safari/537.36',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Galaxy S III',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
+ 'viewport': {
+ 'width': 360,
+ 'height': 640,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'order': 30,
- 'device': {
- 'show-by-default': true,
- 'title': 'Nexus 6P',
- 'screen': {
- 'horizontal': {
- 'outline' : {
- 'image': '@url(Nexus6P-landscape.svg)',
- 'insets' : { 'left': 94, 'top': 17, 'right': 88, 'bottom': 17 }
- },
- 'width': 732,
- 'height': 412
- },
- 'device-pixel-ratio': 3.5,
- 'vertical': {
- 'outline' : {
- 'image': '@url(Nexus6P-portrait.svg)',
- 'insets' : { 'left': 16, 'top': 94, 'right': 16, 'bottom': 88 }
- },
- 'width': 412,
- 'height': 732
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Mobile Safari/537.36',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Galaxy S III landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
+ 'viewport': {
+ 'width': 640,
+ 'height': 360,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'LG Optimus L70',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 384
- },
- 'device-pixel-ratio': 1.25,
- 'vertical': {
- 'width': 384,
- 'height': 640
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.104 Mobile Safari/537.36',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Galaxy S5',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 360,
+ 'height': 640,
+ 'deviceScaleFactor': 3,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Nokia N9',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 360
- },
- 'device-pixel-ratio': 1,
- 'vertical': {
- 'width': 360,
- 'height': 640
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Galaxy S5 landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 640,
+ 'height': 360,
+ 'deviceScaleFactor': 3,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Nokia Lumia 520',
- 'screen': {
- 'horizontal': {
- 'width': 533,
- 'height': 320
- },
- 'device-pixel-ratio': 1.5,
- 'vertical': {
- 'width': 320,
- 'height': 533
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPad',
+ 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 768,
+ 'height': 1024,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Microsoft Lumia 550',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 360
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 640,
- 'height': 360
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPad landscape',
+ 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 1024,
+ 'height': 768,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Microsoft Lumia 950',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 360
- },
- 'device-pixel-ratio': 4,
- 'vertical': {
- 'width': 360,
- 'height': 640
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPad Mini',
+ 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 768,
+ 'height': 1024,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Galaxy S III',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 360
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 360,
- 'height': 640
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPad Mini landscape',
+ 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 1024,
+ 'height': 768,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'order': 10,
- 'device': {
- 'show-by-default': true,
- 'title': 'Galaxy S5',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 360
- },
- 'device-pixel-ratio': 3,
- 'vertical': {
- 'width': 360,
- 'height': 640
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Mobile Safari/537.36',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPad Pro',
+ 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 1024,
+ 'height': 1366,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Kindle Fire HDX',
- 'screen': {
- 'horizontal': {
- 'width': 2560,
- 'height': 1600
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 1600,
- 'height': 2560
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true',
- 'type': 'tablet',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPad Pro landscape',
+ 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 1366,
+ 'height': 1024,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'iPad Mini',
- 'screen': {
- 'horizontal': {
- 'width': 1024,
- 'height': 768
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 768,
- 'height': 1024
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
- 'type': 'tablet',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPhone 4',
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 320,
+ 'height': 480,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'order': 70,
- 'device': {
- 'show-by-default': true,
- 'title': 'iPad',
- 'screen': {
- 'horizontal': {
- 'outline' : {
- 'image': '@url(iPad-landscape.svg)',
- 'insets' : { 'left': 112, 'top': 56, 'right': 116, 'bottom': 52 }
- },
- 'width': 1024,
- 'height': 768
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'outline' : {
- 'image': '@url(iPad-portrait.svg)',
- 'insets' : { 'left': 52, 'top': 114, 'right': 55, 'bottom': 114 }
- },
- 'width': 768,
- 'height': 1024
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
- 'type': 'tablet',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPhone 4 landscape',
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 480,
+ 'height': 320,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'order': 80,
- 'device': {
- 'show-by-default': true,
- 'title': 'iPad Pro',
- 'screen': {
- 'horizontal': {
- 'width': 1366,
- 'height': 1024
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 1024,
- 'height': 1366
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
- 'type': 'tablet',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPhone 5',
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 320,
+ 'height': 568,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Blackberry PlayBook',
- 'screen': {
- 'horizontal': {
- 'width': 1024,
- 'height': 600
- },
- 'device-pixel-ratio': 1,
- 'vertical': {
- 'width': 600,
- 'height': 1024
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+',
- 'type': 'tablet',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPhone 5 landscape',
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 568,
+ 'height': 320,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Nexus 10',
- 'screen': {
- 'horizontal': {
- 'width': 1280,
- 'height': 800
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 800,
- 'height': 1280
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36',
- 'type': 'tablet',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPhone 6',
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 375,
+ 'height': 667,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Nexus 7',
- 'screen': {
- 'horizontal': {
- 'width': 960,
- 'height': 600
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 600,
- 'height': 960
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36',
- 'type': 'tablet',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPhone 6 landscape',
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 667,
+ 'height': 375,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Galaxy Note 3',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 360
- },
- 'device-pixel-ratio': 3,
- 'vertical': {
- 'width': 360,
- 'height': 640
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPhone 6 Plus',
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 414,
+ 'height': 736,
+ 'deviceScaleFactor': 3,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Galaxy Note II',
- 'screen': {
- 'horizontal': {
- 'width': 640,
- 'height': 360
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 360,
- 'height': 640
- }
- },
- 'capabilities': [
- 'touch',
- 'mobile'
- ],
- 'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
- 'type': 'phone',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'vertical',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- },
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'iPhone 6 Plus landscape',
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
+ 'viewport': {
+ 'width': 736,
+ 'height': 414,
+ 'deviceScaleFactor': 3,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Laptop with touch',
- 'screen': {
- 'horizontal': {
- 'width': 1280,
- 'height': 950
- },
- 'device-pixel-ratio': 1,
- 'vertical': {
- 'width': 950,
- 'height': 1280
- }
- },
- 'capabilities': [
- 'touch'
- ],
- 'user-agent': '',
- 'type': 'notebook',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Kindle Fire HDX',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true',
+ 'viewport': {
+ 'width': 800,
+ 'height': 1280,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Laptop with HiDPI screen',
- 'screen': {
- 'horizontal': {
- 'width': 1440,
- 'height': 900
- },
- 'device-pixel-ratio': 2,
- 'vertical': {
- 'width': 900,
- 'height': 1440
- }
- },
- 'capabilities': [],
- 'user-agent': '',
- 'type': 'notebook',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'Kindle Fire HDX landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true',
+ 'viewport': {
+ 'width': 1280,
+ 'height': 800,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
},
{
- 'type': 'emulated-device',
- 'device': {
- 'show-by-default': false,
- 'title': 'Laptop with MDPI screen',
- 'screen': {
- 'horizontal': {
- 'width': 1280,
- 'height': 800
- },
- 'device-pixel-ratio': 1,
- 'vertical': {
- 'width': 800,
- 'height': 1280
- }
- },
- 'capabilities': [],
- 'user-agent': '',
- 'type': 'notebook',
- 'modes': [
- {
- 'title': 'default',
- 'orientation': 'horizontal',
- 'insets': { 'left': 0, 'top': 0, 'right': 0, 'bottom': 0 }
- }
- ]
+ 'name': 'LG Optimus L70',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 384,
+ 'height': 640,
+ 'deviceScaleFactor': 1.25,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'LG Optimus L70 landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 640,
+ 'height': 384,
+ 'deviceScaleFactor': 1.25,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Microsoft Lumia 550',
+ 'userAgent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
+ 'viewport': {
+ 'width': 640,
+ 'height': 360,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Microsoft Lumia 950',
+ 'userAgent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
+ 'viewport': {
+ 'width': 360,
+ 'height': 640,
+ 'deviceScaleFactor': 4,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Microsoft Lumia 950 landscape',
+ 'userAgent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
+ 'viewport': {
+ 'width': 640,
+ 'height': 360,
+ 'deviceScaleFactor': 4,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Nexus 10',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36',
+ 'viewport': {
+ 'width': 800,
+ 'height': 1280,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Nexus 10 landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36',
+ 'viewport': {
+ 'width': 1280,
+ 'height': 800,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Nexus 4',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 384,
+ 'height': 640,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Nexus 4 landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 640,
+ 'height': 384,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Nexus 5',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 360,
+ 'height': 640,
+ 'deviceScaleFactor': 3,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Nexus 5 landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 640,
+ 'height': 360,
+ 'deviceScaleFactor': 3,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Nexus 5X',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 412,
+ 'height': 732,
+ 'deviceScaleFactor': 2.625,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Nexus 5X landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 732,
+ 'height': 412,
+ 'deviceScaleFactor': 2.625,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Nexus 6',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 412,
+ 'height': 732,
+ 'deviceScaleFactor': 3.5,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Nexus 6 landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 732,
+ 'height': 412,
+ 'deviceScaleFactor': 3.5,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Nexus 6P',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 412,
+ 'height': 732,
+ 'deviceScaleFactor': 3.5,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Nexus 6P landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36',
+ 'viewport': {
+ 'width': 732,
+ 'height': 412,
+ 'deviceScaleFactor': 3.5,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Nexus 7',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36',
+ 'viewport': {
+ 'width': 600,
+ 'height': 960,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Nexus 7 landscape',
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36',
+ 'viewport': {
+ 'width': 960,
+ 'height': 600,
+ 'deviceScaleFactor': 2,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Nokia Lumia 520',
+ 'userAgent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)',
+ 'viewport': {
+ 'width': 320,
+ 'height': 533,
+ 'deviceScaleFactor': 1.5,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Nokia Lumia 520 landscape',
+ 'userAgent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)',
+ 'viewport': {
+ 'width': 533,
+ 'height': 320,
+ 'deviceScaleFactor': 1.5,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
+ }
+ },
+ {
+ 'name': 'Nokia N9',
+ 'userAgent': 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13',
+ 'viewport': {
+ 'width': 480,
+ 'height': 854,
+ 'deviceScaleFactor': 1,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': false
+ }
+ },
+ {
+ 'name': 'Nokia N9 landscape',
+ 'userAgent': 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13',
+ 'viewport': {
+ 'width': 854,
+ 'height': 480,
+ 'deviceScaleFactor': 1,
+ 'isMobile': true,
+ 'hasTouch': true,
+ 'isLandscape': true
}
}
];
+for (let device of module.exports)
+ module.exports[device.name] = device;
diff --git a/lib/EmulationManager.js b/lib/EmulationManager.js
index 85425ad617f..ce78c41664b 100644
--- a/lib/EmulationManager.js
+++ b/lib/EmulationManager.js
@@ -21,7 +21,7 @@ class EmulationManager {
* @return {!Promise>}
*/
static deviceNames() {
- return Promise.resolve(DeviceDescriptors.map(entry => entry['device'].title));
+ return Promise.resolve(DeviceDescriptors.map(device => device.name));
}
/**
@@ -29,31 +29,20 @@ class EmulationManager {
* @param {!Object=} options
* @return {!Page.Viewport}
*/
- static deviceViewport(name, options) {
- options = options || {};
- const descriptor = DeviceDescriptors.find(entry => entry['device'].title === name)['device'];
- if (!descriptor)
+ static deviceViewport(name) {
+ const device = DeviceDescriptors.find(device => device.name === name);
+ if (!device)
throw new Error(`Unable to emulate ${name}, no such device metrics in the library.`);
- const device = EmulationManager.loadFromJSONV1(descriptor);
- const viewport = options.landscape ? device.horizontal : device.vertical;
- return {
- width: viewport.width,
- height: viewport.height,
- deviceScaleFactor: device.deviceScaleFactor,
- isMobile: device.capabilities.includes('mobile'),
- hasTouch: device.capabilities.includes('touch'),
- isLandscape: options.landscape || false
- };
+ return device.viewport;
}
/**
* @param {string} name
*/
- static deviceUserAgent(name, options) {
- const descriptor = DeviceDescriptors.find(entry => entry['device'].title === name)['device'];
- if (!descriptor)
+ static deviceUserAgent(name) {
+ const device = DeviceDescriptors.find(device => device.name === name);
+ if (!device)
throw new Error(`Unable to emulate ${name}, no such device metrics in the library.`);
- const device = EmulationManager.loadFromJSONV1(descriptor);
return device.userAgent;
}
@@ -110,86 +99,6 @@ class EmulationManager {
}
return reloadNeeded;
}
-
- /**
- * @param {*} json
- * @return {?Object}
- */
- static loadFromJSONV1(json) {
- /**
- * @param {*} object
- * @param {string} key
- * @param {string} type
- * @param {*=} defaultValue
- * @return {*}
- */
- function parseValue(object, key, type, defaultValue) {
- if (typeof object !== 'object' || object === null || !object.hasOwnProperty(key)) {
- if (typeof defaultValue !== 'undefined')
- return defaultValue;
- throw new Error('Emulated device is missing required property \'' + key + '\'');
- }
- const value = object[key];
- if (typeof value !== type || value === null)
- throw new Error('Emulated device property \'' + key + '\' has wrong type \'' + typeof value + '\'');
- return value;
- }
-
- /**
- * @param {*} object
- * @param {string} key
- * @return {number}
- */
- function parseIntValue(object, key) {
- const value = /** @type {number} */ (parseValue(object, key, 'number'));
- if (value !== Math.abs(value))
- throw new Error('Emulated device value \'' + key + '\' must be integer');
- return value;
- }
-
- /**
- * @param {*} json
- * @return {!{width: number, height: number}}
- */
- function parseOrientation(json) {
- const result = {};
- const minDeviceSize = 50;
- const maxDeviceSize = 9999;
- result.width = parseIntValue(json, 'width');
- if (result.width < 0 || result.width > maxDeviceSize ||
- result.width < minDeviceSize)
- throw new Error('Emulated device has wrong width: ' + result.width);
-
- result.height = parseIntValue(json, 'height');
- if (result.height < 0 || result.height > maxDeviceSize ||
- result.height < minDeviceSize)
- throw new Error('Emulated device has wrong height: ' + result.height);
-
- return /** @type {!{width: number, height: number}} */ (result);
- }
-
- const result = {};
- result.type = /** @type {string} */ (parseValue(json, 'type', 'string'));
- result.userAgent = /** @type {string} */ (parseValue(json, 'user-agent', 'string'));
-
- const capabilities = parseValue(json, 'capabilities', 'object', []);
- if (!Array.isArray(capabilities))
- throw new Error('Emulated device capabilities must be an array');
- result.capabilities = [];
- for (let i = 0; i < capabilities.length; ++i) {
- if (typeof capabilities[i] !== 'string')
- throw new Error('Emulated device capability must be a string');
- result.capabilities.push(capabilities[i]);
- }
-
- result.deviceScaleFactor = /** @type {number} */ (parseValue(json['screen'], 'device-pixel-ratio', 'number'));
- if (result.deviceScaleFactor < 0 || result.deviceScaleFactor > 100)
- throw new Error('Emulated device has wrong deviceScaleFactor: ' + result.deviceScaleFactor);
-
- result.vertical = parseOrientation(parseValue(json['screen'], 'vertical', 'object'));
- result.horizontal = parseOrientation(parseValue(json['screen'], 'horizontal', 'object'));
- return result;
- }
}
EmulationManager._touchScriptId = Symbol('emulatingTouchScriptId');
diff --git a/lib/Page.js b/lib/Page.js
index 88091bffedb..630c9268736 100644
--- a/lib/Page.js
+++ b/lib/Page.js
@@ -358,13 +358,12 @@ class Page extends EventEmitter {
/**
* @param {string} name
- * @param {!Object=} options
* @return {!Promise}
*/
- emulate(name, options) {
+ emulate(name) {
return Promise.all([
this.setUserAgent(EmulationManager.deviceUserAgent(name)),
- this.setViewport(EmulationManager.deviceViewport(name, options))
+ this.setViewport(EmulationManager.deviceViewport(name))
]);
}
diff --git a/utils/fetch_devices.js b/utils/fetch_devices.js
new file mode 100755
index 00000000000..5f102589387
--- /dev/null
+++ b/utils/fetch_devices.js
@@ -0,0 +1,224 @@
+#!/usr/bin/env node
+/**
+ * Copyright 2017 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const util = require('util');
+const fs = require('fs');
+const path = require('path');
+const DEVICES_URL = 'https://raw.githubusercontent.com/ChromeDevTools/devtools-frontend/master/front_end/emulated_devices/module.json';
+
+const template = `/**
+ * Copyright 2017 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = %s;
+for (let device of module.exports)
+ module.exports[device.name] = device;
+`;
+
+const help = `Usage: node ${path.basename(__filename)} [-u ]
+ -u, --url The URL to load devices descriptor from. If not set,
+ devices will be fetched from the tip-of-tree of DevTools
+ frontend.
+
+ -h, --help Show this help message
+
+Fetch Chrome DevTools front-end emulation devices from given URL, convert them to puppeteer
+devices and save to the .
+`;
+
+let argv = require('minimist')(process.argv.slice(2), {
+ alias: { u: 'url', h: 'help' },
+});
+
+if (argv.help) {
+ console.log(help);
+ return;
+}
+
+let url = argv.url || DEVICES_URL;
+let outputPath = argv._[0];
+if (!outputPath) {
+ console.log('ERROR: output file name is missing. Use --help for help.');
+ return;
+}
+
+main(url);
+
+async function main(url) {
+ console.log('GET ' + url);
+ let text = await httpGET(url);
+ let json = null;
+ try {
+ json = JSON.parse(text);
+ } catch (e) {
+ console.error(`FAILED: error parsing response - ${e.message}`);
+ return;
+ }
+ let devicePayloads = json.extensions.filter(extension => extension.type === 'emulated-device').map(extension => extension.device);
+ let devices = [];
+ for (let payload of devicePayloads) {
+ let device = createDevice(payload, false);
+ let landscape = createDevice(payload, true);
+ devices.push(device);
+ if (landscape.viewport.width !== device.viewport.width || landscape.viewport.height !== device.viewport.height)
+ devices.push(landscape);
+ }
+ devices = devices.filter(device => device.viewport.isMobile);
+ devices.sort((a, b) => a.name.localeCompare(b.name));
+ // Use single-quotes instead of double-quotes to conform with codestyle.
+ let serialized = JSON.stringify(devices, null, 2)
+ .replace(/'/g, `\\'`)
+ .replace(/"/g, `'`);
+ let result = util.format(template, serialized);
+ fs.writeFileSync(outputPath, result, 'utf8');
+}
+
+/**
+ * @param {*} descriptor
+ * @param {boolean} landscape
+ * @return {!Object}
+ */
+function createDevice(descriptor, landscape) {
+ const devicePayload = loadFromJSONV1(descriptor);
+ const viewportPayload = landscape ? devicePayload.horizontal : devicePayload.vertical;
+ return {
+ name: descriptor.title + (landscape ? ' landscape' : ''),
+ userAgent: devicePayload.userAgent,
+ viewport: {
+ width: viewportPayload.width,
+ height: viewportPayload.height,
+ deviceScaleFactor: devicePayload.deviceScaleFactor,
+ isMobile: devicePayload.capabilities.includes('mobile'),
+ hasTouch: devicePayload.capabilities.includes('touch'),
+ isLandscape: landscape || false
+ }
+ };
+}
+
+/**
+ * @param {*} json
+ * @return {?Object}
+ */
+function loadFromJSONV1(json) {
+ /**
+ * @param {*} object
+ * @param {string} key
+ * @param {string} type
+ * @param {*=} defaultValue
+ * @return {*}
+ */
+ function parseValue(object, key, type, defaultValue) {
+ if (typeof object !== 'object' || object === null || !object.hasOwnProperty(key)) {
+ if (typeof defaultValue !== 'undefined')
+ return defaultValue;
+ throw new Error('Emulated device is missing required property \'' + key + '\'');
+ }
+ const value = object[key];
+ if (typeof value !== type || value === null)
+ throw new Error('Emulated device property \'' + key + '\' has wrong type \'' + typeof value + '\'');
+ return value;
+ }
+
+ /**
+ * @param {*} object
+ * @param {string} key
+ * @return {number}
+ */
+ function parseIntValue(object, key) {
+ const value = /** @type {number} */ (parseValue(object, key, 'number'));
+ if (value !== Math.abs(value))
+ throw new Error('Emulated device value \'' + key + '\' must be integer');
+ return value;
+ }
+
+ /**
+ * @param {*} json
+ * @return {!{width: number, height: number}}
+ */
+ function parseOrientation(json) {
+ const result = {};
+ const minDeviceSize = 50;
+ const maxDeviceSize = 9999;
+ result.width = parseIntValue(json, 'width');
+ if (result.width < 0 || result.width > maxDeviceSize ||
+ result.width < minDeviceSize)
+ throw new Error('Emulated device has wrong width: ' + result.width);
+
+ result.height = parseIntValue(json, 'height');
+ if (result.height < 0 || result.height > maxDeviceSize ||
+ result.height < minDeviceSize)
+ throw new Error('Emulated device has wrong height: ' + result.height);
+
+ return /** @type {!{width: number, height: number}} */ (result);
+ }
+
+ const result = {};
+ result.type = /** @type {string} */ (parseValue(json, 'type', 'string'));
+ result.userAgent = /** @type {string} */ (parseValue(json, 'user-agent', 'string'));
+
+ const capabilities = parseValue(json, 'capabilities', 'object', []);
+ if (!Array.isArray(capabilities))
+ throw new Error('Emulated device capabilities must be an array');
+ result.capabilities = [];
+ for (let i = 0; i < capabilities.length; ++i) {
+ if (typeof capabilities[i] !== 'string')
+ throw new Error('Emulated device capability must be a string');
+ result.capabilities.push(capabilities[i]);
+ }
+
+ result.deviceScaleFactor = /** @type {number} */ (parseValue(json['screen'], 'device-pixel-ratio', 'number'));
+ if (result.deviceScaleFactor < 0 || result.deviceScaleFactor > 100)
+ throw new Error('Emulated device has wrong deviceScaleFactor: ' + result.deviceScaleFactor);
+
+ result.vertical = parseOrientation(parseValue(json['screen'], 'vertical', 'object'));
+ result.horizontal = parseOrientation(parseValue(json['screen'], 'horizontal', 'object'));
+ return result;
+}
+
+/**
+ * @param {url}
+ * @return {!Promise}
+ */
+function httpGET(url) {
+ let fulfill, reject;
+ const promise = new Promise((res, rej) => {
+ fulfill = res;
+ reject = rej;
+ });
+ const driver = url.startsWith('https://') ? require('https') : require('http');
+ const request = driver.get(url, response => {
+ let data = '';
+ response.setEncoding('utf8');
+ response.on('data', chunk => data += chunk);
+ response.on('end', () => fulfill(data));
+ response.on('error', reject);
+ });
+ request.on('error', reject);
+ return promise;
+}