@lvce-editor/test-worker 1.0.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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/index.js +1901 -0
- package/package.json +73 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1901 @@
|
|
|
1
|
+
const state$3 = {
|
|
2
|
+
/**
|
|
3
|
+
* @type {any}
|
|
4
|
+
*/
|
|
5
|
+
ipc: undefined
|
|
6
|
+
};
|
|
7
|
+
const get$1 = () => {
|
|
8
|
+
return state$3.ipc;
|
|
9
|
+
};
|
|
10
|
+
const set$1 = ipc => {
|
|
11
|
+
state$3.ipc = ipc;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const Two = '2.0';
|
|
15
|
+
let AssertionError$1 = class AssertionError extends Error {
|
|
16
|
+
constructor(message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'AssertionError';
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const getType$1 = value => {
|
|
22
|
+
switch (typeof value) {
|
|
23
|
+
case 'number':
|
|
24
|
+
return 'number';
|
|
25
|
+
case 'function':
|
|
26
|
+
return 'function';
|
|
27
|
+
case 'string':
|
|
28
|
+
return 'string';
|
|
29
|
+
case 'object':
|
|
30
|
+
if (value === null) {
|
|
31
|
+
return 'null';
|
|
32
|
+
}
|
|
33
|
+
if (Array.isArray(value)) {
|
|
34
|
+
return 'array';
|
|
35
|
+
}
|
|
36
|
+
return 'object';
|
|
37
|
+
case 'boolean':
|
|
38
|
+
return 'boolean';
|
|
39
|
+
default:
|
|
40
|
+
return 'unknown';
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const number = value => {
|
|
44
|
+
const type = getType$1(value);
|
|
45
|
+
if (type !== 'number') {
|
|
46
|
+
throw new AssertionError$1('expected value to be of type number');
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const state$1$1 = {
|
|
50
|
+
callbacks: Object.create(null)
|
|
51
|
+
};
|
|
52
|
+
const set = (id, fn) => {
|
|
53
|
+
state$1$1.callbacks[id] = fn;
|
|
54
|
+
};
|
|
55
|
+
const get = id => {
|
|
56
|
+
return state$1$1.callbacks[id];
|
|
57
|
+
};
|
|
58
|
+
const remove = id => {
|
|
59
|
+
delete state$1$1.callbacks[id];
|
|
60
|
+
};
|
|
61
|
+
const state$2 = {
|
|
62
|
+
id: 0
|
|
63
|
+
};
|
|
64
|
+
const create$3 = () => {
|
|
65
|
+
return ++state$2.id;
|
|
66
|
+
};
|
|
67
|
+
const warn = (...args) => {
|
|
68
|
+
console.warn(...args);
|
|
69
|
+
};
|
|
70
|
+
const withResolvers$1 = () => {
|
|
71
|
+
/**
|
|
72
|
+
* @type {any}
|
|
73
|
+
*/
|
|
74
|
+
let _resolve;
|
|
75
|
+
const promise = new Promise(resolve => {
|
|
76
|
+
_resolve = resolve;
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
resolve: _resolve,
|
|
80
|
+
promise
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
const registerPromise = () => {
|
|
84
|
+
const id = create$3();
|
|
85
|
+
const {
|
|
86
|
+
resolve,
|
|
87
|
+
promise
|
|
88
|
+
} = withResolvers$1();
|
|
89
|
+
set(id, resolve);
|
|
90
|
+
return {
|
|
91
|
+
id,
|
|
92
|
+
promise
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
const resolve = (id, args) => {
|
|
96
|
+
number(id);
|
|
97
|
+
const fn = get(id);
|
|
98
|
+
if (!fn) {
|
|
99
|
+
console.log(args);
|
|
100
|
+
warn(`callback ${id} may already be disposed`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
fn(args);
|
|
104
|
+
remove(id);
|
|
105
|
+
};
|
|
106
|
+
const create$2 = (method, params) => {
|
|
107
|
+
const {
|
|
108
|
+
id,
|
|
109
|
+
promise
|
|
110
|
+
} = registerPromise();
|
|
111
|
+
const message = {
|
|
112
|
+
jsonrpc: Two,
|
|
113
|
+
method,
|
|
114
|
+
params,
|
|
115
|
+
id
|
|
116
|
+
};
|
|
117
|
+
return {
|
|
118
|
+
message,
|
|
119
|
+
promise
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
class JsonRpcError extends Error {
|
|
123
|
+
constructor(message) {
|
|
124
|
+
super(message);
|
|
125
|
+
this.name = 'JsonRpcError';
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const NewLine$3 = '\n';
|
|
129
|
+
const DomException = 'DOMException';
|
|
130
|
+
const ReferenceError$1 = 'ReferenceError';
|
|
131
|
+
const SyntaxError$1 = 'SyntaxError';
|
|
132
|
+
const TypeError$1 = 'TypeError';
|
|
133
|
+
const getErrorConstructor = (message, type) => {
|
|
134
|
+
if (type) {
|
|
135
|
+
switch (type) {
|
|
136
|
+
case DomException:
|
|
137
|
+
// @ts-ignore
|
|
138
|
+
return DOMException;
|
|
139
|
+
case TypeError$1:
|
|
140
|
+
return TypeError;
|
|
141
|
+
case SyntaxError$1:
|
|
142
|
+
return SyntaxError;
|
|
143
|
+
case ReferenceError$1:
|
|
144
|
+
return ReferenceError;
|
|
145
|
+
default:
|
|
146
|
+
return Error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (message.startsWith('TypeError: ')) {
|
|
150
|
+
return TypeError;
|
|
151
|
+
}
|
|
152
|
+
if (message.startsWith('SyntaxError: ')) {
|
|
153
|
+
return SyntaxError;
|
|
154
|
+
}
|
|
155
|
+
if (message.startsWith('ReferenceError: ')) {
|
|
156
|
+
return ReferenceError;
|
|
157
|
+
}
|
|
158
|
+
return Error;
|
|
159
|
+
};
|
|
160
|
+
const constructError = (message, type, name) => {
|
|
161
|
+
const ErrorConstructor = getErrorConstructor(message, type);
|
|
162
|
+
// @ts-ignore
|
|
163
|
+
if (ErrorConstructor === DOMException && name) {
|
|
164
|
+
return new ErrorConstructor(message, name);
|
|
165
|
+
}
|
|
166
|
+
if (ErrorConstructor === Error) {
|
|
167
|
+
const error = new Error(message);
|
|
168
|
+
if (name && name !== 'VError') {
|
|
169
|
+
error.name = name;
|
|
170
|
+
}
|
|
171
|
+
return error;
|
|
172
|
+
}
|
|
173
|
+
return new ErrorConstructor(message);
|
|
174
|
+
};
|
|
175
|
+
const getNewLineIndex$2 = (string, startIndex = undefined) => {
|
|
176
|
+
return string.indexOf(NewLine$3, startIndex);
|
|
177
|
+
};
|
|
178
|
+
const joinLines$1 = lines => {
|
|
179
|
+
return lines.join(NewLine$3);
|
|
180
|
+
};
|
|
181
|
+
const MethodNotFound = -32601;
|
|
182
|
+
const Custom = -32001;
|
|
183
|
+
const splitLines$1 = lines => {
|
|
184
|
+
return lines.split(NewLine$3);
|
|
185
|
+
};
|
|
186
|
+
const getParentStack = error => {
|
|
187
|
+
let parentStack = error.stack || error.data || error.message || '';
|
|
188
|
+
if (parentStack.startsWith(' at')) {
|
|
189
|
+
parentStack = error.message + NewLine$3 + parentStack;
|
|
190
|
+
}
|
|
191
|
+
return parentStack;
|
|
192
|
+
};
|
|
193
|
+
const restoreJsonRpcError = error => {
|
|
194
|
+
if (error && error instanceof Error) {
|
|
195
|
+
return error;
|
|
196
|
+
}
|
|
197
|
+
const currentStack = joinLines$1(splitLines$1(new Error().stack).slice(1));
|
|
198
|
+
if (error && error.code && error.code === MethodNotFound) {
|
|
199
|
+
const restoredError = new JsonRpcError(error.message);
|
|
200
|
+
const parentStack = getParentStack(error);
|
|
201
|
+
restoredError.stack = parentStack + NewLine$3 + currentStack;
|
|
202
|
+
return restoredError;
|
|
203
|
+
}
|
|
204
|
+
if (error && error.message) {
|
|
205
|
+
const restoredError = constructError(error.message, error.type, error.name);
|
|
206
|
+
if (error.data) {
|
|
207
|
+
if (error.data.stack && error.data.type && error.message) {
|
|
208
|
+
restoredError.stack = error.data.type + ': ' + error.message + NewLine$3 + error.data.stack + NewLine$3 + currentStack;
|
|
209
|
+
} else if (error.data.stack) {
|
|
210
|
+
restoredError.stack = error.data.stack;
|
|
211
|
+
}
|
|
212
|
+
if (error.data.codeFrame) {
|
|
213
|
+
// @ts-ignore
|
|
214
|
+
restoredError.codeFrame = error.data.codeFrame;
|
|
215
|
+
}
|
|
216
|
+
if (error.data.code) {
|
|
217
|
+
// @ts-ignore
|
|
218
|
+
restoredError.code = error.data.code;
|
|
219
|
+
}
|
|
220
|
+
if (error.data.type) {
|
|
221
|
+
// @ts-ignore
|
|
222
|
+
restoredError.name = error.data.type;
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
if (error.stack) {
|
|
226
|
+
// TODO accessing stack might be slow
|
|
227
|
+
const lowerStack = restoredError.stack || '';
|
|
228
|
+
// @ts-ignore
|
|
229
|
+
const indexNewLine = getNewLineIndex$2(lowerStack);
|
|
230
|
+
const parentStack = getParentStack(error);
|
|
231
|
+
// @ts-ignore
|
|
232
|
+
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
233
|
+
}
|
|
234
|
+
if (error.codeFrame) {
|
|
235
|
+
// @ts-ignore
|
|
236
|
+
restoredError.codeFrame = error.codeFrame;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return restoredError;
|
|
240
|
+
}
|
|
241
|
+
if (typeof error === 'string') {
|
|
242
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
243
|
+
}
|
|
244
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
245
|
+
};
|
|
246
|
+
const unwrapJsonRpcResult = responseMessage => {
|
|
247
|
+
if ('error' in responseMessage) {
|
|
248
|
+
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
249
|
+
throw restoredError;
|
|
250
|
+
}
|
|
251
|
+
if ('result' in responseMessage) {
|
|
252
|
+
return responseMessage.result;
|
|
253
|
+
}
|
|
254
|
+
throw new JsonRpcError('unexpected response message');
|
|
255
|
+
};
|
|
256
|
+
const create$1 = (message, error) => {
|
|
257
|
+
return {
|
|
258
|
+
jsonrpc: Two,
|
|
259
|
+
id: message.id,
|
|
260
|
+
error
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
264
|
+
const getErrorProperty = (error, prettyError) => {
|
|
265
|
+
if (error && error.code === E_COMMAND_NOT_FOUND) {
|
|
266
|
+
return {
|
|
267
|
+
code: MethodNotFound,
|
|
268
|
+
message: error.message,
|
|
269
|
+
data: error.stack
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
code: Custom,
|
|
274
|
+
message: prettyError.message,
|
|
275
|
+
data: {
|
|
276
|
+
stack: prettyError.stack,
|
|
277
|
+
codeFrame: prettyError.codeFrame,
|
|
278
|
+
type: prettyError.type,
|
|
279
|
+
code: prettyError.code
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
const getErrorResponse = (message, error, preparePrettyError, logError) => {
|
|
284
|
+
const prettyError = preparePrettyError(error);
|
|
285
|
+
logError(error, prettyError);
|
|
286
|
+
const errorProperty = getErrorProperty(error, prettyError);
|
|
287
|
+
return create$1(message, errorProperty);
|
|
288
|
+
};
|
|
289
|
+
const create$4 = (message, result) => {
|
|
290
|
+
return {
|
|
291
|
+
jsonrpc: Two,
|
|
292
|
+
id: message.id,
|
|
293
|
+
result: result ?? null
|
|
294
|
+
};
|
|
295
|
+
};
|
|
296
|
+
const getSuccessResponse = (message, result) => {
|
|
297
|
+
const resultProperty = result ?? null;
|
|
298
|
+
return create$4(message, resultProperty);
|
|
299
|
+
};
|
|
300
|
+
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
|
|
301
|
+
try {
|
|
302
|
+
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
|
|
303
|
+
return getSuccessResponse(message, result);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
return getErrorResponse(message, error, preparePrettyError, logError);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
const handleJsonRpcMessage = async (ipc, message, execute, resolve, preparePrettyError, logError, requiresSocket) => {
|
|
309
|
+
if ('id' in message) {
|
|
310
|
+
if ('method' in message) {
|
|
311
|
+
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
312
|
+
try {
|
|
313
|
+
ipc.send(response);
|
|
314
|
+
} catch (error) {
|
|
315
|
+
const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
|
|
316
|
+
ipc.send(errorResponse);
|
|
317
|
+
}
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
resolve(message.id, message);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
if ('method' in message) {
|
|
324
|
+
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
throw new JsonRpcError('unexpected message');
|
|
328
|
+
};
|
|
329
|
+
const invoke$1 = async (ipc, method, ...params) => {
|
|
330
|
+
const {
|
|
331
|
+
message,
|
|
332
|
+
promise
|
|
333
|
+
} = create$2(method, params);
|
|
334
|
+
ipc.send(message);
|
|
335
|
+
const responseMessage = await promise;
|
|
336
|
+
const result = unwrapJsonRpcResult(responseMessage);
|
|
337
|
+
return result;
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
const invoke = (method, ...params) => {
|
|
341
|
+
const ipc = get$1();
|
|
342
|
+
return invoke$1(ipc, method, ...params);
|
|
343
|
+
};
|
|
344
|
+
const listen$4 = ipc => {
|
|
345
|
+
set$1(ipc);
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
const Fail = 'fail';
|
|
349
|
+
const Pass = 'pass';
|
|
350
|
+
|
|
351
|
+
const now = () => {
|
|
352
|
+
return performance.now();
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const normalizeLine$1 = line => {
|
|
356
|
+
if (line.startsWith('Error: ')) {
|
|
357
|
+
return line.slice(`Error: `.length);
|
|
358
|
+
}
|
|
359
|
+
if (line.startsWith('VError: ')) {
|
|
360
|
+
return line.slice(`VError: `.length);
|
|
361
|
+
}
|
|
362
|
+
return line;
|
|
363
|
+
};
|
|
364
|
+
const getCombinedMessage$1 = (error, message) => {
|
|
365
|
+
const stringifiedError = normalizeLine$1(`${error}`);
|
|
366
|
+
if (message) {
|
|
367
|
+
return `${message}: ${stringifiedError}`;
|
|
368
|
+
}
|
|
369
|
+
return stringifiedError;
|
|
370
|
+
};
|
|
371
|
+
const NewLine$2 = '\n';
|
|
372
|
+
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
373
|
+
return string.indexOf(NewLine$2, startIndex);
|
|
374
|
+
};
|
|
375
|
+
const mergeStacks$1 = (parent, child) => {
|
|
376
|
+
if (!child) {
|
|
377
|
+
return parent;
|
|
378
|
+
}
|
|
379
|
+
const parentNewLineIndex = getNewLineIndex$1(parent);
|
|
380
|
+
const childNewLineIndex = getNewLineIndex$1(child);
|
|
381
|
+
if (childNewLineIndex === -1) {
|
|
382
|
+
return parent;
|
|
383
|
+
}
|
|
384
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
385
|
+
const childRest = child.slice(childNewLineIndex);
|
|
386
|
+
const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
|
|
387
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
388
|
+
return parentFirstLine + childRest;
|
|
389
|
+
}
|
|
390
|
+
return child;
|
|
391
|
+
};
|
|
392
|
+
let VError$1 = class VError extends Error {
|
|
393
|
+
constructor(error, message) {
|
|
394
|
+
const combinedMessage = getCombinedMessage$1(error, message);
|
|
395
|
+
super(combinedMessage);
|
|
396
|
+
this.name = 'VError';
|
|
397
|
+
if (error instanceof Error) {
|
|
398
|
+
this.stack = mergeStacks$1(this.stack, error.stack);
|
|
399
|
+
}
|
|
400
|
+
if (error.codeFrame) {
|
|
401
|
+
// @ts-ignore
|
|
402
|
+
this.codeFrame = error.codeFrame;
|
|
403
|
+
}
|
|
404
|
+
if (error.code) {
|
|
405
|
+
// @ts-ignore
|
|
406
|
+
this.code = error.code;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
const printError = error => {
|
|
412
|
+
if (error && error.constructor.name === 'AssertionError') {
|
|
413
|
+
console.error(error.message);
|
|
414
|
+
} else {
|
|
415
|
+
console.error(error);
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
const stringifyError = error => {
|
|
419
|
+
if (!error) {
|
|
420
|
+
return `${error}`;
|
|
421
|
+
}
|
|
422
|
+
if (error && error.message && error.constructor.name && error.constructor.name !== 'Error' && error.constructor.name !== 'VError') {
|
|
423
|
+
return `${error}`;
|
|
424
|
+
}
|
|
425
|
+
return `${error.message}`;
|
|
426
|
+
};
|
|
427
|
+
const formatDuration = duration => {
|
|
428
|
+
return duration.toFixed(2) + 'ms';
|
|
429
|
+
};
|
|
430
|
+
const executeTest = async (name, fn, globals = {}) => {
|
|
431
|
+
let _error;
|
|
432
|
+
let _start;
|
|
433
|
+
let _end;
|
|
434
|
+
let _duration;
|
|
435
|
+
let _formattedDuration;
|
|
436
|
+
try {
|
|
437
|
+
_start = now();
|
|
438
|
+
await fn(globals);
|
|
439
|
+
_end = now();
|
|
440
|
+
_duration = _end - _start;
|
|
441
|
+
_formattedDuration = formatDuration(_duration);
|
|
442
|
+
console.info(`PASS ${name} in ${_formattedDuration}`);
|
|
443
|
+
} catch (error) {
|
|
444
|
+
if (error &&
|
|
445
|
+
// @ts-ignore
|
|
446
|
+
error.message.startsWith('Failed to load command TestFrameWork.')) {
|
|
447
|
+
console.error(error);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
// @ts-ignore
|
|
451
|
+
_error = stringifyError(error);
|
|
452
|
+
if (!(error instanceof VError$1)) {
|
|
453
|
+
error = new VError$1(error, `Test failed: ${name}`);
|
|
454
|
+
}
|
|
455
|
+
// @ts-ignore
|
|
456
|
+
printError(error);
|
|
457
|
+
}
|
|
458
|
+
let state;
|
|
459
|
+
let background;
|
|
460
|
+
let text;
|
|
461
|
+
if (_error) {
|
|
462
|
+
state = Fail;
|
|
463
|
+
background = 'red';
|
|
464
|
+
text = `test failed: ${_error}`;
|
|
465
|
+
} else {
|
|
466
|
+
background = 'green';
|
|
467
|
+
text = `test passed in ${_formattedDuration}`;
|
|
468
|
+
state = Pass;
|
|
469
|
+
}
|
|
470
|
+
await invoke('TestFrameWork.showOverlay', state, background, text);
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
const importScript = async url => {
|
|
474
|
+
try {
|
|
475
|
+
return await import(url);
|
|
476
|
+
} catch (error) {
|
|
477
|
+
throw error;
|
|
478
|
+
// TODO
|
|
479
|
+
// const actualErrorMessage = await TryToGetactualImportErrorMessage.tryToGetActualImportErrorMessage(url, error)
|
|
480
|
+
// throw new Error(actualErrorMessage)
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
const importTest = async url => {
|
|
485
|
+
try {
|
|
486
|
+
return await importScript(url);
|
|
487
|
+
} catch (error) {
|
|
488
|
+
throw new VError$1(error, 'Failed to import test');
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
// @ts-nocheck
|
|
493
|
+
|
|
494
|
+
const Assert = {
|
|
495
|
+
string(value, message) {
|
|
496
|
+
if (typeof value !== 'string') {
|
|
497
|
+
throw new TypeError(message);
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
number(value, message) {
|
|
501
|
+
if (typeof value !== 'number' || isNaN(value)) {
|
|
502
|
+
throw new TypeError(message);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
const expect$1 = locator => {
|
|
507
|
+
return {
|
|
508
|
+
async checkSingleElementCondition(fnName, options) {
|
|
509
|
+
Assert.string(fnName);
|
|
510
|
+
return invoke('TestFrameWork.checkSingleElementCondition', locator, fnName, options);
|
|
511
|
+
},
|
|
512
|
+
async checkMultiElementCondition(fnName, options) {
|
|
513
|
+
return invoke('TestFrameWork.checkMultiElementCondition', locator, fnName, options);
|
|
514
|
+
},
|
|
515
|
+
async toBeVisible() {
|
|
516
|
+
if (this.negated) {
|
|
517
|
+
throw new Error('use toBeHidden instead of not.toBeVisible');
|
|
518
|
+
}
|
|
519
|
+
return this.checkSingleElementCondition('toBeVisible', {});
|
|
520
|
+
},
|
|
521
|
+
async toHaveText(text) {
|
|
522
|
+
Assert.string(text, 'text must be of type string');
|
|
523
|
+
return this.checkSingleElementCondition('toHaveText', {
|
|
524
|
+
text
|
|
525
|
+
});
|
|
526
|
+
},
|
|
527
|
+
async toHaveValue(value) {
|
|
528
|
+
Assert.string(value, 'value must be of type string');
|
|
529
|
+
return this.checkSingleElementCondition('toHaveValue', {
|
|
530
|
+
value
|
|
531
|
+
});
|
|
532
|
+
},
|
|
533
|
+
async toBeFocused() {
|
|
534
|
+
return this.checkSingleElementCondition('toBeFocused');
|
|
535
|
+
},
|
|
536
|
+
async toHaveCSS(key, value) {
|
|
537
|
+
return this.checkSingleElementCondition('toHaveCss', {
|
|
538
|
+
key,
|
|
539
|
+
value
|
|
540
|
+
});
|
|
541
|
+
},
|
|
542
|
+
async toHaveAttribute(key, value) {
|
|
543
|
+
Assert.string(key, 'key must be of type string');
|
|
544
|
+
// Assert.string(value, 'value must be of type string')
|
|
545
|
+
return this.checkSingleElementCondition('toHaveAttribute', {
|
|
546
|
+
key,
|
|
547
|
+
value
|
|
548
|
+
});
|
|
549
|
+
},
|
|
550
|
+
async toHaveClass(className) {
|
|
551
|
+
Assert.string(className, 'className must be of type string');
|
|
552
|
+
return this.checkSingleElementCondition('toHaveClass', {
|
|
553
|
+
className
|
|
554
|
+
});
|
|
555
|
+
},
|
|
556
|
+
async toHaveId(id) {
|
|
557
|
+
Assert.string(id, 'id must be of type string');
|
|
558
|
+
return this.checkSingleElementCondition('toHaveId', {
|
|
559
|
+
id
|
|
560
|
+
});
|
|
561
|
+
},
|
|
562
|
+
async toHaveCount(count) {
|
|
563
|
+
Assert.number(count, 'count must be of type string');
|
|
564
|
+
return this.checkMultiElementCondition('toHaveCount', {
|
|
565
|
+
count
|
|
566
|
+
});
|
|
567
|
+
},
|
|
568
|
+
async toBeHidden() {
|
|
569
|
+
return this.checkMultiElementCondition('toBeHidden', {});
|
|
570
|
+
},
|
|
571
|
+
get not() {
|
|
572
|
+
this.negated = true;
|
|
573
|
+
return this;
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
const nameAnonymousFunction = (fn, name) => {
|
|
579
|
+
Object.defineProperty(fn, 'name', {
|
|
580
|
+
value: name
|
|
581
|
+
});
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
class AssertionError extends Error {
|
|
585
|
+
constructor(message) {
|
|
586
|
+
super(message);
|
|
587
|
+
this.name = 'AssertionError';
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// TODO treeshake out this whole module in production
|
|
592
|
+
|
|
593
|
+
const getType = value => {
|
|
594
|
+
switch (typeof value) {
|
|
595
|
+
case 'number':
|
|
596
|
+
return 'number';
|
|
597
|
+
case 'function':
|
|
598
|
+
return 'function';
|
|
599
|
+
case 'string':
|
|
600
|
+
return 'string';
|
|
601
|
+
case 'object':
|
|
602
|
+
if (value === null) {
|
|
603
|
+
return 'null';
|
|
604
|
+
}
|
|
605
|
+
if (Array.isArray(value)) {
|
|
606
|
+
return 'array';
|
|
607
|
+
}
|
|
608
|
+
if (value instanceof Uint32Array) {
|
|
609
|
+
return 'uint32array';
|
|
610
|
+
}
|
|
611
|
+
return 'object';
|
|
612
|
+
case 'boolean':
|
|
613
|
+
return 'boolean';
|
|
614
|
+
default:
|
|
615
|
+
return 'unknown';
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
const object = value => {
|
|
619
|
+
const type = getType(value);
|
|
620
|
+
if (type !== 'object') {
|
|
621
|
+
throw new AssertionError('expected value to be of type object');
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
const string = value => {
|
|
625
|
+
const type = getType(value);
|
|
626
|
+
if (type !== 'string') {
|
|
627
|
+
throw new AssertionError('expected value to be of type string');
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
// @ts-nocheck
|
|
632
|
+
|
|
633
|
+
const state$1 = {
|
|
634
|
+
/**
|
|
635
|
+
* @type {any[]}
|
|
636
|
+
*/
|
|
637
|
+
pendingTests: [],
|
|
638
|
+
mockRpcs: Object.create(null)
|
|
639
|
+
};
|
|
640
|
+
const addTest = (name, fn) => {
|
|
641
|
+
state$1.pendingTests.push({
|
|
642
|
+
name,
|
|
643
|
+
fn
|
|
644
|
+
});
|
|
645
|
+
};
|
|
646
|
+
const getTests = () => {
|
|
647
|
+
const tests = state$1.pendingTests;
|
|
648
|
+
state$1.pendingTests = [];
|
|
649
|
+
return tests;
|
|
650
|
+
};
|
|
651
|
+
const setMockRpc = mockRpc => {
|
|
652
|
+
object(mockRpc);
|
|
653
|
+
string(mockRpc.name);
|
|
654
|
+
state$1.mockRpcs[mockRpc.name] = mockRpc;
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
// @ts-nocheck
|
|
658
|
+
|
|
659
|
+
const create = (selector, options) => {
|
|
660
|
+
return new Locator(selector, options);
|
|
661
|
+
};
|
|
662
|
+
const Locator = function (selector, {
|
|
663
|
+
nth = -1,
|
|
664
|
+
hasText = ''
|
|
665
|
+
} = {}) {
|
|
666
|
+
this._selector = selector;
|
|
667
|
+
this._nth = nth;
|
|
668
|
+
this._hasText = hasText;
|
|
669
|
+
};
|
|
670
|
+
const performAction = async (locator, fnName, options) => {
|
|
671
|
+
return invoke('TestFrameWork.performAction', locator, fnName, options);
|
|
672
|
+
};
|
|
673
|
+
const toButtonNumber = buttonType => {
|
|
674
|
+
switch (buttonType) {
|
|
675
|
+
case 'left':
|
|
676
|
+
return 0;
|
|
677
|
+
case 'middle':
|
|
678
|
+
return 1;
|
|
679
|
+
case 'right':
|
|
680
|
+
return 2;
|
|
681
|
+
default:
|
|
682
|
+
throw new Error(`unsupported button type: ${buttonType}`);
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
Locator.prototype.click = async function ({
|
|
686
|
+
button = 'left'
|
|
687
|
+
} = {}) {
|
|
688
|
+
const options = {
|
|
689
|
+
cancable: true,
|
|
690
|
+
bubbles: true,
|
|
691
|
+
button: toButtonNumber(button),
|
|
692
|
+
detail: 1
|
|
693
|
+
};
|
|
694
|
+
return performAction(this, 'click', options);
|
|
695
|
+
};
|
|
696
|
+
Locator.prototype.hover = async function () {
|
|
697
|
+
const options = {
|
|
698
|
+
cancable: true,
|
|
699
|
+
bubbles: true
|
|
700
|
+
};
|
|
701
|
+
return performAction(this, 'hover', options);
|
|
702
|
+
};
|
|
703
|
+
Locator.prototype.first = function () {
|
|
704
|
+
return create(this._selector, {
|
|
705
|
+
nth: 0
|
|
706
|
+
});
|
|
707
|
+
};
|
|
708
|
+
Locator.prototype.locator = function (subSelector) {
|
|
709
|
+
if (this._nth !== -1) {
|
|
710
|
+
return create(`${this._selector}:nth-of-type(${this._nth + 1}) ${subSelector}`);
|
|
711
|
+
}
|
|
712
|
+
return create(`${this._selector} ${subSelector}`);
|
|
713
|
+
};
|
|
714
|
+
Locator.prototype.nth = function (nth) {
|
|
715
|
+
return create(this._selector, {
|
|
716
|
+
nth
|
|
717
|
+
});
|
|
718
|
+
};
|
|
719
|
+
Locator.prototype.type = async function (text) {
|
|
720
|
+
const options = {
|
|
721
|
+
text
|
|
722
|
+
};
|
|
723
|
+
return performAction(this, 'type', options);
|
|
724
|
+
};
|
|
725
|
+
Locator.prototype.dispatchEvent = async function (type, init) {
|
|
726
|
+
return performAction(this, 'dispatchEvent', {
|
|
727
|
+
type,
|
|
728
|
+
init
|
|
729
|
+
});
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
const getTmpDir$1 = async () => {
|
|
733
|
+
return 'memfs://';
|
|
734
|
+
};
|
|
735
|
+
const test = async (name, fn) => {
|
|
736
|
+
nameAnonymousFunction(fn, `test/${name}`);
|
|
737
|
+
addTest(name, fn);
|
|
738
|
+
};
|
|
739
|
+
test.skip = async (id, fn) => {
|
|
740
|
+
const state = 'skip';
|
|
741
|
+
const background = 'yellow';
|
|
742
|
+
const text = `test skipped ${id}`;
|
|
743
|
+
await invoke('TestFrameWork.showOverlay', state, background, text);
|
|
744
|
+
};
|
|
745
|
+
const expect = expect$1;
|
|
746
|
+
|
|
747
|
+
const TestFrameWork = {
|
|
748
|
+
__proto__: null,
|
|
749
|
+
Locator: create,
|
|
750
|
+
expect,
|
|
751
|
+
getTmpDir: getTmpDir$1,
|
|
752
|
+
test
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
const focus$2 = async () => {
|
|
756
|
+
await invoke('ActivityBar.focus');
|
|
757
|
+
};
|
|
758
|
+
const focusFirst$2 = async () => {
|
|
759
|
+
await invoke('ActivityBar.focusFirst');
|
|
760
|
+
};
|
|
761
|
+
const focusLast$2 = async () => {
|
|
762
|
+
await invoke('ActivityBar.focusLast');
|
|
763
|
+
};
|
|
764
|
+
const focusNext$4 = async () => {
|
|
765
|
+
await invoke('ActivityBar.focusNext');
|
|
766
|
+
};
|
|
767
|
+
const focusPrevious$2 = async () => {
|
|
768
|
+
await invoke('ActivityBar.focusPrevious');
|
|
769
|
+
};
|
|
770
|
+
const handleClick$1 = async index => {
|
|
771
|
+
await invoke('ActivityBar.handleClick', index);
|
|
772
|
+
};
|
|
773
|
+
const handleContextMenu = async () => {
|
|
774
|
+
await invoke('ActivityBar.handleContextMenu');
|
|
775
|
+
};
|
|
776
|
+
const selectCurrent = async () => {
|
|
777
|
+
await invoke('ActivityBar.selectCurrent');
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
const TestFrameworkComponentActivityBar = {
|
|
781
|
+
__proto__: null,
|
|
782
|
+
focus: focus$2,
|
|
783
|
+
focusFirst: focusFirst$2,
|
|
784
|
+
focusLast: focusLast$2,
|
|
785
|
+
focusNext: focusNext$4,
|
|
786
|
+
focusPrevious: focusPrevious$2,
|
|
787
|
+
handleClick: handleClick$1,
|
|
788
|
+
handleContextMenu,
|
|
789
|
+
selectCurrent
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
const Electron = 'electron';
|
|
793
|
+
const Remote = 'remote';
|
|
794
|
+
|
|
795
|
+
// @ts-nocheck
|
|
796
|
+
|
|
797
|
+
const getPlatform = () => {
|
|
798
|
+
// @ts-expect-error
|
|
799
|
+
if (typeof PLATFORM !== 'undefined') {
|
|
800
|
+
// @ts-expect-error
|
|
801
|
+
return PLATFORM;
|
|
802
|
+
}
|
|
803
|
+
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
|
|
804
|
+
return 'test';
|
|
805
|
+
}
|
|
806
|
+
// TODO find a better way to pass runtime environment
|
|
807
|
+
if (typeof name !== 'undefined' && name.endsWith('(Electron)')) {
|
|
808
|
+
return Electron;
|
|
809
|
+
}
|
|
810
|
+
return Remote;
|
|
811
|
+
};
|
|
812
|
+
const platform = getPlatform(); // TODO tree-shake this out in production
|
|
813
|
+
|
|
814
|
+
const getAssetDir = () => {
|
|
815
|
+
// @ts-expect-error
|
|
816
|
+
if (typeof ASSET_DIR !== 'undefined') {
|
|
817
|
+
// @ts-expect-error
|
|
818
|
+
return ASSET_DIR;
|
|
819
|
+
}
|
|
820
|
+
if (platform === Electron) {
|
|
821
|
+
return '../../../../..';
|
|
822
|
+
}
|
|
823
|
+
return '';
|
|
824
|
+
};
|
|
825
|
+
const assetDir = getAssetDir();
|
|
826
|
+
|
|
827
|
+
const getBaseUrl = () => {
|
|
828
|
+
return `${location.origin}/${assetDir}`;
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
const TestFrameWorkComponentBaseUrl = {
|
|
832
|
+
__proto__: null,
|
|
833
|
+
getBaseUrl
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
const execute$2 = async (id, ...args) => {
|
|
837
|
+
return invoke(id, ...args);
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
const TestFrameWorkComponentCommand = {
|
|
841
|
+
__proto__: null,
|
|
842
|
+
execute: execute$2
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
const selectItem$1 = async text => {
|
|
846
|
+
await invoke('Menu.selectItem', text);
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
const TestFrameWorkComponentContextMenu = {
|
|
850
|
+
__proto__: null,
|
|
851
|
+
selectItem: selectItem$1
|
|
852
|
+
};
|
|
853
|
+
|
|
854
|
+
const setCursor = async (rowIndex, columnIndex) => {
|
|
855
|
+
await invoke('Editor.cursorSet', rowIndex, columnIndex);
|
|
856
|
+
};
|
|
857
|
+
const openCompletion = async () => {
|
|
858
|
+
await invoke('Editor.openCompletion');
|
|
859
|
+
};
|
|
860
|
+
const openEditorContextMenu = async () => {
|
|
861
|
+
await invoke('Editor.handleContextMenu', 0, 0);
|
|
862
|
+
};
|
|
863
|
+
const invokeTabCompletion = async () => {
|
|
864
|
+
await invoke('Editor.tabCompletion');
|
|
865
|
+
};
|
|
866
|
+
const executeTabCompletion = async () => {
|
|
867
|
+
await invoke('Editor.tabCompletion');
|
|
868
|
+
};
|
|
869
|
+
const invokeBraceCompletion = async text => {
|
|
870
|
+
await invoke('Editor.braceCompletion', text);
|
|
871
|
+
};
|
|
872
|
+
const cursorCharacterRight = async () => {
|
|
873
|
+
await invoke('Editor.cursorCharacterRight');
|
|
874
|
+
};
|
|
875
|
+
const cursorCharacterLeft = async () => {
|
|
876
|
+
await invoke('Editor.cursorCharacterLeft');
|
|
877
|
+
};
|
|
878
|
+
const copyLineDown = async () => {
|
|
879
|
+
await invoke('Editor.copyLineDown');
|
|
880
|
+
};
|
|
881
|
+
const cursorDown = async () => {
|
|
882
|
+
await invoke('Editor.cursorDown');
|
|
883
|
+
};
|
|
884
|
+
const cursorUp = async () => {
|
|
885
|
+
await invoke('Editor.cursorUp');
|
|
886
|
+
};
|
|
887
|
+
const cursorWordLeft = async () => {
|
|
888
|
+
await invoke('Editor.cursorWordLeft');
|
|
889
|
+
};
|
|
890
|
+
const cursorWordRight = async () => {
|
|
891
|
+
await invoke('Editor.cursorWordRight');
|
|
892
|
+
};
|
|
893
|
+
const goToDefinition = async () => {
|
|
894
|
+
await invoke('Editor.goToDefinition');
|
|
895
|
+
};
|
|
896
|
+
const openHover = async () => {
|
|
897
|
+
await invoke('Editor.showHover');
|
|
898
|
+
};
|
|
899
|
+
const goToTypeDefinition = async () => {
|
|
900
|
+
await invoke('Editor.goToTypeDefinition');
|
|
901
|
+
};
|
|
902
|
+
const type = async text => {
|
|
903
|
+
await invoke('Editor.type');
|
|
904
|
+
};
|
|
905
|
+
const findAllReferences = async () => {
|
|
906
|
+
await invoke('SideBar.show', 'References', /* focus */true);
|
|
907
|
+
};
|
|
908
|
+
const findAllImplementations = async () => {
|
|
909
|
+
await invoke('SideBar.show', 'Implementations', /* focus */true);
|
|
910
|
+
};
|
|
911
|
+
const setSelections = async selections => {
|
|
912
|
+
await invoke('Editor.setSelections', selections);
|
|
913
|
+
};
|
|
914
|
+
const openFindWidget = async () => {
|
|
915
|
+
await invoke('Editor.openFind');
|
|
916
|
+
};
|
|
917
|
+
const setDeltaY = async deltaY => {
|
|
918
|
+
await invoke('Editor.setDeltaY', deltaY);
|
|
919
|
+
};
|
|
920
|
+
const format = async () => {
|
|
921
|
+
await invoke('Editor.format');
|
|
922
|
+
};
|
|
923
|
+
const insertLineBreak = async () => {
|
|
924
|
+
await invoke('Editor.insertLineBreak');
|
|
925
|
+
};
|
|
926
|
+
const openSourceActions = async () => {
|
|
927
|
+
await invoke('Editor.showSourceActions');
|
|
928
|
+
};
|
|
929
|
+
const sourceActionsSelectCurrent = async () => {
|
|
930
|
+
await invoke('EditorSourceActions.selectCurrent');
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
const TestFrameWorkComponentEditor = {
|
|
934
|
+
__proto__: null,
|
|
935
|
+
copyLineDown,
|
|
936
|
+
cursorCharacterLeft,
|
|
937
|
+
cursorCharacterRight,
|
|
938
|
+
cursorDown,
|
|
939
|
+
cursorUp,
|
|
940
|
+
cursorWordLeft,
|
|
941
|
+
cursorWordRight,
|
|
942
|
+
executeTabCompletion,
|
|
943
|
+
findAllImplementations,
|
|
944
|
+
findAllReferences,
|
|
945
|
+
format,
|
|
946
|
+
goToDefinition,
|
|
947
|
+
goToTypeDefinition,
|
|
948
|
+
insertLineBreak,
|
|
949
|
+
invokeBraceCompletion,
|
|
950
|
+
invokeTabCompletion,
|
|
951
|
+
openCompletion,
|
|
952
|
+
openEditorContextMenu,
|
|
953
|
+
openFindWidget,
|
|
954
|
+
openHover,
|
|
955
|
+
openSourceActions,
|
|
956
|
+
setCursor,
|
|
957
|
+
setDeltaY,
|
|
958
|
+
setSelections,
|
|
959
|
+
sourceActionsSelectCurrent,
|
|
960
|
+
type
|
|
961
|
+
};
|
|
962
|
+
|
|
963
|
+
const openContextMenu = async index => {
|
|
964
|
+
await invoke('Explorer.handleContextMenuKeyboard', index);
|
|
965
|
+
};
|
|
966
|
+
const focus$1 = async () => {
|
|
967
|
+
await invoke('Explorer.focusIndex', -1);
|
|
968
|
+
};
|
|
969
|
+
const focusNext$3 = async () => {
|
|
970
|
+
await invoke('Explorer.focusNext');
|
|
971
|
+
};
|
|
972
|
+
const focusIndex$2 = async index => {
|
|
973
|
+
await invoke('Explorer.focusIndex', index);
|
|
974
|
+
};
|
|
975
|
+
const clickCurrent = async () => {
|
|
976
|
+
await invoke('Explorer.handleClickCurrent');
|
|
977
|
+
};
|
|
978
|
+
const handleArrowLeft = async () => {
|
|
979
|
+
await invoke('Explorer.handleArrowLeft');
|
|
980
|
+
};
|
|
981
|
+
const focusLast$1 = async () => {
|
|
982
|
+
await invoke('Explorer.focusLast');
|
|
983
|
+
};
|
|
984
|
+
const focusFirst$1 = async () => {
|
|
985
|
+
await invoke('Explorer.focusFirst');
|
|
986
|
+
};
|
|
987
|
+
const removeDirent = async () => {
|
|
988
|
+
await invoke('Explorer.removeDirent');
|
|
989
|
+
};
|
|
990
|
+
const expandRecursively = async () => {
|
|
991
|
+
await invoke('Explorer.expandRecursively');
|
|
992
|
+
};
|
|
993
|
+
const newFile = async () => {
|
|
994
|
+
await invoke('Explorer.newFile');
|
|
995
|
+
};
|
|
996
|
+
const handleClick = async index => {
|
|
997
|
+
await invoke('Explorer.handleClick', index);
|
|
998
|
+
};
|
|
999
|
+
const rename = async () => {
|
|
1000
|
+
await invoke('Explorer.rename');
|
|
1001
|
+
};
|
|
1002
|
+
const cancelEdit = async () => {
|
|
1003
|
+
await invoke('Explorer.cancelEdit');
|
|
1004
|
+
};
|
|
1005
|
+
const acceptEdit = async () => {
|
|
1006
|
+
await invoke('Explorer.acceptEdit');
|
|
1007
|
+
};
|
|
1008
|
+
const updateEditingValue = async value => {
|
|
1009
|
+
await invoke('Explorer.updateEditingValue', value);
|
|
1010
|
+
};
|
|
1011
|
+
const expandAll = async value => {
|
|
1012
|
+
await invoke('Explorer.expandAll', value);
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
const TestFrameWorkComponentExplorer = {
|
|
1016
|
+
__proto__: null,
|
|
1017
|
+
acceptEdit,
|
|
1018
|
+
cancelEdit,
|
|
1019
|
+
clickCurrent,
|
|
1020
|
+
expandAll,
|
|
1021
|
+
expandRecursively,
|
|
1022
|
+
focus: focus$1,
|
|
1023
|
+
focusFirst: focusFirst$1,
|
|
1024
|
+
focusIndex: focusIndex$2,
|
|
1025
|
+
focusLast: focusLast$1,
|
|
1026
|
+
focusNext: focusNext$3,
|
|
1027
|
+
handleArrowLeft,
|
|
1028
|
+
handleClick,
|
|
1029
|
+
newFile,
|
|
1030
|
+
openContextMenu,
|
|
1031
|
+
removeDirent,
|
|
1032
|
+
rename,
|
|
1033
|
+
updateEditingValue
|
|
1034
|
+
};
|
|
1035
|
+
|
|
1036
|
+
const addWebExtension = async relativePath => {
|
|
1037
|
+
// TODO compute absolutePath
|
|
1038
|
+
const absolutePath = relativePath;
|
|
1039
|
+
await invoke('ExtensionMeta.addWebExtension', absolutePath);
|
|
1040
|
+
};
|
|
1041
|
+
const addNodeExtension = async relativePath => {
|
|
1042
|
+
// TODO compute absolutePath
|
|
1043
|
+
const absolutePath = relativePath;
|
|
1044
|
+
await invoke('ExtensionMeta.addNodeExtension', absolutePath);
|
|
1045
|
+
};
|
|
1046
|
+
|
|
1047
|
+
const TestFrameWorkComponentExtension = {
|
|
1048
|
+
__proto__: null,
|
|
1049
|
+
addNodeExtension,
|
|
1050
|
+
addWebExtension
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
const Memfs = 'memfs';
|
|
1054
|
+
|
|
1055
|
+
const Slash$1 = '/';
|
|
1056
|
+
|
|
1057
|
+
const Slash = Slash$1;
|
|
1058
|
+
|
|
1059
|
+
const writeFile = async (path, content) => {
|
|
1060
|
+
await invoke('FileSystem.writeFile', path, content);
|
|
1061
|
+
};
|
|
1062
|
+
const mkdir = async path => {
|
|
1063
|
+
await invoke('FileSystem.mkdir', path);
|
|
1064
|
+
};
|
|
1065
|
+
const getTmpDir = async ({
|
|
1066
|
+
scheme = Memfs
|
|
1067
|
+
} = {}) => {
|
|
1068
|
+
switch (scheme) {
|
|
1069
|
+
case Memfs:
|
|
1070
|
+
return 'memfs:///workspace';
|
|
1071
|
+
default:
|
|
1072
|
+
return invoke('PlatformPaths.getTmpDir');
|
|
1073
|
+
}
|
|
1074
|
+
};
|
|
1075
|
+
const chmod = async (uri, permissions) => {
|
|
1076
|
+
await invoke('FileSystem.chmod', uri, permissions);
|
|
1077
|
+
};
|
|
1078
|
+
const createExecutable = async content => {
|
|
1079
|
+
const tmpDir = await getTmpDir({
|
|
1080
|
+
scheme: 'file'
|
|
1081
|
+
});
|
|
1082
|
+
const nodePath = await invoke('PlatformPaths.getNodePath');
|
|
1083
|
+
const gitPath = `${tmpDir}/git`;
|
|
1084
|
+
await writeFile(gitPath, `#!${nodePath}
|
|
1085
|
+
${content}`);
|
|
1086
|
+
await chmod(gitPath, '755');
|
|
1087
|
+
return gitPath;
|
|
1088
|
+
};
|
|
1089
|
+
const createExecutableFrom = async path => {
|
|
1090
|
+
const testPath = await invoke('PlatformPaths.getTestPath');
|
|
1091
|
+
const absolutePath = testPath + Slash + path;
|
|
1092
|
+
const content = await invoke('Ajax.getText', absolutePath);
|
|
1093
|
+
return createExecutable(content);
|
|
1094
|
+
};
|
|
1095
|
+
|
|
1096
|
+
const TestFrameWorkComponentFileSystem = {
|
|
1097
|
+
__proto__: null,
|
|
1098
|
+
chmod,
|
|
1099
|
+
createExecutable,
|
|
1100
|
+
createExecutableFrom,
|
|
1101
|
+
getTmpDir,
|
|
1102
|
+
mkdir,
|
|
1103
|
+
writeFile
|
|
1104
|
+
};
|
|
1105
|
+
|
|
1106
|
+
const focusNext$2 = async () => {
|
|
1107
|
+
await invoke('FindWidget.focusNext');
|
|
1108
|
+
};
|
|
1109
|
+
const setValue$2 = async value => {
|
|
1110
|
+
await invoke('FindWidget.handleInput', value);
|
|
1111
|
+
};
|
|
1112
|
+
|
|
1113
|
+
const TestFrameWorkComponentFindWidget = {
|
|
1114
|
+
__proto__: null,
|
|
1115
|
+
focusNext: focusNext$2,
|
|
1116
|
+
setValue: setValue$2
|
|
1117
|
+
};
|
|
1118
|
+
|
|
1119
|
+
const setIconTheme = async id => {
|
|
1120
|
+
await invoke('IconTheme.setIconTheme', id);
|
|
1121
|
+
};
|
|
1122
|
+
|
|
1123
|
+
const TestFrameWorkComponentIconTheme = {
|
|
1124
|
+
__proto__: null,
|
|
1125
|
+
setIconTheme
|
|
1126
|
+
};
|
|
1127
|
+
|
|
1128
|
+
const getKeyOptions = rawKey => {
|
|
1129
|
+
if (rawKey.includes('+')) {
|
|
1130
|
+
const parts = rawKey.split('+');
|
|
1131
|
+
let ctrlKey = false;
|
|
1132
|
+
let altKey = false;
|
|
1133
|
+
let key = '';
|
|
1134
|
+
for (const part of parts) {
|
|
1135
|
+
switch (part) {
|
|
1136
|
+
case 'Control':
|
|
1137
|
+
ctrlKey = true;
|
|
1138
|
+
break;
|
|
1139
|
+
case 'Space':
|
|
1140
|
+
key = ' ';
|
|
1141
|
+
break;
|
|
1142
|
+
case 'Alt':
|
|
1143
|
+
altKey = true;
|
|
1144
|
+
break;
|
|
1145
|
+
default:
|
|
1146
|
+
key = part;
|
|
1147
|
+
break;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
return {
|
|
1151
|
+
key,
|
|
1152
|
+
ctrlKey,
|
|
1153
|
+
altKey
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
return {
|
|
1157
|
+
key: rawKey,
|
|
1158
|
+
ctrlKey: false,
|
|
1159
|
+
altKey: false
|
|
1160
|
+
};
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
const press = async key => {
|
|
1164
|
+
const keyOptions = getKeyOptions(key);
|
|
1165
|
+
const options = {
|
|
1166
|
+
cancelable: true,
|
|
1167
|
+
bubbles: true,
|
|
1168
|
+
...keyOptions
|
|
1169
|
+
};
|
|
1170
|
+
await invoke('TestFrameWork.performKeyBoardAction', 'press', options);
|
|
1171
|
+
};
|
|
1172
|
+
|
|
1173
|
+
const TestFrameWorkComponentKeyBoard = {
|
|
1174
|
+
__proto__: null,
|
|
1175
|
+
press
|
|
1176
|
+
};
|
|
1177
|
+
|
|
1178
|
+
const openUri = async uri => {
|
|
1179
|
+
await invoke('Main.openUri', uri);
|
|
1180
|
+
};
|
|
1181
|
+
const splitRight = async () => {
|
|
1182
|
+
await invoke('Main.splitRight');
|
|
1183
|
+
};
|
|
1184
|
+
|
|
1185
|
+
const TestFrameWorkComponentMain = {
|
|
1186
|
+
__proto__: null,
|
|
1187
|
+
openUri,
|
|
1188
|
+
splitRight
|
|
1189
|
+
};
|
|
1190
|
+
|
|
1191
|
+
const open$2 = async id => {
|
|
1192
|
+
await invoke('Layout.showPanel', id);
|
|
1193
|
+
};
|
|
1194
|
+
|
|
1195
|
+
const TestFrameWorkComponentPanel = {
|
|
1196
|
+
__proto__: null,
|
|
1197
|
+
open: open$2
|
|
1198
|
+
};
|
|
1199
|
+
|
|
1200
|
+
const getIsFirefox = () => {
|
|
1201
|
+
if (typeof navigator === 'undefined') {
|
|
1202
|
+
return false;
|
|
1203
|
+
}
|
|
1204
|
+
if (
|
|
1205
|
+
// @ts-expect-error
|
|
1206
|
+
navigator.userAgentData?.brands) {
|
|
1207
|
+
// @ts-expect-error
|
|
1208
|
+
return navigator.userAgentData.brands.includes('Firefox');
|
|
1209
|
+
}
|
|
1210
|
+
return navigator.userAgent.toLowerCase().includes('firefox');
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
/**
|
|
1214
|
+
* @type {boolean}
|
|
1215
|
+
*/
|
|
1216
|
+
const isFirefox$1 = getIsFirefox();
|
|
1217
|
+
|
|
1218
|
+
const getNodePath$1 = () => {
|
|
1219
|
+
return invoke( /* Platform.getNodePath */'Platform.getNodePath');
|
|
1220
|
+
};
|
|
1221
|
+
|
|
1222
|
+
const getNodePath = () => {
|
|
1223
|
+
return getNodePath$1();
|
|
1224
|
+
};
|
|
1225
|
+
const isFirefox = () => {
|
|
1226
|
+
return isFirefox$1;
|
|
1227
|
+
};
|
|
1228
|
+
|
|
1229
|
+
const TestFrameWorkComponentPlatform = {
|
|
1230
|
+
__proto__: null,
|
|
1231
|
+
getNodePath,
|
|
1232
|
+
isFirefox
|
|
1233
|
+
};
|
|
1234
|
+
|
|
1235
|
+
const show = async () => {
|
|
1236
|
+
await invoke('Panel.selectIndex', 0);
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
const TestFrameWorkComponentProblems = {
|
|
1240
|
+
__proto__: null,
|
|
1241
|
+
show
|
|
1242
|
+
};
|
|
1243
|
+
|
|
1244
|
+
const QuickPick = 'QuickPick';
|
|
1245
|
+
|
|
1246
|
+
const open$1 = async () => {
|
|
1247
|
+
await invoke('Viewlet.openWidget', QuickPick, 'everything');
|
|
1248
|
+
};
|
|
1249
|
+
const setValue$1 = async value => {
|
|
1250
|
+
await invoke('QuickPick.handleInput', value, 0);
|
|
1251
|
+
};
|
|
1252
|
+
const focusNext$1 = async () => {
|
|
1253
|
+
await invoke('QuickPick.focusNext');
|
|
1254
|
+
};
|
|
1255
|
+
const focusIndex$1 = async index => {
|
|
1256
|
+
await invoke('QuickPick.focusIndex', index);
|
|
1257
|
+
};
|
|
1258
|
+
const focusPrevious$1 = async () => {
|
|
1259
|
+
await invoke('QuickPick.focusPrevious');
|
|
1260
|
+
};
|
|
1261
|
+
const selectItem = async label => {
|
|
1262
|
+
await invoke('QuickPick.selectItem', label);
|
|
1263
|
+
};
|
|
1264
|
+
|
|
1265
|
+
const TestFrameWorkComponentQuickPick = {
|
|
1266
|
+
__proto__: null,
|
|
1267
|
+
focusIndex: focusIndex$1,
|
|
1268
|
+
focusNext: focusNext$1,
|
|
1269
|
+
focusPrevious: focusPrevious$1,
|
|
1270
|
+
open: open$1,
|
|
1271
|
+
selectItem,
|
|
1272
|
+
setValue: setValue$1
|
|
1273
|
+
};
|
|
1274
|
+
|
|
1275
|
+
const setValue = async value => {
|
|
1276
|
+
await invoke('Search.handleInput', value);
|
|
1277
|
+
};
|
|
1278
|
+
|
|
1279
|
+
const TestFrameWorkComponentSearch = {
|
|
1280
|
+
__proto__: null,
|
|
1281
|
+
setValue
|
|
1282
|
+
};
|
|
1283
|
+
|
|
1284
|
+
const update$1 = settings => {
|
|
1285
|
+
return invoke('Preferences.update', settings);
|
|
1286
|
+
};
|
|
1287
|
+
|
|
1288
|
+
const TestFrameWorkComponentSettings = {
|
|
1289
|
+
__proto__: null,
|
|
1290
|
+
update: update$1
|
|
1291
|
+
};
|
|
1292
|
+
|
|
1293
|
+
const open = async id => {
|
|
1294
|
+
await invoke('SideBar.openViewlet', id);
|
|
1295
|
+
};
|
|
1296
|
+
const hide = async () => {
|
|
1297
|
+
await invoke('Layout.hideSideBar');
|
|
1298
|
+
};
|
|
1299
|
+
|
|
1300
|
+
const TestFrameWorkComponentSideBar = {
|
|
1301
|
+
__proto__: null,
|
|
1302
|
+
hide,
|
|
1303
|
+
open
|
|
1304
|
+
};
|
|
1305
|
+
|
|
1306
|
+
const acceptInput = async () => {
|
|
1307
|
+
await invoke('Source Control.acceptInput');
|
|
1308
|
+
};
|
|
1309
|
+
const handleInput = async text => {
|
|
1310
|
+
await invoke('Source Control.handleInput', text);
|
|
1311
|
+
};
|
|
1312
|
+
|
|
1313
|
+
const TestFrameWorkComponentSourceControl = {
|
|
1314
|
+
__proto__: null,
|
|
1315
|
+
acceptInput,
|
|
1316
|
+
handleInput
|
|
1317
|
+
};
|
|
1318
|
+
|
|
1319
|
+
const update = async () => {
|
|
1320
|
+
await invoke('StatusBar.updateStatusBarItems');
|
|
1321
|
+
};
|
|
1322
|
+
|
|
1323
|
+
const TestFrameWorkComponentStatusBar = {
|
|
1324
|
+
__proto__: null,
|
|
1325
|
+
update
|
|
1326
|
+
};
|
|
1327
|
+
|
|
1328
|
+
const closeMenu = async () => {
|
|
1329
|
+
await invoke('TitleBarMenuBar.closeMenu');
|
|
1330
|
+
};
|
|
1331
|
+
const focus = async () => {
|
|
1332
|
+
await invoke('TitleBarMenuBar.focus');
|
|
1333
|
+
};
|
|
1334
|
+
const focusFirst = async () => {
|
|
1335
|
+
await invoke('TitleBarMenuBar.focusFirst');
|
|
1336
|
+
};
|
|
1337
|
+
const focusIndex = async index => {
|
|
1338
|
+
await invoke('TitleBarMenuBar.focusIndex', index);
|
|
1339
|
+
};
|
|
1340
|
+
const focusLast = async () => {
|
|
1341
|
+
await invoke('TitleBarMenuBar.focusLast');
|
|
1342
|
+
};
|
|
1343
|
+
const focusNext = async () => {
|
|
1344
|
+
await invoke('TitleBarMenuBar.focusNext');
|
|
1345
|
+
};
|
|
1346
|
+
const focusPrevious = async () => {
|
|
1347
|
+
await invoke('TitleBarMenuBar.focusPrevious');
|
|
1348
|
+
};
|
|
1349
|
+
const handleKeyArrowDown = async () => {
|
|
1350
|
+
await invoke('TitleBarMenuBar.handleKeyArrowDown');
|
|
1351
|
+
};
|
|
1352
|
+
const handleKeyArrowLeft = async () => {
|
|
1353
|
+
await invoke('TitleBarMenuBar.handleKeyArrowLeft');
|
|
1354
|
+
};
|
|
1355
|
+
const handleKeyArrowRight = async () => {
|
|
1356
|
+
await invoke('TitleBarMenuBar.handleKeyArrowRight');
|
|
1357
|
+
};
|
|
1358
|
+
const handleKeyArrowUp = async () => {
|
|
1359
|
+
await invoke('TitleBarMenuBar.handleKeyArrowUp');
|
|
1360
|
+
};
|
|
1361
|
+
const handleKeyEnd = async () => {
|
|
1362
|
+
await invoke('TitleBarMenuBar.handleKeyEnd');
|
|
1363
|
+
};
|
|
1364
|
+
const handleKeyHome = async () => {
|
|
1365
|
+
await invoke('TitleBarMenuBar.handleKeyHome');
|
|
1366
|
+
};
|
|
1367
|
+
const handleKeySpace = async () => {
|
|
1368
|
+
await invoke('TitleBarMenuBar.handleKeySpace');
|
|
1369
|
+
};
|
|
1370
|
+
const handleKeyEscape = async () => {
|
|
1371
|
+
await invoke('TitleBarMenuBar.handleKeyEscape');
|
|
1372
|
+
};
|
|
1373
|
+
const toggleIndex = async index => {
|
|
1374
|
+
await invoke('TitleBarMenuBar.toggleIndex', index);
|
|
1375
|
+
};
|
|
1376
|
+
const toggleMenu = async () => {
|
|
1377
|
+
await invoke('TitleBarMenuBar.toggleMenu');
|
|
1378
|
+
};
|
|
1379
|
+
|
|
1380
|
+
const TestFrameWorkComponentTitleBarMenuBar = {
|
|
1381
|
+
__proto__: null,
|
|
1382
|
+
closeMenu,
|
|
1383
|
+
focus,
|
|
1384
|
+
focusFirst,
|
|
1385
|
+
focusIndex,
|
|
1386
|
+
focusLast,
|
|
1387
|
+
focusNext,
|
|
1388
|
+
focusPrevious,
|
|
1389
|
+
handleKeyArrowDown,
|
|
1390
|
+
handleKeyArrowLeft,
|
|
1391
|
+
handleKeyArrowRight,
|
|
1392
|
+
handleKeyArrowUp,
|
|
1393
|
+
handleKeyEnd,
|
|
1394
|
+
handleKeyEscape,
|
|
1395
|
+
handleKeyHome,
|
|
1396
|
+
handleKeySpace,
|
|
1397
|
+
toggleIndex,
|
|
1398
|
+
toggleMenu
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1401
|
+
const setPath = async path => {
|
|
1402
|
+
await invoke('Workspace.setPath', path);
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1405
|
+
const TestFrameWorkComponentWorkspace = {
|
|
1406
|
+
__proto__: null,
|
|
1407
|
+
setPath
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1410
|
+
const TestFrameWorkComponent = {
|
|
1411
|
+
__proto__: null,
|
|
1412
|
+
ActivityBar: TestFrameworkComponentActivityBar,
|
|
1413
|
+
BaseUrl: TestFrameWorkComponentBaseUrl,
|
|
1414
|
+
Command: TestFrameWorkComponentCommand,
|
|
1415
|
+
ContextMenu: TestFrameWorkComponentContextMenu,
|
|
1416
|
+
Editor: TestFrameWorkComponentEditor,
|
|
1417
|
+
Explorer: TestFrameWorkComponentExplorer,
|
|
1418
|
+
Extension: TestFrameWorkComponentExtension,
|
|
1419
|
+
FileSystem: TestFrameWorkComponentFileSystem,
|
|
1420
|
+
FindWidget: TestFrameWorkComponentFindWidget,
|
|
1421
|
+
IconTheme: TestFrameWorkComponentIconTheme,
|
|
1422
|
+
KeyBoard: TestFrameWorkComponentKeyBoard,
|
|
1423
|
+
Main: TestFrameWorkComponentMain,
|
|
1424
|
+
Panel: TestFrameWorkComponentPanel,
|
|
1425
|
+
Platform: TestFrameWorkComponentPlatform,
|
|
1426
|
+
Problems: TestFrameWorkComponentProblems,
|
|
1427
|
+
QuickPick: TestFrameWorkComponentQuickPick,
|
|
1428
|
+
Search: TestFrameWorkComponentSearch,
|
|
1429
|
+
Settings: TestFrameWorkComponentSettings,
|
|
1430
|
+
SideBar: TestFrameWorkComponentSideBar,
|
|
1431
|
+
SourceControl: TestFrameWorkComponentSourceControl,
|
|
1432
|
+
StatusBar: TestFrameWorkComponentStatusBar,
|
|
1433
|
+
TitleBarMenuBar: TestFrameWorkComponentTitleBarMenuBar,
|
|
1434
|
+
Workspace: TestFrameWorkComponentWorkspace
|
|
1435
|
+
};
|
|
1436
|
+
|
|
1437
|
+
const execute$1 = async href => {
|
|
1438
|
+
const globals = {
|
|
1439
|
+
...TestFrameWorkComponent,
|
|
1440
|
+
...TestFrameWork
|
|
1441
|
+
};
|
|
1442
|
+
// TODO
|
|
1443
|
+
// 0. wait for page to be ready
|
|
1444
|
+
// 1. get script to import from renderer process (url or from html)
|
|
1445
|
+
const scriptUrl = href;
|
|
1446
|
+
// 2. import that script
|
|
1447
|
+
const module = await importTest(scriptUrl);
|
|
1448
|
+
if (module.mockRpc) {
|
|
1449
|
+
setMockRpc(module.mockRpc);
|
|
1450
|
+
}
|
|
1451
|
+
if (module.test) {
|
|
1452
|
+
if (module.skip) {
|
|
1453
|
+
await test.skip(module.name, () => {});
|
|
1454
|
+
} else {
|
|
1455
|
+
await executeTest(module.name, module.test, globals);
|
|
1456
|
+
}
|
|
1457
|
+
} else {
|
|
1458
|
+
const tests = getTests();
|
|
1459
|
+
for (const test of tests) {
|
|
1460
|
+
// @ts-ignore
|
|
1461
|
+
await executeTest(test.name, test.fn);
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
// 3. if import fails, display error message
|
|
1465
|
+
|
|
1466
|
+
// 4. run the test
|
|
1467
|
+
// 5. if test fails, display error message
|
|
1468
|
+
// 6. if test succeeds, display success message
|
|
1469
|
+
};
|
|
1470
|
+
|
|
1471
|
+
const commandMap = {
|
|
1472
|
+
'Test.execute': execute$1
|
|
1473
|
+
};
|
|
1474
|
+
|
|
1475
|
+
const state = {
|
|
1476
|
+
commands: Object.create(null)
|
|
1477
|
+
};
|
|
1478
|
+
const registerCommand = (key, fn) => {
|
|
1479
|
+
state.commands[key] = fn;
|
|
1480
|
+
};
|
|
1481
|
+
const registerCommands = commandMap => {
|
|
1482
|
+
for (const [key, value] of Object.entries(commandMap)) {
|
|
1483
|
+
registerCommand(key, value);
|
|
1484
|
+
}
|
|
1485
|
+
};
|
|
1486
|
+
const getCommand = key => {
|
|
1487
|
+
return state.commands[key];
|
|
1488
|
+
};
|
|
1489
|
+
|
|
1490
|
+
const processName = 'embeds-worker';
|
|
1491
|
+
|
|
1492
|
+
const execute = (command, ...args) => {
|
|
1493
|
+
const fn = getCommand(command);
|
|
1494
|
+
if (!fn) {
|
|
1495
|
+
throw new Error(`[${processName}] command not found ${command}`);
|
|
1496
|
+
}
|
|
1497
|
+
return fn(...args);
|
|
1498
|
+
};
|
|
1499
|
+
|
|
1500
|
+
const requiresSocket = () => {
|
|
1501
|
+
return false;
|
|
1502
|
+
};
|
|
1503
|
+
const preparePrettyError = error => {
|
|
1504
|
+
return error;
|
|
1505
|
+
};
|
|
1506
|
+
const logError = error => {
|
|
1507
|
+
console.error(error);
|
|
1508
|
+
};
|
|
1509
|
+
const handleMessage = event => {
|
|
1510
|
+
return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
|
|
1511
|
+
};
|
|
1512
|
+
|
|
1513
|
+
const handleIpc = ipc => {
|
|
1514
|
+
ipc.addEventListener('message', handleMessage);
|
|
1515
|
+
};
|
|
1516
|
+
|
|
1517
|
+
const MessagePort = 1;
|
|
1518
|
+
const ModuleWorker = 2;
|
|
1519
|
+
const ReferencePort = 3;
|
|
1520
|
+
const ModuleWorkerAndMessagePort = 8;
|
|
1521
|
+
const Auto = () => {
|
|
1522
|
+
// @ts-ignore
|
|
1523
|
+
if (globalThis.acceptPort) {
|
|
1524
|
+
return MessagePort;
|
|
1525
|
+
}
|
|
1526
|
+
// @ts-ignore
|
|
1527
|
+
if (globalThis.acceptReferencePort) {
|
|
1528
|
+
return ReferencePort;
|
|
1529
|
+
}
|
|
1530
|
+
return ModuleWorkerAndMessagePort;
|
|
1531
|
+
};
|
|
1532
|
+
|
|
1533
|
+
const getData$1 = event => {
|
|
1534
|
+
return event.data;
|
|
1535
|
+
};
|
|
1536
|
+
const attachEvents = that => {
|
|
1537
|
+
const handleMessage = (...args) => {
|
|
1538
|
+
const data = that.getData(...args);
|
|
1539
|
+
that.dispatchEvent(new MessageEvent('message', {
|
|
1540
|
+
data
|
|
1541
|
+
}));
|
|
1542
|
+
};
|
|
1543
|
+
that.onMessage(handleMessage);
|
|
1544
|
+
const handleClose = event => {
|
|
1545
|
+
that.dispatchEvent(new Event('close'));
|
|
1546
|
+
};
|
|
1547
|
+
that.onClose(handleClose);
|
|
1548
|
+
};
|
|
1549
|
+
class Ipc extends EventTarget {
|
|
1550
|
+
constructor(rawIpc) {
|
|
1551
|
+
super();
|
|
1552
|
+
this._rawIpc = rawIpc;
|
|
1553
|
+
attachEvents(this);
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
const readyMessage = 'ready';
|
|
1557
|
+
const listen$3 = () => {
|
|
1558
|
+
// @ts-ignore
|
|
1559
|
+
if (typeof WorkerGlobalScope === 'undefined') {
|
|
1560
|
+
throw new TypeError('module is not in web worker scope');
|
|
1561
|
+
}
|
|
1562
|
+
return globalThis;
|
|
1563
|
+
};
|
|
1564
|
+
const signal$2 = global => {
|
|
1565
|
+
global.postMessage(readyMessage);
|
|
1566
|
+
};
|
|
1567
|
+
class IpcChildWithModuleWorker extends Ipc {
|
|
1568
|
+
getData(event) {
|
|
1569
|
+
return getData$1(event);
|
|
1570
|
+
}
|
|
1571
|
+
send(message) {
|
|
1572
|
+
// @ts-ignore
|
|
1573
|
+
this._rawIpc.postMessage(message);
|
|
1574
|
+
}
|
|
1575
|
+
sendAndTransfer(message, transfer) {
|
|
1576
|
+
// @ts-ignore
|
|
1577
|
+
this._rawIpc.postMessage(message, transfer);
|
|
1578
|
+
}
|
|
1579
|
+
dispose() {
|
|
1580
|
+
// ignore
|
|
1581
|
+
}
|
|
1582
|
+
onClose(callback) {
|
|
1583
|
+
// ignore
|
|
1584
|
+
}
|
|
1585
|
+
onMessage(callback) {
|
|
1586
|
+
this._rawIpc.addEventListener('message', callback);
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
const wrap$5 = global => {
|
|
1590
|
+
return new IpcChildWithModuleWorker(global);
|
|
1591
|
+
};
|
|
1592
|
+
const IpcChildWithModuleWorker$1 = {
|
|
1593
|
+
__proto__: null,
|
|
1594
|
+
listen: listen$3,
|
|
1595
|
+
signal: signal$2,
|
|
1596
|
+
wrap: wrap$5
|
|
1597
|
+
};
|
|
1598
|
+
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
1599
|
+
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
1600
|
+
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
1601
|
+
const NewLine$1 = '\n';
|
|
1602
|
+
const joinLines = lines => {
|
|
1603
|
+
return lines.join(NewLine$1);
|
|
1604
|
+
};
|
|
1605
|
+
const splitLines = lines => {
|
|
1606
|
+
return lines.split(NewLine$1);
|
|
1607
|
+
};
|
|
1608
|
+
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
|
|
1609
|
+
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
|
|
1610
|
+
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
1611
|
+
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
1612
|
+
const RE_AT = /^\s+at/;
|
|
1613
|
+
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
1614
|
+
const isUnhelpfulNativeModuleError = stderr => {
|
|
1615
|
+
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
1616
|
+
};
|
|
1617
|
+
const isMessageCodeBlockStartIndex = line => {
|
|
1618
|
+
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
1619
|
+
};
|
|
1620
|
+
const isMessageCodeBlockEndIndex = line => {
|
|
1621
|
+
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
1622
|
+
};
|
|
1623
|
+
const getMessageCodeBlock = stderr => {
|
|
1624
|
+
const lines = splitLines(stderr);
|
|
1625
|
+
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
|
|
1626
|
+
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
|
|
1627
|
+
const relevantLines = lines.slice(startIndex, endIndex);
|
|
1628
|
+
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
1629
|
+
return relevantMessage;
|
|
1630
|
+
};
|
|
1631
|
+
const getNativeModuleErrorMessage = stderr => {
|
|
1632
|
+
const message = getMessageCodeBlock(stderr);
|
|
1633
|
+
return {
|
|
1634
|
+
message: `Incompatible native node module: ${message}`,
|
|
1635
|
+
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
1636
|
+
};
|
|
1637
|
+
};
|
|
1638
|
+
const isModulesSyntaxError = stderr => {
|
|
1639
|
+
if (!stderr) {
|
|
1640
|
+
return false;
|
|
1641
|
+
}
|
|
1642
|
+
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
1643
|
+
};
|
|
1644
|
+
const getModuleSyntaxError = () => {
|
|
1645
|
+
return {
|
|
1646
|
+
message: `ES Modules are not supported in electron`,
|
|
1647
|
+
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
|
|
1648
|
+
};
|
|
1649
|
+
};
|
|
1650
|
+
const isModuleNotFoundError = stderr => {
|
|
1651
|
+
if (!stderr) {
|
|
1652
|
+
return false;
|
|
1653
|
+
}
|
|
1654
|
+
return stderr.includes('ERR_MODULE_NOT_FOUND');
|
|
1655
|
+
};
|
|
1656
|
+
const isModuleNotFoundMessage = line => {
|
|
1657
|
+
return line.includes('ERR_MODULE_NOT_FOUND');
|
|
1658
|
+
};
|
|
1659
|
+
const getModuleNotFoundError = stderr => {
|
|
1660
|
+
const lines = splitLines(stderr);
|
|
1661
|
+
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
1662
|
+
const message = lines[messageIndex];
|
|
1663
|
+
return {
|
|
1664
|
+
message,
|
|
1665
|
+
code: ERR_MODULE_NOT_FOUND
|
|
1666
|
+
};
|
|
1667
|
+
};
|
|
1668
|
+
const isNormalStackLine = line => {
|
|
1669
|
+
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
1670
|
+
};
|
|
1671
|
+
const getDetails = lines => {
|
|
1672
|
+
const index = lines.findIndex(isNormalStackLine);
|
|
1673
|
+
if (index === -1) {
|
|
1674
|
+
return {
|
|
1675
|
+
actualMessage: joinLines(lines),
|
|
1676
|
+
rest: []
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
let lastIndex = index - 1;
|
|
1680
|
+
while (++lastIndex < lines.length) {
|
|
1681
|
+
if (!isNormalStackLine(lines[lastIndex])) {
|
|
1682
|
+
break;
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
return {
|
|
1686
|
+
actualMessage: lines[index - 1],
|
|
1687
|
+
rest: lines.slice(index, lastIndex)
|
|
1688
|
+
};
|
|
1689
|
+
};
|
|
1690
|
+
const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
1691
|
+
if (isUnhelpfulNativeModuleError(stderr)) {
|
|
1692
|
+
return getNativeModuleErrorMessage(stderr);
|
|
1693
|
+
}
|
|
1694
|
+
if (isModulesSyntaxError(stderr)) {
|
|
1695
|
+
return getModuleSyntaxError();
|
|
1696
|
+
}
|
|
1697
|
+
if (isModuleNotFoundError(stderr)) {
|
|
1698
|
+
return getModuleNotFoundError(stderr);
|
|
1699
|
+
}
|
|
1700
|
+
const lines = splitLines(stderr);
|
|
1701
|
+
const {
|
|
1702
|
+
actualMessage,
|
|
1703
|
+
rest
|
|
1704
|
+
} = getDetails(lines);
|
|
1705
|
+
return {
|
|
1706
|
+
message: `${actualMessage}`,
|
|
1707
|
+
code: '',
|
|
1708
|
+
stack: rest
|
|
1709
|
+
};
|
|
1710
|
+
};
|
|
1711
|
+
const normalizeLine = line => {
|
|
1712
|
+
if (line.startsWith('Error: ')) {
|
|
1713
|
+
return line.slice(`Error: `.length);
|
|
1714
|
+
}
|
|
1715
|
+
if (line.startsWith('VError: ')) {
|
|
1716
|
+
return line.slice(`VError: `.length);
|
|
1717
|
+
}
|
|
1718
|
+
return line;
|
|
1719
|
+
};
|
|
1720
|
+
const getCombinedMessage = (error, message) => {
|
|
1721
|
+
const stringifiedError = normalizeLine(`${error}`);
|
|
1722
|
+
if (message) {
|
|
1723
|
+
return `${message}: ${stringifiedError}`;
|
|
1724
|
+
}
|
|
1725
|
+
return stringifiedError;
|
|
1726
|
+
};
|
|
1727
|
+
const NewLine = '\n';
|
|
1728
|
+
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
1729
|
+
return string.indexOf(NewLine, startIndex);
|
|
1730
|
+
};
|
|
1731
|
+
const mergeStacks = (parent, child) => {
|
|
1732
|
+
if (!child) {
|
|
1733
|
+
return parent;
|
|
1734
|
+
}
|
|
1735
|
+
const parentNewLineIndex = getNewLineIndex(parent);
|
|
1736
|
+
const childNewLineIndex = getNewLineIndex(child);
|
|
1737
|
+
if (childNewLineIndex === -1) {
|
|
1738
|
+
return parent;
|
|
1739
|
+
}
|
|
1740
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
1741
|
+
const childRest = child.slice(childNewLineIndex);
|
|
1742
|
+
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
1743
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
1744
|
+
return parentFirstLine + childRest;
|
|
1745
|
+
}
|
|
1746
|
+
return child;
|
|
1747
|
+
};
|
|
1748
|
+
class VError extends Error {
|
|
1749
|
+
constructor(error, message) {
|
|
1750
|
+
const combinedMessage = getCombinedMessage(error, message);
|
|
1751
|
+
super(combinedMessage);
|
|
1752
|
+
this.name = 'VError';
|
|
1753
|
+
if (error instanceof Error) {
|
|
1754
|
+
this.stack = mergeStacks(this.stack, error.stack);
|
|
1755
|
+
}
|
|
1756
|
+
if (error.codeFrame) {
|
|
1757
|
+
// @ts-ignore
|
|
1758
|
+
this.codeFrame = error.codeFrame;
|
|
1759
|
+
}
|
|
1760
|
+
if (error.code) {
|
|
1761
|
+
// @ts-ignore
|
|
1762
|
+
this.code = error.code;
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
class IpcError extends VError {
|
|
1767
|
+
// @ts-ignore
|
|
1768
|
+
constructor(betterMessage, stdout = '', stderr = '') {
|
|
1769
|
+
if (stdout || stderr) {
|
|
1770
|
+
// @ts-ignore
|
|
1771
|
+
const {
|
|
1772
|
+
message,
|
|
1773
|
+
code,
|
|
1774
|
+
stack
|
|
1775
|
+
} = getHelpfulChildProcessError(stdout, stderr);
|
|
1776
|
+
const cause = new Error(message);
|
|
1777
|
+
// @ts-ignore
|
|
1778
|
+
cause.code = code;
|
|
1779
|
+
cause.stack = stack;
|
|
1780
|
+
super(cause, betterMessage);
|
|
1781
|
+
} else {
|
|
1782
|
+
super(betterMessage);
|
|
1783
|
+
}
|
|
1784
|
+
// @ts-ignore
|
|
1785
|
+
this.name = 'IpcError';
|
|
1786
|
+
// @ts-ignore
|
|
1787
|
+
this.stdout = stdout;
|
|
1788
|
+
// @ts-ignore
|
|
1789
|
+
this.stderr = stderr;
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
const withResolvers = () => {
|
|
1793
|
+
let _resolve;
|
|
1794
|
+
const promise = new Promise(resolve => {
|
|
1795
|
+
_resolve = resolve;
|
|
1796
|
+
});
|
|
1797
|
+
return {
|
|
1798
|
+
resolve: _resolve,
|
|
1799
|
+
promise
|
|
1800
|
+
};
|
|
1801
|
+
};
|
|
1802
|
+
const waitForFirstMessage = async port => {
|
|
1803
|
+
const {
|
|
1804
|
+
resolve,
|
|
1805
|
+
promise
|
|
1806
|
+
} = withResolvers();
|
|
1807
|
+
port.addEventListener('message', resolve, {
|
|
1808
|
+
once: true
|
|
1809
|
+
});
|
|
1810
|
+
const event = await promise;
|
|
1811
|
+
// @ts-ignore
|
|
1812
|
+
return event.data;
|
|
1813
|
+
};
|
|
1814
|
+
const listen$2 = async () => {
|
|
1815
|
+
const parentIpcRaw = listen$3();
|
|
1816
|
+
signal$2(parentIpcRaw);
|
|
1817
|
+
const parentIpc = wrap$5(parentIpcRaw);
|
|
1818
|
+
const firstMessage = await waitForFirstMessage(parentIpc);
|
|
1819
|
+
if (firstMessage.method !== 'initialize') {
|
|
1820
|
+
throw new IpcError('unexpected first message');
|
|
1821
|
+
}
|
|
1822
|
+
const type = firstMessage.params[0];
|
|
1823
|
+
if (type === 'message-port') {
|
|
1824
|
+
parentIpc.dispose();
|
|
1825
|
+
const port = firstMessage.params[1];
|
|
1826
|
+
return port;
|
|
1827
|
+
}
|
|
1828
|
+
return globalThis;
|
|
1829
|
+
};
|
|
1830
|
+
class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
|
|
1831
|
+
constructor(port) {
|
|
1832
|
+
super(port);
|
|
1833
|
+
}
|
|
1834
|
+
getData(event) {
|
|
1835
|
+
return getData$1(event);
|
|
1836
|
+
}
|
|
1837
|
+
send(message) {
|
|
1838
|
+
this._rawIpc.postMessage(message);
|
|
1839
|
+
}
|
|
1840
|
+
sendAndTransfer(message, transfer) {
|
|
1841
|
+
this._rawIpc.postMessage(message, transfer);
|
|
1842
|
+
}
|
|
1843
|
+
dispose() {
|
|
1844
|
+
if (this._rawIpc.close) {
|
|
1845
|
+
this._rawIpc.close();
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
onClose(callback) {
|
|
1849
|
+
// ignore
|
|
1850
|
+
}
|
|
1851
|
+
onMessage(callback) {
|
|
1852
|
+
this._rawIpc.addEventListener('message', callback);
|
|
1853
|
+
this._rawIpc.start();
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
const wrap$4 = port => {
|
|
1857
|
+
return new IpcChildWithModuleWorkerAndMessagePort(port);
|
|
1858
|
+
};
|
|
1859
|
+
const IpcChildWithModuleWorkerAndMessagePort$1 = {
|
|
1860
|
+
__proto__: null,
|
|
1861
|
+
listen: listen$2,
|
|
1862
|
+
wrap: wrap$4
|
|
1863
|
+
};
|
|
1864
|
+
|
|
1865
|
+
const getModule = method => {
|
|
1866
|
+
switch (method) {
|
|
1867
|
+
case ModuleWorker:
|
|
1868
|
+
return IpcChildWithModuleWorker$1;
|
|
1869
|
+
case ModuleWorkerAndMessagePort:
|
|
1870
|
+
return IpcChildWithModuleWorkerAndMessagePort$1;
|
|
1871
|
+
default:
|
|
1872
|
+
throw new Error('unexpected ipc type');
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
|
|
1876
|
+
const listen$1 = async ({
|
|
1877
|
+
method
|
|
1878
|
+
}) => {
|
|
1879
|
+
const module = await getModule(method);
|
|
1880
|
+
const rawIpc = await module.listen();
|
|
1881
|
+
if (module.signal) {
|
|
1882
|
+
module.signal(rawIpc);
|
|
1883
|
+
}
|
|
1884
|
+
const ipc = module.wrap(rawIpc);
|
|
1885
|
+
return ipc;
|
|
1886
|
+
};
|
|
1887
|
+
|
|
1888
|
+
const listen = async () => {
|
|
1889
|
+
registerCommands(commandMap);
|
|
1890
|
+
const ipc = await listen$1({
|
|
1891
|
+
method: Auto()
|
|
1892
|
+
});
|
|
1893
|
+
handleIpc(ipc);
|
|
1894
|
+
listen$4(ipc);
|
|
1895
|
+
};
|
|
1896
|
+
|
|
1897
|
+
const main = async () => {
|
|
1898
|
+
await listen();
|
|
1899
|
+
};
|
|
1900
|
+
|
|
1901
|
+
main();
|