system-testing 1.0.32 → 1.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/system-test-browser-helper.d.ts +106 -0
- package/dist/system-test-browser-helper.js +237 -0
- package/dist/system-test-browser-helper.js.map +1 -0
- package/dist/system-test-communicator.d.ts +50 -0
- package/dist/system-test-communicator.js +105 -0
- package/dist/system-test-communicator.js.map +1 -0
- package/dist/system-test-http-server.d.ts +17 -0
- package/dist/system-test-http-server.js +66 -0
- package/dist/system-test-http-server.js.map +1 -0
- package/dist/system-test.d.ts +297 -0
- package/dist/system-test.js +705 -0
- package/dist/system-test.js.map +1 -0
- package/dist/use-system-test.d.ts +13 -0
- package/dist/use-system-test.js +79 -0
- package/dist/use-system-test.js.map +1 -0
- package/package.json +8 -4
- package/.github/dependabot.yml +0 -9
- package/eslint.config.js +0 -23
- package/peak_flow.yml +0 -5
- package/src/system-test-browser-helper.js +0 -269
- package/src/system-test-communicator.js +0 -120
- package/src/system-test-http-server.js +0 -77
- package/src/system-test.js +0 -790
- package/src/use-system-test.js +0 -94
- package/tsconfig.json +0 -15
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const stub: "Hello world";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export default class SystemTestBrowserHelper {
|
|
2
|
+
static current(): SystemTestBrowserHelper;
|
|
3
|
+
communicator: SystemTestCommunicator;
|
|
4
|
+
_enabled: boolean;
|
|
5
|
+
events: EventEmitter<any>;
|
|
6
|
+
startScoundrel(): Promise<void>;
|
|
7
|
+
scoundrelWs: WebSocket;
|
|
8
|
+
scoundrelClientWebSocket: any;
|
|
9
|
+
scoundrelClient: any;
|
|
10
|
+
waitForScoundrelStarted(): Promise<any>;
|
|
11
|
+
getScoundrel(): any;
|
|
12
|
+
connectOnError(): void;
|
|
13
|
+
connectUnhandledRejection(): void;
|
|
14
|
+
/**
|
|
15
|
+
* @param {object} data
|
|
16
|
+
* @param {string} [data.backtrace]
|
|
17
|
+
* @param {Error} [data.error]
|
|
18
|
+
* @param {string} [data.errorClass]
|
|
19
|
+
* @param {string} [data.file]
|
|
20
|
+
* @param {number} [data.line]
|
|
21
|
+
* @param {string} [data.message]
|
|
22
|
+
* @param {string} [data.type]
|
|
23
|
+
* @param {string} [data.url]
|
|
24
|
+
* @returns {void}
|
|
25
|
+
*/
|
|
26
|
+
handleError(data: {
|
|
27
|
+
backtrace?: string;
|
|
28
|
+
error?: Error;
|
|
29
|
+
errorClass?: string;
|
|
30
|
+
file?: string;
|
|
31
|
+
line?: number;
|
|
32
|
+
message?: string;
|
|
33
|
+
type?: string;
|
|
34
|
+
url?: string;
|
|
35
|
+
}): void;
|
|
36
|
+
/**
|
|
37
|
+
* @returns {void}
|
|
38
|
+
*/
|
|
39
|
+
connectWebSocket(): void;
|
|
40
|
+
ws: WebSocket;
|
|
41
|
+
/**
|
|
42
|
+
* @returns {void}
|
|
43
|
+
*/
|
|
44
|
+
enableOnBrowser(): void;
|
|
45
|
+
/**
|
|
46
|
+
* @returns {boolean}
|
|
47
|
+
*/
|
|
48
|
+
getEnabled(): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* @returns {EventEmitter}
|
|
51
|
+
*/
|
|
52
|
+
getEvents(): EventEmitter;
|
|
53
|
+
/**
|
|
54
|
+
* @param {any[]} args
|
|
55
|
+
* @returns {void}
|
|
56
|
+
*/
|
|
57
|
+
fakeConsoleError: (...args: any[]) => void;
|
|
58
|
+
/**
|
|
59
|
+
* @param {any[]} args
|
|
60
|
+
* @returns {void}
|
|
61
|
+
*/
|
|
62
|
+
fakeConsoleLog: (...args: any[]) => void;
|
|
63
|
+
/**
|
|
64
|
+
* @param {any} arg
|
|
65
|
+
* @param {any[]} [scannedObjects]
|
|
66
|
+
* @returns {any}
|
|
67
|
+
*/
|
|
68
|
+
consoleLogMessage(arg: any, scannedObjects?: any[]): any;
|
|
69
|
+
/**
|
|
70
|
+
* @param {{data: {path: string, type: string}}} args
|
|
71
|
+
* @returns {Promise<{result: string} | void>}
|
|
72
|
+
*/
|
|
73
|
+
onCommand: ({ data }: {
|
|
74
|
+
data: {
|
|
75
|
+
path: string;
|
|
76
|
+
type: string;
|
|
77
|
+
};
|
|
78
|
+
}) => Promise<{
|
|
79
|
+
result: string;
|
|
80
|
+
} | void>;
|
|
81
|
+
/**
|
|
82
|
+
* @param {function() : void} callback
|
|
83
|
+
* @returns {void}
|
|
84
|
+
*/
|
|
85
|
+
onInitialize(callback: () => void): void;
|
|
86
|
+
_onInitializeCallback: () => void;
|
|
87
|
+
/**
|
|
88
|
+
* @returns {void}
|
|
89
|
+
*/
|
|
90
|
+
overrideConsoleLog(): void;
|
|
91
|
+
originalConsoleError: {
|
|
92
|
+
(...data: any[]): void;
|
|
93
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
94
|
+
};
|
|
95
|
+
originalConsoleLog: {
|
|
96
|
+
(...data: any[]): void;
|
|
97
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* @param {string} sql
|
|
101
|
+
* @returns {Promise<Array<Record<string, any>>>}
|
|
102
|
+
*/
|
|
103
|
+
sendQuery(sql: string): Promise<Array<Record<string, any>>>;
|
|
104
|
+
}
|
|
105
|
+
import SystemTestCommunicator from "./system-test-communicator.js";
|
|
106
|
+
import EventEmitter from "events";
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import Client from "scoundrel-remote-eval/src/client/index.js";
|
|
3
|
+
import ClientWebSocket from "scoundrel-remote-eval/src/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
|
+
this.scoundrelClientWebSocket = new ClientWebSocket(this.scoundrelWs);
|
|
70
|
+
await this.scoundrelClientWebSocket.waitForOpened();
|
|
71
|
+
this.scoundrelClient = new Client(this.scoundrelClientWebSocket);
|
|
72
|
+
this.events.emit("scoundrelStarted");
|
|
73
|
+
}
|
|
74
|
+
waitForScoundrelStarted() {
|
|
75
|
+
return new Promise((resolve) => {
|
|
76
|
+
if (this.scoundrelClient) {
|
|
77
|
+
resolve(undefined);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.events.once("scoundrelStarted", () => {
|
|
81
|
+
resolve(undefined);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
getScoundrel() {
|
|
87
|
+
if (!this.scoundrelClient) {
|
|
88
|
+
throw new Error("Scoundrel client is not started yet");
|
|
89
|
+
}
|
|
90
|
+
return this.scoundrelClient;
|
|
91
|
+
}
|
|
92
|
+
connectOnError() {
|
|
93
|
+
window.addEventListener("error", (event) => {
|
|
94
|
+
this.handleError({
|
|
95
|
+
type: "error",
|
|
96
|
+
error: event.error,
|
|
97
|
+
errorClass: event.error?.name,
|
|
98
|
+
file: event.filename,
|
|
99
|
+
line: event.lineno,
|
|
100
|
+
message: event.message || "Unknown error",
|
|
101
|
+
url: window.location.href
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
connectUnhandledRejection() {
|
|
106
|
+
window.addEventListener("unhandledrejection", (event) => {
|
|
107
|
+
this.handleError({
|
|
108
|
+
type: "unhandledrejection",
|
|
109
|
+
error: event.reason,
|
|
110
|
+
errorClass: "UnhandledRejection",
|
|
111
|
+
message: event.reason.message || event.reason || "Unhandled promise rejection without a message",
|
|
112
|
+
url: window.location.href
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* @param {object} data
|
|
118
|
+
* @param {string} [data.backtrace]
|
|
119
|
+
* @param {Error} [data.error]
|
|
120
|
+
* @param {string} [data.errorClass]
|
|
121
|
+
* @param {string} [data.file]
|
|
122
|
+
* @param {number} [data.line]
|
|
123
|
+
* @param {string} [data.message]
|
|
124
|
+
* @param {string} [data.type]
|
|
125
|
+
* @param {string} [data.url]
|
|
126
|
+
* @returns {void}
|
|
127
|
+
*/
|
|
128
|
+
handleError(data) {
|
|
129
|
+
let backtrace;
|
|
130
|
+
if (data.error && data.error.stack) {
|
|
131
|
+
backtrace = data.error.stack.split("\n");
|
|
132
|
+
backtrace.shift();
|
|
133
|
+
backtrace = backtrace.join("\n");
|
|
134
|
+
}
|
|
135
|
+
else if (data.file) {
|
|
136
|
+
backtrace = `${data.file}:${data.line}`;
|
|
137
|
+
}
|
|
138
|
+
data.backtrace = backtrace;
|
|
139
|
+
this.communicator.sendCommand(data);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* @returns {void}
|
|
143
|
+
*/
|
|
144
|
+
connectWebSocket() {
|
|
145
|
+
this.ws = new WebSocket("ws://localhost:1985");
|
|
146
|
+
this.communicator.ws = this.ws;
|
|
147
|
+
this.ws.addEventListener("error", digg(this, "communicator", "onError"));
|
|
148
|
+
this.ws.addEventListener("open", digg(this, "communicator", "onOpen"));
|
|
149
|
+
this.ws.addEventListener("message", (event) => this.communicator.onMessage(event.data));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* @returns {void}
|
|
153
|
+
*/
|
|
154
|
+
enableOnBrowser() {
|
|
155
|
+
this._enabled = true;
|
|
156
|
+
this.connectWebSocket();
|
|
157
|
+
this.connectOnError();
|
|
158
|
+
this.connectUnhandledRejection();
|
|
159
|
+
this.overrideConsoleLog();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* @returns {boolean}
|
|
163
|
+
*/
|
|
164
|
+
getEnabled() { return this._enabled; }
|
|
165
|
+
/**
|
|
166
|
+
* @returns {EventEmitter}
|
|
167
|
+
*/
|
|
168
|
+
getEvents() { return this.events; }
|
|
169
|
+
/**
|
|
170
|
+
* @param {any} arg
|
|
171
|
+
* @param {any[]} [scannedObjects]
|
|
172
|
+
* @returns {any}
|
|
173
|
+
*/
|
|
174
|
+
consoleLogMessage(arg, scannedObjects = []) {
|
|
175
|
+
if (Array.isArray(arg)) {
|
|
176
|
+
if (scannedObjects.includes(arg)) {
|
|
177
|
+
return "[recursive]";
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
scannedObjects.push(arg);
|
|
181
|
+
}
|
|
182
|
+
const result = [];
|
|
183
|
+
for (const value of arg) {
|
|
184
|
+
result.push(this.consoleLogMessage(value, scannedObjects));
|
|
185
|
+
}
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
else if (Object.prototype.toString.call(arg) === '[object Object]') {
|
|
189
|
+
if (scannedObjects.includes(arg)) {
|
|
190
|
+
return "[recursive]";
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
scannedObjects.push(arg);
|
|
194
|
+
}
|
|
195
|
+
/** @type {Record<string, any>} */
|
|
196
|
+
const result = {};
|
|
197
|
+
for (const key in arg) {
|
|
198
|
+
result[key] = this.consoleLogMessage(arg[key], scannedObjects);
|
|
199
|
+
}
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
else if (typeof arg == "object") {
|
|
203
|
+
return `[object ${arg?.constructor?.name}]`;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
return arg;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* @param {function() : void} callback
|
|
211
|
+
* @returns {void}
|
|
212
|
+
*/
|
|
213
|
+
onInitialize(callback) {
|
|
214
|
+
this._onInitializeCallback = callback;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* @returns {void}
|
|
218
|
+
*/
|
|
219
|
+
overrideConsoleLog() {
|
|
220
|
+
if (this.originalConsoleError || this.originalConsoleLog) {
|
|
221
|
+
throw new Error("Console methods has already been overridden!");
|
|
222
|
+
}
|
|
223
|
+
this.originalConsoleError = console.error;
|
|
224
|
+
this.originalConsoleLog = console.log;
|
|
225
|
+
console.error = this.fakeConsoleError;
|
|
226
|
+
console.log = this.fakeConsoleLog;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* @param {string} sql
|
|
230
|
+
* @returns {Promise<Array<Record<string, any>>>}
|
|
231
|
+
*/
|
|
232
|
+
async sendQuery(sql) {
|
|
233
|
+
// @ts-expect-error
|
|
234
|
+
return await this.communicator.sendCommand({ type: "query", sql });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=system-test-browser-helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-test-browser-helper.js","sourceRoot":"","sources":["../src/system-test-browser-helper.js"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export default class SystemTestCommunicator {
|
|
2
|
+
/**
|
|
3
|
+
* @param {object} args
|
|
4
|
+
* @param {(args: Record<string, any>) => Promise<{result: string} | void>} args.onCommand
|
|
5
|
+
* @param {object} [args.parent]
|
|
6
|
+
*/
|
|
7
|
+
constructor({ onCommand, parent }: {
|
|
8
|
+
onCommand: (args: Record<string, any>) => Promise<{
|
|
9
|
+
result: string;
|
|
10
|
+
} | void>;
|
|
11
|
+
parent?: object;
|
|
12
|
+
});
|
|
13
|
+
/** @type {Record<string, {resolve: (data: any) => void, reject: (data: any) => void}>} */
|
|
14
|
+
_responses: Record<string, {
|
|
15
|
+
resolve: (data: any) => void;
|
|
16
|
+
reject: (data: any) => void;
|
|
17
|
+
}>;
|
|
18
|
+
/** @type {Record<string, any>} */
|
|
19
|
+
_sendQueue: Record<string, any>;
|
|
20
|
+
_sendQueueCount: number;
|
|
21
|
+
/** @type {WebSocket | null} */
|
|
22
|
+
ws: WebSocket | null;
|
|
23
|
+
onCommand: (args: Record<string, any>) => Promise<{
|
|
24
|
+
result: string;
|
|
25
|
+
} | void>;
|
|
26
|
+
parent: any;
|
|
27
|
+
flushSendQueue(): void;
|
|
28
|
+
/** @param {Error} error */
|
|
29
|
+
onError: (error: Error) => void;
|
|
30
|
+
/** @param {string} rawData */
|
|
31
|
+
onMessage: (rawData: string) => Promise<void>;
|
|
32
|
+
onOpen: () => void;
|
|
33
|
+
/**
|
|
34
|
+
* @param {Record<string, any>} data
|
|
35
|
+
* @returns {void}
|
|
36
|
+
*/
|
|
37
|
+
send(data: Record<string, any>): void;
|
|
38
|
+
/**
|
|
39
|
+
* Sends a command and returns a promise that resolves with the response.
|
|
40
|
+
* @param {Record<string, any>} data - The command data to send.
|
|
41
|
+
* @returns {Promise<void>} A promise that resolves with the response data.
|
|
42
|
+
*/
|
|
43
|
+
sendCommand(data: Record<string, any>): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* @param {number} id
|
|
46
|
+
* @param {Record<string, any>} data
|
|
47
|
+
* @returns {void}
|
|
48
|
+
*/
|
|
49
|
+
respond(id: number, data: Record<string, any>): void;
|
|
50
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-test-communicator.js","sourceRoot":"","sources":["../src/system-test-communicator.js"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export default class SystemTestHttpServer {
|
|
2
|
+
/** @returns {void} */
|
|
3
|
+
close(): void;
|
|
4
|
+
/**
|
|
5
|
+
* @param {http.IncomingMessage} request
|
|
6
|
+
* @param {http.ServerResponse} response
|
|
7
|
+
* @returns {Promise<void>}
|
|
8
|
+
*/
|
|
9
|
+
onHttpServerRequest: (request: http.IncomingMessage, response: http.ServerResponse) => Promise<void>;
|
|
10
|
+
/** @returns {Promise<void>} */
|
|
11
|
+
start(): Promise<void>;
|
|
12
|
+
basePath: string;
|
|
13
|
+
/** @returns {Promise<void>} */
|
|
14
|
+
startHttpServer(): Promise<void>;
|
|
15
|
+
httpServer: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
|
|
16
|
+
}
|
|
17
|
+
import http from "node:http";
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|