@percy/core 1.12.0 → 1.13.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/dist/api.js +60 -45
- package/dist/browser.js +82 -68
- package/dist/config.js +16 -9
- package/dist/discovery.js +65 -60
- package/dist/install.js +29 -27
- package/dist/network.js +72 -79
- package/dist/page.js +47 -54
- package/dist/percy.js +85 -85
- package/dist/queue.js +103 -146
- package/dist/server.js +51 -88
- package/dist/session.js +8 -15
- package/dist/snapshot.js +105 -92
- package/dist/utils.js +60 -58
- package/package.json +6 -6
package/dist/server.js
CHANGED
|
@@ -1,38 +1,28 @@
|
|
|
1
1
|
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
|
|
2
|
-
|
|
3
2
|
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
|
4
|
-
|
|
5
3
|
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
6
|
-
|
|
7
4
|
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
|
8
|
-
|
|
9
5
|
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
|
|
10
|
-
|
|
11
6
|
function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
|
|
12
|
-
|
|
13
7
|
function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
|
|
14
|
-
|
|
15
8
|
function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
|
|
16
|
-
|
|
17
9
|
function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
|
|
18
|
-
|
|
19
10
|
import fs from 'fs';
|
|
20
11
|
import path from 'path';
|
|
21
12
|
import http from 'http';
|
|
22
13
|
import mime from 'mime-types';
|
|
23
14
|
import disposition from 'content-disposition';
|
|
24
|
-
import { pathToRegexp, match as pathToMatch, compile as makeToPath } from 'path-to-regexp';
|
|
25
|
-
// buffer respectively; both available after the 'end' event is emitted
|
|
15
|
+
import { pathToRegexp, match as pathToMatch, compile as makeToPath } from 'path-to-regexp';
|
|
26
16
|
|
|
17
|
+
// custom incoming message adds a `url` and `body` properties containing the parsed URL and message
|
|
18
|
+
// buffer respectively; both available after the 'end' event is emitted
|
|
27
19
|
export class IncomingMessage extends http.IncomingMessage {
|
|
28
20
|
constructor(socket) {
|
|
29
21
|
let buffer = [];
|
|
30
22
|
super(socket).on('data', d => buffer.push(d)).on('end', () => {
|
|
31
23
|
var _this$headers$content;
|
|
32
|
-
|
|
33
24
|
this.url = new URL(this.url, `http://${this.headers.host}`);
|
|
34
25
|
if (buffer.length) this.body = Buffer.concat(buffer);
|
|
35
|
-
|
|
36
26
|
if (this.body && (_this$headers$content = this.headers['content-type']) !== null && _this$headers$content !== void 0 && _this$headers$content.includes('json')) {
|
|
37
27
|
try {
|
|
38
28
|
this.body = JSON.parse(this.body);
|
|
@@ -40,9 +30,9 @@ export class IncomingMessage extends http.IncomingMessage {
|
|
|
40
30
|
}
|
|
41
31
|
});
|
|
42
32
|
}
|
|
33
|
+
}
|
|
43
34
|
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
// custom server response adds additional convenience methods
|
|
46
36
|
export class ServerResponse extends http.ServerResponse {
|
|
47
37
|
// responds with a status, headers, and body; the second argument can be an content-type string,
|
|
48
38
|
// or a headers object, with content-length being automatically set when a `body` is provided
|
|
@@ -51,41 +41,39 @@ export class ServerResponse extends http.ServerResponse {
|
|
|
51
41
|
this.setHeader('Content-Type', headers);
|
|
52
42
|
headers = null;
|
|
53
43
|
}
|
|
54
|
-
|
|
55
44
|
if (body != null && !this.hasHeader('Content-Length')) {
|
|
56
45
|
this.setHeader('Content-Length', Buffer.byteLength(body));
|
|
57
46
|
}
|
|
58
|
-
|
|
59
47
|
return this.writeHead(status, headers).end(body);
|
|
60
|
-
}
|
|
61
|
-
|
|
48
|
+
}
|
|
62
49
|
|
|
50
|
+
// responds with a status and content with a plain/text content-type
|
|
63
51
|
text(status, content) {
|
|
64
52
|
if (arguments.length < 2) [status, content] = [200, status];
|
|
65
53
|
return this.send(status, 'text/plain', content.toString());
|
|
66
|
-
}
|
|
67
|
-
|
|
54
|
+
}
|
|
68
55
|
|
|
56
|
+
// responds with a status and stringified `data` with a json content-type
|
|
69
57
|
json(status, data) {
|
|
70
58
|
if (arguments.length < 2) [status, data] = [200, status];
|
|
71
59
|
return this.send(status, 'application/json', JSON.stringify(data));
|
|
72
|
-
}
|
|
73
|
-
|
|
60
|
+
}
|
|
74
61
|
|
|
62
|
+
// responds with a status and streams a file with appropriate headers
|
|
75
63
|
file(status, filepath) {
|
|
76
64
|
if (arguments.length < 2) [status, filepath] = [200, status];
|
|
77
65
|
filepath = path.resolve(filepath);
|
|
78
66
|
let {
|
|
79
67
|
size
|
|
80
68
|
} = fs.lstatSync(filepath);
|
|
81
|
-
let range = parseByteRange(this.req.headers.range, size);
|
|
69
|
+
let range = parseByteRange(this.req.headers.range, size);
|
|
82
70
|
|
|
71
|
+
// support simple range requests
|
|
83
72
|
if (this.req.headers.range) {
|
|
84
73
|
let byteRange = range ? `${range.start}-${range.end}` : '*';
|
|
85
74
|
this.setHeader('Content-Range', `bytes ${byteRange}/${size}`);
|
|
86
75
|
if (!range) return this.send(416);
|
|
87
76
|
}
|
|
88
|
-
|
|
89
77
|
this.writeHead(range ? 206 : status, {
|
|
90
78
|
'Accept-Ranges': 'bytes',
|
|
91
79
|
'Content-Type': mime.contentType(path.extname(filepath)),
|
|
@@ -97,31 +85,25 @@ export class ServerResponse extends http.ServerResponse {
|
|
|
97
85
|
fs.createReadStream(filepath, range).pipe(this);
|
|
98
86
|
return this;
|
|
99
87
|
}
|
|
88
|
+
}
|
|
100
89
|
|
|
101
|
-
|
|
102
|
-
|
|
90
|
+
// custom server error with a status and default reason
|
|
103
91
|
export class ServerError extends Error {
|
|
104
92
|
static throw(status, reason) {
|
|
105
93
|
throw new this(status, reason);
|
|
106
94
|
}
|
|
107
|
-
|
|
108
95
|
constructor(status = 500, reason) {
|
|
109
96
|
super(reason || http.STATUS_CODES[status]);
|
|
110
97
|
this.status = status;
|
|
111
98
|
}
|
|
99
|
+
}
|
|
112
100
|
|
|
113
|
-
|
|
114
|
-
|
|
101
|
+
// custom server class handles routing requests and provides alternate methods and properties
|
|
115
102
|
var _sockets = /*#__PURE__*/new WeakMap();
|
|
116
|
-
|
|
117
103
|
var _defaultPort = /*#__PURE__*/new WeakMap();
|
|
118
|
-
|
|
119
104
|
var _routes = /*#__PURE__*/new WeakMap();
|
|
120
|
-
|
|
121
105
|
var _route = /*#__PURE__*/new WeakSet();
|
|
122
|
-
|
|
123
106
|
var _handleRequest = /*#__PURE__*/new WeakSet();
|
|
124
|
-
|
|
125
107
|
export class Server extends http.Server {
|
|
126
108
|
constructor({
|
|
127
109
|
port
|
|
@@ -130,28 +112,22 @@ export class Server extends http.Server {
|
|
|
130
112
|
IncomingMessage,
|
|
131
113
|
ServerResponse
|
|
132
114
|
});
|
|
133
|
-
|
|
134
115
|
_classPrivateMethodInitSpec(this, _handleRequest);
|
|
135
|
-
|
|
136
116
|
_classPrivateMethodInitSpec(this, _route);
|
|
137
|
-
|
|
138
117
|
_classPrivateFieldInitSpec(this, _sockets, {
|
|
139
118
|
writable: true,
|
|
140
119
|
value: new Set()
|
|
141
120
|
});
|
|
142
|
-
|
|
143
121
|
_classPrivateFieldInitSpec(this, _defaultPort, {
|
|
144
122
|
writable: true,
|
|
145
123
|
value: void 0
|
|
146
124
|
});
|
|
147
|
-
|
|
148
125
|
_classPrivateFieldInitSpec(this, _routes, {
|
|
149
126
|
writable: true,
|
|
150
127
|
value: [{
|
|
151
128
|
priority: -1,
|
|
152
129
|
handle: (req, res, next) => {
|
|
153
130
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
154
|
-
|
|
155
131
|
if (req.method === 'OPTIONS') {
|
|
156
132
|
let allowHeaders = req.headers['access-control-request-headers'] || '*';
|
|
157
133
|
let allowMethods = [...new Set(_classPrivateFieldGet(this, _routes).flatMap(route => (!route.match || route.match(req.url.pathname)) && route.methods || []))].join(', ');
|
|
@@ -168,55 +144,50 @@ export class Server extends http.Server {
|
|
|
168
144
|
handle: req => ServerError.throw(404)
|
|
169
145
|
}]
|
|
170
146
|
});
|
|
147
|
+
_classPrivateFieldSet(this, _defaultPort, port);
|
|
171
148
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
149
|
+
// handle requests on end
|
|
175
150
|
this.on('request', (req, res) => {
|
|
176
151
|
req.on('end', () => _classPrivateMethodGet(this, _handleRequest, _handleRequest2).call(this, req, res));
|
|
177
|
-
});
|
|
178
|
-
|
|
152
|
+
});
|
|
153
|
+
// track open connections to terminate when the server closes
|
|
179
154
|
this.on('connection', socket => {
|
|
180
155
|
let handleClose = () => _classPrivateFieldGet(this, _sockets).delete(socket);
|
|
181
|
-
|
|
182
156
|
_classPrivateFieldGet(this, _sockets).add(socket.on('close', handleClose));
|
|
183
157
|
});
|
|
184
|
-
}
|
|
185
|
-
|
|
158
|
+
}
|
|
186
159
|
|
|
160
|
+
// return the listening port or any default port
|
|
187
161
|
get port() {
|
|
188
162
|
var _super$address;
|
|
189
|
-
|
|
190
163
|
return ((_super$address = super.address()) === null || _super$address === void 0 ? void 0 : _super$address.port) ?? _classPrivateFieldGet(this, _defaultPort);
|
|
191
|
-
}
|
|
192
|
-
|
|
164
|
+
}
|
|
193
165
|
|
|
166
|
+
// return a string representation of the server address
|
|
194
167
|
address() {
|
|
195
168
|
let port = this.port;
|
|
196
169
|
let host = 'http://localhost';
|
|
197
170
|
return port ? `${host}:${port}` : host;
|
|
198
|
-
}
|
|
199
|
-
|
|
171
|
+
}
|
|
200
172
|
|
|
173
|
+
// return a promise that resolves when the server is listening
|
|
201
174
|
listen(port = _classPrivateFieldGet(this, _defaultPort)) {
|
|
202
175
|
return new Promise((resolve, reject) => {
|
|
203
176
|
let handle = err => off() && err ? reject(err) : resolve(this);
|
|
204
|
-
|
|
205
177
|
let off = () => this.off('error', handle).off('listening', handle);
|
|
206
|
-
|
|
207
178
|
super.listen(port, handle).once('error', handle);
|
|
208
179
|
});
|
|
209
|
-
}
|
|
210
|
-
|
|
180
|
+
}
|
|
211
181
|
|
|
182
|
+
// return a promise that resolves when the server closes
|
|
212
183
|
close() {
|
|
213
184
|
return new Promise(resolve => {
|
|
214
185
|
_classPrivateFieldGet(this, _sockets).forEach(socket => socket.destroy());
|
|
215
|
-
|
|
216
186
|
super.close(resolve);
|
|
217
187
|
});
|
|
218
|
-
}
|
|
188
|
+
}
|
|
219
189
|
|
|
190
|
+
// initial routes include cors and 404 handling
|
|
220
191
|
|
|
221
192
|
// set request routing and handling for pathnames and methods
|
|
222
193
|
route(method, pathname, handle) {
|
|
@@ -229,12 +200,11 @@ export class Server extends http.Server {
|
|
|
229
200
|
match: pathname && pathToMatch(pathname),
|
|
230
201
|
handle
|
|
231
202
|
});
|
|
232
|
-
}
|
|
233
|
-
|
|
203
|
+
}
|
|
234
204
|
|
|
205
|
+
// install a route that serves requested files from the provided directory
|
|
235
206
|
serve(pathname, directory, options) {
|
|
236
207
|
var _options;
|
|
237
|
-
|
|
238
208
|
if (typeof directory !== 'string') [options, directory] = [directory];
|
|
239
209
|
if (!directory) [pathname, directory] = ['/', pathname];
|
|
240
210
|
let root = path.resolve(directory);
|
|
@@ -258,7 +228,6 @@ export class Server extends http.Server {
|
|
|
258
228
|
handle: async (req, res, next) => {
|
|
259
229
|
try {
|
|
260
230
|
var _options2;
|
|
261
|
-
|
|
262
231
|
let pathname = rewritePath(req.url.pathname);
|
|
263
232
|
let file = await getFile(root, pathname, (_options2 = options) === null || _options2 === void 0 ? void 0 : _options2.cleanUrls);
|
|
264
233
|
if (!(file !== null && file !== void 0 && file.stats.isFile())) return await next();
|
|
@@ -270,28 +239,24 @@ export class Server extends http.Server {
|
|
|
270
239
|
}
|
|
271
240
|
}
|
|
272
241
|
});
|
|
273
|
-
}
|
|
274
|
-
|
|
242
|
+
}
|
|
275
243
|
|
|
276
|
-
|
|
244
|
+
// route and respond to requests; handling errors if necessary
|
|
245
|
+
}
|
|
277
246
|
|
|
247
|
+
// create a url rewriter from provided rewrite rules
|
|
278
248
|
function _route2(route) {
|
|
279
249
|
let i = _classPrivateFieldGet(this, _routes).findIndex(r => r.priority >= route.priority);
|
|
280
|
-
|
|
281
250
|
_classPrivateFieldGet(this, _routes).splice(i, 0, route);
|
|
282
|
-
|
|
283
251
|
return this;
|
|
284
252
|
}
|
|
285
|
-
|
|
286
253
|
async function _handleRequest2(req, res) {
|
|
287
254
|
// support node < 15.7.0
|
|
288
255
|
res.req ?? (res.req = req);
|
|
289
|
-
|
|
290
256
|
try {
|
|
291
257
|
// invoke routes like middleware
|
|
292
258
|
await async function cont(routes, i = 0) {
|
|
293
259
|
let next = () => cont(routes, i + 1);
|
|
294
|
-
|
|
295
260
|
let {
|
|
296
261
|
methods,
|
|
297
262
|
match,
|
|
@@ -304,12 +269,12 @@ async function _handleRequest2(req, res) {
|
|
|
304
269
|
}(_classPrivateFieldGet(this, _routes));
|
|
305
270
|
} catch (error) {
|
|
306
271
|
var _req$headers$accept, _req$headers$content;
|
|
307
|
-
|
|
308
272
|
let {
|
|
309
273
|
status = 500,
|
|
310
274
|
message
|
|
311
|
-
} = error;
|
|
275
|
+
} = error;
|
|
312
276
|
|
|
277
|
+
// fallback error handling
|
|
313
278
|
if ((_req$headers$accept = req.headers.accept) !== null && _req$headers$accept !== void 0 && _req$headers$accept.includes('json') || (_req$headers$content = req.headers['content-type']) !== null && _req$headers$content !== void 0 && _req$headers$content.includes('json')) {
|
|
314
279
|
res.json(status, {
|
|
315
280
|
error: message
|
|
@@ -319,10 +284,8 @@ async function _handleRequest2(req, res) {
|
|
|
319
284
|
}
|
|
320
285
|
}
|
|
321
286
|
}
|
|
322
|
-
|
|
323
287
|
function createRewriter(rewrites = [], cb) {
|
|
324
288
|
let normalize = p => path.posix.normalize(path.posix.join('/', p));
|
|
325
|
-
|
|
326
289
|
if (!Array.isArray(rewrites)) rewrites = Object.entries(rewrites);
|
|
327
290
|
let rewrite = [{
|
|
328
291
|
// resolve and normalize the path before rewriting
|
|
@@ -337,23 +300,23 @@ function createRewriter(rewrites = [], cb) {
|
|
|
337
300
|
};
|
|
338
301
|
})).reduceRight((next, rule) => pathname => {
|
|
339
302
|
var _rule$match;
|
|
340
|
-
|
|
341
303
|
// compose all rewrites into a single function
|
|
342
304
|
let result = ((_rule$match = rule.match) === null || _rule$match === void 0 ? void 0 : _rule$match.call(rule, pathname)) ?? pathname;
|
|
343
305
|
if (result) pathname = rule.apply(result);
|
|
344
306
|
return next(pathname);
|
|
345
|
-
}, p => p);
|
|
307
|
+
}, p => p);
|
|
346
308
|
|
|
309
|
+
// allow additional pathname processing around the rewriter
|
|
347
310
|
return p => cb(p, rewrite);
|
|
348
|
-
}
|
|
349
|
-
|
|
311
|
+
}
|
|
350
312
|
|
|
313
|
+
// returns true if the pathname is inside the root pathname
|
|
351
314
|
function isPathInside(root, pathname) {
|
|
352
315
|
let abs = path.resolve(path.join(root, pathname));
|
|
353
316
|
return !abs.lastIndexOf(root, 0) && (abs[root.length] === path.sep || !abs[root.length]);
|
|
354
|
-
}
|
|
355
|
-
|
|
317
|
+
}
|
|
356
318
|
|
|
319
|
+
// get the absolute path and stats of a possible file
|
|
357
320
|
async function getFile(root, pathname, cleanUrls) {
|
|
358
321
|
for (let filename of [pathname].concat(cleanUrls ? path.join(pathname, 'index.html') : [], cleanUrls && pathname.length > 2 ? pathname.replace(/\/?$/, '.html') : [])) {
|
|
359
322
|
let filepath = path.resolve(path.join(root, filename));
|
|
@@ -363,11 +326,10 @@ async function getFile(root, pathname, cleanUrls) {
|
|
|
363
326
|
stats
|
|
364
327
|
};
|
|
365
328
|
}
|
|
366
|
-
}
|
|
367
|
-
|
|
329
|
+
}
|
|
368
330
|
|
|
331
|
+
// returns the start and end of a byte range or undefined if unable to parse
|
|
369
332
|
const RANGE_REGEXP = /^bytes=(\d*)?-(\d*)?(?:\b|$)/;
|
|
370
|
-
|
|
371
333
|
function parseByteRange(range, size) {
|
|
372
334
|
let [, start, end = size] = (range === null || range === void 0 ? void 0 : range.match(RANGE_REGEXP)) ?? [0, 0, 0];
|
|
373
335
|
start = Math.max(parseInt(start, 10), 0);
|
|
@@ -377,9 +339,9 @@ function parseByteRange(range, size) {
|
|
|
377
339
|
start,
|
|
378
340
|
end
|
|
379
341
|
};
|
|
380
|
-
}
|
|
381
|
-
|
|
342
|
+
}
|
|
382
343
|
|
|
344
|
+
// shorthand function for creating a new server with specific options
|
|
383
345
|
export function createServer(options = {}) {
|
|
384
346
|
let {
|
|
385
347
|
serve,
|
|
@@ -391,8 +353,9 @@ export function createServer(options = {}) {
|
|
|
391
353
|
port
|
|
392
354
|
});
|
|
393
355
|
return serve ? server.serve(baseUrl, serve, opts) : server;
|
|
394
|
-
}
|
|
356
|
+
}
|
|
395
357
|
|
|
358
|
+
// include some exports as static properties
|
|
396
359
|
Server.Error = ServerError;
|
|
397
360
|
Server.createRewriter = createRewriter;
|
|
398
361
|
Server.createServer = createServer;
|
package/dist/session.js
CHANGED
|
@@ -4,13 +4,11 @@ export class Session extends EventEmitter {
|
|
|
4
4
|
#callbacks = new Map();
|
|
5
5
|
log = logger('core:session');
|
|
6
6
|
children = new Map();
|
|
7
|
-
|
|
8
7
|
constructor(browser, {
|
|
9
8
|
params,
|
|
10
9
|
sessionId: parentId
|
|
11
10
|
}) {
|
|
12
11
|
var _this$parent;
|
|
13
|
-
|
|
14
12
|
super();
|
|
15
13
|
this.browser = browser;
|
|
16
14
|
this.sessionId = params.sessionId;
|
|
@@ -21,7 +19,6 @@ export class Session extends EventEmitter {
|
|
|
21
19
|
(_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.children.set(this.sessionId, this);
|
|
22
20
|
this.on('Inspector.targetCrashed', this._handleTargetCrashed);
|
|
23
21
|
}
|
|
24
|
-
|
|
25
22
|
async close() {
|
|
26
23
|
if (!this.browser || this.closing) return;
|
|
27
24
|
this.closing = true;
|
|
@@ -29,20 +26,20 @@ export class Session extends EventEmitter {
|
|
|
29
26
|
targetId: this.targetId
|
|
30
27
|
}).catch(this._handleClosedError);
|
|
31
28
|
}
|
|
32
|
-
|
|
33
29
|
async send(method, params) {
|
|
34
30
|
/* istanbul ignore next: race condition paranoia */
|
|
35
31
|
if (this.closedReason) {
|
|
36
32
|
throw new Error(`Protocol error (${method}): ${this.closedReason}`);
|
|
37
|
-
}
|
|
38
|
-
|
|
33
|
+
}
|
|
39
34
|
|
|
35
|
+
// send a raw message to the browser so we can provide a sessionId
|
|
40
36
|
let id = await this.browser.send({
|
|
41
37
|
sessionId: this.sessionId,
|
|
42
38
|
method,
|
|
43
39
|
params
|
|
44
|
-
});
|
|
40
|
+
});
|
|
45
41
|
|
|
42
|
+
// will resolve or reject when a matching response is received
|
|
46
43
|
return new Promise((resolve, reject) => {
|
|
47
44
|
this.#callbacks.set(id, {
|
|
48
45
|
error: new Error(),
|
|
@@ -52,14 +49,13 @@ export class Session extends EventEmitter {
|
|
|
52
49
|
});
|
|
53
50
|
});
|
|
54
51
|
}
|
|
55
|
-
|
|
56
52
|
_handleMessage(data) {
|
|
57
53
|
if (data.id && this.#callbacks.has(data.id)) {
|
|
58
54
|
// resolve or reject a pending promise created with #send()
|
|
59
55
|
let callback = this.#callbacks.get(data.id);
|
|
60
56
|
this.#callbacks.delete(data.id);
|
|
61
|
-
/* istanbul ignore next: races with browser._handleMessage() */
|
|
62
57
|
|
|
58
|
+
/* istanbul ignore next: races with browser._handleMessage() */
|
|
63
59
|
if (data.error) {
|
|
64
60
|
callback.reject(Object.assign(callback.error, {
|
|
65
61
|
message: `Protocol error (${callback.method}): ${data.error.message}` + ('data' in data.error ? `: ${data.error.data}` : '')
|
|
@@ -72,29 +68,26 @@ export class Session extends EventEmitter {
|
|
|
72
68
|
this.emit(data.method, data.params);
|
|
73
69
|
}
|
|
74
70
|
}
|
|
75
|
-
|
|
76
71
|
_handleClose() {
|
|
77
72
|
var _this$parent2;
|
|
73
|
+
this.closedReason || (this.closedReason = 'Session closed.');
|
|
78
74
|
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
// reject any pending callbacks
|
|
81
76
|
for (let callback of this.#callbacks.values()) {
|
|
82
77
|
callback.reject(Object.assign(callback.error, {
|
|
83
78
|
message: `Protocol error (${callback.method}): ${this.closedReason}`
|
|
84
79
|
}));
|
|
85
80
|
}
|
|
86
|
-
|
|
87
81
|
this.#callbacks.clear();
|
|
88
82
|
(_this$parent2 = this.parent) === null || _this$parent2 === void 0 ? void 0 : _this$parent2.children.delete(this.sessionId);
|
|
89
83
|
this.browser = null;
|
|
90
84
|
}
|
|
91
|
-
|
|
92
85
|
_handleTargetCrashed = () => {
|
|
93
86
|
this.closedReason = 'Session crashed!';
|
|
94
87
|
this.close();
|
|
95
88
|
};
|
|
96
|
-
/* istanbul ignore next: encountered during closing races */
|
|
97
89
|
|
|
90
|
+
/* istanbul ignore next: encountered during closing races */
|
|
98
91
|
_handleClosedError = error => {
|
|
99
92
|
if (!(error.message ?? error).endsWith(this.closedReason)) {
|
|
100
93
|
this.log.debug(error, this.meta);
|