feat(launch): connect to process.env.SELENIUM_REMOTE_URL instead of local launch (#9056)
This commit is contained in:
Родитель
1bebbc31b2
Коммит
2afe76d86d
|
@ -82,6 +82,7 @@
|
|||
"ansi-to-html": "^0.7.1",
|
||||
"babel-loader": "^8.2.2",
|
||||
"chokidar": "^3.5.0",
|
||||
"chromedriver": "^93.0.1",
|
||||
"commonmark": "^0.29.1",
|
||||
"concurrently": "^6.2.1",
|
||||
"cross-env": "^7.0.2",
|
||||
|
@ -1358,6 +1359,12 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@testim/chrome-version": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.0.7.tgz",
|
||||
"integrity": "sha512-8UT/J+xqCYfn3fKtOznAibsHpiuDshCb0fwgWxRazTT19Igp9ovoXMPhXyLD6m3CKQGTMHgqoxaFfMWaL40Rnw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/anymatch": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
|
||||
|
@ -2123,6 +2130,19 @@
|
|||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/aggregate-error": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
|
||||
"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"clean-stack": "^2.0.0",
|
||||
"indent-string": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
|
@ -2379,6 +2399,15 @@
|
|||
"node": ">= 4.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.21.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-loader": {
|
||||
"version": "8.2.2",
|
||||
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz",
|
||||
|
@ -3064,6 +3093,28 @@
|
|||
"node": ">=6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/chromedriver": {
|
||||
"version": "93.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-93.0.1.tgz",
|
||||
"integrity": "sha512-KDzbW34CvQLF5aTkm3b5VdlTrvdIt4wEpCzT2p4XJIQWQZEPco5pNce7Lu9UqZQGkhQ4mpZt4Ky6NKVyIS2N8A==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@testim/chrome-version": "^1.0.7",
|
||||
"axios": "^0.21.2",
|
||||
"del": "^6.0.0",
|
||||
"extract-zip": "^2.0.1",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"proxy-from-env": "^1.1.0",
|
||||
"tcp-port-used": "^1.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"chromedriver": "bin/chromedriver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/cipher-base": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
||||
|
@ -3113,6 +3164,15 @@
|
|||
"node": ">= 4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/clean-stack": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
||||
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cli": {
|
||||
"version": "0.4.5",
|
||||
"resolved": "https://registry.npmjs.org/cli/-/cli-0.4.5.tgz",
|
||||
|
@ -3899,6 +3959,28 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/del": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz",
|
||||
"integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"globby": "^11.0.1",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"is-glob": "^4.0.1",
|
||||
"is-path-cwd": "^2.2.0",
|
||||
"is-path-inside": "^3.0.2",
|
||||
"p-map": "^4.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/des.js": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
|
||||
|
@ -5222,6 +5304,26 @@
|
|||
"readable-stream": "^2.3.6"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.14.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
|
||||
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
|
@ -5987,6 +6089,15 @@
|
|||
"node": ">=0.8.19"
|
||||
}
|
||||
},
|
||||
"node_modules/indent-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/infer-owner": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
|
||||
|
@ -6022,6 +6133,15 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/ip-regex": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
|
||||
"integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-accessor-descriptor": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
|
||||
|
@ -6244,6 +6364,24 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-path-cwd": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
|
||||
"integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/is-path-inside": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
|
||||
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
||||
|
@ -6290,6 +6428,12 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-url": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
|
||||
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
|
@ -6308,6 +6452,20 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/is2": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/is2/-/is2-2.0.7.tgz",
|
||||
"integrity": "sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"deep-is": "^0.1.3",
|
||||
"ip-regex": "^4.1.0",
|
||||
"is-url": "^1.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
|
@ -7454,6 +7612,21 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/p-map": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
|
||||
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"aggregate-error": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
|
@ -9258,6 +9431,16 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tcp-port-used": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
|
||||
"integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "4.3.1",
|
||||
"is2": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
|
||||
|
@ -11626,6 +11809,12 @@
|
|||
"defer-to-connect": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"@testim/chrome-version": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.0.7.tgz",
|
||||
"integrity": "sha512-8UT/J+xqCYfn3fKtOznAibsHpiuDshCb0fwgWxRazTT19Igp9ovoXMPhXyLD6m3CKQGTMHgqoxaFfMWaL40Rnw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/anymatch": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
|
||||
|
@ -12296,6 +12485,16 @@
|
|||
"debug": "4"
|
||||
}
|
||||
},
|
||||
"aggregate-error": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
|
||||
"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clean-stack": "^2.0.0",
|
||||
"indent-string": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
|
@ -12509,6 +12708,15 @@
|
|||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.21.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.0"
|
||||
}
|
||||
},
|
||||
"babel-loader": {
|
||||
"version": "8.2.2",
|
||||
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz",
|
||||
|
@ -13086,6 +13294,21 @@
|
|||
"integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
|
||||
"dev": true
|
||||
},
|
||||
"chromedriver": {
|
||||
"version": "93.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-93.0.1.tgz",
|
||||
"integrity": "sha512-KDzbW34CvQLF5aTkm3b5VdlTrvdIt4wEpCzT2p4XJIQWQZEPco5pNce7Lu9UqZQGkhQ4mpZt4Ky6NKVyIS2N8A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@testim/chrome-version": "^1.0.7",
|
||||
"axios": "^0.21.2",
|
||||
"del": "^6.0.0",
|
||||
"extract-zip": "^2.0.1",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"proxy-from-env": "^1.1.0",
|
||||
"tcp-port-used": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"cipher-base": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
||||
|
@ -13128,6 +13351,12 @@
|
|||
"source-map": "~0.6.0"
|
||||
}
|
||||
},
|
||||
"clean-stack": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
||||
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
|
||||
"dev": true
|
||||
},
|
||||
"cli": {
|
||||
"version": "0.4.5",
|
||||
"resolved": "https://registry.npmjs.org/cli/-/cli-0.4.5.tgz",
|
||||
|
@ -13756,6 +13985,22 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"del": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz",
|
||||
"integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"globby": "^11.0.1",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"is-glob": "^4.0.1",
|
||||
"is-path-cwd": "^2.2.0",
|
||||
"is-path-inside": "^3.0.2",
|
||||
"p-map": "^4.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"des.js": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
|
||||
|
@ -14860,6 +15105,12 @@
|
|||
"readable-stream": "^2.3.6"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.14.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
|
||||
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==",
|
||||
"dev": true
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
|
@ -15483,6 +15734,12 @@
|
|||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
|
||||
"dev": true
|
||||
},
|
||||
"indent-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
||||
"dev": true
|
||||
},
|
||||
"infer-owner": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
|
||||
|
@ -15515,6 +15772,12 @@
|
|||
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
|
||||
"dev": true
|
||||
},
|
||||
"ip-regex": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
|
||||
"integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==",
|
||||
"dev": true
|
||||
},
|
||||
"is-accessor-descriptor": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
|
||||
|
@ -15680,6 +15943,18 @@
|
|||
"integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==",
|
||||
"dev": true
|
||||
},
|
||||
"is-path-cwd": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
|
||||
"integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-path-inside": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
|
||||
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
||||
|
@ -15714,6 +15989,12 @@
|
|||
"has-symbols": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"is-url": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
|
||||
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
|
||||
"dev": true
|
||||
},
|
||||
"is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
|
@ -15726,6 +16007,17 @@
|
|||
"integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
|
||||
"dev": true
|
||||
},
|
||||
"is2": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/is2/-/is2-2.0.7.tgz",
|
||||
"integrity": "sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"deep-is": "^0.1.3",
|
||||
"ip-regex": "^4.1.0",
|
||||
"is-url": "^1.2.4"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
|
@ -16670,6 +16962,15 @@
|
|||
"p-limit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-map": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
|
||||
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aggregate-error": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
|
@ -18144,6 +18445,16 @@
|
|||
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
|
||||
"dev": true
|
||||
},
|
||||
"tcp-port-used": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
|
||||
"integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "4.3.1",
|
||||
"is2": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
"ansi-to-html": "^0.7.1",
|
||||
"babel-loader": "^8.2.2",
|
||||
"chokidar": "^3.5.0",
|
||||
"chromedriver": "^93.0.1",
|
||||
"commonmark": "^0.29.1",
|
||||
"concurrently": "^6.2.1",
|
||||
"cross-env": "^7.0.2",
|
||||
|
|
|
@ -57,6 +57,9 @@ export abstract class BrowserType extends SdkObject {
|
|||
const controller = new ProgressController(metadata, this);
|
||||
controller.setLogName('browser');
|
||||
const browser = await controller.run(progress => {
|
||||
const seleniumHubUrl = (options as any).__testHookSeleniumRemoteURL || process.env.SELENIUM_REMOTE_URL;
|
||||
if (seleniumHubUrl)
|
||||
return this._launchWithSeleniumHub(progress, seleniumHubUrl, options);
|
||||
return this._innerLaunchWithRetries(progress, options, undefined, helper.debugProtocolLogger(protocolLogger)).catch(e => { throw this._rewriteStartupError(e); });
|
||||
}, TimeoutSettings.timeout(options));
|
||||
return browser;
|
||||
|
@ -243,6 +246,10 @@ export abstract class BrowserType extends SdkObject {
|
|||
throw new Error('CDP connections are only supported by Chromium');
|
||||
}
|
||||
|
||||
async _launchWithSeleniumHub(progress: Progress, hubUrl: string, options: types.LaunchOptions): Promise<Browser> {
|
||||
throw new Error('Connecting to SELENIUM_REMOTE_URL is only supported by Chromium');
|
||||
}
|
||||
|
||||
private _validateLaunchOptions<Options extends types.LaunchOptions>(options: Options): Options {
|
||||
const { devtools = false } = options;
|
||||
let { headless = !devtools, downloadsPath, proxy } = options;
|
||||
|
|
|
@ -27,9 +27,9 @@ import { ConnectionTransport, ProtocolRequest, WebSocketTransport } from '../tra
|
|||
import { CRDevTools } from './crDevTools';
|
||||
import { BrowserOptions, BrowserProcess, PlaywrightOptions } from '../browser';
|
||||
import * as types from '../types';
|
||||
import { debugMode, headersArrayToObject, removeFolders } from '../../utils/utils';
|
||||
import { debugMode, fetchData, headersArrayToObject, removeFolders, streamToString } from '../../utils/utils';
|
||||
import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||
import { ProgressController } from '../progress';
|
||||
import { Progress, ProgressController } from '../progress';
|
||||
import { TimeoutSettings } from '../../utils/timeoutSettings';
|
||||
import { helper } from '../helper';
|
||||
import { CallMetadata } from '../instrumentation';
|
||||
|
@ -52,42 +52,45 @@ export class Chromium extends BrowserType {
|
|||
override async connectOverCDP(metadata: CallMetadata, endpointURL: string, options: { slowMo?: number, headers?: types.HeadersArray }, timeout?: number) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
controller.setLogName('browser');
|
||||
const browserLogsCollector = new RecentLogsCollector();
|
||||
return controller.run(async progress => {
|
||||
let headersMap: { [key: string]: string; } | undefined;
|
||||
if (options.headers)
|
||||
headersMap = headersArrayToObject(options.headers, false);
|
||||
|
||||
const artifactsDir = await fs.promises.mkdtemp(ARTIFACTS_FOLDER);
|
||||
|
||||
const chromeTransport = await WebSocketTransport.connect(progress, await urlToWSEndpoint(endpointURL), headersMap);
|
||||
const browserProcess: BrowserProcess = {
|
||||
close: async () => {
|
||||
await removeFolders([ artifactsDir ]);
|
||||
await chromeTransport.closeAndWait();
|
||||
},
|
||||
kill: async () => {
|
||||
await removeFolders([ artifactsDir ]);
|
||||
await chromeTransport.closeAndWait();
|
||||
}
|
||||
};
|
||||
const browserOptions: BrowserOptions = {
|
||||
...this._playwrightOptions,
|
||||
slowMo: options.slowMo,
|
||||
name: 'chromium',
|
||||
isChromium: true,
|
||||
persistent: { noDefaultViewport: true },
|
||||
browserProcess,
|
||||
protocolLogger: helper.debugProtocolLogger(),
|
||||
browserLogsCollector,
|
||||
artifactsDir,
|
||||
downloadsPath: artifactsDir,
|
||||
tracesDir: artifactsDir
|
||||
};
|
||||
return await CRBrowser.connect(chromeTransport, browserOptions);
|
||||
return await this._connectOverCDPInternal(progress, endpointURL, options);
|
||||
}, TimeoutSettings.timeout({timeout}));
|
||||
}
|
||||
|
||||
async _connectOverCDPInternal(progress: Progress, endpointURL: string, options: { slowMo?: number, headers?: types.HeadersArray }, onClose?: () => Promise<void>) {
|
||||
let headersMap: { [key: string]: string; } | undefined;
|
||||
if (options.headers)
|
||||
headersMap = headersArrayToObject(options.headers, false);
|
||||
|
||||
const artifactsDir = await fs.promises.mkdtemp(ARTIFACTS_FOLDER);
|
||||
|
||||
const wsEndpoint = await urlToWSEndpoint(endpointURL);
|
||||
progress.throwIfAborted();
|
||||
|
||||
const chromeTransport = await WebSocketTransport.connect(progress, wsEndpoint, headersMap);
|
||||
const doClose = async () => {
|
||||
await removeFolders([ artifactsDir ]);
|
||||
await chromeTransport.closeAndWait();
|
||||
await onClose?.();
|
||||
};
|
||||
const browserProcess: BrowserProcess = { close: doClose, kill: doClose };
|
||||
const browserOptions: BrowserOptions = {
|
||||
...this._playwrightOptions,
|
||||
slowMo: options.slowMo,
|
||||
name: 'chromium',
|
||||
isChromium: true,
|
||||
persistent: { noDefaultViewport: true },
|
||||
browserProcess,
|
||||
protocolLogger: helper.debugProtocolLogger(),
|
||||
browserLogsCollector: new RecentLogsCollector(),
|
||||
artifactsDir,
|
||||
downloadsPath: artifactsDir,
|
||||
tracesDir: artifactsDir
|
||||
};
|
||||
progress.throwIfAborted();
|
||||
return await CRBrowser.connect(chromeTransport, browserOptions);
|
||||
}
|
||||
|
||||
private _createDevTools() {
|
||||
// TODO: this is totally wrong when using channels.
|
||||
const directory = registry.findExecutable('chromium').directory;
|
||||
|
@ -128,7 +131,77 @@ export class Chromium extends BrowserType {
|
|||
transport.send(message);
|
||||
}
|
||||
|
||||
override async _launchWithSeleniumHub(progress: Progress, hubUrl: string, options: types.LaunchOptions): Promise<CRBrowser> {
|
||||
if (!hubUrl.endsWith('/'))
|
||||
hubUrl = hubUrl + '/';
|
||||
|
||||
const args = this._innerDefaultArgs(options);
|
||||
args.push('--remote-debugging-port=0');
|
||||
const desiredCapabilities = { 'browserName': 'chrome', 'goog:chromeOptions': { args } };
|
||||
|
||||
progress.log(`<connecting to selenium> ${hubUrl}`);
|
||||
const response = await fetchData({
|
||||
url: hubUrl + 'session',
|
||||
method: 'POST',
|
||||
data: JSON.stringify({
|
||||
desiredCapabilities,
|
||||
capabilities: { alwaysMatch: desiredCapabilities }
|
||||
}),
|
||||
timeout: progress.timeUntilDeadline(),
|
||||
}, async response => {
|
||||
const body = await streamToString(response);
|
||||
let message = '';
|
||||
try {
|
||||
const json = JSON.parse(body);
|
||||
message = json.value.localizedMessage || json.value.message;
|
||||
} catch (e) {
|
||||
}
|
||||
return new Error(`Error connecting to Selenium at ${hubUrl}: ${message}`);
|
||||
});
|
||||
const value = JSON.parse(response).value;
|
||||
const sessionId = value.sessionId;
|
||||
progress.log(`<connected to selenium> sessionId=${sessionId}`);
|
||||
|
||||
const disconnectFromSelenium = async () => {
|
||||
progress.log(`<disconnecting from selenium> sessionId=${sessionId}`);
|
||||
await fetchData({
|
||||
url: hubUrl + 'session/' + sessionId,
|
||||
method: 'DELETE',
|
||||
}).catch(error => progress.log(`<error disconnecting from selenium>: ${error}`));
|
||||
progress.log(`<disconnected from selenium> sessionId=${sessionId}`);
|
||||
};
|
||||
|
||||
try {
|
||||
const capabilities = value.capabilities;
|
||||
const maybeChromeOptions = capabilities['goog:chromeOptions'];
|
||||
const chromeOptions = maybeChromeOptions && typeof maybeChromeOptions === 'object' ? maybeChromeOptions : undefined;
|
||||
const debuggerAddress = chromeOptions && typeof chromeOptions.debuggerAddress === 'string' ? chromeOptions.debuggerAddress : undefined;
|
||||
const chromeOptionsURL = typeof maybeChromeOptions === 'string' ? maybeChromeOptions : undefined;
|
||||
let endpointURL = capabilities['se:cdp'] || debuggerAddress || chromeOptionsURL;
|
||||
if (!['ws://', 'wss://', 'http://', 'https://'].some(protocol => endpointURL.startsWith(protocol)))
|
||||
endpointURL = 'http://' + endpointURL;
|
||||
return this._connectOverCDPInternal(progress, endpointURL, { slowMo: options.slowMo }, disconnectFromSelenium);
|
||||
} catch (e) {
|
||||
await disconnectFromSelenium();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
_defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string): string[] {
|
||||
const chromeArguments = this._innerDefaultArgs(options);
|
||||
chromeArguments.push(`--user-data-dir=${userDataDir}`);
|
||||
if (options.useWebSocket)
|
||||
chromeArguments.push('--remote-debugging-port=0');
|
||||
else
|
||||
chromeArguments.push('--remote-debugging-pipe');
|
||||
if (isPersistent)
|
||||
chromeArguments.push('about:blank');
|
||||
else
|
||||
chromeArguments.push('--no-startup-window');
|
||||
return chromeArguments;
|
||||
}
|
||||
|
||||
private _innerDefaultArgs(options: types.LaunchOptions): string[] {
|
||||
const { args = [], proxy } = options;
|
||||
const userDataDirArg = args.find(arg => arg.startsWith('--user-data-dir'));
|
||||
if (userDataDirArg)
|
||||
|
@ -138,16 +211,11 @@ export class Chromium extends BrowserType {
|
|||
if (args.find(arg => !arg.startsWith('-')))
|
||||
throw new Error('Arguments can not specify page to be opened');
|
||||
const chromeArguments = [...DEFAULT_ARGS];
|
||||
chromeArguments.push(`--user-data-dir=${userDataDir}`);
|
||||
|
||||
// See https://github.com/microsoft/playwright/issues/7362
|
||||
if (os.platform() === 'darwin')
|
||||
chromeArguments.push('--enable-use-zoom-for-dsf=false');
|
||||
|
||||
if (options.useWebSocket)
|
||||
chromeArguments.push('--remote-debugging-port=0');
|
||||
else
|
||||
chromeArguments.push('--remote-debugging-pipe');
|
||||
if (options.devtools)
|
||||
chromeArguments.push('--auto-open-devtools-for-tabs');
|
||||
if (options.headless) {
|
||||
|
@ -179,10 +247,6 @@ export class Chromium extends BrowserType {
|
|||
chromeArguments.push(`--proxy-bypass-list=${proxyBypassRules.join(';')}`);
|
||||
}
|
||||
chromeArguments.push(...args);
|
||||
if (isPersistent)
|
||||
chromeArguments.push('about:blank');
|
||||
else
|
||||
chromeArguments.push('--no-startup-window');
|
||||
return chromeArguments;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ type HTTPRequestParams = {
|
|||
method?: string,
|
||||
headers?: http.OutgoingHttpHeaders,
|
||||
data?: string | Buffer,
|
||||
timeout?: number,
|
||||
};
|
||||
|
||||
function httpRequest(params: HTTPRequestParams, onResponse: (r: http.IncomingMessage) => void, onError: (error: Error) => void) {
|
||||
|
@ -81,14 +82,26 @@ function httpRequest(params: HTTPRequestParams, onResponse: (r: http.IncomingMes
|
|||
https.request(options, requestCallback) :
|
||||
http.request(options, requestCallback);
|
||||
request.on('error', onError);
|
||||
if (params.timeout !== undefined) {
|
||||
const rejectOnTimeout = () => {
|
||||
onError(new Error(`Request to ${params.url} timed out after ${params.timeout}ms`));
|
||||
request.abort();
|
||||
};
|
||||
if (params.timeout <= 0) {
|
||||
rejectOnTimeout();
|
||||
return;
|
||||
}
|
||||
request.setTimeout(params.timeout, rejectOnTimeout);
|
||||
}
|
||||
request.end(params.data);
|
||||
}
|
||||
|
||||
export function fetchData(params: HTTPRequestParams): Promise<string> {
|
||||
export function fetchData(params: HTTPRequestParams, onError?: (response: http.IncomingMessage) => Promise<Error>): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
httpRequest(params, response => {
|
||||
httpRequest(params, async response => {
|
||||
if (response.statusCode !== 200) {
|
||||
reject(new Error(`fetch failed: server returned code ${response.statusCode}. URL: ${params.url}`));
|
||||
const error = onError ? await onError(response) : new Error(`fetch failed: server returned code ${response.statusCode}. URL: ${params.url}`);
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
let body = '';
|
||||
|
@ -426,3 +439,12 @@ export function wrapInASCIIBox(text: string, padding = 0): string {
|
|||
export function isFilePayload(value: any): boolean {
|
||||
return typeof value === 'object' && value['name'] && value['mimeType'] && value['buffer'];
|
||||
}
|
||||
|
||||
export function streamToString(stream: stream.Readable): Promise<string> {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const chunks: Buffer[] = [];
|
||||
stream.on('data', chunk => chunks.push(Buffer.from(chunk)));
|
||||
stream.on('error', reject);
|
||||
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Download locations:
|
||||
- https://github.com/SeleniumHQ/selenium/releases/download/selenium-3.141.59/selenium-server-standalone-3.141.59.jar
|
||||
- https://github.com/SeleniumHQ/selenium/releases/download/selenium-4.0.0-rc-1/selenium-server-4.0.0-rc-1.jar
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
process.exit(1);
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"capabilities":
|
||||
[
|
||||
{
|
||||
"browserName": "chrome",
|
||||
"maxInstances": 5,
|
||||
"seleniumProtocol": "WebDriver"
|
||||
}
|
||||
],
|
||||
"role": "standalone",
|
||||
"port": 4444,
|
||||
"debug": false,
|
||||
"browserTimeout": 0,
|
||||
"timeout": 1800,
|
||||
"enablePassThrough": true,
|
||||
"server": {
|
||||
"port": 4444
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* 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 { playwrightTest as test, expect } from './config/browserTest';
|
||||
import type { TestInfo } from '../types/test';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
const chromeDriver = require('chromedriver').path;
|
||||
const brokenDriver = path.join(__dirname, 'assets', 'selenium-grid', 'broken-selenium-driver.js');
|
||||
const seleniumConfigStandalone = path.join(__dirname, 'assets', 'selenium-grid', 'selenium-config-standalone.json');
|
||||
const standalone_3_141_59 = path.join(__dirname, 'assets', 'selenium-grid', 'selenium-server-standalone-3.141.59.jar');
|
||||
const selenium_4_0_0_rc1 = path.join(__dirname, 'assets', 'selenium-grid', 'selenium-server-4.0.0-rc-1.jar');
|
||||
|
||||
function writeSeleniumConfig(testInfo: TestInfo, port: number) {
|
||||
const content = fs.readFileSync(seleniumConfigStandalone, 'utf8').replace(/4444/g, String(port));
|
||||
const file = testInfo.outputPath('selenium-config.json');
|
||||
fs.writeFileSync(file, content, 'utf8');
|
||||
return file;
|
||||
}
|
||||
|
||||
test.skip(({ mode }) => mode !== 'default', 'Using test hooks');
|
||||
test.skip(() => !!process.env.INSIDE_DOCKER, 'Docker image does not have Java');
|
||||
|
||||
test('selenium grid 3.141.59 standalone chromium', async ({ browserOptions, browserName, childProcess, waitForPort, browserType }, testInfo) => {
|
||||
test.skip(browserName !== 'chromium');
|
||||
|
||||
const port = testInfo.workerIndex + 15123;
|
||||
const grid = childProcess({
|
||||
command: ['java', `-Dwebdriver.chrome.driver=${chromeDriver}`, '-jar', standalone_3_141_59, '-config', writeSeleniumConfig(testInfo, port)],
|
||||
cwd: __dirname,
|
||||
});
|
||||
await waitForPort(port);
|
||||
|
||||
const __testHookSeleniumRemoteURL = `http://localhost:${port}/wd/hub`;
|
||||
const browser = await browserType.launch({ ...browserOptions, __testHookSeleniumRemoteURL } as any);
|
||||
const page = await browser.newPage();
|
||||
await page.setContent('<title>Hello world</title><div>Get Started</div>');
|
||||
await page.click('text=Get Started');
|
||||
await expect(page).toHaveTitle('Hello world');
|
||||
await browser.close();
|
||||
|
||||
expect(grid.output).toContain('Starting ChromeDriver');
|
||||
expect(grid.output).toContain('Started new session');
|
||||
await grid.waitForOutput('Removing session');
|
||||
});
|
||||
|
||||
test('selenium grid 4.0.0-rc-1 standalone chromium', async ({ browserOptions, browserName, childProcess, waitForPort, browserType }, testInfo) => {
|
||||
test.skip(browserName !== 'chromium');
|
||||
|
||||
const port = testInfo.workerIndex + 15123;
|
||||
const grid = childProcess({
|
||||
command: ['java', `-Dwebdriver.chrome.driver=${chromeDriver}`, '-jar', selenium_4_0_0_rc1, 'standalone', '--config', writeSeleniumConfig(testInfo, port)],
|
||||
cwd: __dirname,
|
||||
});
|
||||
await waitForPort(port);
|
||||
|
||||
const __testHookSeleniumRemoteURL = `http://localhost:${port}/wd/hub`;
|
||||
const browser = await browserType.launch({ ...browserOptions, __testHookSeleniumRemoteURL } as any);
|
||||
const page = await browser.newPage();
|
||||
await page.setContent('<title>Hello world</title><div>Get Started</div>');
|
||||
await page.click('text=Get Started');
|
||||
await expect(page).toHaveTitle('Hello world');
|
||||
await browser.close();
|
||||
|
||||
expect(grid.output).toContain('Starting ChromeDriver');
|
||||
expect(grid.output).toContain('Session created');
|
||||
await grid.waitForOutput('Deleted session');
|
||||
});
|
||||
|
||||
test('selenium grid 4.0.0-rc-1 standalone chromium broken driver', async ({ browserOptions, browserName, childProcess, waitForPort, browserType }, testInfo) => {
|
||||
test.skip(browserName !== 'chromium');
|
||||
|
||||
const port = testInfo.workerIndex + 15123;
|
||||
const grid = childProcess({
|
||||
command: ['java', `-Dwebdriver.chrome.driver=${brokenDriver}`, '-jar', selenium_4_0_0_rc1, 'standalone', '--config', writeSeleniumConfig(testInfo, port)],
|
||||
cwd: __dirname,
|
||||
});
|
||||
await waitForPort(port);
|
||||
|
||||
const __testHookSeleniumRemoteURL = `http://localhost:${port}/wd/hub`;
|
||||
const error = await browserType.launch({ ...browserOptions, __testHookSeleniumRemoteURL } as any).catch(e => e);
|
||||
expect(error.message).toContain(`Error connecting to Selenium at http://localhost:${port}/wd/hub/: Could not start a new session`);
|
||||
|
||||
expect(grid.output).not.toContain('Starting ChromeDriver');
|
||||
});
|
||||
|
||||
test('selenium grid 3.141.59 standalone non-chromium', async ({ browserName, browserType }, testInfo) => {
|
||||
test.skip(browserName === 'chromium');
|
||||
|
||||
const __testHookSeleniumRemoteURL = `http://localhost:4444/wd/hub`;
|
||||
const error = await browserType.launch({ __testHookSeleniumRemoteURL } as any).catch(e => e);
|
||||
expect(error.message).toContain('Connecting to SELENIUM_REMOTE_URL is only supported by Chromium');
|
||||
});
|
|
@ -34,6 +34,8 @@ export class TestChildProcess {
|
|||
exited: Promise<{ exitCode: number | null, signal: string | null }>;
|
||||
exitCode: Promise<number>;
|
||||
|
||||
private _outputCallbacks = new Set<() => void>();
|
||||
|
||||
constructor(params: TestChildParams) {
|
||||
this.params = params;
|
||||
this.process = spawn(params.command[0], params.command.slice(1), {
|
||||
|
@ -53,6 +55,9 @@ export class TestChildProcess {
|
|||
if (process.env.PWTEST_DEBUG)
|
||||
process.stdout.write(String(chunk));
|
||||
this.onOutput?.();
|
||||
for (const cb of this._outputCallbacks)
|
||||
cb();
|
||||
this._outputCallbacks.clear();
|
||||
};
|
||||
|
||||
this.process.stderr.on('data', appendChunk);
|
||||
|
@ -91,6 +96,11 @@ export class TestChildProcess {
|
|||
if (r.signal)
|
||||
throw new Error(`Process recieved signal: ${r.signal}`);
|
||||
}
|
||||
|
||||
async waitForOutput(substring: string) {
|
||||
while (!this.output.includes(substring))
|
||||
await new Promise<void>(f => this._outputCallbacks.add(f));
|
||||
}
|
||||
}
|
||||
|
||||
export type CommonFixtures = {
|
||||
|
|
|
@ -87,6 +87,15 @@ Example:
|
|||
process.stdout.write(execSync('npm run --silent doc'));
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (browserName === 'chromium') {
|
||||
// 5. Update chromedriver.
|
||||
console.log('\nUpdating chromedriver...');
|
||||
try {
|
||||
process.stdout.write(execSync('npm install --save-dev chromedriver@latest'));
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(`\nRolled ${browserName} to ${revision}`);
|
||||
})().catch(err => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче