presidium 3.2.0 → 3.3.1
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/DynamoDBStream.js +8 -5
- package/GoogleChromeDevTools.js +208 -42
- package/GoogleChromeForTesting.js +50 -15
- package/LICENSE +5 -17
- package/package.json +1 -1
package/DynamoDBStream.js
CHANGED
|
@@ -467,15 +467,18 @@ class DynamoDBStream {
|
|
|
467
467
|
let exists = false
|
|
468
468
|
while (!exists) {
|
|
469
469
|
await sleep(100)
|
|
470
|
-
|
|
470
|
+
|
|
471
|
+
try {
|
|
472
|
+
const streamData = await this.describe()
|
|
473
|
+
if (streamData.TableStatus == 'ACTIVE') {
|
|
474
|
+
exists = true
|
|
475
|
+
}
|
|
476
|
+
} catch (error) {
|
|
471
477
|
if (error.message == `DynamoDB Stream for ${this.table} not found.`) {
|
|
472
|
-
//
|
|
478
|
+
// continue
|
|
473
479
|
} else {
|
|
474
480
|
throw error
|
|
475
481
|
}
|
|
476
|
-
})
|
|
477
|
-
if (streamData.TableStatus == 'ACTIVE') {
|
|
478
|
-
exists = true
|
|
479
482
|
}
|
|
480
483
|
}
|
|
481
484
|
}
|
package/GoogleChromeDevTools.js
CHANGED
|
@@ -178,38 +178,6 @@ class GoogleChromeDevToolsPage {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
/**
|
|
182
|
-
* @name Event: DOM.attributeModified
|
|
183
|
-
*/
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* @name Event: DOM.attributeRemoved
|
|
187
|
-
*/
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* @name Event: DOM.characterDataModified
|
|
191
|
-
*/
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* @name Event: DOM.childNodeCountUpdated
|
|
195
|
-
*/
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* @name Event: DOM.childNodeInserted
|
|
199
|
-
*/
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* @name Event: DOM.childNodeRemoved
|
|
203
|
-
*/
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* @name Event: DOM.documentUpdated
|
|
207
|
-
*/
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* @name Event: DOM.setChildNodes
|
|
211
|
-
*/
|
|
212
|
-
|
|
213
181
|
class GoogleChromeDevToolsDOM {
|
|
214
182
|
constructor(websocket) {
|
|
215
183
|
this.websocket = websocket
|
|
@@ -497,8 +465,179 @@ class GoogleChromeDevToolsDOM {
|
|
|
497
465
|
return _Method.call(this, 'DOM.focus', options)
|
|
498
466
|
}
|
|
499
467
|
|
|
468
|
+
/**
|
|
469
|
+
* @name Event: DOM.attributeModified
|
|
470
|
+
*
|
|
471
|
+
* @docs
|
|
472
|
+
* ```coffeescript [specscript]
|
|
473
|
+
* emit('DOM.attributeModified', data {
|
|
474
|
+
* nodeId: string,
|
|
475
|
+
* name: string,
|
|
476
|
+
* value: string,
|
|
477
|
+
* })
|
|
478
|
+
* ```
|
|
479
|
+
*
|
|
480
|
+
* The `DOM.attributeModified` event. Emitted when an attribute of an element is modified.
|
|
481
|
+
*
|
|
482
|
+
* Event Data:
|
|
483
|
+
* `data`
|
|
484
|
+
* * `nodeId` - the ID of the element or node.
|
|
485
|
+
* * `name` - the name of the modified attribute.
|
|
486
|
+
* * `value` - the value of the modified attribute.
|
|
487
|
+
*
|
|
488
|
+
* ```javascript
|
|
489
|
+
* googleChromeDevTools.on('DOM.attributeModified', data => {
|
|
490
|
+
* console.log('attribute modified:', data)
|
|
491
|
+
* })
|
|
492
|
+
* ```
|
|
493
|
+
*/
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* @name Event: DOM.attributeRemoved
|
|
497
|
+
*
|
|
498
|
+
* @docs
|
|
499
|
+
* ```coffeescript [specscript]
|
|
500
|
+
* emit('DOM.attributeRemoved', data {
|
|
501
|
+
* nodeId: string,
|
|
502
|
+
* name: string,
|
|
503
|
+
* })
|
|
504
|
+
* ```
|
|
505
|
+
*
|
|
506
|
+
* The `DOM.attributeRemoved` event. Emitted when an attribute of an element is removed.
|
|
507
|
+
*
|
|
508
|
+
* Event Data:
|
|
509
|
+
* * `data`
|
|
510
|
+
* * `nodeId` - the ID of the element or node.
|
|
511
|
+
* * `name` - the name of the removed attribute.
|
|
512
|
+
*
|
|
513
|
+
* ```javascript
|
|
514
|
+
* googleChromeDevTools.on('DOM.attributeModified', data => {
|
|
515
|
+
* console.log('attribute removed:', data)
|
|
516
|
+
* })
|
|
517
|
+
* ```
|
|
518
|
+
*/
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* @name Event: DOM.characterDataModified
|
|
522
|
+
*
|
|
523
|
+
* @docs
|
|
524
|
+
* ```coffeescript [specscript]
|
|
525
|
+
* emit('DOM.characterDataModified', data {
|
|
526
|
+
* nodeId: string,
|
|
527
|
+
* childNodeCount: number,
|
|
528
|
+
* })
|
|
529
|
+
* ```
|
|
530
|
+
*
|
|
531
|
+
* The `DOM.characterDataModified` event. Emitted when a text node is modified.
|
|
532
|
+
*
|
|
533
|
+
* Event Data:
|
|
534
|
+
* * `data`
|
|
535
|
+
* * `nodeId` - the ID of the element or node.
|
|
536
|
+
* * `characterData` - the new text value.
|
|
537
|
+
*
|
|
538
|
+
* ```javascript
|
|
539
|
+
* googleChromeDevTools.on('DOM.characterDataModified', data => {
|
|
540
|
+
* console.log('text modified:', data)
|
|
541
|
+
* })
|
|
542
|
+
* ```
|
|
543
|
+
*/
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* @name Event: DOM.childNodeCountUpdated
|
|
547
|
+
*
|
|
548
|
+
* @docs
|
|
549
|
+
* ```coffeescript [specscript]
|
|
550
|
+
* emit('DOM.childNodeCountUpdated', data {
|
|
551
|
+
* nodeId: string,
|
|
552
|
+
* childNodeCount: number,
|
|
553
|
+
* })
|
|
554
|
+
* ```
|
|
555
|
+
*
|
|
556
|
+
* The `DOM.childNodeCountUpdated` event. Emitted when the child node count of a node is updated.
|
|
557
|
+
*
|
|
558
|
+
* Event Data:
|
|
559
|
+
* * `data`
|
|
560
|
+
* * `nodeId` - the ID of the element or node.
|
|
561
|
+
* * `childNodeCount` - the updated count of child nodes.
|
|
562
|
+
*
|
|
563
|
+
* ```javascript
|
|
564
|
+
* googleChromeDevTools.on('DOM.childNodeCountUpdated', data => {
|
|
565
|
+
* console.log('child node count updated:', data)
|
|
566
|
+
* })
|
|
567
|
+
* ```
|
|
568
|
+
*/
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* @name Event: DOM.childNodeInserted
|
|
572
|
+
*
|
|
573
|
+
* @docs
|
|
574
|
+
* ```javascript
|
|
575
|
+
* module CDPDOM 'https://chromedevtools.github.io/devtools-protocol/tot/DOM/'
|
|
576
|
+
*
|
|
577
|
+
* emit('DOM.childNodeInserted', data {
|
|
578
|
+
* parentNodeId: string,
|
|
579
|
+
* previousNodeId: string,
|
|
580
|
+
* node: CDPDOM.Node,
|
|
581
|
+
* })
|
|
582
|
+
* ```
|
|
583
|
+
*
|
|
584
|
+
* The `DOM.childNodeInserted` event. Emitted when a node is inserted into the DOM as a child of another node.
|
|
585
|
+
*
|
|
586
|
+
* Event Data:
|
|
587
|
+
* * `data`
|
|
588
|
+
* * `parentNodeId` - the id of the parent node.
|
|
589
|
+
* * `previousNodeId` - the id of the node immediately preceding the inserted node.
|
|
590
|
+
* * `node` - [`CDPDOM.Node`](https://chromedevtools.github.io/devtools-protocol/tot/DOM/#type-Node) - data about the inserted node.
|
|
591
|
+
*/
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* @name Event: DOM.childNodeRemoved
|
|
595
|
+
*
|
|
596
|
+
* @docs
|
|
597
|
+
* ```javascript
|
|
598
|
+
* emit('DOM.childNodeRemoved', data {
|
|
599
|
+
* parentNodeId: string,
|
|
600
|
+
* nodeId: string,
|
|
601
|
+
* })
|
|
602
|
+
* ```
|
|
603
|
+
*
|
|
604
|
+
* The `DOM.childNodeRemoved` event. Emitted when a node is removed from the DOM as a child of another node.
|
|
605
|
+
*
|
|
606
|
+
* Event Data:
|
|
607
|
+
* * `data`
|
|
608
|
+
* * `parentNodeId` - the id of the parent node.
|
|
609
|
+
* * `nodeId` - the id of the removed node.
|
|
610
|
+
*
|
|
611
|
+
* ```javascript
|
|
612
|
+
* googleChromeDevTools.on('DOM.childNodeRemoved', data => {
|
|
613
|
+
* console.log('child node removed:', data.nodeId)
|
|
614
|
+
* })
|
|
615
|
+
* ```
|
|
616
|
+
*/
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* @name Event: DOM.documentUpdated
|
|
620
|
+
*
|
|
621
|
+
* @docs
|
|
622
|
+
* ```coffeescript [specscript]
|
|
623
|
+
* emit('DOM.documentUpdated')
|
|
624
|
+
* ```
|
|
625
|
+
*
|
|
626
|
+
* The `DOM.documentUpdated` event. Emitted when the `Document` object has been totally updated and node IDs are no longer valid.
|
|
627
|
+
*
|
|
628
|
+
* Event Data:
|
|
629
|
+
* * (none)
|
|
630
|
+
*
|
|
631
|
+
* ```javascript
|
|
632
|
+
* googleChromeDevTools.on('DOM.documentUpdated', () => {
|
|
633
|
+
* console.log('Document updated')
|
|
634
|
+
* })
|
|
635
|
+
* ```
|
|
636
|
+
*/
|
|
637
|
+
|
|
500
638
|
}
|
|
501
639
|
|
|
640
|
+
|
|
502
641
|
class GoogleChromeDevToolsInput {
|
|
503
642
|
constructor(websocket) {
|
|
504
643
|
this.websocket = websocket
|
|
@@ -849,24 +988,20 @@ class GoogleChromeDevToolsRuntime {
|
|
|
849
988
|
* Supported platforms:
|
|
850
989
|
* * `mac-arm64`
|
|
851
990
|
* * `linux64`
|
|
991
|
+
* * `win64`
|
|
852
992
|
*
|
|
853
993
|
* ## Further Installation
|
|
854
994
|
* Some further installation may be required for Linux platforms.
|
|
855
995
|
*
|
|
856
|
-
* ### Install headless dependencies for Amazon Linux 2023
|
|
996
|
+
* ### Install headless dependencies for Amazon Linux 2023 / Red Hat
|
|
857
997
|
* ```sh
|
|
858
998
|
* sudo dnf install -y cairo pango nss nspr atk at-spi2-atk cups-libs libdrm libxkbcommon libXcomposite libXdamage libXfixes libXrandr mesa-libgbm alsa-lib
|
|
859
999
|
* ```
|
|
860
1000
|
*
|
|
861
|
-
* ### Install headless dependencies for Ubuntu
|
|
1001
|
+
* ### Install headless dependencies for Ubuntu / Debian
|
|
862
1002
|
* ```sh
|
|
863
1003
|
* 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
|
|
864
|
-
*
|
|
865
|
-
* # disable AppArmor unprivileged security restriction
|
|
866
|
-
* echo "kernel.apparmor_restrict_unprivileged_userns=0" | sudo tee /etc/sysctl.d/60-apparmor-namespace.conf
|
|
867
|
-
* sudo sysctl -p /etc/sysctl.d/60-apparmor-namespace.conf
|
|
868
1004
|
* ```
|
|
869
|
-
*
|
|
870
1005
|
*/
|
|
871
1006
|
class GoogleChromeDevTools extends EventEmitter {
|
|
872
1007
|
constructor(options = {}) {
|
|
@@ -921,7 +1056,11 @@ class GoogleChromeDevTools extends EventEmitter {
|
|
|
921
1056
|
offerPerMessageDeflate: false,
|
|
922
1057
|
})
|
|
923
1058
|
this.websocket.on('error', error => {
|
|
924
|
-
|
|
1059
|
+
if (this.closed && error.code == 'ECONNRESET') {
|
|
1060
|
+
console.error('Reset after close:', error)
|
|
1061
|
+
} else {
|
|
1062
|
+
throw error
|
|
1063
|
+
}
|
|
925
1064
|
})
|
|
926
1065
|
|
|
927
1066
|
this.websocket.on('message', message => {
|
|
@@ -995,10 +1134,37 @@ class GoogleChromeDevTools extends EventEmitter {
|
|
|
995
1134
|
* ```
|
|
996
1135
|
*/
|
|
997
1136
|
close() {
|
|
1137
|
+
this.closed = true
|
|
998
1138
|
this.websocket.sendClose()
|
|
999
|
-
this.websocket.close()
|
|
1000
|
-
|
|
1139
|
+
this.websocket.on('close', () => {
|
|
1140
|
+
this.googleChromeForTesting.cmd.on('close', () => {
|
|
1141
|
+
this.emit('close')
|
|
1142
|
+
})
|
|
1143
|
+
this.googleChromeForTesting.close()
|
|
1144
|
+
})
|
|
1001
1145
|
}
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* @name Event: close
|
|
1149
|
+
*
|
|
1150
|
+
* @docs
|
|
1151
|
+
* ```coffeescript [specscript]
|
|
1152
|
+
* emit('close')
|
|
1153
|
+
* ```
|
|
1154
|
+
*
|
|
1155
|
+
* The `close` event. Emitted when the websocket connection to the DevTools server is closed and the Google Chrome for Testing process is terminated.
|
|
1156
|
+
*
|
|
1157
|
+
* Event Data:
|
|
1158
|
+
* * (none)
|
|
1159
|
+
*
|
|
1160
|
+
* ```javascript
|
|
1161
|
+
* googleChromeForTesting.on('close', () => {
|
|
1162
|
+
* console.log('WebSocket connection closed and Google Chrome for Testing process terminated.')
|
|
1163
|
+
* })
|
|
1164
|
+
* ```
|
|
1165
|
+
*/
|
|
1166
|
+
|
|
1002
1167
|
}
|
|
1003
1168
|
|
|
1169
|
+
|
|
1004
1170
|
module.exports = GoogleChromeDevTools
|
|
@@ -18,7 +18,7 @@ async function getChromeVersions() {
|
|
|
18
18
|
return data
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
function updateConsoleLog(message) {
|
|
21
|
+
function updateConsoleLog(message, platform) {
|
|
22
22
|
readline.cursorTo(process.stdout, 0, undefined);
|
|
23
23
|
readline.clearLine(process.stdout, 0);
|
|
24
24
|
process.stdout.write(message);
|
|
@@ -33,7 +33,11 @@ function getPlatform() {
|
|
|
33
33
|
|
|
34
34
|
if (platform == 'mac') {
|
|
35
35
|
platform = `${platform}-${arch}`
|
|
36
|
-
}
|
|
36
|
+
}
|
|
37
|
+
else if (platform == 'win32') {
|
|
38
|
+
platform = `win${arch.slice(1)}`
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
37
41
|
platform = `${platform}${arch.slice(1)}`
|
|
38
42
|
}
|
|
39
43
|
|
|
@@ -58,13 +62,26 @@ async function getChromeUrl() {
|
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
async function installChrome() {
|
|
65
|
+
const platform = getPlatform()
|
|
66
|
+
const delimiter = platform.startsWith('win') ? '\\' : '/'
|
|
61
67
|
const url = await getChromeUrl.call(this)
|
|
62
|
-
|
|
63
|
-
|
|
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('/')) {
|
|
64
76
|
filepath = path.join(process.cwd(), filepath)
|
|
65
77
|
}
|
|
66
|
-
|
|
67
|
-
|
|
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('/')) {
|
|
68
85
|
parentDir = path.join(process.cwd(), parentDir)
|
|
69
86
|
}
|
|
70
87
|
await fs.promises.mkdir(parentDir, { recursive: true })
|
|
@@ -81,9 +98,9 @@ async function installChrome() {
|
|
|
81
98
|
response.on('data', chunk => {
|
|
82
99
|
downloadedLength += chunk.length
|
|
83
100
|
if (downloadedLength == contentLength) {
|
|
84
|
-
updateConsoleLog(`Downloading ${url} (${downloadedLength} / ${contentLength} bytes)\n
|
|
101
|
+
updateConsoleLog(`Downloading ${url} (${downloadedLength} / ${contentLength} bytes)\n`, platform)
|
|
85
102
|
} else {
|
|
86
|
-
updateConsoleLog(`Downloading ${url} (${downloadedLength} / ${contentLength} bytes)
|
|
103
|
+
updateConsoleLog(`Downloading ${url} (${downloadedLength} / ${contentLength} bytes)`, platform)
|
|
87
104
|
}
|
|
88
105
|
|
|
89
106
|
fileStream.write(chunk)
|
|
@@ -98,10 +115,11 @@ async function installChrome() {
|
|
|
98
115
|
})
|
|
99
116
|
await promise
|
|
100
117
|
|
|
118
|
+
console.log('Extracting', filepath)
|
|
101
119
|
try {
|
|
102
120
|
await extract(filepath, { dir: parentDir })
|
|
103
|
-
} catch {
|
|
104
|
-
await sleep(
|
|
121
|
+
} catch (_error) {
|
|
122
|
+
await sleep(1000)
|
|
105
123
|
await extract(filepath, { dir: parentDir })
|
|
106
124
|
}
|
|
107
125
|
}
|
|
@@ -113,14 +131,21 @@ async function getChromeFilepath() {
|
|
|
113
131
|
const parentDir = `${filepath.split('/').slice(0, -1).join('/')}`
|
|
114
132
|
|
|
115
133
|
try {
|
|
134
|
+
const dirents = await fs.promises.readdir(parentDir)
|
|
135
|
+
if (dirents.length <= 1) {
|
|
136
|
+
await installChrome.call(this)
|
|
137
|
+
}
|
|
138
|
+
|
|
116
139
|
for await (const filepath of walk(parentDir)) {
|
|
117
|
-
console.log(filepath)
|
|
118
140
|
if (platform.startsWith('mac') && filepath.endsWith('Google Chrome for Testing')) {
|
|
119
141
|
return filepath
|
|
120
142
|
}
|
|
121
143
|
if (platform.startsWith('linux') && filepath.endsWith('chrome')) {
|
|
122
144
|
return filepath
|
|
123
145
|
}
|
|
146
|
+
if (platform.startsWith('win') && filepath.endsWith('chrome.exe')) {
|
|
147
|
+
return filepath
|
|
148
|
+
}
|
|
124
149
|
}
|
|
125
150
|
} catch (error) {
|
|
126
151
|
if (error.code == 'ENOENT') {
|
|
@@ -173,6 +198,7 @@ async function getChromeFilepath() {
|
|
|
173
198
|
* Supported platforms:
|
|
174
199
|
* * `mac-arm64`
|
|
175
200
|
* * `linux64`
|
|
201
|
+
* * `win64`
|
|
176
202
|
*
|
|
177
203
|
* ## Further Installation
|
|
178
204
|
* Some further installation may be required for Linux platforms.
|
|
@@ -185,10 +211,6 @@ async function getChromeFilepath() {
|
|
|
185
211
|
* ### Install headless dependencies for Ubuntu / Debian
|
|
186
212
|
* ```sh
|
|
187
213
|
* 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
|
|
188
|
-
*
|
|
189
|
-
* # disable AppArmor unprivileged security restriction
|
|
190
|
-
* echo "kernel.apparmor_restrict_unprivileged_userns=0" | sudo tee /etc/sysctl.d/60-apparmor-namespace.conf
|
|
191
|
-
* sudo sysctl -p /etc/sysctl.d/60-apparmor-namespace.conf
|
|
192
214
|
* ```
|
|
193
215
|
*/
|
|
194
216
|
class GoogleChromeForTesting {
|
|
@@ -236,6 +258,7 @@ class GoogleChromeForTesting {
|
|
|
236
258
|
`--user-data-dir=${this.userDataDir}`,
|
|
237
259
|
...this.headless ? ['--headless'] : [],
|
|
238
260
|
...this.useMockKeychain ? ['--use-mock-keychain'] : [],
|
|
261
|
+
'--no-sandbox',
|
|
239
262
|
])
|
|
240
263
|
cmd.stdout.pipe(process.stdout)
|
|
241
264
|
cmd.stderr.pipe(process.stderr)
|
|
@@ -288,6 +311,18 @@ class GoogleChromeForTesting {
|
|
|
288
311
|
* ```coffeescript [specscript]
|
|
289
312
|
* close() -> undefined
|
|
290
313
|
* ```
|
|
314
|
+
*
|
|
315
|
+
* Terminates the Google Chrome for Testing process.
|
|
316
|
+
*
|
|
317
|
+
* Arguments:
|
|
318
|
+
* * (none)
|
|
319
|
+
*
|
|
320
|
+
* Return:
|
|
321
|
+
* * `undefined`
|
|
322
|
+
*
|
|
323
|
+
* ```javascript
|
|
324
|
+
* googleChromeForTesting.close()
|
|
325
|
+
* ```
|
|
291
326
|
*/
|
|
292
327
|
close() {
|
|
293
328
|
this.cmd.kill('SIGKILL')
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
The
|
|
1
|
+
The CLOUT Free and Open Source Software License (CFOSS)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
© Richard Yufei Tong, King of Software
|
|
4
4
|
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
all copies or substantial portions of the Software.
|
|
7
|
+
1. This permission notice is included in all copies or substantial portions of the Software.
|
|
14
8
|
|
|
15
|
-
THE SOFTWARE IS PROVIDED
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
-
THE SOFTWARE.
|
|
9
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE, OR IN THE USE OF OR OTHER DEALINGS OF THE SOFTWARE.
|