@wdio/utils 7.20.3 → 7.20.8-alpha.504
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/build/constants.d.ts +75 -75
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +1 -4
- package/build/envDetector.js +5 -13
- package/build/index.d.ts +11 -11
- package/build/index.d.ts.map +1 -1
- package/build/index.js +21 -39
- package/build/initialisePlugin.d.ts +2 -2
- package/build/initialisePlugin.d.ts.map +1 -1
- package/build/initialisePlugin.js +7 -13
- package/build/initialiseServices.d.ts +3 -3
- package/build/initialiseServices.d.ts.map +1 -1
- package/build/initialiseServices.js +9 -17
- package/build/monad.d.ts +4 -1
- package/build/monad.d.ts.map +1 -1
- package/build/monad.js +18 -17
- package/build/shim.d.ts +1 -27
- package/build/shim.d.ts.map +1 -1
- package/build/shim.js +18 -184
- package/build/test-framework/errorHandler.js +1 -5
- package/build/test-framework/index.d.ts +2 -2
- package/build/test-framework/index.d.ts.map +1 -1
- package/build/test-framework/index.js +3 -7
- package/build/test-framework/testFnWrapper.d.ts +1 -1
- package/build/test-framework/testFnWrapper.d.ts.map +1 -1
- package/build/test-framework/testFnWrapper.js +10 -27
- package/build/test-framework/testInterfaceWrapper.d.ts +3 -4
- package/build/test-framework/testInterfaceWrapper.d.ts.map +1 -1
- package/build/test-framework/testInterfaceWrapper.js +19 -26
- package/build/test-framework/types.d.ts +1 -2
- package/build/test-framework/types.d.ts.map +1 -1
- package/build/test-framework/types.js +1 -2
- package/build/utils.d.ts +2 -2
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +26 -48
- package/package.json +11 -8
package/build/shim.d.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
declare let hasWdioSyncSupport: boolean;
|
|
2
|
-
declare let runSync: (this: unknown, fn: Function, repeatTest: any, args: unknown[]) => (resolve: Function, reject: Function) => unknown;
|
|
3
1
|
interface Retries {
|
|
4
2
|
limit: number;
|
|
5
3
|
attempts: number;
|
|
6
4
|
}
|
|
7
5
|
declare global {
|
|
8
|
-
var _HAS_FIBER_CONTEXT: boolean;
|
|
9
|
-
var browser: any;
|
|
10
6
|
var expectAsync: any;
|
|
11
7
|
}
|
|
12
8
|
declare global {
|
|
@@ -17,26 +13,13 @@ declare global {
|
|
|
17
13
|
}
|
|
18
14
|
}
|
|
19
15
|
}
|
|
20
|
-
export declare function expectAsyncShim(actual?: any, syncMatcher?: Function): any;
|
|
21
|
-
export declare let runAsync: boolean;
|
|
22
|
-
export declare let asyncSpec: boolean;
|
|
23
16
|
declare let executeHooksWithArgs: <T>(hookName: string, hooks?: Function | Function[], args?: any[]) => Promise<(Error | T)[]>;
|
|
24
|
-
declare let runFnInFiberContext: (fn: Function) => (this: any, ...args: any[]) => Promise<any>;
|
|
25
17
|
/**
|
|
26
18
|
* wrap command to enable before and after command to be executed
|
|
27
19
|
* @param commandName name of the command (e.g. getTitle)
|
|
28
20
|
* @param fn command function
|
|
29
21
|
*/
|
|
30
22
|
declare let wrapCommand: <T>(commandName: string, fn: Function) => (...args: any) => Promise<T>;
|
|
31
|
-
/**
|
|
32
|
-
* execute test or hook synchronously
|
|
33
|
-
*
|
|
34
|
-
* @param {Function} fn spec or hook method
|
|
35
|
-
* @param {Number} retries { limit: number, attempts: number }
|
|
36
|
-
* @param {Array} args arguments passed to hook
|
|
37
|
-
* @return {Promise} that gets resolved once test/hook is done or was retried enough
|
|
38
|
-
*/
|
|
39
|
-
declare function executeSyncFn(this: any, fn: Function, retries: Retries, args?: any[]): Promise<unknown>;
|
|
40
23
|
/**
|
|
41
24
|
* execute test or hook asynchronously
|
|
42
25
|
*
|
|
@@ -46,14 +29,5 @@ declare function executeSyncFn(this: any, fn: Function, retries: Retries, args?:
|
|
|
46
29
|
* @return {Promise} that gets resolved once test/hook is done or was retried enough
|
|
47
30
|
*/
|
|
48
31
|
declare function executeAsync(this: any, fn: Function, retries: Retries, args?: any[]): Promise<unknown>;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Method to switch between sync and async execution. It allows to have async
|
|
52
|
-
* tests in between synchronous tests. `fn` can either return a promise (e.g. for `executeSync`)
|
|
53
|
-
* or a function (e.g. for `runSync`). In both cases we need to make sure that
|
|
54
|
-
* we flip `runAsync` flag to true to that commands are wrapped with the @wdio/sync
|
|
55
|
-
* wrapper.
|
|
56
|
-
*/
|
|
57
|
-
export declare function switchSyncFlag(fn: Function): (this: unknown, ...args: any[]) => any;
|
|
58
|
-
export { executeHooksWithArgs, runFnInFiberContext, wrapCommand, hasWdioSyncSupport, executeSync, executeAsync, runSync };
|
|
32
|
+
export { executeHooksWithArgs, wrapCommand, executeAsync, };
|
|
59
33
|
//# sourceMappingURL=shim.d.ts.map
|
package/build/shim.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shim.d.ts","sourceRoot":"","sources":["../src/shim.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shim.d.ts","sourceRoot":"","sources":["../src/shim.ts"],"names":[],"mappings":"AAQA,UAAU,OAAO;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IACX,IAAI,WAAW,EAAE,GAAG,CAAA;CACvB;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM,CAAC;QACb,UAAU,MAAM;YACZ,MAAM,EAAE,GAAG,CAAA;YACX,WAAW,EAAE,GAAG,CAAA;SACnB;KACJ;CACJ;AAaD,QAAA,IAAI,oBAAoB,gBAAyD,MAAM,UAAS,QAAQ,GAAG,QAAQ,EAAE,SAAa,GAAG,EAAE,2BA6CtI,CAAA;AAED;;;;GAIG;AACH,QAAA,IAAI,WAAW,mBAAwC,MAAM,MAAM,QAAQ,eAAa,GAAG,eAkL1F,CAAA;AAED;;;;;;;GAOG;AACH,iBAAe,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE,GAAG,EAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBzG;AAED,OAAO,EACH,oBAAoB,EACpB,WAAW,EACX,YAAY,GACf,CAAA"}
|
package/build/shim.js
CHANGED
|
@@ -1,42 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.runSync = exports.executeAsync = exports.executeSync = exports.hasWdioSyncSupport = exports.wrapCommand = exports.runFnInFiberContext = exports.executeHooksWithArgs = exports.switchSyncFlag = exports.asyncSpec = exports.runAsync = exports.expectAsyncShim = void 0;
|
|
7
|
-
const p_iteration_1 = __importDefault(require("p-iteration"));
|
|
8
|
-
const logger_1 = __importDefault(require("@wdio/logger"));
|
|
9
|
-
const log = (0, logger_1.default)('@wdio/utils:shim');
|
|
1
|
+
import * as iterators from 'p-iteration';
|
|
2
|
+
import logger from '@wdio/logger';
|
|
3
|
+
const log = logger('@wdio/utils:shim');
|
|
10
4
|
let inCommandHook = false;
|
|
11
|
-
let hasWdioSyncSupport = false;
|
|
12
|
-
exports.hasWdioSyncSupport = hasWdioSyncSupport;
|
|
13
|
-
let runSync;
|
|
14
|
-
exports.runSync = runSync;
|
|
15
|
-
/**
|
|
16
|
-
* Jasmine differentiates between sync and async matchers.
|
|
17
|
-
* In order to offer a consistent experience WebdriverIO is
|
|
18
|
-
* replacing `expect` with `expectAsync` in every spec file
|
|
19
|
-
* that is async. Now to also allow assertions of literal values
|
|
20
|
-
* like string, numbers etc. in an async function we overwrite expect
|
|
21
|
-
* with this shim to check the input value. If we assert a promise,
|
|
22
|
-
* a browser or element object we use `expectAsync` otherwise the
|
|
23
|
-
* normal sync `expect`.
|
|
24
|
-
*
|
|
25
|
-
* Note: `syncMatcher` as parameter is only for testing purposes
|
|
26
|
-
*/
|
|
27
|
-
let expectSync;
|
|
28
|
-
function expectAsyncShim(actual, syncMatcher = expectSync) {
|
|
29
|
-
const expectAsync = global.expectAsync;
|
|
30
|
-
const useSync = (!actual ||
|
|
31
|
-
(typeof actual.then !== 'function' &&
|
|
32
|
-
!actual.sessionId &&
|
|
33
|
-
!actual.elementId));
|
|
34
|
-
if (useSync) {
|
|
35
|
-
return syncMatcher(actual);
|
|
36
|
-
}
|
|
37
|
-
return expectAsync(actual);
|
|
38
|
-
}
|
|
39
|
-
exports.expectAsyncShim = expectAsyncShim;
|
|
40
5
|
const ELEMENT_QUERY_COMMANDS = [
|
|
41
6
|
'$', '$$', 'custom$', 'custom$$', 'shadow$', 'shadow$$', 'react$',
|
|
42
7
|
'react$$', 'nextElement', 'previousElement', 'parentElement'
|
|
@@ -45,31 +10,9 @@ const ELEMENT_PROPS = [
|
|
|
45
10
|
'elementId', 'error', 'selector', 'parent', 'index', 'isReactElement',
|
|
46
11
|
'length'
|
|
47
12
|
];
|
|
13
|
+
const ACTION_COMMANDS = ['action', 'actions'];
|
|
48
14
|
const PROMISE_METHODS = ['then', 'catch', 'finally'];
|
|
49
|
-
/**
|
|
50
|
-
* shim to make sure that we only wrap commands if wdio-sync is installed as dependency
|
|
51
|
-
*/
|
|
52
|
-
let wdioSync;
|
|
53
|
-
exports.runAsync = false;
|
|
54
|
-
exports.asyncSpec = false;
|
|
55
|
-
try {
|
|
56
|
-
const packageName = '@wdio/sync';
|
|
57
|
-
wdioSync = require(packageName);
|
|
58
|
-
exports.hasWdioSyncSupport = hasWdioSyncSupport = true;
|
|
59
|
-
/**
|
|
60
|
-
* only print within worker process
|
|
61
|
-
*/
|
|
62
|
-
if (process.send) {
|
|
63
|
-
log.warn('You are running tests with @wdio/sync which will be discontinued starting Node.js v16.' +
|
|
64
|
-
'Read more on https://github.com/webdriverio/webdriverio/discussions/6702');
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
exports.runAsync = true;
|
|
69
|
-
exports.asyncSpec = true;
|
|
70
|
-
}
|
|
71
15
|
let executeHooksWithArgs = async function executeHooksWithArgsShim(hookName, hooks = [], args = []) {
|
|
72
|
-
exports.runAsync = true;
|
|
73
16
|
/**
|
|
74
17
|
* make sure hooks are an array of functions
|
|
75
18
|
*/
|
|
@@ -110,14 +53,6 @@ let executeHooksWithArgs = async function executeHooksWithArgsShim(hookName, hoo
|
|
|
110
53
|
}
|
|
111
54
|
return result;
|
|
112
55
|
};
|
|
113
|
-
exports.executeHooksWithArgs = executeHooksWithArgs;
|
|
114
|
-
let runFnInFiberContext = function (fn) {
|
|
115
|
-
return function (...args) {
|
|
116
|
-
exports.runAsync = true;
|
|
117
|
-
return Promise.resolve(fn.apply(this, args));
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
|
-
exports.runFnInFiberContext = runFnInFiberContext;
|
|
121
56
|
/**
|
|
122
57
|
* wrap command to enable before and after command to be executed
|
|
123
58
|
* @param commandName name of the command (e.g. getTitle)
|
|
@@ -210,10 +145,10 @@ let wrapCommand = function wrapCommand(commandName, fn) {
|
|
|
210
145
|
* await $('body').$('header').$$('div').map((elem) => elem.getLocation())
|
|
211
146
|
* ```
|
|
212
147
|
*/
|
|
213
|
-
if (commandName.endsWith('$$') && typeof
|
|
148
|
+
if (commandName.endsWith('$$') && typeof iterators[prop] === 'function') {
|
|
214
149
|
return (mapIterator) => wrapElementFn(target, function (mapIterator) {
|
|
215
150
|
// @ts-ignore
|
|
216
|
-
return
|
|
151
|
+
return iterators[prop](this, mapIterator);
|
|
217
152
|
}, [mapIterator]);
|
|
218
153
|
}
|
|
219
154
|
/**
|
|
@@ -260,53 +195,21 @@ let wrapCommand = function wrapCommand(commandName, fn) {
|
|
|
260
195
|
}
|
|
261
196
|
return function (...args) {
|
|
262
197
|
/**
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
* - if a global.browser is define so we run with wdio testrunner
|
|
266
|
-
* - we are in a fiber context (flag is set when outer function is wrapped into fibers context)
|
|
267
|
-
*
|
|
268
|
-
* also if we run command asynchronous and the command suppose to return an element, we
|
|
269
|
-
* apply `chainElementQuery` to allow chaining of these promises.
|
|
198
|
+
* if the command suppose to return an element, we apply `chainElementQuery` to allow
|
|
199
|
+
* chaining of these promises.
|
|
270
200
|
*/
|
|
271
|
-
const command =
|
|
272
|
-
?
|
|
273
|
-
:
|
|
274
|
-
|
|
201
|
+
const command = ELEMENT_QUERY_COMMANDS.includes(commandName) || commandName.endsWith('$')
|
|
202
|
+
? chainElementQuery
|
|
203
|
+
: ACTION_COMMANDS.includes(commandName)
|
|
204
|
+
/**
|
|
205
|
+
* actions commands are a bit special as they return their own
|
|
206
|
+
* sync interface
|
|
207
|
+
*/
|
|
208
|
+
? fn
|
|
275
209
|
: wrapCommandFn;
|
|
276
210
|
return command.apply(this, args);
|
|
277
211
|
};
|
|
278
212
|
};
|
|
279
|
-
exports.wrapCommand = wrapCommand;
|
|
280
|
-
/**
|
|
281
|
-
* execute test or hook synchronously
|
|
282
|
-
*
|
|
283
|
-
* @param {Function} fn spec or hook method
|
|
284
|
-
* @param {Number} retries { limit: number, attempts: number }
|
|
285
|
-
* @param {Array} args arguments passed to hook
|
|
286
|
-
* @return {Promise} that gets resolved once test/hook is done or was retried enough
|
|
287
|
-
*/
|
|
288
|
-
async function executeSyncFn(fn, retries, args = []) {
|
|
289
|
-
this.wdioRetries = retries.attempts;
|
|
290
|
-
try {
|
|
291
|
-
exports.runAsync = true;
|
|
292
|
-
let res = fn.apply(this, args);
|
|
293
|
-
/**
|
|
294
|
-
* sometimes function result is Promise,
|
|
295
|
-
* we need to await result before proceeding
|
|
296
|
-
*/
|
|
297
|
-
if (res instanceof Promise) {
|
|
298
|
-
return await res;
|
|
299
|
-
}
|
|
300
|
-
return res;
|
|
301
|
-
}
|
|
302
|
-
catch (err) {
|
|
303
|
-
if (retries.limit > retries.attempts) {
|
|
304
|
-
retries.attempts++;
|
|
305
|
-
return await executeSyncFn.call(this, fn, retries, args);
|
|
306
|
-
}
|
|
307
|
-
return Promise.reject(err);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
213
|
/**
|
|
311
214
|
* execute test or hook asynchronously
|
|
312
215
|
*
|
|
@@ -316,28 +219,11 @@ async function executeSyncFn(fn, retries, args = []) {
|
|
|
316
219
|
* @return {Promise} that gets resolved once test/hook is done or was retried enough
|
|
317
220
|
*/
|
|
318
221
|
async function executeAsync(fn, retries, args = []) {
|
|
319
|
-
const isJasmine = global.jasmine && global.expectAsync;
|
|
320
|
-
const asyncSpecBefore = exports.asyncSpec;
|
|
321
222
|
this.wdioRetries = retries.attempts;
|
|
322
|
-
if (!expectSync) {
|
|
323
|
-
// @ts-ignore
|
|
324
|
-
expectSync = global.expect.bind({});
|
|
325
|
-
}
|
|
326
|
-
if (isJasmine) {
|
|
327
|
-
// @ts-ignore
|
|
328
|
-
global.expect = expectAsyncShim;
|
|
329
|
-
}
|
|
330
223
|
try {
|
|
331
|
-
exports.runAsync = true;
|
|
332
|
-
exports.asyncSpec = true;
|
|
333
224
|
const result = fn.apply(this, args);
|
|
334
225
|
if (result && typeof result.finally === 'function') {
|
|
335
|
-
result
|
|
336
|
-
.finally(() => (exports.asyncSpec = asyncSpecBefore))
|
|
337
|
-
.catch((err) => err);
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
exports.asyncSpec = asyncSpecBefore;
|
|
226
|
+
result.catch((err) => err);
|
|
341
227
|
}
|
|
342
228
|
return await result;
|
|
343
229
|
}
|
|
@@ -348,57 +234,5 @@ async function executeAsync(fn, retries, args = []) {
|
|
|
348
234
|
}
|
|
349
235
|
throw err;
|
|
350
236
|
}
|
|
351
|
-
finally {
|
|
352
|
-
if (isJasmine) {
|
|
353
|
-
// @ts-ignore
|
|
354
|
-
global.expect = expectSync;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
exports.executeAsync = executeAsync;
|
|
359
|
-
let executeSync = executeSyncFn;
|
|
360
|
-
exports.executeSync = executeSync;
|
|
361
|
-
/**
|
|
362
|
-
* Method to switch between sync and async execution. It allows to have async
|
|
363
|
-
* tests in between synchronous tests. `fn` can either return a promise (e.g. for `executeSync`)
|
|
364
|
-
* or a function (e.g. for `runSync`). In both cases we need to make sure that
|
|
365
|
-
* we flip `runAsync` flag to true to that commands are wrapped with the @wdio/sync
|
|
366
|
-
* wrapper.
|
|
367
|
-
*/
|
|
368
|
-
function switchSyncFlag(fn) {
|
|
369
|
-
return function (...args) {
|
|
370
|
-
const switchFlag = exports.runAsync;
|
|
371
|
-
exports.runAsync = false;
|
|
372
|
-
const result = fn.apply(this, args);
|
|
373
|
-
if (typeof result.finally === 'function') {
|
|
374
|
-
exports.runAsync = switchFlag;
|
|
375
|
-
return result;
|
|
376
|
-
}
|
|
377
|
-
if (typeof result === 'function') {
|
|
378
|
-
return function (...args) {
|
|
379
|
-
const switchFlagWithinFn = exports.runAsync;
|
|
380
|
-
const res = result.apply(this, args);
|
|
381
|
-
if (typeof result.finally === 'function') {
|
|
382
|
-
return result.finally(() => (exports.runAsync = switchFlagWithinFn));
|
|
383
|
-
}
|
|
384
|
-
exports.runAsync = switchFlagWithinFn;
|
|
385
|
-
return res;
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
exports.runAsync = switchFlag;
|
|
389
|
-
return result;
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
exports.switchSyncFlag = switchSyncFlag;
|
|
393
|
-
/**
|
|
394
|
-
* only require `@wdio/sync` if `WDIO_NO_SYNC_SUPPORT` which allows us to
|
|
395
|
-
* create a smoke test scenario to test actual absence of the package
|
|
396
|
-
* (internal use only)
|
|
397
|
-
*/
|
|
398
|
-
/* istanbul ignore if */
|
|
399
|
-
if (!process.env.WDIO_NO_SYNC_SUPPORT && hasWdioSyncSupport && wdioSync) {
|
|
400
|
-
exports.runFnInFiberContext = runFnInFiberContext = switchSyncFlag(wdioSync.runFnInFiberContext);
|
|
401
|
-
exports.executeHooksWithArgs = executeHooksWithArgs = switchSyncFlag(wdioSync.executeHooksWithArgs);
|
|
402
|
-
exports.executeSync = executeSync = switchSyncFlag(wdioSync.executeSync);
|
|
403
|
-
exports.runSync = runSync = switchSyncFlag(wdioSync.runSync);
|
|
404
237
|
}
|
|
238
|
+
export { executeHooksWithArgs, wrapCommand, executeAsync, };
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.logHookError = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* notify `WDIOCLInterface` about failure in hook
|
|
6
3
|
* we need to do it this way because `beforeFn` and `afterFn` are not real hooks.
|
|
@@ -10,7 +7,7 @@ exports.logHookError = void 0;
|
|
|
10
7
|
* @param {Array} hookResults hook functions results array
|
|
11
8
|
* @param {string} cid cid
|
|
12
9
|
*/
|
|
13
|
-
const logHookError = (hookName, hookResults = [], cid) => {
|
|
10
|
+
export const logHookError = (hookName, hookResults = [], cid) => {
|
|
14
11
|
const result = hookResults.find(result => result instanceof Error);
|
|
15
12
|
if (typeof result === 'undefined') {
|
|
16
13
|
return;
|
|
@@ -32,4 +29,3 @@ const logHookError = (hookName, hookResults = [], cid) => {
|
|
|
32
29
|
content
|
|
33
30
|
});
|
|
34
31
|
};
|
|
35
|
-
exports.logHookError = logHookError;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { testFnWrapper } from './testFnWrapper';
|
|
2
|
-
import { runTestInFiberContext } from './testInterfaceWrapper';
|
|
1
|
+
import { testFnWrapper } from './testFnWrapper.js';
|
|
2
|
+
import { runTestInFiberContext } from './testInterfaceWrapper.js';
|
|
3
3
|
export { testFnWrapper, runTestInFiberContext };
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test-framework/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test-framework/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AAEjE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,CAAA"}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/* istanbul ignore file */
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Object.defineProperty(exports, "testFnWrapper", { enumerable: true, get: function () { return testFnWrapper_1.testFnWrapper; } });
|
|
7
|
-
const testInterfaceWrapper_1 = require("./testInterfaceWrapper");
|
|
8
|
-
Object.defineProperty(exports, "runTestInFiberContext", { enumerable: true, get: function () { return testInterfaceWrapper_1.runTestInFiberContext; } });
|
|
2
|
+
import { testFnWrapper } from './testFnWrapper.js';
|
|
3
|
+
import { runTestInFiberContext } from './testInterfaceWrapper.js';
|
|
4
|
+
export { testFnWrapper, runTestInFiberContext };
|
|
@@ -23,7 +23,7 @@ export declare const testFnWrapper: (this: unknown, args_0: string, args_1: Spec
|
|
|
23
23
|
* @param {number} repeatTest number of retries if test fails
|
|
24
24
|
* @return {*} specFn result
|
|
25
25
|
*/
|
|
26
|
-
export declare const testFrameworkFnWrapper: (this: unknown, { executeHooksWithArgs, executeAsync
|
|
26
|
+
export declare const testFrameworkFnWrapper: (this: unknown, { executeHooksWithArgs, executeAsync }: WrapperMethods, type: string, { specFn, specFnArgs }: SpecFunction, { beforeFn, beforeFnArgs }: BeforeHookParam<unknown>, { afterFn, afterFnArgs }: AfterHookParam<unknown>, cid: string, repeatTest?: number) => Promise<unknown>;
|
|
27
27
|
/**
|
|
28
28
|
* Filter out internal stacktraces. exporting to allow testing of the function
|
|
29
29
|
* @param {string} stack Stacktrace
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testFnWrapper.d.ts","sourceRoot":"","sources":["../../src/test-framework/testFnWrapper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"testFnWrapper.d.ts","sourceRoot":"","sources":["../../src/test-framework/testFnWrapper.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,cAAc,EACd,YAAY,EACZ,eAAe,EACf,cAAc,EAEjB,MAAM,SAAS,CAAA;AAShB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,SAChB,OAAO,8JAWhB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,SACzB,OAAO,0CAC2B,cAAc,QAChD,MAAM,0BACY,YAAY,8BACR,gBAAgB,OAAO,CAAC,4BAC1B,eAAe,OAAO,CAAC,OAC5C,MAAM,0CA8Cd,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,UAAW,MAAM,KAAG,MAKhD,CAAA"}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.filterStackTrace = exports.testFrameworkFnWrapper = exports.testFnWrapper = void 0;
|
|
4
|
-
const utils_1 = require("../utils");
|
|
5
|
-
const errorHandler_1 = require("./errorHandler");
|
|
6
|
-
const shim_1 = require("../shim");
|
|
1
|
+
import { logHookError } from './errorHandler.js';
|
|
2
|
+
import { executeHooksWithArgs, executeAsync } from '../shim.js';
|
|
7
3
|
const STACKTRACE_FILTER = [
|
|
8
4
|
'node_modules/webdriver/',
|
|
9
5
|
'node_modules/webdriverio/',
|
|
@@ -21,10 +17,9 @@ const STACKTRACE_FILTER = [
|
|
|
21
17
|
* @param {number} repeatTest number of retries if test fails
|
|
22
18
|
* @return {*} specFn result
|
|
23
19
|
*/
|
|
24
|
-
const testFnWrapper = function (...args) {
|
|
25
|
-
return
|
|
20
|
+
export const testFnWrapper = function (...args) {
|
|
21
|
+
return testFrameworkFnWrapper.call(this, { executeHooksWithArgs, executeAsync }, ...args);
|
|
26
22
|
};
|
|
27
|
-
exports.testFnWrapper = testFnWrapper;
|
|
28
23
|
/**
|
|
29
24
|
* wraps test framework spec/hook function with WebdriverIO before/after hooks
|
|
30
25
|
*
|
|
@@ -37,29 +32,19 @@ exports.testFnWrapper = testFnWrapper;
|
|
|
37
32
|
* @param {number} repeatTest number of retries if test fails
|
|
38
33
|
* @return {*} specFn result
|
|
39
34
|
*/
|
|
40
|
-
const testFrameworkFnWrapper = async function ({ executeHooksWithArgs, executeAsync
|
|
35
|
+
export const testFrameworkFnWrapper = async function ({ executeHooksWithArgs, executeAsync }, type, { specFn, specFnArgs }, { beforeFn, beforeFnArgs }, { afterFn, afterFnArgs }, cid, repeatTest = 0) {
|
|
41
36
|
const retries = { attempts: 0, limit: repeatTest };
|
|
42
37
|
const beforeArgs = beforeFnArgs(this);
|
|
43
|
-
await
|
|
44
|
-
let promise;
|
|
38
|
+
await logHookError(`Before${type}`, await executeHooksWithArgs(`before${type}`, beforeFn, beforeArgs), cid);
|
|
45
39
|
let result;
|
|
46
40
|
let error;
|
|
47
|
-
/**
|
|
48
|
-
* user wants handle async command using promises, no need to wrap in fiber context
|
|
49
|
-
*/
|
|
50
|
-
if ((0, utils_1.isFunctionAsync)(specFn) || !runSync) {
|
|
51
|
-
promise = executeAsync.call(this, specFn, retries, specFnArgs);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
promise = new Promise(runSync.call(this, specFn, retries, specFnArgs));
|
|
55
|
-
}
|
|
56
41
|
const testStart = Date.now();
|
|
57
42
|
try {
|
|
58
|
-
result = await
|
|
43
|
+
result = await executeAsync.call(this, specFn, retries, specFnArgs);
|
|
59
44
|
}
|
|
60
45
|
catch (err) {
|
|
61
46
|
if (err.stack) {
|
|
62
|
-
err.stack =
|
|
47
|
+
err.stack = filterStackTrace(err.stack);
|
|
63
48
|
}
|
|
64
49
|
error = err;
|
|
65
50
|
}
|
|
@@ -80,22 +65,20 @@ const testFrameworkFnWrapper = async function ({ executeHooksWithArgs, executeAs
|
|
|
80
65
|
duration,
|
|
81
66
|
passed: !error
|
|
82
67
|
});
|
|
83
|
-
await
|
|
68
|
+
await logHookError(`After${type}`, await executeHooksWithArgs(`after${type}`, afterFn, [...afterArgs]), cid);
|
|
84
69
|
if (error && !error.matcherName) {
|
|
85
70
|
throw error;
|
|
86
71
|
}
|
|
87
72
|
return result;
|
|
88
73
|
};
|
|
89
|
-
exports.testFrameworkFnWrapper = testFrameworkFnWrapper;
|
|
90
74
|
/**
|
|
91
75
|
* Filter out internal stacktraces. exporting to allow testing of the function
|
|
92
76
|
* @param {string} stack Stacktrace
|
|
93
77
|
* @returns {string}
|
|
94
78
|
*/
|
|
95
|
-
const filterStackTrace = (stack) => {
|
|
79
|
+
export const filterStackTrace = (stack) => {
|
|
96
80
|
return stack
|
|
97
81
|
.split('\n')
|
|
98
82
|
.filter(line => !STACKTRACE_FILTER.some(l => line.includes(l)))
|
|
99
83
|
.join('\n');
|
|
100
84
|
};
|
|
101
|
-
exports.filterStackTrace = filterStackTrace;
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { HookFnArgs, SpecArguments } from './types';
|
|
9
9
|
/**
|
|
10
|
-
* runs a hook
|
|
11
|
-
* it also executes before/after hook
|
|
10
|
+
* runs a hook and execute before/after hook
|
|
12
11
|
*
|
|
13
12
|
* @param {Function} hookFn function that was passed to the framework hook
|
|
14
13
|
* @param {Function} origFn original framework hook function
|
|
@@ -22,7 +21,7 @@ import type { HookFnArgs, SpecArguments } from './types';
|
|
|
22
21
|
*/
|
|
23
22
|
export declare const runHook: (this: unknown, hookFn: Function, origFn: Function, beforeFn: Function | Function[], beforeFnArgs: HookFnArgs<unknown>, afterFn: Function | Function[], afterFnArgs: HookFnArgs<unknown>, cid: string, repeatTest: number, timeout: number) => any;
|
|
24
23
|
/**
|
|
25
|
-
* runs a spec function (test function)
|
|
24
|
+
* runs a spec function (test function)
|
|
26
25
|
*
|
|
27
26
|
* @param {string} specTitle test description
|
|
28
27
|
* @param {Function} specFn test function that got passed in from the user
|
|
@@ -51,7 +50,7 @@ export declare const runSpec: (this: unknown, specTitle: string, specFn: Functio
|
|
|
51
50
|
*/
|
|
52
51
|
export declare const wrapTestFunction: (this: unknown, origFn: Function, isSpec: boolean, beforeFn: Function | Function[], beforeArgsFn: HookFnArgs<unknown>, afterFn: Function | Function[], afterArgsFn: HookFnArgs<unknown>, cid: string) => (...specArguments: SpecArguments) => any;
|
|
53
52
|
/**
|
|
54
|
-
* Wraps global test function like `it
|
|
53
|
+
* Wraps global test function like `it`.
|
|
55
54
|
*
|
|
56
55
|
* The scope parameter is used in the qunit framework since all functions are bound to global.QUnit instead of global
|
|
57
56
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testInterfaceWrapper.d.ts","sourceRoot":"","sources":["../../src/test-framework/testInterfaceWrapper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EACR,UAAU,EAIV,aAAa,EAChB,MAAM,SAAS,CAAA;AAIhB
|
|
1
|
+
{"version":3,"file":"testInterfaceWrapper.d.ts","sourceRoot":"","sources":["../../src/test-framework/testInterfaceWrapper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EACR,UAAU,EAIV,aAAa,EAChB,MAAM,SAAS,CAAA;AAIhB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,OAAO,SACV,OAAO,UACL,QAAQ,UACR,QAAQ,YACN,QAAQ,GAAG,QAAQ,EAAE,gBACjB,WAAW,OAAO,CAAC,WACxB,QAAQ,GAAG,QAAQ,EAAE,eACjB,WAAW,OAAO,CAAC,OAC3B,MAAM,cACC,MAAM,WACT,MAAM,QAgClB,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,OAAO,SACV,OAAO,aACF,MAAM,UACT,QAAQ,UACR,QAAQ,YACN,QAAQ,GAAG,QAAQ,EAAE,gBACjB,WAAW,OAAO,CAAC,WACxB,QAAQ,GAAG,QAAQ,EAAE,eACjB,WAAW,OAAO,CAAC,OAC3B,MAAM,cACC,MAAM,WACT,MAAM,QAgClB,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,SACnB,OAAO,UACL,QAAQ,UACR,OAAO,YACL,QAAQ,GAAG,QAAQ,EAAE,gBACjB,WAAW,OAAO,CAAC,WACxB,QAAQ,GAAG,QAAQ,EAAE,eACjB,WAAW,OAAO,CAAC,OAC3B,MAAM,wBAEwB,aAAa,QAkEnD,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,SACxB,OAAO,UACL,OAAO,YACL,QAAQ,GAAG,QAAQ,EAAE,gBACjB,WAAW,OAAO,CAAC,WACxB,QAAQ,GAAG,QAAQ,EAAE,eACjB,WAAW,OAAO,CAAC,UACxB,MAAM,OACT,MAAM,oCAcd,CAAA"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* used to wrap mocha, jasmine test frameworks functions (`it`, `beforeEach` and other)
|
|
4
3
|
* with WebdriverIO before/after Test/Hook hooks.
|
|
@@ -6,14 +5,11 @@
|
|
|
6
5
|
*
|
|
7
6
|
* NOTE: not used by cucumber test framework. `testFnWrapper` is called directly there
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const utils_1 = require("../utils");
|
|
12
|
-
const testFnWrapper_1 = require("./testFnWrapper");
|
|
8
|
+
import { filterSpecArgs } from '../utils.js';
|
|
9
|
+
import { testFnWrapper } from './testFnWrapper.js';
|
|
13
10
|
const MOCHA_COMMANDS = ['skip', 'only'];
|
|
14
11
|
/**
|
|
15
|
-
* runs a hook
|
|
16
|
-
* it also executes before/after hook
|
|
12
|
+
* runs a hook and execute before/after hook
|
|
17
13
|
*
|
|
18
14
|
* @param {Function} hookFn function that was passed to the framework hook
|
|
19
15
|
* @param {Function} origFn original framework hook function
|
|
@@ -25,11 +21,11 @@ const MOCHA_COMMANDS = ['skip', 'only'];
|
|
|
25
21
|
* @param {Number} repeatTest number of retries if hook fails
|
|
26
22
|
* @return {Function} wrapped framework hook function
|
|
27
23
|
*/
|
|
28
|
-
const runHook = function (hookFn, origFn, beforeFn, beforeFnArgs, afterFn, afterFnArgs, cid, repeatTest, timeout) {
|
|
24
|
+
export const runHook = function (hookFn, origFn, beforeFn, beforeFnArgs, afterFn, afterFnArgs, cid, repeatTest, timeout) {
|
|
29
25
|
return origFn(function (...hookFnArgs) {
|
|
30
|
-
return
|
|
26
|
+
return testFnWrapper.call(this, 'Hook', {
|
|
31
27
|
specFn: hookFn,
|
|
32
|
-
specFnArgs:
|
|
28
|
+
specFnArgs: filterSpecArgs(hookFnArgs)
|
|
33
29
|
}, {
|
|
34
30
|
beforeFn,
|
|
35
31
|
beforeFnArgs
|
|
@@ -39,9 +35,8 @@ const runHook = function (hookFn, origFn, beforeFn, beforeFnArgs, afterFn, after
|
|
|
39
35
|
}, cid, repeatTest);
|
|
40
36
|
}, timeout);
|
|
41
37
|
};
|
|
42
|
-
exports.runHook = runHook;
|
|
43
38
|
/**
|
|
44
|
-
* runs a spec function (test function)
|
|
39
|
+
* runs a spec function (test function)
|
|
45
40
|
*
|
|
46
41
|
* @param {string} specTitle test description
|
|
47
42
|
* @param {Function} specFn test function that got passed in from the user
|
|
@@ -54,11 +49,11 @@ exports.runHook = runHook;
|
|
|
54
49
|
* @param {Number} repeatTest number of retries if test fails
|
|
55
50
|
* @return {Function} wrapped test function
|
|
56
51
|
*/
|
|
57
|
-
const runSpec = function (specTitle, specFn, origFn, beforeFn, beforeFnArgs, afterFn, afterFnArgs, cid, repeatTest, timeout) {
|
|
52
|
+
export const runSpec = function (specTitle, specFn, origFn, beforeFn, beforeFnArgs, afterFn, afterFnArgs, cid, repeatTest, timeout) {
|
|
58
53
|
return origFn(specTitle, function (...specFnArgs) {
|
|
59
|
-
return
|
|
54
|
+
return testFnWrapper.call(this, 'Test', {
|
|
60
55
|
specFn,
|
|
61
|
-
specFnArgs:
|
|
56
|
+
specFnArgs: filterSpecArgs(specFnArgs)
|
|
62
57
|
}, {
|
|
63
58
|
beforeFn,
|
|
64
59
|
beforeFnArgs
|
|
@@ -68,7 +63,6 @@ const runSpec = function (specTitle, specFn, origFn, beforeFn, beforeFnArgs, aft
|
|
|
68
63
|
}, cid, repeatTest);
|
|
69
64
|
}, timeout);
|
|
70
65
|
};
|
|
71
|
-
exports.runSpec = runSpec;
|
|
72
66
|
/**
|
|
73
67
|
* wraps hooks and test function of a framework within a fiber context
|
|
74
68
|
*
|
|
@@ -82,9 +76,8 @@ exports.runSpec = runSpec;
|
|
|
82
76
|
* @param {String} cid cid
|
|
83
77
|
* @return {Function} wrapped test/hook function
|
|
84
78
|
*/
|
|
85
|
-
const wrapTestFunction = function (origFn, isSpec, beforeFn, beforeArgsFn, afterFn, afterArgsFn, cid) {
|
|
79
|
+
export const wrapTestFunction = function (origFn, isSpec, beforeFn, beforeArgsFn, afterFn, afterArgsFn, cid) {
|
|
86
80
|
return function (...specArguments) {
|
|
87
|
-
var _a;
|
|
88
81
|
/**
|
|
89
82
|
* Variadic arguments:
|
|
90
83
|
* [title, fn], [title], [fn]
|
|
@@ -97,7 +90,9 @@ const wrapTestFunction = function (origFn, isSpec, beforeFn, beforeArgsFn, after
|
|
|
97
90
|
* Jasmine uses a timeout value as last parameter, in this case the arguments
|
|
98
91
|
* should be [title, fn, timeout, retryCnt]
|
|
99
92
|
*/
|
|
100
|
-
|
|
93
|
+
// @ts-expect-error
|
|
94
|
+
let timeout = global.jasmine?.DEFAULT_TIMEOUT_INTERVAL;
|
|
95
|
+
// @ts-expect-error
|
|
101
96
|
if (global.jasmine) {
|
|
102
97
|
// if we have [title, fn, timeout, retryCnt]
|
|
103
98
|
if (typeof specArguments[specArguments.length - 1] === 'number') {
|
|
@@ -114,19 +109,18 @@ const wrapTestFunction = function (origFn, isSpec, beforeFn, beforeArgsFn, after
|
|
|
114
109
|
const specTitle = specArguments[0];
|
|
115
110
|
if (isSpec) {
|
|
116
111
|
if (specFn) {
|
|
117
|
-
return
|
|
112
|
+
return runSpec(specTitle, specFn, origFn, beforeFn, beforeArgsFn, afterFn, afterArgsFn, cid, retryCnt, timeout);
|
|
118
113
|
}
|
|
119
114
|
/**
|
|
120
115
|
* if specFn is undefined we are dealing with a pending function
|
|
121
116
|
*/
|
|
122
117
|
return origFn(specTitle);
|
|
123
118
|
}
|
|
124
|
-
return
|
|
119
|
+
return runHook(specFn, origFn, beforeFn, beforeArgsFn, afterFn, afterArgsFn, cid, retryCnt, timeout);
|
|
125
120
|
};
|
|
126
121
|
};
|
|
127
|
-
exports.wrapTestFunction = wrapTestFunction;
|
|
128
122
|
/**
|
|
129
|
-
* Wraps global test function like `it
|
|
123
|
+
* Wraps global test function like `it`.
|
|
130
124
|
*
|
|
131
125
|
* The scope parameter is used in the qunit framework since all functions are bound to global.QUnit instead of global
|
|
132
126
|
*
|
|
@@ -139,12 +133,11 @@ exports.wrapTestFunction = wrapTestFunction;
|
|
|
139
133
|
* @param {String} cid cid
|
|
140
134
|
* @param {Object} scope the scope to run command from, defaults to global
|
|
141
135
|
*/
|
|
142
|
-
const runTestInFiberContext = function (isSpec, beforeFn, beforeArgsFn, afterFn, afterArgsFn, fnName, cid, scope = global) {
|
|
136
|
+
export const runTestInFiberContext = function (isSpec, beforeFn, beforeArgsFn, afterFn, afterArgsFn, fnName, cid, scope = global) {
|
|
143
137
|
const origFn = scope[fnName];
|
|
144
|
-
scope[fnName] =
|
|
138
|
+
scope[fnName] = wrapTestFunction(origFn, isSpec, beforeFn, beforeArgsFn, afterFn, afterArgsFn, cid);
|
|
145
139
|
addMochaCommands(origFn, scope[fnName]);
|
|
146
140
|
};
|
|
147
|
-
exports.runTestInFiberContext = runTestInFiberContext;
|
|
148
141
|
/**
|
|
149
142
|
* support `it.skip` and `it.only` for the Mocha framework
|
|
150
143
|
* @param {Function} origFn original function
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type { executeHooksWithArgs, executeAsync
|
|
1
|
+
import type { executeHooksWithArgs, executeAsync } from '../shim';
|
|
2
2
|
export declare type HookFnArgs<T> = (ctx: T) => [unknown, T];
|
|
3
3
|
export interface WrapperMethods {
|
|
4
4
|
executeHooksWithArgs: typeof executeHooksWithArgs;
|
|
5
5
|
executeAsync: typeof executeAsync;
|
|
6
|
-
runSync: typeof runSync;
|
|
7
6
|
}
|
|
8
7
|
export interface SpecFunction {
|
|
9
8
|
specFn: Function;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/test-framework/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/test-framework/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEjE,oBAAY,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;AAEpD,MAAM,WAAW,cAAc;IAC3B,oBAAoB,EAAE,OAAO,oBAAoB,CAAA;IACjD,YAAY,EAAE,OAAO,YAAY,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,QAAQ,CAAA;IAChB,UAAU,EAAE,GAAG,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAC9B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAAA;IAC/B,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;CAC9B;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC7B,OAAO,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAAA;IAC9B,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,cAAc;IAC3B,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACrD;AAED,oBAAY,aAAa,GAAG;AACxB;;GAEG;AACH;IAAC,QAAQ;CAAC;AACV;;GAEG;AACH;IAAC,QAAQ;IAAE,MAAM;CAAC;AAClB;;GAEG;AACH;IAAC,MAAM;IAAE,QAAQ;CAAC;AAClB;;GAEG;AACH;IAAC,MAAM;IAAE,QAAQ;IAAE,MAAM;CAAC,CAC7B,CAAA"}
|