mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-01 08:34:02 +03:00
feat(electron): experimental electron support (#2166)
This commit is contained in:
parent
a2bee2ca73
commit
ffe7084652
@ -15,7 +15,10 @@
|
||||
*/
|
||||
|
||||
const { Playwright } = require('./lib/server/playwright');
|
||||
const { Electron } = require('./lib/server/electron');
|
||||
const path = require('path');
|
||||
|
||||
const playwrightRoot = path.join(__dirname, 'packages', 'playwright');
|
||||
module.exports = new Playwright(playwrightRoot, require(path.join(playwrightRoot, 'browsers.json'))['browsers']);
|
||||
const playwright = new Playwright(playwrightRoot, require(path.join(playwrightRoot, 'browsers.json'))['browsers']);
|
||||
playwright.electron = new Electron();
|
||||
module.exports = playwright;
|
||||
|
513
package-lock.json
generated
513
package-lock.json
generated
@ -30,6 +30,38 @@
|
||||
"js-tokens": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@electron/get": {
|
||||
"version": "1.12.2",
|
||||
"resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.2.tgz",
|
||||
"integrity": "sha512-vAuHUbfvBQpYTJ5wB7uVIDq5c/Ry0fiTBMs7lnEYAo/qXXppIVcWdfBr57u6eRnKdVso7KSiH6p/LbQAG6Izrg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"env-paths": "^2.2.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"global-agent": "^2.0.2",
|
||||
"global-tunnel-ng": "^2.7.1",
|
||||
"got": "^9.6.0",
|
||||
"progress": "^2.0.3",
|
||||
"sanitize-filename": "^1.6.2",
|
||||
"sumchecker": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
|
||||
"integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@szmarczak/http-timer": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
|
||||
"integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"defer-to-connect": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"@types/color-name": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
||||
@ -810,6 +842,13 @@
|
||||
"integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==",
|
||||
"dev": true
|
||||
},
|
||||
"boolean": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.1.tgz",
|
||||
"integrity": "sha512-HRZPIjPcbwAVQvOTxR4YE3o8Xs98NqbbL1iEZDCz7CL8ql0Lt5iOyJFxfnAB0oFs8Oh02F/lLlg30Mexv46LjA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
@ -1012,6 +1051,29 @@
|
||||
"unset-value": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"cacheable-request": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
|
||||
"integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clone-response": "^1.0.2",
|
||||
"get-stream": "^5.1.0",
|
||||
"http-cache-semantics": "^4.0.0",
|
||||
"keyv": "^3.0.0",
|
||||
"lowercase-keys": "^2.0.0",
|
||||
"normalize-url": "^4.1.0",
|
||||
"responselike": "^1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"lowercase-keys": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
|
||||
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
@ -1250,6 +1312,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"clone-response": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
|
||||
"integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-response": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"collection-visit": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
|
||||
@ -1328,6 +1399,17 @@
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"config-chain": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
|
||||
"integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ini": "^1.3.4",
|
||||
"proto-list": "~1.2.1"
|
||||
}
|
||||
},
|
||||
"console-browserify": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
|
||||
@ -1371,6 +1453,13 @@
|
||||
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
|
||||
"dev": true
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.6.5",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
|
||||
"integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
@ -1497,12 +1586,37 @@
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
||||
"dev": true
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
|
||||
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-response": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"deep-is": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
|
||||
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
|
||||
"dev": true
|
||||
},
|
||||
"defer-to-connect": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
|
||||
"integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
|
||||
"dev": true
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"object-keys": "^1.0.12"
|
||||
}
|
||||
},
|
||||
"define-property": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
|
||||
@ -1560,6 +1674,13 @@
|
||||
"integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
|
||||
"dev": true
|
||||
},
|
||||
"detect-node": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
|
||||
"integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"diffie-hellman": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
|
||||
@ -1594,6 +1715,12 @@
|
||||
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
|
||||
"dev": true
|
||||
},
|
||||
"duplexer3": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
|
||||
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
|
||||
"dev": true
|
||||
},
|
||||
"duplexify": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
|
||||
@ -1606,6 +1733,52 @@
|
||||
"stream-shift": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"electron": {
|
||||
"version": "9.0.0-beta.24",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-9.0.0-beta.24.tgz",
|
||||
"integrity": "sha512-25L3XMqm/1CCaV5CgU5ZkhKXw9830WeipJrTW0+VC5XTKp/3xHwhxyQ5G1kQnOTJd7IGwOamvw237D6e1YKnng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@electron/get": "^1.0.1",
|
||||
"@types/node": "^12.0.12",
|
||||
"extract-zip": "^1.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "12.12.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.38.tgz",
|
||||
"integrity": "sha512-75eLjX0pFuTcUXnnWmALMzzkYorjND0ezNEycaKesbUBg9eGZp4GHPuDmkRc4mQQvIpe29zrzATNRA6hkYqwmA==",
|
||||
"dev": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"extract-zip": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
|
||||
"integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"concat-stream": "^1.6.2",
|
||||
"debug": "^2.6.9",
|
||||
"mkdirp": "^0.5.4",
|
||||
"yauzl": "^2.10.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
|
||||
@ -1641,6 +1814,13 @@
|
||||
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
@ -1666,6 +1846,12 @@
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
||||
"dev": true
|
||||
},
|
||||
"env-paths": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
|
||||
"integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
|
||||
"dev": true
|
||||
},
|
||||
"errno": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
|
||||
@ -1675,6 +1861,13 @@
|
||||
"prr": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"es6-error": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
|
||||
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
@ -2317,6 +2510,17 @@
|
||||
"readable-stream": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"fs-write-stream-atomic": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
|
||||
@ -2393,6 +2597,31 @@
|
||||
"is-glob": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"global-agent": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.8.tgz",
|
||||
"integrity": "sha512-VpBe/rhY6Rw2VDOTszAMNambg+4Qv8j0yiTNDYEXXXxkUNGWLHp8A3ztK4YDBbFNcWF4rgsec6/5gPyryya/+A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"boolean": "^3.0.0",
|
||||
"core-js": "^3.6.4",
|
||||
"es6-error": "^4.1.1",
|
||||
"matcher": "^2.1.0",
|
||||
"roarr": "^2.15.2",
|
||||
"semver": "^7.1.2",
|
||||
"serialize-error": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"global-modules": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
|
||||
@ -2428,6 +2657,19 @@
|
||||
"which": "^1.2.14"
|
||||
}
|
||||
},
|
||||
"global-tunnel-ng": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz",
|
||||
"integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"encodeurl": "^1.0.2",
|
||||
"lodash": "^4.17.10",
|
||||
"npm-conf": "^1.1.3",
|
||||
"tunnel": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "12.4.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
|
||||
@ -2437,6 +2679,46 @@
|
||||
"type-fest": "^0.8.1"
|
||||
}
|
||||
},
|
||||
"globalthis": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz",
|
||||
"integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"define-properties": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"got": {
|
||||
"version": "9.6.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
|
||||
"integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@sindresorhus/is": "^0.14.0",
|
||||
"@szmarczak/http-timer": "^1.1.2",
|
||||
"cacheable-request": "^6.0.0",
|
||||
"decompress-response": "^3.3.0",
|
||||
"duplexer3": "^0.1.4",
|
||||
"get-stream": "^4.1.0",
|
||||
"lowercase-keys": "^1.0.1",
|
||||
"mimic-response": "^1.0.1",
|
||||
"p-cancelable": "^1.0.0",
|
||||
"to-readable-stream": "^1.0.0",
|
||||
"url-parse-lax": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||
@ -2561,6 +2843,12 @@
|
||||
"parse-passwd": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
|
||||
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
|
||||
"dev": true
|
||||
},
|
||||
"https-browserify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
|
||||
@ -2932,6 +3220,12 @@
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"json-buffer": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
|
||||
"integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
|
||||
"dev": true
|
||||
},
|
||||
"json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
@ -2950,6 +3244,13 @@
|
||||
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
|
||||
"dev": true
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
@ -2959,6 +3260,24 @@
|
||||
"minimist": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"keyv": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
|
||||
"integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"json-buffer": "3.0.0"
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
@ -3017,6 +3336,12 @@
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
||||
"dev": true
|
||||
},
|
||||
"lowercase-keys": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
|
||||
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
|
||||
"dev": true
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
@ -3068,6 +3393,25 @@
|
||||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"matcher": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz",
|
||||
"integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"escape-string-regexp": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"escape-string-regexp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
|
||||
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"md5.js": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
||||
@ -3145,6 +3489,12 @@
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
|
||||
"dev": true
|
||||
},
|
||||
"minimalistic-assert": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||
@ -3356,6 +3706,32 @@
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true
|
||||
},
|
||||
"normalize-url": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
|
||||
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
|
||||
"dev": true
|
||||
},
|
||||
"npm-conf": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
|
||||
"integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"config-chain": "^1.1.11",
|
||||
"pify": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"npm-run-path": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
|
||||
@ -3402,6 +3778,13 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-visit": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
|
||||
@ -3474,6 +3857,12 @@
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"dev": true
|
||||
},
|
||||
"p-cancelable": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
|
||||
"integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
|
||||
"dev": true
|
||||
},
|
||||
"p-defer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
|
||||
@ -3670,6 +4059,12 @@
|
||||
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
|
||||
"dev": true
|
||||
},
|
||||
"prepend-http": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
|
||||
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
|
||||
"dev": true
|
||||
},
|
||||
"process": {
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||
@ -3693,6 +4088,13 @@
|
||||
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
|
||||
"dev": true
|
||||
},
|
||||
"proto-list": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
|
||||
"integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
@ -4024,6 +4426,15 @@
|
||||
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
|
||||
"dev": true
|
||||
},
|
||||
"responselike": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
|
||||
"integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lowercase-keys": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"restore-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
|
||||
@ -4058,6 +4469,30 @@
|
||||
"inherits": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"roarr": {
|
||||
"version": "2.15.3",
|
||||
"resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.3.tgz",
|
||||
"integrity": "sha512-AEjYvmAhlyxOeB9OqPUzQCo3kuAkNfuDk/HqWbZdFsqDFpapkTjiw+p4svNEoRLvuqNTxqfL+s+gtD4eDgZ+CA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"boolean": "^3.0.0",
|
||||
"detect-node": "^2.0.4",
|
||||
"globalthis": "^1.0.1",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"semver-compare": "^1.0.0",
|
||||
"sprintf-js": "^1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"sprintf-js": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
|
||||
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"run-async": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
||||
@ -4103,6 +4538,15 @@
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true
|
||||
},
|
||||
"sanitize-filename": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
|
||||
"integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"truncate-utf8-bytes": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
|
||||
@ -4120,6 +4564,23 @@
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"dev": true
|
||||
},
|
||||
"semver-compare": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
|
||||
"integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"serialize-error": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz",
|
||||
"integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.8.0"
|
||||
}
|
||||
},
|
||||
"serialize-javascript": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
|
||||
@ -4532,6 +4993,15 @@
|
||||
"integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
|
||||
"dev": true
|
||||
},
|
||||
"sumchecker": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
|
||||
"integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
@ -4700,6 +5170,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"to-readable-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
|
||||
"dev": true
|
||||
},
|
||||
"to-regex": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
|
||||
@ -4721,6 +5197,15 @@
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"truncate-utf8-bytes": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
|
||||
"integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"utf8-byte-length": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz",
|
||||
@ -4755,6 +5240,13 @@
|
||||
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
|
||||
"dev": true
|
||||
},
|
||||
"tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
|
||||
@ -4812,6 +5304,12 @@
|
||||
"imurmurhash": "^0.1.4"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true
|
||||
},
|
||||
"unset-value": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
|
||||
@ -4891,12 +5389,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"url-parse-lax": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
|
||||
"integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"prepend-http": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"use": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
|
||||
"dev": true
|
||||
},
|
||||
"utf8-byte-length": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
|
||||
"integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=",
|
||||
"dev": true
|
||||
},
|
||||
"util": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
|
||||
|
@ -64,6 +64,7 @@
|
||||
"colors": "^1.4.0",
|
||||
"commonmark": "^0.28.1",
|
||||
"cross-env": "^5.0.5",
|
||||
"electron": "^9.0.0-beta.24",
|
||||
"eslint": "^6.6.0",
|
||||
"esprima": "^4.0.0",
|
||||
"formidable": "^1.2.1",
|
||||
|
2
packages/playwright-electron/README.md
Normal file
2
packages/playwright-electron/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# playwright-electron
|
||||
This package contains the [Electron](https://www.electronjs.org/) flavor of [Playwright](http://github.com/microsoft/playwright).
|
3
packages/playwright-electron/browsers.json
Normal file
3
packages/playwright-electron/browsers.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"browsers": []
|
||||
}
|
20
packages/playwright-electron/index.d.ts
vendored
Normal file
20
packages/playwright-electron/index.d.ts
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import * as types from 'playwright-core/types/types';
|
||||
|
||||
export * from 'playwright-core/types/types';
|
||||
export const electron: types.BrowserType<types.Electron>;
|
22
packages/playwright-electron/index.js
Normal file
22
packages/playwright-electron/index.js
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* 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 { Playwright } = require('playwright-core/lib/server/playwright');
|
||||
const { Electron } = require('playwright-core/lib/server/electron');
|
||||
|
||||
const playwright = new Playwright(__dirname, require('./browsers.json')['browsers']);
|
||||
playwright.electron = new Electron();
|
||||
module.exports = playwright;
|
16
packages/playwright-electron/package.json
Normal file
16
packages/playwright-electron/package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "playwright-electron",
|
||||
"version": "0.1.0",
|
||||
"description": "A high-level API to automate Electron",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
"main": "index.js",
|
||||
"scripts": {},
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "^1.0.1"
|
||||
}
|
||||
}
|
198
src/server/electron.ts
Normal file
198
src/server/electron.ts
Normal file
@ -0,0 +1,198 @@
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import * as path from 'path';
|
||||
import { CRBrowser, CRBrowserContext } from '../chromium/crBrowser';
|
||||
import { CRConnection, CRSession } from '../chromium/crConnection';
|
||||
import { CRExecutionContext } from '../chromium/crExecutionContext';
|
||||
import { TimeoutError } from '../errors';
|
||||
import { Events } from '../events';
|
||||
import { ExtendedEventEmitter } from '../extendedEventEmitter';
|
||||
import { helper } from '../helper';
|
||||
import * as js from '../javascript';
|
||||
import { InnerLogger, Logger, RootLogger } from '../logger';
|
||||
import { Page } from '../page';
|
||||
import { TimeoutSettings } from '../timeoutSettings';
|
||||
import { WebSocketTransport } from '../transport';
|
||||
import * as types from '../types';
|
||||
import { BrowserServer } from './browserServer';
|
||||
import { launchProcess, waitForLine } from './processLauncher';
|
||||
import { BrowserContext } from '../browserContext';
|
||||
|
||||
type ElectronLaunchOptions = {
|
||||
args?: string[],
|
||||
cwd?: string,
|
||||
env?: {[key: string]: string|number|boolean},
|
||||
handleSIGINT?: boolean,
|
||||
handleSIGTERM?: boolean,
|
||||
handleSIGHUP?: boolean,
|
||||
timeout?: number,
|
||||
logger?: Logger,
|
||||
};
|
||||
|
||||
export const ElectronEvents = {
|
||||
ElectronApplication: {
|
||||
Close: 'close',
|
||||
Window: 'window',
|
||||
}
|
||||
};
|
||||
|
||||
export class ElectronApplication extends ExtendedEventEmitter {
|
||||
private _logger: InnerLogger;
|
||||
private _browserContext: CRBrowserContext;
|
||||
private _nodeConnection: CRConnection;
|
||||
private _nodeSession: CRSession;
|
||||
private _nodeExecutionContext: js.ExecutionContext | undefined;
|
||||
private _nodeElectronHandle: js.JSHandle<any> | undefined;
|
||||
private _windows = new Set<Page>();
|
||||
private _lastWindowId = 0;
|
||||
readonly _timeoutSettings = new TimeoutSettings();
|
||||
|
||||
constructor(logger: InnerLogger, browser: CRBrowser, nodeConnection: CRConnection) {
|
||||
super();
|
||||
this._logger = logger;
|
||||
this._browserContext = browser._defaultContext!;
|
||||
this._browserContext.on(Events.BrowserContext.Close, () => this.emit(ElectronEvents.ElectronApplication.Close));
|
||||
this._browserContext.on(Events.BrowserContext.Page, event => this._onPage(event));
|
||||
this._nodeConnection = nodeConnection;
|
||||
this._nodeSession = nodeConnection.rootSession;
|
||||
}
|
||||
|
||||
private async _onPage(page: Page) {
|
||||
// Needs to be sync.
|
||||
const windowId = ++this._lastWindowId;
|
||||
// Can be async.
|
||||
const handle = await this._nodeElectronHandle!.evaluateHandle(({ BrowserWindow }, windowId) => BrowserWindow.fromId(windowId), windowId);
|
||||
(page as any).browserWindow = handle;
|
||||
(page as any)._browserWindowId = windowId;
|
||||
page.on(Events.Page.Close, () => {
|
||||
(page as any).browserWindow.dispose();
|
||||
this._windows.delete(page);
|
||||
});
|
||||
this._windows.add(page);
|
||||
this.emit(ElectronEvents.ElectronApplication.Window, page);
|
||||
}
|
||||
|
||||
windows(): Page[] {
|
||||
return [...this._windows];
|
||||
}
|
||||
|
||||
async newBrowserWindow(options: any): Promise<Page> {
|
||||
const windowId = await this.evaluate(async ({ BrowserWindow }, options) => {
|
||||
const win = new BrowserWindow(options);
|
||||
win.loadURL('about:blank');
|
||||
return win.id;
|
||||
}, options);
|
||||
|
||||
for (const page of this._windows) {
|
||||
if ((page as any)._browserWindowId === windowId)
|
||||
return page;
|
||||
}
|
||||
|
||||
return await this.waitForEvent(ElectronEvents.ElectronApplication.Window, (page: Page) => (page as any)._browserWindowId === windowId);
|
||||
}
|
||||
|
||||
context(): BrowserContext {
|
||||
return this._browserContext;
|
||||
}
|
||||
|
||||
async close() {
|
||||
await this.evaluate(({ app }) => app.quit());
|
||||
this._nodeConnection.close();
|
||||
}
|
||||
|
||||
async _init() {
|
||||
this._nodeSession.once('Runtime.executionContextCreated', event => {
|
||||
this._nodeExecutionContext = new js.ExecutionContext(new CRExecutionContext(this._nodeSession, event.context), this._logger);
|
||||
});
|
||||
await this._nodeSession.send('Runtime.enable', {}).catch(e => {});
|
||||
this._nodeElectronHandle = await this._nodeExecutionContext!.evaluateHandleInternal(() => {
|
||||
// Resolving the race between the debugger and the boot-time script.
|
||||
if ((global as any)._playwrightRun)
|
||||
return (global as any)._playwrightRun();
|
||||
return new Promise(f => (global as any)._playwrightRunCallback = f);
|
||||
});
|
||||
}
|
||||
|
||||
async evaluate<R, Arg>(pageFunction: types.FuncOn<any, Arg, R>, arg: Arg): Promise<R>;
|
||||
async evaluate<R>(pageFunction: types.FuncOn<any, void, R>, arg?: any): Promise<R>;
|
||||
async evaluate<R, Arg>(pageFunction: types.FuncOn<any, Arg, R>, arg: Arg): Promise<R> {
|
||||
return this._nodeElectronHandle!.evaluate(pageFunction, arg);
|
||||
}
|
||||
|
||||
async evaluateHandle<R, Arg>(pageFunction: types.FuncOn<any, Arg, R>, arg: Arg): Promise<types.SmartHandle<R>>;
|
||||
async evaluateHandle<R>(pageFunction: types.FuncOn<any, void, R>, arg?: any): Promise<types.SmartHandle<R>>;
|
||||
async evaluateHandle<R, Arg>(pageFunction: types.FuncOn<any, Arg, R>, arg: Arg): Promise<types.SmartHandle<R>> {
|
||||
return this._nodeElectronHandle!.evaluateHandle(pageFunction, arg);
|
||||
}
|
||||
|
||||
protected _computeDeadline(options?: types.TimeoutOptions): number {
|
||||
return this._timeoutSettings.computeDeadline(options);
|
||||
}
|
||||
}
|
||||
|
||||
export class Electron {
|
||||
async launch(executablePath: string, options: ElectronLaunchOptions = {}): Promise<ElectronApplication> {
|
||||
const {
|
||||
args = [],
|
||||
env = process.env,
|
||||
handleSIGINT = true,
|
||||
handleSIGTERM = true,
|
||||
handleSIGHUP = true,
|
||||
timeout = 30000,
|
||||
} = options;
|
||||
const deadline = TimeoutSettings.computeDeadline(timeout);
|
||||
|
||||
let app: ElectronApplication | undefined = undefined;
|
||||
|
||||
const logger = new RootLogger(options.logger);
|
||||
const electronArguments = ['--inspect=0', '--remote-debugging-port=0', '--require', path.join(__dirname, 'electronLoader.js'), ...args];
|
||||
const { launchedProcess, gracefullyClose } = await launchProcess({
|
||||
executablePath,
|
||||
args: electronArguments,
|
||||
env,
|
||||
handleSIGINT,
|
||||
handleSIGTERM,
|
||||
handleSIGHUP,
|
||||
logger,
|
||||
pipe: true,
|
||||
cwd: options.cwd,
|
||||
omitDownloads: true,
|
||||
attemptToGracefullyClose: () => app!.close(),
|
||||
onkill: (exitCode, signal) => {
|
||||
if (app)
|
||||
app.emit(ElectronEvents.ElectronApplication.Close, exitCode, signal);
|
||||
},
|
||||
});
|
||||
|
||||
const timeoutError = new TimeoutError(`Timed out while trying to connect to Electron!`);
|
||||
const nodeMatch = await waitForLine(launchedProcess, launchedProcess.stderr, /^Debugger listening on (ws:\/\/.*)$/, helper.timeUntilDeadline(deadline), timeoutError);
|
||||
const nodeConnection = await WebSocketTransport.connect(nodeMatch[1], transport => {
|
||||
return new CRConnection(transport, logger);
|
||||
});
|
||||
|
||||
const chromeMatch = await waitForLine(launchedProcess, launchedProcess.stderr, /^DevTools listening on (ws:\/\/.*)$/, helper.timeUntilDeadline(deadline), timeoutError);
|
||||
const chromeTransport = await WebSocketTransport.connect(chromeMatch[1], transport => {
|
||||
return transport;
|
||||
});
|
||||
const browserServer = new BrowserServer(launchedProcess, gracefullyClose, null);
|
||||
const browser = await CRBrowser.connect(chromeTransport, true, logger, { ...options, viewport: null });
|
||||
browser._ownedServer = browserServer;
|
||||
app = new ElectronApplication(logger, browser, nodeConnection);
|
||||
await app._init();
|
||||
return app;
|
||||
}
|
||||
}
|
72
src/server/electronLoader.ts
Normal file
72
src/server/electronLoader.ts
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import * as electron from 'electron';
|
||||
|
||||
// Electron loader is passed to Electron as --require electronLoader.js and
|
||||
// defers the app ready event until remote debugging is established.
|
||||
|
||||
(async () => {
|
||||
const app = electron.app;
|
||||
const originalEmitMethod = app.emit.bind(app);
|
||||
const originalIsReadyMethod = app.isReady.bind(app);
|
||||
const originalWhenReadyMethod = app.whenReady.bind(app);
|
||||
|
||||
const deferredEmits: { event: string | symbol, args: any[] }[] = [];
|
||||
let attached = false;
|
||||
let isReady = false;
|
||||
let readyCallback: () => void;
|
||||
const readyPromise = new Promise(f => readyCallback = f);
|
||||
|
||||
app.isReady = () => {
|
||||
if (attached)
|
||||
return originalIsReadyMethod();
|
||||
return isReady;
|
||||
};
|
||||
|
||||
app.whenReady = async () => {
|
||||
if (attached)
|
||||
return originalWhenReadyMethod();
|
||||
await readyPromise;
|
||||
};
|
||||
|
||||
app.emit = (event: string | symbol, ...args: any[]): boolean => {
|
||||
if (attached)
|
||||
return originalEmitMethod(event, ...args);
|
||||
deferredEmits.push({ event, args });
|
||||
return true;
|
||||
};
|
||||
|
||||
const playwrightRun = () => {
|
||||
while (deferredEmits.length) {
|
||||
const emit = deferredEmits.shift();
|
||||
if (emit!.event === 'ready') {
|
||||
isReady = true;
|
||||
readyCallback();
|
||||
}
|
||||
originalEmitMethod(emit!.event, ...emit!.args);
|
||||
}
|
||||
attached = true;
|
||||
return electron;
|
||||
};
|
||||
|
||||
// Resolving the race between the debugger and the boot-time script.
|
||||
if ((global as any)._playwrightRunCallback) {
|
||||
(global as any)._playwrightRunCallback(playwrightRun());
|
||||
return;
|
||||
}
|
||||
(global as any)._playwrightRun = playwrightRun;
|
||||
})();
|
165
test/electron/electron.spec.js
Normal file
165
test/electron/electron.spec.js
Normal file
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* 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 path = require('path');
|
||||
const config = require('../test.config');
|
||||
|
||||
const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
||||
|
||||
describe('Electron', function() {
|
||||
beforeEach(async (state, testRun) => {
|
||||
const electronPath = path.join(__dirname, '..', '..', 'node_modules', '.bin', electronName);
|
||||
state.application = await playwright.electron.launch(electronPath, {
|
||||
args: [path.join(__dirname, 'testApp.js')],
|
||||
logger: {
|
||||
isEnabled: (name, severity) => {
|
||||
return name === 'browser' ||
|
||||
(name === 'protocol' && config.dumpProtocolOnFailure);
|
||||
},
|
||||
log: (name, severity, message, args) => {
|
||||
if (name === 'browser') {
|
||||
if (severity === 'warning')
|
||||
testRun.log(`\x1b[31m[browser]\x1b[0m ${message}`)
|
||||
else
|
||||
testRun.log(`\x1b[33m[browser]\x1b[0m ${message}`)
|
||||
} else if (name === 'protocol' && config.dumpProtocolOnFailure) {
|
||||
testRun.log(`\x1b[32m[protocol]\x1b[0m ${message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
afterEach(async (state, testRun) => {
|
||||
await state.application.close();
|
||||
if (config.dumpProtocolOnFailure) {
|
||||
if (testRun.ok())
|
||||
testRun.output().splice(0);
|
||||
}
|
||||
});
|
||||
it('should script application', async ({ application }) => {
|
||||
const appPath = await application.evaluate(async ({ app }) => app.getAppPath());
|
||||
expect(appPath).toContain('electron');
|
||||
});
|
||||
it('should create window', async ({ application }) => {
|
||||
const [ page ] = await Promise.all([
|
||||
application.waitForEvent('window'),
|
||||
application.evaluate(({ BrowserWindow }) => {
|
||||
const window = new BrowserWindow({ width: 800, height: 600 });
|
||||
window.loadURL('data:text/html,<title>Hello World 1</title>');
|
||||
})
|
||||
]);
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
expect(await page.title()).toBe('Hello World 1');
|
||||
});
|
||||
it('should create window 2', async ({ application }) => {
|
||||
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
||||
await page.goto('data:text/html,<title>Hello World 2</title>');
|
||||
expect(await page.title()).toBe('Hello World 2');
|
||||
});
|
||||
it('should create multiple windows', async ({ application }) => {
|
||||
const createPage = async ordinal => {
|
||||
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.browserWindow.evaluate((window, ordinal) => window.loadURL(`data:text/html,<title>Hello World ${ordinal}</title>`), ordinal)
|
||||
]);
|
||||
return page;
|
||||
};
|
||||
|
||||
const page1 = await createPage(1);
|
||||
const page2 = await createPage(2);
|
||||
const page3 = await createPage(3);
|
||||
await page1.close();
|
||||
const page4 = await createPage(4);
|
||||
const titles = [];
|
||||
for (const window of application.windows())
|
||||
titles.push(await window.title());
|
||||
expect(titles).toEqual(['Hello World 2', 'Hello World 3', 'Hello World 4']);
|
||||
});
|
||||
it('should route network', async ({ application }) => {
|
||||
await application.context().route('**/empty.html', (route, request) => {
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'text/html',
|
||||
body: '<title>Hello World</title>',
|
||||
})
|
||||
});
|
||||
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
||||
await page.goto('https://localhost:1000/empty.html');
|
||||
expect(await page.title()).toBe('Hello World');
|
||||
});
|
||||
it('should support init script', async ({ application }) => {
|
||||
await application.context().addInitScript('window.magic = 42;')
|
||||
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
||||
await page.goto('data:text/html,<script>window.copy = magic</script>');
|
||||
expect(await page.evaluate(() => copy)).toBe(42);
|
||||
});
|
||||
it('should expose function', async ({ application }) => {
|
||||
const result = new Promise(f => callback = f);
|
||||
const t = Date.now();
|
||||
await application.context().exposeFunction('add', (a, b) => a + b);
|
||||
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
||||
await page.goto('data:text/html,<script>window.result = add(20, 22);</script>');
|
||||
expect(await page.evaluate(() => result)).toBe(42);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Electron window', function() {
|
||||
beforeAll(async state => {
|
||||
const electronPath = path.join(__dirname, '..', '..', 'node_modules', '.bin', electronName);
|
||||
state.application = await playwright.electron.launch(electronPath, {
|
||||
args: [path.join(__dirname, 'testApp.js')]
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async state => {
|
||||
await state.application.close();
|
||||
});
|
||||
|
||||
beforeEach(async state => {
|
||||
state.page = await state.application.newBrowserWindow({ width: 800, height: 600 });
|
||||
});
|
||||
|
||||
afterEach(async state => {
|
||||
await state.page.close();
|
||||
});
|
||||
|
||||
it('should click the button', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.click('button');
|
||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
||||
});
|
||||
it('should check the box', async({page}) => {
|
||||
await page.setContent(`<input id='checkbox' type='checkbox'></input>`);
|
||||
await page.check('input');
|
||||
expect(await page.evaluate(() => checkbox.checked)).toBe(true);
|
||||
});
|
||||
it('should not check the checked box', async({page}) => {
|
||||
await page.setContent(`<input id='checkbox' type='checkbox' checked></input>`);
|
||||
await page.check('input');
|
||||
expect(await page.evaluate(() => checkbox.checked)).toBe(true);
|
||||
});
|
||||
it('should type into a textarea', async({page, server}) => {
|
||||
await page.evaluate(() => {
|
||||
const textarea = document.createElement('textarea');
|
||||
document.body.appendChild(textarea);
|
||||
textarea.focus();
|
||||
});
|
||||
const text = 'Hello world. I am the text that was typed!';
|
||||
await page.keyboard.type(text);
|
||||
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe(text);
|
||||
});
|
||||
});
|
3
test/electron/testApp.js
Normal file
3
test/electron/testApp.js
Normal file
@ -0,0 +1,3 @@
|
||||
const { app } = require('electron');
|
||||
|
||||
app.on('window-all-closed', e => e.preventDefault());
|
@ -229,6 +229,15 @@ module.exports = {
|
||||
environments: [customEnvironment],
|
||||
},
|
||||
|
||||
{
|
||||
files: [
|
||||
'./electron/electron.spec.js',
|
||||
],
|
||||
browsers: ['chromium'],
|
||||
title: '[Electron]',
|
||||
environments: [customEnvironment],
|
||||
},
|
||||
|
||||
{
|
||||
files: [
|
||||
'./apicoverage.spec.js',
|
||||
|
Loading…
Reference in New Issue
Block a user