presidium 3.1.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GoogleChromeDevTools.js +112 -20
- package/{internal/GoogleChromeForTesting.js → GoogleChromeForTesting.js} +126 -24
- package/README.md +6 -2
- package/index.js +1 -0
- package/package.json +2 -1
- package/internal/GoogleChromeForTesting.test.js +0 -50
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-69977DD3-9B6F.pma +0 -0
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-69977DD4-9B86.pma +0 -0
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-69978250-A191.pma +0 -0
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-69978251-A1AD.pma +0 -0
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-69978277-A1FA.pma +0 -0
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-69978278-A209.pma +0 -0
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-6997A286-BC0E.pma +0 -0
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-6997A287-BC46.pma +0 -0
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-6997A7D0-C1E4.pma +0 -0
- package/internal/tmp/chrome/BrowserMetrics/BrowserMetrics-6997A7D1-C1FE.pma +0 -0
- package/internal/tmp/chrome/ChromeFeatureState +0 -1
- package/internal/tmp/chrome/Default/Affiliation Database +0 -0
- package/internal/tmp/chrome/Default/Affiliation Database-journal +0 -0
- package/internal/tmp/chrome/Default/ClientCertificates/LOCK +0 -0
- package/internal/tmp/chrome/Default/ClientCertificates/LOG +0 -0
- package/internal/tmp/chrome/Default/ClientCertificates/LOG.old +0 -0
- package/internal/tmp/chrome/Default/Extension Rules/000003.log +0 -0
- package/internal/tmp/chrome/Default/Extension Rules/CURRENT +0 -1
- package/internal/tmp/chrome/Default/Extension Rules/LOCK +0 -0
- package/internal/tmp/chrome/Default/Extension Rules/LOG +0 -3
- package/internal/tmp/chrome/Default/Extension Rules/LOG.old +0 -3
- package/internal/tmp/chrome/Default/Extension Rules/MANIFEST-000001 +0 -0
- package/internal/tmp/chrome/Default/Extension Scripts/000003.log +0 -0
- package/internal/tmp/chrome/Default/Extension Scripts/CURRENT +0 -1
- package/internal/tmp/chrome/Default/Extension Scripts/LOCK +0 -0
- package/internal/tmp/chrome/Default/Extension Scripts/LOG +0 -3
- package/internal/tmp/chrome/Default/Extension Scripts/LOG.old +0 -3
- package/internal/tmp/chrome/Default/Extension Scripts/MANIFEST-000001 +0 -0
- package/internal/tmp/chrome/Default/Favicons +0 -0
- package/internal/tmp/chrome/Default/Favicons-journal +0 -0
- package/internal/tmp/chrome/Default/History +0 -0
- package/internal/tmp/chrome/Default/History-journal +0 -0
- package/internal/tmp/chrome/Default/LOCK +0 -0
- package/internal/tmp/chrome/Default/LOG +0 -0
- package/internal/tmp/chrome/Default/LOG.old +0 -0
- package/internal/tmp/chrome/Default/Local Storage/leveldb/000003.log +0 -0
- package/internal/tmp/chrome/Default/Local Storage/leveldb/CURRENT +0 -1
- package/internal/tmp/chrome/Default/Local Storage/leveldb/LOCK +0 -0
- package/internal/tmp/chrome/Default/Local Storage/leveldb/LOG.old +0 -2
- package/internal/tmp/chrome/Default/Local Storage/leveldb/MANIFEST-000001 +0 -0
- package/internal/tmp/chrome/Default/PersistentOriginTrials/LOCK +0 -0
- package/internal/tmp/chrome/Default/PersistentOriginTrials/LOG +0 -0
- package/internal/tmp/chrome/Default/PersistentOriginTrials/LOG.old +0 -0
- package/internal/tmp/chrome/Default/README +0 -1
- package/internal/tmp/chrome/Default/Segmentation Platform/SegmentInfoDB/LOCK +0 -0
- package/internal/tmp/chrome/Default/Segmentation Platform/SegmentInfoDB/LOG +0 -0
- package/internal/tmp/chrome/Default/Segmentation Platform/SegmentInfoDB/LOG.old +0 -0
- package/internal/tmp/chrome/Default/Segmentation Platform/SignalDB/LOCK +0 -0
- package/internal/tmp/chrome/Default/Segmentation Platform/SignalDB/LOG +0 -0
- package/internal/tmp/chrome/Default/Segmentation Platform/SignalDB/LOG.old +0 -0
- package/internal/tmp/chrome/Default/Segmentation Platform/SignalStorageConfigDB/LOCK +0 -0
- package/internal/tmp/chrome/Default/Segmentation Platform/SignalStorageConfigDB/LOG +0 -0
- package/internal/tmp/chrome/Default/Segmentation Platform/SignalStorageConfigDB/LOG.old +0 -0
- package/internal/tmp/chrome/Default/ServerCertificate +0 -0
- package/internal/tmp/chrome/Default/ServerCertificate-journal +0 -0
- package/internal/tmp/chrome/Default/Site Characteristics Database/000003.log +0 -0
- package/internal/tmp/chrome/Default/Site Characteristics Database/CURRENT +0 -1
- package/internal/tmp/chrome/Default/Site Characteristics Database/LOCK +0 -0
- package/internal/tmp/chrome/Default/Site Characteristics Database/LOG +0 -3
- package/internal/tmp/chrome/Default/Site Characteristics Database/LOG.old +0 -3
- package/internal/tmp/chrome/Default/Site Characteristics Database/MANIFEST-000001 +0 -0
- package/internal/tmp/chrome/Default/Sync Data/LevelDB/000003.log +0 -0
- package/internal/tmp/chrome/Default/Sync Data/LevelDB/CURRENT +0 -1
- package/internal/tmp/chrome/Default/Sync Data/LevelDB/LOCK +0 -0
- package/internal/tmp/chrome/Default/Sync Data/LevelDB/LOG +0 -3
- package/internal/tmp/chrome/Default/Sync Data/LevelDB/LOG.old +0 -3
- package/internal/tmp/chrome/Default/Sync Data/LevelDB/MANIFEST-000001 +0 -0
- package/internal/tmp/chrome/Default/chrome_cart_db/LOCK +0 -0
- package/internal/tmp/chrome/Default/chrome_cart_db/LOG +0 -0
- package/internal/tmp/chrome/Default/chrome_cart_db/LOG.old +0 -0
- package/internal/tmp/chrome/Default/commerce_subscription_db/LOCK +0 -0
- package/internal/tmp/chrome/Default/commerce_subscription_db/LOG +0 -0
- package/internal/tmp/chrome/Default/commerce_subscription_db/LOG.old +0 -0
- package/internal/tmp/chrome/Default/discount_infos_db/LOCK +0 -0
- package/internal/tmp/chrome/Default/discount_infos_db/LOG +0 -0
- package/internal/tmp/chrome/Default/discount_infos_db/LOG.old +0 -0
- package/internal/tmp/chrome/Default/discounts_db/LOCK +0 -0
- package/internal/tmp/chrome/Default/discounts_db/LOG +0 -0
- package/internal/tmp/chrome/Default/discounts_db/LOG.old +0 -0
- package/internal/tmp/chrome/Default/parcel_tracking_db/LOCK +0 -0
- package/internal/tmp/chrome/Default/parcel_tracking_db/LOG +0 -0
- package/internal/tmp/chrome/Default/parcel_tracking_db/LOG.old +0 -0
- package/internal/tmp/chrome/Default/power_bookmarks/PowerBookmarks.db +0 -0
- package/internal/tmp/chrome/Default/power_bookmarks/PowerBookmarks.db-journal +0 -0
- package/internal/tmp/chrome/First Run +0 -0
- package/internal/tmp/chrome/Last Version +0 -1
- package/internal/tmp/chrome/Local State +0 -1
- package/internal/tmp/chrome/ShaderCache/data_0 +0 -0
- package/internal/tmp/chrome/ShaderCache/data_1 +0 -0
- package/internal/tmp/chrome/ShaderCache/data_2 +0 -0
- package/internal/tmp/chrome/ShaderCache/data_3 +0 -0
- package/internal/tmp/chrome/ShaderCache/index +0 -0
- package/internal/tmp/chrome/Variations +0 -1
- package/internal/tmp/chrome/segmentation_platform/ukm_db +0 -0
- package/internal/tmp/chrome/segmentation_platform/ukm_db-wal +0 -0
package/GoogleChromeDevTools.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const EventEmitter = require('events')
|
|
2
|
-
const GoogleChromeForTesting = require('./
|
|
2
|
+
const GoogleChromeForTesting = require('./GoogleChromeForTesting')
|
|
3
3
|
const WebSocket = require('./WebSocket')
|
|
4
4
|
|
|
5
5
|
let id = 0
|
|
@@ -743,24 +743,40 @@ class GoogleChromeDevToolsRuntime {
|
|
|
743
743
|
*
|
|
744
744
|
* @docs
|
|
745
745
|
* ```coffeescript [specscript]
|
|
746
|
+
* new GoogleChromeDevTools(
|
|
747
|
+
* googleChromeForTesting GoogleChromeForTesting
|
|
748
|
+
* ) -> googleChromeDevTools GoogleChromeDevTools
|
|
749
|
+
*
|
|
746
750
|
* new GoogleChromeDevTools(options {
|
|
747
751
|
* chromeVersion: 'stable'|'beta'|'dev'|'canary'|string,
|
|
752
|
+
* chromeDir: string,
|
|
753
|
+
* remoteDebuggingPort: number,
|
|
748
754
|
* headless: boolean,
|
|
755
|
+
* userDataDir: string,
|
|
756
|
+
* useMockKeychain: boolean,
|
|
749
757
|
* }) -> googleChromeDevTools GoogleChromeDevTools
|
|
750
758
|
* ```
|
|
751
759
|
*
|
|
752
760
|
* Presidium GoogleChromeDevTools client for test automation.
|
|
753
761
|
*
|
|
754
762
|
* Arguments:
|
|
763
|
+
* * `googleChromeForTesting` - an instance of a Presidium [GoogleChromeForTesting](/docs/GoogleChromeForTesting) client.
|
|
755
764
|
* * `options`
|
|
756
|
-
* * `chromeVersion` - the version of Google Chrome for Testing to download.
|
|
757
|
-
* * `
|
|
765
|
+
* * `chromeVersion` - the version of Google Chrome for Testing to download. Defaults to `'stable'`.
|
|
766
|
+
* * `chromeDir` - the directory that Google Chrome for Testing will install to. Defaults to ``google-chrome-for-testing'`.
|
|
767
|
+
* * `remoteDebuggingPort` - the port that the Chrome DevTools Protocol server will listen on. Defaults to `9222`
|
|
768
|
+
* * `headless` - whether to run Google Chrome for Testing in headless mode. Defaults to `false`.
|
|
769
|
+
* * `userDataDir` - directory for storing user profile data such as history, bookmarks, cookies, and settings. Defaults to `tmp/chrome`.
|
|
770
|
+
* * `useMockKeychain` - whether to use a mock keychain instead of the system's real security keychain. Defaults to `true`.
|
|
758
771
|
*
|
|
759
772
|
* Returns:
|
|
760
|
-
* * `googleChromeDevTools` - an instance of the
|
|
773
|
+
* * `googleChromeDevTools` - an instance of the Presidium GoogleChromeDevTools client.
|
|
761
774
|
*
|
|
762
775
|
* ```javascript
|
|
763
|
-
* const
|
|
776
|
+
* const googleChromeForTesting = new GoogleChromeForTesting()
|
|
777
|
+
* await googleChromeForTesting.init()
|
|
778
|
+
*
|
|
779
|
+
* const googleChromeDevTools = new GoogleChromeDevTools(googleChromeForTesting)
|
|
764
780
|
* await googleChromeDevTools.init()
|
|
765
781
|
*
|
|
766
782
|
* const target = await googleChromeDevTools.Target.getTargets()
|
|
@@ -802,7 +818,10 @@ class GoogleChromeDevToolsRuntime {
|
|
|
802
818
|
* Every Chrome DevTools Protocol client needs to first attach to the target using the `Target.attachToTarget` command. The command will establish a protocol session with the given target and return a `sessionId`. The returned `sessionId` should be set on the `GoogleChromeDevTools` client using [`setSessionId`](#setSessionId) or included in every message to the DevTools server.
|
|
803
819
|
*
|
|
804
820
|
* ```javascript
|
|
805
|
-
* const
|
|
821
|
+
* const googleChromeForTesting = new GoogleChromeForTesting()
|
|
822
|
+
* await googleChromeForTesting.init()
|
|
823
|
+
*
|
|
824
|
+
* const googleChromeDevTools = new GoogleChromeDevTools(googleChromeForTesting)
|
|
806
825
|
* await googleChromeDevTools.init()
|
|
807
826
|
*
|
|
808
827
|
* // get targets
|
|
@@ -823,26 +842,42 @@ class GoogleChromeDevToolsRuntime {
|
|
|
823
842
|
* })
|
|
824
843
|
* ```
|
|
825
844
|
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
* ```
|
|
845
|
+
* References:
|
|
846
|
+
* * [Getting Started with the Chrome Devtools Protocol](https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md)
|
|
847
|
+
* * [Chrome Devtools Protocol](https://chromedevtools.github.io/devtools-protocol/)
|
|
830
848
|
*
|
|
831
849
|
* Supported platforms:
|
|
832
850
|
* * `mac-arm64`
|
|
833
851
|
* * `linux64`
|
|
852
|
+
* * `win64`
|
|
834
853
|
*
|
|
835
|
-
*
|
|
836
|
-
*
|
|
837
|
-
*
|
|
854
|
+
* ## Further Installation
|
|
855
|
+
* Some further installation may be required for Linux platforms.
|
|
856
|
+
*
|
|
857
|
+
* ### Install headless dependencies for Amazon Linux 2023 / Red Hat
|
|
858
|
+
* ```sh
|
|
859
|
+
* sudo dnf install -y cairo pango nss nspr atk at-spi2-atk cups-libs libdrm libxkbcommon libXcomposite libXdamage libXfixes libXrandr mesa-libgbm alsa-lib
|
|
860
|
+
* ```
|
|
838
861
|
*
|
|
862
|
+
* ### Install headless dependencies for Ubuntu / Debian
|
|
863
|
+
* ```sh
|
|
864
|
+
* sudo apt-get update && sudo apt-get install -y libcairo2 libpango-1.0-0 libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libatspi2.0-0 libcups2 libdrm-dev libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm-dev libasound2-dev
|
|
865
|
+
* ```
|
|
839
866
|
*/
|
|
840
867
|
class GoogleChromeDevTools extends EventEmitter {
|
|
841
868
|
constructor(options = {}) {
|
|
842
869
|
super()
|
|
843
870
|
|
|
871
|
+
if (options.constructor == GoogleChromeForTesting) {
|
|
872
|
+
this.googleChromeForTesting = options
|
|
873
|
+
}
|
|
874
|
+
|
|
844
875
|
this.chromeVersion = options.chromeVersion ?? 'stable'
|
|
876
|
+
this.chromeDir = options.chromeDir ?? 'google-chrome-for-testing'
|
|
877
|
+
this.remoteDebuggingPort = options.remoteDebuggingPort ?? 9222
|
|
845
878
|
this.headless = options.headless ?? false
|
|
879
|
+
this.userDataDir = options.userDataDir ?? 'tmp/chrome'
|
|
880
|
+
this.useMockKeychain = options.useMockKeychain ?? true
|
|
846
881
|
}
|
|
847
882
|
|
|
848
883
|
/**
|
|
@@ -868,20 +903,25 @@ class GoogleChromeDevTools extends EventEmitter {
|
|
|
868
903
|
* ```
|
|
869
904
|
*/
|
|
870
905
|
async init() {
|
|
871
|
-
|
|
906
|
+
this.googleChromeForTesting ??= new GoogleChromeForTesting({
|
|
872
907
|
chromeVersion: this.chromeVersion,
|
|
873
|
-
|
|
874
|
-
|
|
908
|
+
chromeDir: this.chromeDir,
|
|
909
|
+
remoteDebuggingPort: this.remoteDebuggingPort,
|
|
875
910
|
headless: this.headless,
|
|
911
|
+
userDataDir: this.userDataDir,
|
|
912
|
+
useMockKeychain: this.useMockKeychain,
|
|
876
913
|
})
|
|
877
|
-
await googleChromeForTesting.init()
|
|
878
|
-
this.googleChromeForTesting = googleChromeForTesting
|
|
914
|
+
await this.googleChromeForTesting.init()
|
|
879
915
|
|
|
880
|
-
this.websocket = new WebSocket(googleChromeForTesting.devtoolsUrl, {
|
|
916
|
+
this.websocket = new WebSocket(this.googleChromeForTesting.devtoolsUrl, {
|
|
881
917
|
offerPerMessageDeflate: false,
|
|
882
918
|
})
|
|
883
919
|
this.websocket.on('error', error => {
|
|
884
|
-
|
|
920
|
+
if (this.closed && error.code == 'ECONNRESET') {
|
|
921
|
+
console.error('Reset after close:', error)
|
|
922
|
+
} else {
|
|
923
|
+
throw error
|
|
924
|
+
}
|
|
885
925
|
})
|
|
886
926
|
|
|
887
927
|
this.websocket.on('message', message => {
|
|
@@ -934,6 +974,58 @@ class GoogleChromeDevTools extends EventEmitter {
|
|
|
934
974
|
this.Runtime.sessionId = sessionId
|
|
935
975
|
}
|
|
936
976
|
|
|
977
|
+
/**
|
|
978
|
+
* @name close
|
|
979
|
+
*
|
|
980
|
+
* @docs
|
|
981
|
+
* ```coffeescript [specscript]
|
|
982
|
+
* close() -> undefined
|
|
983
|
+
* ```
|
|
984
|
+
*
|
|
985
|
+
* Closes the websocket connection to the DevTools server and terminates the Google Chrome for Testing process.
|
|
986
|
+
*
|
|
987
|
+
* Arguments:
|
|
988
|
+
* * (none)
|
|
989
|
+
*
|
|
990
|
+
* Return:
|
|
991
|
+
* * `undefined`
|
|
992
|
+
*
|
|
993
|
+
* ```javascript
|
|
994
|
+
* googleChromeDevTools.close()
|
|
995
|
+
* ```
|
|
996
|
+
*/
|
|
997
|
+
close() {
|
|
998
|
+
this.closed = true
|
|
999
|
+
this.websocket.sendClose()
|
|
1000
|
+
this.websocket.on('close', () => {
|
|
1001
|
+
this.googleChromeForTesting.cmd.on('close', () => {
|
|
1002
|
+
this.emit('close')
|
|
1003
|
+
})
|
|
1004
|
+
this.googleChromeForTesting.close()
|
|
1005
|
+
})
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* @name Event: close
|
|
1010
|
+
*
|
|
1011
|
+
* @docs
|
|
1012
|
+
* ```coffeescript [specscript]
|
|
1013
|
+
* emit('close')
|
|
1014
|
+
* ```
|
|
1015
|
+
*
|
|
1016
|
+
* The `close` event. Emitted when the websocket connection to the DevTools server is closed and the Google Chrome for Testing process is terminated.
|
|
1017
|
+
*
|
|
1018
|
+
* Event Data:
|
|
1019
|
+
* * (none)
|
|
1020
|
+
*
|
|
1021
|
+
* ```javascript
|
|
1022
|
+
* googleChromeForTesting.on('close', () => {
|
|
1023
|
+
* console.log('WebSocket connection closed and Google Chrome for Testing process terminated.')
|
|
1024
|
+
* })
|
|
1025
|
+
* ```
|
|
1026
|
+
*/
|
|
1027
|
+
|
|
937
1028
|
}
|
|
938
1029
|
|
|
1030
|
+
|
|
939
1031
|
module.exports = GoogleChromeDevTools
|
|
@@ -5,10 +5,11 @@ const path = require('path')
|
|
|
5
5
|
const { spawn } = require('child_process')
|
|
6
6
|
const readline = require('readline')
|
|
7
7
|
const extract = require('extract-zip')
|
|
8
|
-
const HTTP = require('
|
|
9
|
-
const XML = require('
|
|
10
|
-
const Readable = require('
|
|
11
|
-
const walk = require('./walk')
|
|
8
|
+
const HTTP = require('./HTTP')
|
|
9
|
+
const XML = require('./XML')
|
|
10
|
+
const Readable = require('./Readable')
|
|
11
|
+
const walk = require('./internal/walk')
|
|
12
|
+
const sleep = require('./internal/sleep')
|
|
12
13
|
|
|
13
14
|
async function getChromeVersions() {
|
|
14
15
|
const http = new HTTP()
|
|
@@ -17,7 +18,7 @@ async function getChromeVersions() {
|
|
|
17
18
|
return data
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
function updateConsoleLog(message) {
|
|
21
|
+
function updateConsoleLog(message, platform) {
|
|
21
22
|
readline.cursorTo(process.stdout, 0, undefined);
|
|
22
23
|
readline.clearLine(process.stdout, 0);
|
|
23
24
|
process.stdout.write(message);
|
|
@@ -32,7 +33,11 @@ function getPlatform() {
|
|
|
32
33
|
|
|
33
34
|
if (platform == 'mac') {
|
|
34
35
|
platform = `${platform}-${arch}`
|
|
35
|
-
}
|
|
36
|
+
}
|
|
37
|
+
else if (platform == 'win32') {
|
|
38
|
+
platform = `win${arch.slice(1)}`
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
36
41
|
platform = `${platform}${arch.slice(1)}`
|
|
37
42
|
}
|
|
38
43
|
|
|
@@ -57,13 +62,26 @@ async function getChromeUrl() {
|
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
async function installChrome() {
|
|
65
|
+
const platform = getPlatform()
|
|
66
|
+
const delimiter = platform.startsWith('win') ? '\\' : '/'
|
|
60
67
|
const url = await getChromeUrl.call(this)
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
|
|
69
|
+
let filepath = `${this.chromeDir}${delimiter}${url.replace('https://storage.googleapis.com/chrome-for-testing-public/', '')}`
|
|
70
|
+
if (platform.startsWith('win')) {
|
|
71
|
+
filepath = filepath.replace(/\//g, '\\')
|
|
72
|
+
if (!filepath.startsWith(`${__dirname[0]}:`)) {
|
|
73
|
+
filepath = path.join(process.cwd(), filepath)
|
|
74
|
+
}
|
|
75
|
+
} else if (!filepath.startsWith('/')) {
|
|
63
76
|
filepath = path.join(process.cwd(), filepath)
|
|
64
77
|
}
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
|
|
79
|
+
let parentDir = `${filepath.split(delimiter).slice(0, -1).join(delimiter)}`
|
|
80
|
+
if (platform.startsWith('win')) {
|
|
81
|
+
if (!filepath.startsWith(`${__dirname[0]}:`)) {
|
|
82
|
+
parentDir = path.join(process.cwd(), parentDir)
|
|
83
|
+
}
|
|
84
|
+
} else if (!parentDir.startsWith('/')) {
|
|
67
85
|
parentDir = path.join(process.cwd(), parentDir)
|
|
68
86
|
}
|
|
69
87
|
await fs.promises.mkdir(parentDir, { recursive: true })
|
|
@@ -80,9 +98,9 @@ async function installChrome() {
|
|
|
80
98
|
response.on('data', chunk => {
|
|
81
99
|
downloadedLength += chunk.length
|
|
82
100
|
if (downloadedLength == contentLength) {
|
|
83
|
-
updateConsoleLog(`Downloading ${url} (${downloadedLength} / ${contentLength} bytes)\n
|
|
101
|
+
updateConsoleLog(`Downloading ${url} (${downloadedLength} / ${contentLength} bytes)\n`, platform)
|
|
84
102
|
} else {
|
|
85
|
-
updateConsoleLog(`Downloading ${url} (${downloadedLength} / ${contentLength} bytes)
|
|
103
|
+
updateConsoleLog(`Downloading ${url} (${downloadedLength} / ${contentLength} bytes)`, platform)
|
|
86
104
|
}
|
|
87
105
|
|
|
88
106
|
fileStream.write(chunk)
|
|
@@ -97,7 +115,13 @@ async function installChrome() {
|
|
|
97
115
|
})
|
|
98
116
|
await promise
|
|
99
117
|
|
|
100
|
-
|
|
118
|
+
console.log('Extracting', filepath)
|
|
119
|
+
try {
|
|
120
|
+
await extract(filepath, { dir: parentDir })
|
|
121
|
+
} catch (_error) {
|
|
122
|
+
await sleep(1000)
|
|
123
|
+
await extract(filepath, { dir: parentDir })
|
|
124
|
+
}
|
|
101
125
|
}
|
|
102
126
|
|
|
103
127
|
async function getChromeFilepath() {
|
|
@@ -108,13 +132,15 @@ async function getChromeFilepath() {
|
|
|
108
132
|
|
|
109
133
|
try {
|
|
110
134
|
for await (const filepath of walk(parentDir)) {
|
|
111
|
-
console.log(filepath)
|
|
112
135
|
if (platform.startsWith('mac') && filepath.endsWith('Google Chrome for Testing')) {
|
|
113
136
|
return filepath
|
|
114
137
|
}
|
|
115
138
|
if (platform.startsWith('linux') && filepath.endsWith('chrome')) {
|
|
116
139
|
return filepath
|
|
117
140
|
}
|
|
141
|
+
if (platform.startsWith('win') && filepath.endsWith('chrome.exe')) {
|
|
142
|
+
return filepath
|
|
143
|
+
}
|
|
118
144
|
}
|
|
119
145
|
} catch (error) {
|
|
120
146
|
if (error.code == 'ENOENT') {
|
|
@@ -139,11 +165,48 @@ async function getChromeFilepath() {
|
|
|
139
165
|
* headless: boolean,
|
|
140
166
|
* userDataDir: string,
|
|
141
167
|
* useMockKeychain: boolean,
|
|
142
|
-
* }) -> GoogleChromeForTesting
|
|
168
|
+
* }) -> googleChromeForTesting GoogleChromeForTesting
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* Presidium GoogleChromeForTesting client for test automation.
|
|
172
|
+
*
|
|
173
|
+
* Arguments:
|
|
174
|
+
* * `options`
|
|
175
|
+
* * `chromeVersion` - the version of Google Chrome for Testing to download. Defaults to `'stable'`.
|
|
176
|
+
* * `chromeDir` - the directory that Google Chrome for Testing will install to. Defaults to ``google-chrome-for-testing'`.
|
|
177
|
+
* * `remoteDebuggingPort` - the port that the Chrome DevTools Protocol server will listen on. Defaults to `9222`
|
|
178
|
+
* * `headless` - whether to run Google Chrome for Testing in headless mode. Defaults to `false`.
|
|
179
|
+
* * `userDataDir` - directory for storing user profile data such as history, bookmarks, cookies, and settings. Defaults to `tmp/chrome`.
|
|
180
|
+
* * `useMockKeychain` - whether to use a mock keychain instead of the system's real security keychain. Defaults to `true`.
|
|
181
|
+
*
|
|
182
|
+
* Returns:
|
|
183
|
+
* * `googleChromeForTesting` - an instance of the `GoogleChromeForTesting` client.
|
|
184
|
+
*
|
|
185
|
+
* ```javascript
|
|
186
|
+
* const googleChromeForTesting = new GoogleChromeForTesting({ chromeVersion: 'stable' })
|
|
187
|
+
* await googleChromeForTesting.init()
|
|
143
188
|
* ```
|
|
144
189
|
*
|
|
145
|
-
*
|
|
190
|
+
* Google Chrome for Testing versions:
|
|
146
191
|
* * [Chrome for Testing availability](https://googlechromelabs.github.io/chrome-for-testing/)
|
|
192
|
+
*
|
|
193
|
+
* Supported platforms:
|
|
194
|
+
* * `mac-arm64`
|
|
195
|
+
* * `linux64`
|
|
196
|
+
* * `win64`
|
|
197
|
+
*
|
|
198
|
+
* ## Further Installation
|
|
199
|
+
* Some further installation may be required for Linux platforms.
|
|
200
|
+
*
|
|
201
|
+
* ### Install headless dependencies for Amazon Linux 2023 / Red Hat
|
|
202
|
+
* ```sh
|
|
203
|
+
* sudo dnf install -y cairo pango nss nspr atk at-spi2-atk cups-libs libdrm libxkbcommon libXcomposite libXdamage libXfixes libXrandr mesa-libgbm alsa-lib
|
|
204
|
+
* ```
|
|
205
|
+
*
|
|
206
|
+
* ### Install headless dependencies for Ubuntu / Debian
|
|
207
|
+
* ```sh
|
|
208
|
+
* sudo apt-get update && sudo apt-get install -y libcairo2 libpango-1.0-0 libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libatspi2.0-0 libcups2 libdrm-dev libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm-dev libasound2-dev
|
|
209
|
+
* ```
|
|
147
210
|
*/
|
|
148
211
|
class GoogleChromeForTesting {
|
|
149
212
|
constructor(options = {}) {
|
|
@@ -151,8 +214,8 @@ class GoogleChromeForTesting {
|
|
|
151
214
|
this.chromeDir = options.chromeDir ?? 'google-chrome-for-testing'
|
|
152
215
|
this.remoteDebuggingPort = options.remoteDebuggingPort ?? 9222
|
|
153
216
|
this.headless = options.headless ?? false
|
|
154
|
-
this.userDataDir = options.userDataDir ?? '
|
|
155
|
-
this.useMockKeychain = options.useMockKeychain ??
|
|
217
|
+
this.userDataDir = options.userDataDir ?? 'tmp/chrome'
|
|
218
|
+
this.useMockKeychain = options.useMockKeychain ?? true
|
|
156
219
|
this.devtoolsUrl = undefined
|
|
157
220
|
}
|
|
158
221
|
|
|
@@ -163,8 +226,26 @@ class GoogleChromeForTesting {
|
|
|
163
226
|
* ```coffeescript [specscript]
|
|
164
227
|
* init() -> Promise<>
|
|
165
228
|
* ```
|
|
229
|
+
*
|
|
230
|
+
* Initializes the `GoogleChromeForTesting` client.
|
|
231
|
+
*
|
|
232
|
+
* Arguments:
|
|
233
|
+
* * (none)
|
|
234
|
+
*
|
|
235
|
+
* Returns:
|
|
236
|
+
* * `promise` - a promise that resolves when the initialization process is done.
|
|
237
|
+
*
|
|
238
|
+
* ```javascript
|
|
239
|
+
* const googleChromeForTesting = new GoogleChromeForTesting()
|
|
240
|
+
*
|
|
241
|
+
* await googleChromeForTesting.init()
|
|
242
|
+
* ```
|
|
166
243
|
*/
|
|
167
244
|
async init() {
|
|
245
|
+
if (this.devtoolsUrl) {
|
|
246
|
+
return undefined
|
|
247
|
+
}
|
|
248
|
+
|
|
168
249
|
const chromeFilepath = await getChromeFilepath.call(this)
|
|
169
250
|
|
|
170
251
|
const cmd = spawn(chromeFilepath, [
|
|
@@ -172,22 +253,29 @@ class GoogleChromeForTesting {
|
|
|
172
253
|
`--user-data-dir=${this.userDataDir}`,
|
|
173
254
|
...this.headless ? ['--headless'] : [],
|
|
174
255
|
...this.useMockKeychain ? ['--use-mock-keychain'] : [],
|
|
256
|
+
'--no-sandbox',
|
|
175
257
|
])
|
|
176
258
|
cmd.stdout.pipe(process.stdout)
|
|
177
259
|
cmd.stderr.pipe(process.stderr)
|
|
178
260
|
|
|
179
|
-
|
|
261
|
+
let devtoolsUrlResolve
|
|
262
|
+
const devtoolsUrlPromise = new Promise(_resolve => {
|
|
263
|
+
devtoolsUrlResolve = _resolve
|
|
264
|
+
})
|
|
180
265
|
cmd.stderr.on('data', chunk => {
|
|
181
266
|
const line = chunk.toString('utf8').trim()
|
|
182
267
|
if (line.includes('DevTools listening on')) {
|
|
183
268
|
const devtoolsUrl = line.replace('DevTools listening on ', '')
|
|
184
|
-
|
|
269
|
+
devtoolsUrlResolve(devtoolsUrl)
|
|
185
270
|
}
|
|
186
271
|
})
|
|
187
272
|
|
|
188
|
-
|
|
273
|
+
let spawnResolve
|
|
274
|
+
const spawnPromise = new Promise(_resolve => {
|
|
275
|
+
spawnResolve = _resolve
|
|
276
|
+
})
|
|
189
277
|
cmd.on('spawn', () => {
|
|
190
|
-
|
|
278
|
+
spawnResolve()
|
|
191
279
|
})
|
|
192
280
|
|
|
193
281
|
cmd.on('error', error => {
|
|
@@ -205,8 +293,10 @@ class GoogleChromeForTesting {
|
|
|
205
293
|
|
|
206
294
|
this.cmd = cmd
|
|
207
295
|
|
|
208
|
-
await
|
|
209
|
-
this.devtoolsUrl = await
|
|
296
|
+
await spawnPromise
|
|
297
|
+
this.devtoolsUrl = await devtoolsUrlPromise
|
|
298
|
+
|
|
299
|
+
return undefined
|
|
210
300
|
}
|
|
211
301
|
|
|
212
302
|
/**
|
|
@@ -216,6 +306,18 @@ class GoogleChromeForTesting {
|
|
|
216
306
|
* ```coffeescript [specscript]
|
|
217
307
|
* close() -> undefined
|
|
218
308
|
* ```
|
|
309
|
+
*
|
|
310
|
+
* Terminates the Google Chrome for Testing process.
|
|
311
|
+
*
|
|
312
|
+
* Arguments:
|
|
313
|
+
* * (none)
|
|
314
|
+
*
|
|
315
|
+
* Return:
|
|
316
|
+
* * `undefined`
|
|
317
|
+
*
|
|
318
|
+
* ```javascript
|
|
319
|
+
* googleChromeForTesting.close()
|
|
320
|
+
* ```
|
|
219
321
|
*/
|
|
220
322
|
close() {
|
|
221
323
|
this.cmd.kill('SIGKILL')
|
package/README.md
CHANGED
|
@@ -323,10 +323,14 @@ await docker.createService({
|
|
|
323
323
|
|
|
324
324
|
## [Automate tests with Google Chrome for Testing](https://presidium.services/docs/GoogleChromeDevTools)
|
|
325
325
|
```javascript
|
|
326
|
+
const GoogleChromeForTesting = require('presidium/GoogleChromeForTesting')
|
|
326
327
|
const GoogleChromeDevTools = require('presidium/GoogleChromeDevTools')
|
|
327
328
|
|
|
328
|
-
const
|
|
329
|
-
await
|
|
329
|
+
const googleChromeForTesting = new GoogleChromeForTesting()
|
|
330
|
+
await googleChromeForTesting.init() // downloads Google Chrome for Testing
|
|
331
|
+
|
|
332
|
+
const googleChromeDevTools = new GoogleChromeDevTools(googleChromeForTesting)
|
|
333
|
+
await googleChromeDevTools.init() // connects to the DevTools server
|
|
330
334
|
|
|
331
335
|
// get targets
|
|
332
336
|
const targetsData = await googleChromeDevTools.Target.getTargets()
|
package/index.js
CHANGED
|
@@ -6,6 +6,7 @@ module.exports = {
|
|
|
6
6
|
DynamoDBTable: require('./DynamoDBTable.js'),
|
|
7
7
|
ECR: require('./ECR.js'),
|
|
8
8
|
GoogleChromeDevTools: require('./GoogleChromeDevTools.js'),
|
|
9
|
+
GoogleChromeForTesting: require('./GoogleChromeForTesting.js'),
|
|
9
10
|
HTTP: require('./HTTP.js'),
|
|
10
11
|
NpmToken: require('./NpmToken.js'),
|
|
11
12
|
OptionalValidator: require('./OptionalValidator.js'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "presidium",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "A library for creating web services",
|
|
5
5
|
"author": "Richard Tong",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"DynamoDBTable.js",
|
|
20
20
|
"ECR.js",
|
|
21
21
|
"GoogleChromeDevTools.js",
|
|
22
|
+
"GoogleChromeForTesting.js",
|
|
22
23
|
"HTTP.js",
|
|
23
24
|
"index.js",
|
|
24
25
|
"NpmToken.js",
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
const Test = require('thunk-test')
|
|
2
|
-
const assert = require('assert')
|
|
3
|
-
const fs = require('fs')
|
|
4
|
-
const { exec } = require('child_process')
|
|
5
|
-
const Readable = require('../Readable')
|
|
6
|
-
const GoogleChromeForTesting = require('./GoogleChromeForTesting')
|
|
7
|
-
|
|
8
|
-
const test = new Test('GoogleChromeForTesting', async function integration() {
|
|
9
|
-
await fs.promises.rm('google-chrome-for-testing', { recursive: true, force: true })
|
|
10
|
-
|
|
11
|
-
const cmd = await exec('ps aux | grep "Google Chrome for Testing" | awk \'{print $2}\' | xargs kill', {
|
|
12
|
-
stdio: 'inherit',
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
{
|
|
16
|
-
const googleChromeForTesting = new GoogleChromeForTesting({
|
|
17
|
-
userDataDir: `${__dirname}/tmp/chrome`,
|
|
18
|
-
useMockKeychain: true,
|
|
19
|
-
})
|
|
20
|
-
await googleChromeForTesting.init()
|
|
21
|
-
|
|
22
|
-
assert.equal(typeof googleChromeForTesting.devtoolsUrl, 'string')
|
|
23
|
-
assert(googleChromeForTesting.devtoolsUrl.startsWith('ws://'))
|
|
24
|
-
|
|
25
|
-
googleChromeForTesting.close()
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
{
|
|
29
|
-
const googleChromeForTesting = new GoogleChromeForTesting({
|
|
30
|
-
userDataDir: `${__dirname}/tmp/chrome`,
|
|
31
|
-
useMockKeychain: true,
|
|
32
|
-
})
|
|
33
|
-
await googleChromeForTesting.init()
|
|
34
|
-
|
|
35
|
-
assert.equal(typeof googleChromeForTesting.devtoolsUrl, 'string')
|
|
36
|
-
assert(googleChromeForTesting.devtoolsUrl.startsWith('ws://'))
|
|
37
|
-
|
|
38
|
-
googleChromeForTesting.close()
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
await fs.promises.rm('google-chrome-for-testing', { recursive: true, force: true })
|
|
42
|
-
|
|
43
|
-
console.log('Success')
|
|
44
|
-
}).case()
|
|
45
|
-
|
|
46
|
-
if (process.argv[1] == __filename) {
|
|
47
|
-
test()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
module.exports = test
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|