system-testing 1.0.35 → 1.0.37
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/index.js +3 -0
- package/{dist → build}/system-test-browser-helper.d.ts +2 -2
- package/build/system-test-browser-helper.js +238 -0
- package/build/system-test-communicator.js +105 -0
- package/build/system-test-http-server.js +66 -0
- package/{dist → build}/system-test.d.ts +15 -24
- package/build/system-test.js +696 -0
- package/build/use-system-test.js +79 -0
- package/package.json +10 -6
- package/dist/index.js +0 -3
- package/dist/index.js.map +0 -1
- package/dist/system-test-browser-helper.js +0 -238
- package/dist/system-test-browser-helper.js.map +0 -1
- package/dist/system-test-communicator.js +0 -105
- package/dist/system-test-communicator.js.map +0 -1
- package/dist/system-test-http-server.js +0 -66
- package/dist/system-test-http-server.js.map +0 -1
- package/dist/system-test.js +0 -705
- package/dist/system-test.js.map +0 -1
- package/dist/use-system-test.js +0 -79
- package/dist/use-system-test.js.map +0 -1
- /package/{dist → build}/index.d.ts +0 -0
- /package/{dist → build}/system-test-communicator.d.ts +0 -0
- /package/{dist → build}/system-test-http-server.d.ts +0 -0
- /package/{dist → build}/use-system-test.d.ts +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import qs from "qs";
|
|
2
|
+
import SystemTestBrowserHelper from "./system-test-browser-helper.js";
|
|
3
|
+
import { useCallback, useMemo } from "react";
|
|
4
|
+
import useEventEmitter from "@kaspernj/api-maker/build/use-event-emitter.js";
|
|
5
|
+
import { useRouter } from "expo-router";
|
|
6
|
+
const shared = {
|
|
7
|
+
initialized: false,
|
|
8
|
+
systemTestBrowserHelper: null
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* @returns {boolean}
|
|
12
|
+
*/
|
|
13
|
+
function isSystemTestEnabled() {
|
|
14
|
+
let enabled = false;
|
|
15
|
+
const initialUrl = globalThis.location?.href;
|
|
16
|
+
if (initialUrl) {
|
|
17
|
+
const queryString = initialUrl.substring(initialUrl.indexOf("?") + 1, initialUrl.length);
|
|
18
|
+
const queryParams = qs.parse(queryString);
|
|
19
|
+
if (queryParams.systemTest == "true") {
|
|
20
|
+
enabled = true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return enabled;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @returns {SystemTestBrowserHelper}
|
|
27
|
+
*/
|
|
28
|
+
function getSystemTestBrowserHelper() {
|
|
29
|
+
if (!shared.systemTestBrowserHelper) {
|
|
30
|
+
shared.systemTestBrowserHelper = new SystemTestBrowserHelper();
|
|
31
|
+
shared.systemTestBrowserHelper.enableOnBrowser();
|
|
32
|
+
}
|
|
33
|
+
return shared.systemTestBrowserHelper;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A hook that provides system test capabilities.
|
|
37
|
+
* @param {object} options - Options for the hook.
|
|
38
|
+
* @param {function() : void} options.onInitialize - A callback function that is called when the system test browser helper is initialized.
|
|
39
|
+
* @returns {{enabled: boolean, systemTestBrowserHelper: SystemTestBrowserHelper}}
|
|
40
|
+
*/
|
|
41
|
+
export default function useSystemTest({ onInitialize, ...restArgs } = { onInitialize: undefined }) {
|
|
42
|
+
const router = useRouter();
|
|
43
|
+
const enabled = useMemo(() => isSystemTestEnabled(), []);
|
|
44
|
+
const systemTestBrowserHelper = enabled ? getSystemTestBrowserHelper() : null;
|
|
45
|
+
const result = useMemo(() => ({ enabled, systemTestBrowserHelper }), [enabled, systemTestBrowserHelper]);
|
|
46
|
+
const instanceShared = useMemo(() => ({}), []);
|
|
47
|
+
instanceShared.enabled = enabled;
|
|
48
|
+
instanceShared.router = router;
|
|
49
|
+
// Resets navigation when instructed by the system test browser helper
|
|
50
|
+
const onSystemTestBrowserHelperDismissTo = useCallback(({ path }) => {
|
|
51
|
+
if (instanceShared.enabled) {
|
|
52
|
+
try {
|
|
53
|
+
instanceShared.router.dismissTo(path);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error(`Failed to dismiss to path "${path}": ${error.message}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}, []);
|
|
60
|
+
useEventEmitter(shared.systemTestBrowserHelper?.getEvents(), "dismissTo", onSystemTestBrowserHelperDismissTo);
|
|
61
|
+
// Navigates when instructed by the system test browser helper and keeping history of screens
|
|
62
|
+
const onSystemTestBrowserHelperNavigate = useCallback(({ path }) => {
|
|
63
|
+
if (instanceShared.enabled) {
|
|
64
|
+
instanceShared.router.navigate(path);
|
|
65
|
+
}
|
|
66
|
+
}, []);
|
|
67
|
+
useEventEmitter(shared.systemTestBrowserHelper?.getEvents(), "navigate", onSystemTestBrowserHelperNavigate);
|
|
68
|
+
useMemo(() => {
|
|
69
|
+
if (enabled && !shared.initialized) {
|
|
70
|
+
shared.initialized = true;
|
|
71
|
+
shared.systemTestBrowserHelper?.onInitialize(onInitialize);
|
|
72
|
+
}
|
|
73
|
+
}, [enabled, onInitialize, shared.systemTestBrowserHelper]);
|
|
74
|
+
const restArgsKeys = Object.keys(restArgs);
|
|
75
|
+
if (restArgsKeys.length > 0)
|
|
76
|
+
throw new Error(`Unknown arguments given to useSystemTest: ${restArgsKeys.join(", ")}`);
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLXN5c3RlbS10ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3VzZS1zeXN0ZW0tdGVzdC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFDbkIsT0FBTyx1QkFBdUIsTUFBTSxpQ0FBaUMsQ0FBQTtBQUNyRSxPQUFPLEVBQUMsV0FBVyxFQUFFLE9BQU8sRUFBQyxNQUFNLE9BQU8sQ0FBQTtBQUMxQyxPQUFPLGVBQWUsTUFBTSxnREFBZ0QsQ0FBQTtBQUM1RSxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sYUFBYSxDQUFBO0FBRXJDLE1BQU0sTUFBTSxHQUFHO0lBQ2IsV0FBVyxFQUFFLEtBQUs7SUFDbEIsdUJBQXVCLEVBQUUsSUFBSTtDQUM5QixDQUFBO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLG1CQUFtQjtJQUMxQixJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUE7SUFDbkIsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUE7SUFFNUMsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUNmLE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3hGLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUE7UUFFekMsSUFBSSxXQUFXLENBQUMsVUFBVSxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ3JDLE9BQU8sR0FBRyxJQUFJLENBQUE7UUFDaEIsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLE9BQU8sQ0FBQTtBQUNoQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLDBCQUEwQjtJQUNqQyxJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDcEMsTUFBTSxDQUFDLHVCQUF1QixHQUFHLElBQUksdUJBQXVCLEVBQUUsQ0FBQTtRQUM5RCxNQUFNLENBQUMsdUJBQXVCLENBQUMsZUFBZSxFQUFFLENBQUE7SUFDbEQsQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDLHVCQUF1QixDQUFBO0FBQ3ZDLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxPQUFPLFVBQVUsYUFBYSxDQUFDLEVBQUMsWUFBWSxFQUFFLEdBQUcsUUFBUSxFQUFDLEdBQUcsRUFBQyxZQUFZLEVBQUUsU0FBUyxFQUFDO0lBQzNGLE1BQU0sTUFBTSxHQUFHLFNBQVMsRUFBRSxDQUFBO0lBQzFCLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFBO0lBQ3hELE1BQU0sdUJBQXVCLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQywwQkFBMEIsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7SUFDN0UsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLHVCQUF1QixDQUFDLENBQUMsQ0FBQTtJQUN0RyxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUU5QyxjQUFjLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQTtJQUNoQyxjQUFjLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtJQUU5QixzRUFBc0U7SUFDdEUsTUFBTSxrQ0FBa0MsR0FBRyxXQUFXLENBQUMsQ0FBQyxFQUFDLElBQUksRUFBQyxFQUFFLEVBQUU7UUFDaEUsSUFBSSxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDO2dCQUNILGNBQWMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ3ZDLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsOEJBQThCLElBQUksTUFBTSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQTtZQUN4RSxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUVOLGVBQWUsQ0FBQyxNQUFNLENBQUMsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLEVBQUUsV0FBVyxFQUFFLGtDQUFrQyxDQUFDLENBQUE7SUFHN0csNkZBQTZGO0lBQzdGLE1BQU0saUNBQWlDLEdBQUcsV0FBVyxDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUMsRUFBRSxFQUFFO1FBQy9ELElBQUksY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzNCLGNBQWMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ3RDLENBQUM7SUFDSCxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFFTixlQUFlLENBQUMsTUFBTSxDQUFDLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxFQUFFLFVBQVUsRUFBRSxpQ0FBaUMsQ0FBQyxDQUFBO0lBRTNHLE9BQU8sQ0FBQyxHQUFHLEVBQUU7UUFDWCxJQUFJLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNuQyxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQTtZQUN6QixNQUFNLENBQUMsdUJBQXVCLEVBQUUsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBQzVELENBQUM7SUFDSCxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUE7SUFFM0QsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUUxQyxJQUFJLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQztRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRXBILE9BQU8sTUFBTSxDQUFBO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBxcyBmcm9tIFwicXNcIlxuaW1wb3J0IFN5c3RlbVRlc3RCcm93c2VySGVscGVyIGZyb20gXCIuL3N5c3RlbS10ZXN0LWJyb3dzZXItaGVscGVyLmpzXCJcbmltcG9ydCB7dXNlQ2FsbGJhY2ssIHVzZU1lbW99IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgdXNlRXZlbnRFbWl0dGVyIGZyb20gXCJAa2FzcGVybmovYXBpLW1ha2VyL2J1aWxkL3VzZS1ldmVudC1lbWl0dGVyLmpzXCJcbmltcG9ydCB7dXNlUm91dGVyfSBmcm9tIFwiZXhwby1yb3V0ZXJcIlxuXG5jb25zdCBzaGFyZWQgPSB7XG4gIGluaXRpYWxpemVkOiBmYWxzZSxcbiAgc3lzdGVtVGVzdEJyb3dzZXJIZWxwZXI6IG51bGxcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNTeXN0ZW1UZXN0RW5hYmxlZCgpIHtcbiAgbGV0IGVuYWJsZWQgPSBmYWxzZVxuICBjb25zdCBpbml0aWFsVXJsID0gZ2xvYmFsVGhpcy5sb2NhdGlvbj8uaHJlZlxuXG4gIGlmIChpbml0aWFsVXJsKSB7XG4gICAgY29uc3QgcXVlcnlTdHJpbmcgPSBpbml0aWFsVXJsLnN1YnN0cmluZyhpbml0aWFsVXJsLmluZGV4T2YoXCI/XCIpICsgMSwgaW5pdGlhbFVybC5sZW5ndGgpXG4gICAgY29uc3QgcXVlcnlQYXJhbXMgPSBxcy5wYXJzZShxdWVyeVN0cmluZylcblxuICAgIGlmIChxdWVyeVBhcmFtcy5zeXN0ZW1UZXN0ID09IFwidHJ1ZVwiKSB7XG4gICAgICBlbmFibGVkID0gdHJ1ZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbmFibGVkXG59XG5cbi8qKlxuICogQHJldHVybnMge1N5c3RlbVRlc3RCcm93c2VySGVscGVyfVxuICovXG5mdW5jdGlvbiBnZXRTeXN0ZW1UZXN0QnJvd3NlckhlbHBlcigpIHtcbiAgaWYgKCFzaGFyZWQuc3lzdGVtVGVzdEJyb3dzZXJIZWxwZXIpIHtcbiAgICBzaGFyZWQuc3lzdGVtVGVzdEJyb3dzZXJIZWxwZXIgPSBuZXcgU3lzdGVtVGVzdEJyb3dzZXJIZWxwZXIoKVxuICAgIHNoYXJlZC5zeXN0ZW1UZXN0QnJvd3NlckhlbHBlci5lbmFibGVPbkJyb3dzZXIoKVxuICB9XG5cbiAgcmV0dXJuIHNoYXJlZC5zeXN0ZW1UZXN0QnJvd3NlckhlbHBlclxufVxuXG4vKipcbiAqIEEgaG9vayB0aGF0IHByb3ZpZGVzIHN5c3RlbSB0ZXN0IGNhcGFiaWxpdGllcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIGhvb2suXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCkgOiB2b2lkfSBvcHRpb25zLm9uSW5pdGlhbGl6ZSAtIEEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgc3lzdGVtIHRlc3QgYnJvd3NlciBoZWxwZXIgaXMgaW5pdGlhbGl6ZWQuXG4gKiBAcmV0dXJucyB7e2VuYWJsZWQ6IGJvb2xlYW4sIHN5c3RlbVRlc3RCcm93c2VySGVscGVyOiBTeXN0ZW1UZXN0QnJvd3NlckhlbHBlcn19XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVzZVN5c3RlbVRlc3Qoe29uSW5pdGlhbGl6ZSwgLi4ucmVzdEFyZ3N9ID0ge29uSW5pdGlhbGl6ZTogdW5kZWZpbmVkfSkge1xuICBjb25zdCByb3V0ZXIgPSB1c2VSb3V0ZXIoKVxuICBjb25zdCBlbmFibGVkID0gdXNlTWVtbygoKSA9PiBpc1N5c3RlbVRlc3RFbmFibGVkKCksIFtdKVxuICBjb25zdCBzeXN0ZW1UZXN0QnJvd3NlckhlbHBlciA9IGVuYWJsZWQgPyBnZXRTeXN0ZW1UZXN0QnJvd3NlckhlbHBlcigpIDogbnVsbFxuICBjb25zdCByZXN1bHQgPSB1c2VNZW1vKCgpID0+ICh7ZW5hYmxlZCwgc3lzdGVtVGVzdEJyb3dzZXJIZWxwZXJ9KSwgW2VuYWJsZWQsIHN5c3RlbVRlc3RCcm93c2VySGVscGVyXSlcbiAgY29uc3QgaW5zdGFuY2VTaGFyZWQgPSB1c2VNZW1vKCgpID0+ICh7fSksIFtdKVxuXG4gIGluc3RhbmNlU2hhcmVkLmVuYWJsZWQgPSBlbmFibGVkXG4gIGluc3RhbmNlU2hhcmVkLnJvdXRlciA9IHJvdXRlclxuXG4gIC8vIFJlc2V0cyBuYXZpZ2F0aW9uIHdoZW4gaW5zdHJ1Y3RlZCBieSB0aGUgc3lzdGVtIHRlc3QgYnJvd3NlciBoZWxwZXJcbiAgY29uc3Qgb25TeXN0ZW1UZXN0QnJvd3NlckhlbHBlckRpc21pc3NUbyA9IHVzZUNhbGxiYWNrKCh7cGF0aH0pID0+IHtcbiAgICBpZiAoaW5zdGFuY2VTaGFyZWQuZW5hYmxlZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaW5zdGFuY2VTaGFyZWQucm91dGVyLmRpc21pc3NUbyhwYXRoKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIGRpc21pc3MgdG8gcGF0aCBcIiR7cGF0aH1cIjogJHtlcnJvci5tZXNzYWdlfWApXG4gICAgICB9XG4gICAgfVxuICB9LCBbXSlcblxuICB1c2VFdmVudEVtaXR0ZXIoc2hhcmVkLnN5c3RlbVRlc3RCcm93c2VySGVscGVyPy5nZXRFdmVudHMoKSwgXCJkaXNtaXNzVG9cIiwgb25TeXN0ZW1UZXN0QnJvd3NlckhlbHBlckRpc21pc3NUbylcblxuXG4gIC8vIE5hdmlnYXRlcyB3aGVuIGluc3RydWN0ZWQgYnkgdGhlIHN5c3RlbSB0ZXN0IGJyb3dzZXIgaGVscGVyIGFuZCBrZWVwaW5nIGhpc3Rvcnkgb2Ygc2NyZWVuc1xuICBjb25zdCBvblN5c3RlbVRlc3RCcm93c2VySGVscGVyTmF2aWdhdGUgPSB1c2VDYWxsYmFjaygoe3BhdGh9KSA9PiB7XG4gICAgaWYgKGluc3RhbmNlU2hhcmVkLmVuYWJsZWQpIHtcbiAgICAgIGluc3RhbmNlU2hhcmVkLnJvdXRlci5uYXZpZ2F0ZShwYXRoKVxuICAgIH1cbiAgfSwgW10pXG5cbiAgdXNlRXZlbnRFbWl0dGVyKHNoYXJlZC5zeXN0ZW1UZXN0QnJvd3NlckhlbHBlcj8uZ2V0RXZlbnRzKCksIFwibmF2aWdhdGVcIiwgb25TeXN0ZW1UZXN0QnJvd3NlckhlbHBlck5hdmlnYXRlKVxuXG4gIHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmIChlbmFibGVkICYmICFzaGFyZWQuaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHNoYXJlZC5pbml0aWFsaXplZCA9IHRydWVcbiAgICAgIHNoYXJlZC5zeXN0ZW1UZXN0QnJvd3NlckhlbHBlcj8ub25Jbml0aWFsaXplKG9uSW5pdGlhbGl6ZSlcbiAgICB9XG4gIH0sIFtlbmFibGVkLCBvbkluaXRpYWxpemUsIHNoYXJlZC5zeXN0ZW1UZXN0QnJvd3NlckhlbHBlcl0pXG5cbiAgY29uc3QgcmVzdEFyZ3NLZXlzID0gT2JqZWN0LmtleXMocmVzdEFyZ3MpXG5cbiAgaWYgKHJlc3RBcmdzS2V5cy5sZW5ndGggPiAwKSB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gYXJndW1lbnRzIGdpdmVuIHRvIHVzZVN5c3RlbVRlc3Q6ICR7cmVzdEFyZ3NLZXlzLmpvaW4oXCIsIFwiKX1gKVxuXG4gIHJldHVybiByZXN1bHRcbn1cbiJdfQ==
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "system-testing",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.37",
|
|
4
4
|
"description": "System testing with Selenium and browsers.",
|
|
5
|
-
"files": [
|
|
5
|
+
"files": [
|
|
6
|
+
"build/**"
|
|
7
|
+
],
|
|
6
8
|
"keywords": [
|
|
7
9
|
"system",
|
|
8
10
|
"testing",
|
|
@@ -20,18 +22,20 @@
|
|
|
20
22
|
"license": "ISC",
|
|
21
23
|
"author": "kasper@diestoeckels.de",
|
|
22
24
|
"type": "module",
|
|
23
|
-
"main": "
|
|
25
|
+
"main": "build/index.js",
|
|
24
26
|
"scripts": {
|
|
25
|
-
"build": "rm -rf
|
|
26
|
-
"
|
|
27
|
+
"build": "rm -rf build && npm run compile",
|
|
28
|
+
"compile": "tsc",
|
|
29
|
+
"lint": "eslint --max-warnings 0",
|
|
27
30
|
"prepublishOnly": "npm run build",
|
|
28
31
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
29
32
|
"typecheck": "tsc --noEmit",
|
|
30
|
-
"watch": "tsc -
|
|
33
|
+
"watch": "tsc -w"
|
|
31
34
|
},
|
|
32
35
|
"dependencies": {
|
|
33
36
|
"awaitery": "^1.0.2",
|
|
34
37
|
"diggerize": "^1.0.9",
|
|
38
|
+
"eventemitter3": "^5.0.1",
|
|
35
39
|
"htmlfy": "^1.0.0",
|
|
36
40
|
"mime": "^4.0.7",
|
|
37
41
|
"moment": "^2.30.1",
|
package/dist/index.js
DELETED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAAA,MAAM,IAAI,GAAG,aAAa,CAAA;AAE1B,OAAO,EAAC,IAAI,EAAC,CAAA"}
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import Client from "scoundrel-remote-eval/build/client/index.js";
|
|
3
|
-
import ClientWebSocket from "scoundrel-remote-eval/build/client/connections/web-socket/index.js";
|
|
4
|
-
import { digg } from "diggerize";
|
|
5
|
-
import EventEmitter from "events";
|
|
6
|
-
import SystemTestCommunicator from "./system-test-communicator.js";
|
|
7
|
-
/** @type {{systemTestBrowserHelper: SystemTestBrowserHelper | null}} */
|
|
8
|
-
const shared = {
|
|
9
|
-
systemTestBrowserHelper: null
|
|
10
|
-
};
|
|
11
|
-
export default class SystemTestBrowserHelper {
|
|
12
|
-
static current() {
|
|
13
|
-
if (!shared.systemTestBrowserHelper) {
|
|
14
|
-
throw new Error("No current SystemTestBrowserHelper set");
|
|
15
|
-
}
|
|
16
|
-
return shared.systemTestBrowserHelper;
|
|
17
|
-
}
|
|
18
|
-
constructor() {
|
|
19
|
-
/**
|
|
20
|
-
* @param {any[]} args
|
|
21
|
-
* @returns {void}
|
|
22
|
-
*/
|
|
23
|
-
this.fakeConsoleError = (...args) => {
|
|
24
|
-
this.communicator.sendCommand({ type: "console.error", value: this.consoleLogMessage(args) });
|
|
25
|
-
if (this.originalConsoleError) {
|
|
26
|
-
return this.originalConsoleError(...args);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* @param {any[]} args
|
|
31
|
-
* @returns {void}
|
|
32
|
-
*/
|
|
33
|
-
this.fakeConsoleLog = (...args) => {
|
|
34
|
-
this.communicator.sendCommand({ type: "console.log", value: this.consoleLogMessage(args) });
|
|
35
|
-
if (this.originalConsoleLog) {
|
|
36
|
-
return this.originalConsoleLog(...args);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* @param {{data: {path: string, type: string}}} args
|
|
41
|
-
* @returns {Promise<{result: string} | void>}
|
|
42
|
-
*/
|
|
43
|
-
this.onCommand = async ({ data }) => {
|
|
44
|
-
if (data.type == "initialize") {
|
|
45
|
-
this.events.emit("initialize");
|
|
46
|
-
if (this._onInitializeCallback) {
|
|
47
|
-
await this._onInitializeCallback();
|
|
48
|
-
}
|
|
49
|
-
return { result: "initialized" };
|
|
50
|
-
}
|
|
51
|
-
else if (data.type == "visit") {
|
|
52
|
-
this.events.emit("navigate", { path: data.path });
|
|
53
|
-
}
|
|
54
|
-
else if (data.type == "dismissTo") {
|
|
55
|
-
this.events.emit("dismissTo", { path: data.path });
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
throw new Error(`Unknown command type for SystemTestBrowserHelper: ${data.type}`);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
this.communicator = new SystemTestCommunicator({ parent: this, onCommand: this.onCommand });
|
|
62
|
-
this._enabled = false;
|
|
63
|
-
this.events = new EventEmitter();
|
|
64
|
-
shared.systemTestBrowserHelper = this;
|
|
65
|
-
this.startScoundrel();
|
|
66
|
-
}
|
|
67
|
-
async startScoundrel() {
|
|
68
|
-
this.scoundrelWs = new WebSocket("http://localhost:8090");
|
|
69
|
-
// @ts-expect-error
|
|
70
|
-
this.scoundrelClientWebSocket = new ClientWebSocket(this.scoundrelWs);
|
|
71
|
-
await this.scoundrelClientWebSocket.waitForOpened();
|
|
72
|
-
this.scoundrelClient = new Client(this.scoundrelClientWebSocket);
|
|
73
|
-
this.events.emit("scoundrelStarted");
|
|
74
|
-
}
|
|
75
|
-
waitForScoundrelStarted() {
|
|
76
|
-
return new Promise((resolve) => {
|
|
77
|
-
if (this.scoundrelClient) {
|
|
78
|
-
resolve(undefined);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
this.events.once("scoundrelStarted", () => {
|
|
82
|
-
resolve(undefined);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
getScoundrel() {
|
|
88
|
-
if (!this.scoundrelClient) {
|
|
89
|
-
throw new Error("Scoundrel client is not started yet");
|
|
90
|
-
}
|
|
91
|
-
return this.scoundrelClient;
|
|
92
|
-
}
|
|
93
|
-
connectOnError() {
|
|
94
|
-
window.addEventListener("error", (event) => {
|
|
95
|
-
this.handleError({
|
|
96
|
-
type: "error",
|
|
97
|
-
error: event.error,
|
|
98
|
-
errorClass: event.error?.name,
|
|
99
|
-
file: event.filename,
|
|
100
|
-
line: event.lineno,
|
|
101
|
-
message: event.message || "Unknown error",
|
|
102
|
-
url: window.location.href
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
connectUnhandledRejection() {
|
|
107
|
-
window.addEventListener("unhandledrejection", (event) => {
|
|
108
|
-
this.handleError({
|
|
109
|
-
type: "unhandledrejection",
|
|
110
|
-
error: event.reason,
|
|
111
|
-
errorClass: "UnhandledRejection",
|
|
112
|
-
message: event.reason.message || event.reason || "Unhandled promise rejection without a message",
|
|
113
|
-
url: window.location.href
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* @param {object} data
|
|
119
|
-
* @param {string} [data.backtrace]
|
|
120
|
-
* @param {Error} [data.error]
|
|
121
|
-
* @param {string} [data.errorClass]
|
|
122
|
-
* @param {string} [data.file]
|
|
123
|
-
* @param {number} [data.line]
|
|
124
|
-
* @param {string} [data.message]
|
|
125
|
-
* @param {string} [data.type]
|
|
126
|
-
* @param {string} [data.url]
|
|
127
|
-
* @returns {void}
|
|
128
|
-
*/
|
|
129
|
-
handleError(data) {
|
|
130
|
-
let backtrace;
|
|
131
|
-
if (data.error && data.error.stack) {
|
|
132
|
-
backtrace = data.error.stack.split("\n");
|
|
133
|
-
backtrace.shift();
|
|
134
|
-
backtrace = backtrace.join("\n");
|
|
135
|
-
}
|
|
136
|
-
else if (data.file) {
|
|
137
|
-
backtrace = `${data.file}:${data.line}`;
|
|
138
|
-
}
|
|
139
|
-
data.backtrace = backtrace;
|
|
140
|
-
this.communicator.sendCommand(data);
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* @returns {void}
|
|
144
|
-
*/
|
|
145
|
-
connectWebSocket() {
|
|
146
|
-
this.ws = new WebSocket("ws://localhost:1985");
|
|
147
|
-
this.communicator.ws = this.ws;
|
|
148
|
-
this.ws.addEventListener("error", digg(this, "communicator", "onError"));
|
|
149
|
-
this.ws.addEventListener("open", digg(this, "communicator", "onOpen"));
|
|
150
|
-
this.ws.addEventListener("message", (event) => this.communicator.onMessage(event.data));
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* @returns {void}
|
|
154
|
-
*/
|
|
155
|
-
enableOnBrowser() {
|
|
156
|
-
this._enabled = true;
|
|
157
|
-
this.connectWebSocket();
|
|
158
|
-
this.connectOnError();
|
|
159
|
-
this.connectUnhandledRejection();
|
|
160
|
-
this.overrideConsoleLog();
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* @returns {boolean}
|
|
164
|
-
*/
|
|
165
|
-
getEnabled() { return this._enabled; }
|
|
166
|
-
/**
|
|
167
|
-
* @returns {EventEmitter}
|
|
168
|
-
*/
|
|
169
|
-
getEvents() { return this.events; }
|
|
170
|
-
/**
|
|
171
|
-
* @param {any} arg
|
|
172
|
-
* @param {any[]} [scannedObjects]
|
|
173
|
-
* @returns {any}
|
|
174
|
-
*/
|
|
175
|
-
consoleLogMessage(arg, scannedObjects = []) {
|
|
176
|
-
if (Array.isArray(arg)) {
|
|
177
|
-
if (scannedObjects.includes(arg)) {
|
|
178
|
-
return "[recursive]";
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
scannedObjects.push(arg);
|
|
182
|
-
}
|
|
183
|
-
const result = [];
|
|
184
|
-
for (const value of arg) {
|
|
185
|
-
result.push(this.consoleLogMessage(value, scannedObjects));
|
|
186
|
-
}
|
|
187
|
-
return result;
|
|
188
|
-
}
|
|
189
|
-
else if (Object.prototype.toString.call(arg) === '[object Object]') {
|
|
190
|
-
if (scannedObjects.includes(arg)) {
|
|
191
|
-
return "[recursive]";
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
scannedObjects.push(arg);
|
|
195
|
-
}
|
|
196
|
-
/** @type {Record<string, any>} */
|
|
197
|
-
const result = {};
|
|
198
|
-
for (const key in arg) {
|
|
199
|
-
result[key] = this.consoleLogMessage(arg[key], scannedObjects);
|
|
200
|
-
}
|
|
201
|
-
return result;
|
|
202
|
-
}
|
|
203
|
-
else if (typeof arg == "object") {
|
|
204
|
-
return `[object ${arg?.constructor?.name}]`;
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
return arg;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* @param {function() : void} callback
|
|
212
|
-
* @returns {void}
|
|
213
|
-
*/
|
|
214
|
-
onInitialize(callback) {
|
|
215
|
-
this._onInitializeCallback = callback;
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* @returns {void}
|
|
219
|
-
*/
|
|
220
|
-
overrideConsoleLog() {
|
|
221
|
-
if (this.originalConsoleError || this.originalConsoleLog) {
|
|
222
|
-
throw new Error("Console methods has already been overridden!");
|
|
223
|
-
}
|
|
224
|
-
this.originalConsoleError = console.error;
|
|
225
|
-
this.originalConsoleLog = console.log;
|
|
226
|
-
console.error = this.fakeConsoleError;
|
|
227
|
-
console.log = this.fakeConsoleLog;
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* @param {string} sql
|
|
231
|
-
* @returns {Promise<Array<Record<string, any>>>}
|
|
232
|
-
*/
|
|
233
|
-
async sendQuery(sql) {
|
|
234
|
-
// @ts-expect-error
|
|
235
|
-
return await this.communicator.sendCommand({ type: "query", sql });
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
//# sourceMappingURL=system-test-browser-helper.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"system-test-browser-helper.js","sourceRoot":"","sources":["../src/system-test-browser-helper.js"],"names":[],"mappings":"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"}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
export default class SystemTestCommunicator {
|
|
3
|
-
/**
|
|
4
|
-
* @param {object} args
|
|
5
|
-
* @param {(args: Record<string, any>) => Promise<{result: string} | void>} args.onCommand
|
|
6
|
-
* @param {object} [args.parent]
|
|
7
|
-
*/
|
|
8
|
-
constructor({ onCommand, parent }) {
|
|
9
|
-
/** @type {Record<string, {resolve: (data: any) => void, reject: (data: any) => void}>} */
|
|
10
|
-
this._responses = {};
|
|
11
|
-
/** @type {Record<string, any>} */
|
|
12
|
-
this._sendQueue = [];
|
|
13
|
-
this._sendQueueCount = 0;
|
|
14
|
-
/** @type {WebSocket | null} */
|
|
15
|
-
this.ws = null;
|
|
16
|
-
/** @param {Error} error */
|
|
17
|
-
this.onError = (error) => {
|
|
18
|
-
console.error("onWebSocketClientError", error);
|
|
19
|
-
};
|
|
20
|
-
/** @param {string} rawData */
|
|
21
|
-
this.onMessage = async (rawData) => {
|
|
22
|
-
/** @type {{data: any, id: number, type: string, isTrusted?: boolean}} */
|
|
23
|
-
const data = JSON.parse(rawData);
|
|
24
|
-
if (data.isTrusted) {
|
|
25
|
-
// Ignore
|
|
26
|
-
}
|
|
27
|
-
else if (data.type == "command") {
|
|
28
|
-
try {
|
|
29
|
-
const result = await this.onCommand({ data: data.data });
|
|
30
|
-
this.respond(data.id, { result });
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
if (error instanceof Error) {
|
|
34
|
-
this.respond(data.id, { error: error.message });
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
this.respond(data.id, { error: error });
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
else if (data.type == "response") {
|
|
42
|
-
const response = this._responses[data.id];
|
|
43
|
-
if (!response) {
|
|
44
|
-
throw new Error(`No such response: ${data.id}`);
|
|
45
|
-
}
|
|
46
|
-
delete this._responses[data.id];
|
|
47
|
-
if (data.data.error) {
|
|
48
|
-
response.reject(data.data.error);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
response.resolve(data.data.result);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
throw new Error(`Unknown type for SystemTestCommunicator: ${data.type}: ${JSON.stringify(data)}`);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
this.onOpen = () => {
|
|
59
|
-
this.flushSendQueue();
|
|
60
|
-
};
|
|
61
|
-
this.onCommand = onCommand;
|
|
62
|
-
this.parent = parent;
|
|
63
|
-
}
|
|
64
|
-
flushSendQueue() {
|
|
65
|
-
while (this._sendQueue.length !== 0) {
|
|
66
|
-
const data = this._sendQueue.shift();
|
|
67
|
-
if (!this.ws || this.ws.readyState !== 1) {
|
|
68
|
-
throw new Error("WebSocket is not open");
|
|
69
|
-
}
|
|
70
|
-
this.ws.send(JSON.stringify(data));
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* @param {Record<string, any>} data
|
|
75
|
-
* @returns {void}
|
|
76
|
-
*/
|
|
77
|
-
send(data) {
|
|
78
|
-
this._sendQueue.push(data);
|
|
79
|
-
if (this.ws.readyState == 1) {
|
|
80
|
-
this.flushSendQueue();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Sends a command and returns a promise that resolves with the response.
|
|
85
|
-
* @param {Record<string, any>} data - The command data to send.
|
|
86
|
-
* @returns {Promise<void>} A promise that resolves with the response data.
|
|
87
|
-
*/
|
|
88
|
-
sendCommand(data) {
|
|
89
|
-
return new Promise((resolve, reject) => {
|
|
90
|
-
const id = this._sendQueueCount;
|
|
91
|
-
this._sendQueueCount += 1;
|
|
92
|
-
this._responses[id] = { resolve, reject };
|
|
93
|
-
this.send({ type: "command", id, data });
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* @param {number} id
|
|
98
|
-
* @param {Record<string, any>} data
|
|
99
|
-
* @returns {void}
|
|
100
|
-
*/
|
|
101
|
-
respond(id, data) {
|
|
102
|
-
this.send({ type: "response", id, data });
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
//# sourceMappingURL=system-test-communicator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"system-test-communicator.js","sourceRoot":"","sources":["../src/system-test-communicator.js"],"names":[],"mappings":"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"}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
|
-
import http from "node:http";
|
|
4
|
-
import mime from "mime";
|
|
5
|
-
import url from "url";
|
|
6
|
-
export default class SystemTestHttpServer {
|
|
7
|
-
constructor() {
|
|
8
|
-
/**
|
|
9
|
-
* @param {http.IncomingMessage} request
|
|
10
|
-
* @param {http.ServerResponse} response
|
|
11
|
-
* @returns {Promise<void>}
|
|
12
|
-
*/
|
|
13
|
-
this.onHttpServerRequest = async (request, response) => {
|
|
14
|
-
if (!request.url) {
|
|
15
|
-
response.statusCode = 400;
|
|
16
|
-
response.end("Bad Request");
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
const parsedUrl = url.parse(request.url);
|
|
20
|
-
let filePath = `${process.cwd()}/dist${parsedUrl.pathname}`;
|
|
21
|
-
if (filePath.endsWith("/")) {
|
|
22
|
-
filePath += "index.html";
|
|
23
|
-
}
|
|
24
|
-
let fileExists;
|
|
25
|
-
try {
|
|
26
|
-
await fs.stat(filePath);
|
|
27
|
-
fileExists = true;
|
|
28
|
-
}
|
|
29
|
-
catch (_error) { // eslint-disable-line no-unused-vars
|
|
30
|
-
fileExists = false;
|
|
31
|
-
}
|
|
32
|
-
if (!fileExists) {
|
|
33
|
-
filePath = `${process.cwd()}/dist/index.html`;
|
|
34
|
-
}
|
|
35
|
-
const fileContent = await fs.readFile(filePath);
|
|
36
|
-
const mimeType = mime.getType(filePath);
|
|
37
|
-
response.statusCode = 200;
|
|
38
|
-
if (mimeType) {
|
|
39
|
-
response.setHeader("Content-Type", mimeType);
|
|
40
|
-
}
|
|
41
|
-
response.end(fileContent);
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
/** @returns {void} */
|
|
45
|
-
close() {
|
|
46
|
-
if (!this.httpServer) {
|
|
47
|
-
throw new Error("HTTP server is not initialized");
|
|
48
|
-
}
|
|
49
|
-
this.httpServer.close();
|
|
50
|
-
}
|
|
51
|
-
/** @returns {Promise<void>} */
|
|
52
|
-
async start() {
|
|
53
|
-
this.basePath = await fs.realpath(`${__dirname}/../..`);
|
|
54
|
-
await this.startHttpServer();
|
|
55
|
-
}
|
|
56
|
-
/** @returns {Promise<void>} */
|
|
57
|
-
startHttpServer() {
|
|
58
|
-
return new Promise((resolve) => {
|
|
59
|
-
this.httpServer = http.createServer(this.onHttpServerRequest);
|
|
60
|
-
this.httpServer.listen(1984, "localhost", () => {
|
|
61
|
-
resolve();
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
//# sourceMappingURL=system-test-http-server.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"system-test-http-server.js","sourceRoot":"","sources":["../src/system-test-http-server.js"],"names":[],"mappings":"AAAA,YAAY;AAEZ,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,MAAM,CAAC,OAAO,OAAO,oBAAoB;IAAzC;QAUE;;;;WAIG;QACH,wBAAmB,GAAG,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;YAChD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBACjB,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAA;gBACzB,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;gBAC3B,OAAM;YACR,CAAC;YAED,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YACxC,IAAI,QAAQ,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,SAAS,CAAC,QAAQ,EAAE,CAAA;YAE3D,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3B,QAAQ,IAAI,YAAY,CAAA;YAC1B,CAAC;YAED,IAAI,UAAU,CAAA;YAEd,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;gBACvB,UAAU,GAAG,IAAI,CAAA;YACnB,CAAC;YAAC,OAAO,MAAM,EAAE,CAAC,CAAC,qCAAqC;gBACtD,UAAU,GAAG,KAAK,CAAA;YACpB,CAAC;YAED,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,QAAQ,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAA;YAC/C,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;YAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;YAEvC,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAA;YAEzB,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;YAC9C,CAAC;YAED,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAC3B,CAAC,CAAA;IAiBH,CAAC;IApEC,sBAAsB;IACtB,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACnD,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAA;IACzB,CAAC;IA8CD,+BAA+B;IAC/B,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAA;QACvD,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;IAC9B,CAAC;IAED,+BAA+B;IAC/B,eAAe;QACb,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;YAC7D,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;gBAC7C,OAAO,EAAE,CAAA;YACX,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;CACF"}
|