@react-native-harness/bridge 1.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +7 -0
- package/dist/client.d.ts +9 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +28 -0
- package/dist/events.d.ts +45 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/server.d.ts +18 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +64 -0
- package/dist/shared/test-collector.d.ts +35 -0
- package/dist/shared/test-collector.d.ts.map +1 -0
- package/dist/shared/test-collector.js +1 -0
- package/dist/shared/test-runner.d.ts +59 -0
- package/dist/shared/test-runner.d.ts.map +1 -0
- package/dist/shared/test-runner.js +1 -0
- package/dist/shared.d.ts +24 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/eslint.config.mjs +19 -0
- package/package.json +39 -0
- package/src/client.ts +46 -0
- package/src/index.ts +1 -0
- package/src/server.ts +107 -0
- package/src/shared/test-collector.ts +43 -0
- package/src/shared/test-runner.ts +74 -0
- package/src/shared.ts +54 -0
- package/tsconfig.json +10 -0
- package/tsconfig.lib.json +19 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Callstack
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/README.md
ADDED
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BirpcReturn } from 'birpc';
|
|
2
|
+
import type { BridgeClientFunctions, BridgeServerFunctions } from './shared.js';
|
|
3
|
+
export type BridgeClient = {
|
|
4
|
+
rpc: BirpcReturn<BridgeServerFunctions, BridgeClientFunctions>;
|
|
5
|
+
disconnect: () => void;
|
|
6
|
+
};
|
|
7
|
+
declare const getBridgeClient: (url: string, handlers: BridgeClientFunctions) => Promise<BridgeClient>;
|
|
8
|
+
export { getBridgeClient };
|
|
9
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAe,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEhF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,WAAW,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,CAAC;IAC/D,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAEF,QAAA,MAAM,eAAe,GACnB,KAAK,MAAM,EACX,UAAU,qBAAqB,KAC9B,OAAO,CAAC,YAAY,CA+BtB,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { WebSocket } from 'partysocket';
|
|
2
|
+
import { createBirpc } from 'birpc';
|
|
3
|
+
const getBridgeClient = async (url, handlers) => {
|
|
4
|
+
return new Promise((resolve) => {
|
|
5
|
+
const ws = new WebSocket(url);
|
|
6
|
+
const handleOpen = () => {
|
|
7
|
+
const rpc = createBirpc(handlers, {
|
|
8
|
+
post: (data) => ws.send(data),
|
|
9
|
+
on: (handler) => {
|
|
10
|
+
ws.addEventListener('message', (event) => {
|
|
11
|
+
handler(event.data);
|
|
12
|
+
});
|
|
13
|
+
},
|
|
14
|
+
serialize: JSON.stringify,
|
|
15
|
+
deserialize: JSON.parse,
|
|
16
|
+
});
|
|
17
|
+
const client = {
|
|
18
|
+
rpc,
|
|
19
|
+
disconnect: () => {
|
|
20
|
+
ws.close();
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
resolve(client);
|
|
24
|
+
};
|
|
25
|
+
ws.addEventListener('open', handleOpen, { once: true });
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
export { getBridgeClient };
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type ExecutionStartedEvent = {
|
|
2
|
+
type: 'execution-started';
|
|
3
|
+
path: string;
|
|
4
|
+
numberOfTests: number;
|
|
5
|
+
};
|
|
6
|
+
export type ExecutionFinishedEvent = {
|
|
7
|
+
type: 'execution-finished';
|
|
8
|
+
path: string;
|
|
9
|
+
duration: number;
|
|
10
|
+
};
|
|
11
|
+
export type SuiteStartedEvent = {
|
|
12
|
+
type: 'suite-started';
|
|
13
|
+
path: string;
|
|
14
|
+
name: string;
|
|
15
|
+
};
|
|
16
|
+
export type SuiteFinishedEvent = {
|
|
17
|
+
type: 'suite-finished';
|
|
18
|
+
path: string;
|
|
19
|
+
name: string;
|
|
20
|
+
duration: number;
|
|
21
|
+
reason: 'passed' | 'failed' | 'skipped' | 'todo';
|
|
22
|
+
};
|
|
23
|
+
export type TestStartedEvent = {
|
|
24
|
+
type: 'test-started';
|
|
25
|
+
path: string;
|
|
26
|
+
suite: string;
|
|
27
|
+
name: string;
|
|
28
|
+
};
|
|
29
|
+
export type TestFinishedEvent = {
|
|
30
|
+
type: 'test-finished';
|
|
31
|
+
path: string;
|
|
32
|
+
suite: string;
|
|
33
|
+
name: string;
|
|
34
|
+
duration: number;
|
|
35
|
+
reason: 'passed' | 'failed' | 'skipped' | 'todo';
|
|
36
|
+
};
|
|
37
|
+
export type BridgeEvents = {
|
|
38
|
+
'execution-started': ExecutionStartedEvent;
|
|
39
|
+
'execution-finished': ExecutionFinishedEvent;
|
|
40
|
+
'suite-started': SuiteStartedEvent;
|
|
41
|
+
'suite-finished': SuiteFinishedEvent;
|
|
42
|
+
'test-started': TestStartedEvent;
|
|
43
|
+
'test-finished': TestFinishedEvent;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,mBAAmB,EAAE,qBAAqB,CAAC;IAC3C,oBAAoB,EAAE,sBAAsB,CAAC;IAC7C,eAAe,EAAE,iBAAiB,CAAC;IACnC,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,cAAc,EAAE,gBAAgB,CAAC;IACjC,eAAe,EAAE,iBAAiB,CAAC;CACpC,CAAC"}
|
package/dist/events.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './shared.js';
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { WebSocketServer } from 'ws';
|
|
2
|
+
import { type BirpcGroup } from 'birpc';
|
|
3
|
+
import type { BridgeServerFunctions, BridgeClientFunctions, DeviceDescriptor, BridgeEventsMap } from './shared.js';
|
|
4
|
+
export type BridgeServerOptions = {
|
|
5
|
+
port: number;
|
|
6
|
+
};
|
|
7
|
+
export type BridgeServerEvents = {
|
|
8
|
+
ready: (device: DeviceDescriptor) => void;
|
|
9
|
+
} & BridgeEventsMap;
|
|
10
|
+
export type BridgeServer = {
|
|
11
|
+
ws: WebSocketServer;
|
|
12
|
+
rpc: BirpcGroup<BridgeClientFunctions, BridgeServerFunctions>;
|
|
13
|
+
on: <T extends keyof BridgeServerEvents>(event: T, listener: BridgeServerEvents[T]) => void;
|
|
14
|
+
once: <T extends keyof BridgeServerEvents>(event: T, listener: BridgeServerEvents[T]) => void;
|
|
15
|
+
off: <T extends keyof BridgeServerEvents>(event: T, listener: BridgeServerEvents[T]) => void;
|
|
16
|
+
};
|
|
17
|
+
export declare const getBridgeServer: ({ port, }: BridgeServerOptions) => Promise<BridgeServer>;
|
|
18
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,CAAC;AACrD,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EAChB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC3C,GAAG,eAAe,CAAC;AAEpB,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,eAAe,CAAC;IACpB,GAAG,EAAE,UAAU,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,CAAC;IAC9D,EAAE,EAAE,CAAC,CAAC,SAAS,MAAM,kBAAkB,EACrC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAC5B,IAAI,CAAC;IACV,IAAI,EAAE,CAAC,CAAC,SAAS,MAAM,kBAAkB,EACvC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAC5B,IAAI,CAAC;IACV,GAAG,EAAE,CAAC,CAAC,SAAS,MAAM,kBAAkB,EACtC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAC5B,IAAI,CAAC;CACX,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,WAEnC,mBAAmB,KAAG,OAAO,CAAC,YAAY,CAoE5C,CAAC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { WebSocketServer } from 'ws';
|
|
2
|
+
import { createBirpcGroup } from 'birpc';
|
|
3
|
+
import { logger } from '@react-native-harness/tools';
|
|
4
|
+
import { EventEmitter } from 'node:events';
|
|
5
|
+
export const getBridgeServer = async ({ port, }) => {
|
|
6
|
+
const wss = await new Promise((resolve) => {
|
|
7
|
+
const server = new WebSocketServer({ port, host: '0.0.0.0' }, () => {
|
|
8
|
+
resolve(server);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
const emitter = new EventEmitter();
|
|
12
|
+
const clients = new Set();
|
|
13
|
+
const group = createBirpcGroup({
|
|
14
|
+
reportReady: (device) => {
|
|
15
|
+
emitter.emit('ready', device);
|
|
16
|
+
},
|
|
17
|
+
emitEvent: (event, data) => {
|
|
18
|
+
emitter.emit(event, data);
|
|
19
|
+
},
|
|
20
|
+
}, []);
|
|
21
|
+
wss.on('connection', (ws) => {
|
|
22
|
+
logger.debug('Client connected to the bridge');
|
|
23
|
+
ws.on('close', () => {
|
|
24
|
+
logger.debug('Client disconnected from the bridge');
|
|
25
|
+
// TODO: Remove channel when connection is closed.
|
|
26
|
+
clients.delete(ws);
|
|
27
|
+
});
|
|
28
|
+
group.updateChannels((channels) => {
|
|
29
|
+
channels.push({
|
|
30
|
+
post: (data) => ws.send(data),
|
|
31
|
+
on: (handler) => {
|
|
32
|
+
ws.on('message', (event) => {
|
|
33
|
+
const message = event.toString();
|
|
34
|
+
handler(message);
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
serialize: (data) => {
|
|
38
|
+
if (data.e) {
|
|
39
|
+
// Serialize error by hand (include message, stack and cause).
|
|
40
|
+
return JSON.stringify({
|
|
41
|
+
...data,
|
|
42
|
+
e: {
|
|
43
|
+
...data.e,
|
|
44
|
+
name: data.e.name,
|
|
45
|
+
message: data.e.message,
|
|
46
|
+
stack: data.e.stack,
|
|
47
|
+
cause: data.e.cause,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return JSON.stringify(data);
|
|
52
|
+
},
|
|
53
|
+
deserialize: JSON.parse,
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
ws: wss,
|
|
59
|
+
rpc: group,
|
|
60
|
+
on: emitter.on.bind(emitter),
|
|
61
|
+
once: emitter.once.bind(emitter),
|
|
62
|
+
off: emitter.off.bind(emitter),
|
|
63
|
+
};
|
|
64
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type TestStatus = 'active' | 'skipped' | 'todo';
|
|
2
|
+
export type TestFn = () => void | Promise<void>;
|
|
3
|
+
export type TestCase = {
|
|
4
|
+
name: string;
|
|
5
|
+
fn: TestFn;
|
|
6
|
+
status: TestStatus;
|
|
7
|
+
};
|
|
8
|
+
export type TestSuite = {
|
|
9
|
+
name: string;
|
|
10
|
+
tests: TestCase[];
|
|
11
|
+
suites: TestSuite[];
|
|
12
|
+
parent?: TestSuite;
|
|
13
|
+
beforeAll: TestFn[];
|
|
14
|
+
afterAll: TestFn[];
|
|
15
|
+
beforeEach: TestFn[];
|
|
16
|
+
afterEach: TestFn[];
|
|
17
|
+
status?: TestStatus;
|
|
18
|
+
_hasFocused?: boolean;
|
|
19
|
+
};
|
|
20
|
+
export type CollectionResult = {
|
|
21
|
+
testSuite: TestSuite;
|
|
22
|
+
/** Number of tests that will actually be executed (excludes skipped and todo tests) */
|
|
23
|
+
totalTests: number;
|
|
24
|
+
};
|
|
25
|
+
export type TestCollectionStartedEvent = {
|
|
26
|
+
type: 'collection-started';
|
|
27
|
+
file: string;
|
|
28
|
+
};
|
|
29
|
+
export type TestCollectionFinishedEvent = {
|
|
30
|
+
type: 'collection-finished';
|
|
31
|
+
file: string;
|
|
32
|
+
duration: number;
|
|
33
|
+
};
|
|
34
|
+
export type TestCollectorEvents = TestCollectionStartedEvent | TestCollectionFinishedEvent;
|
|
35
|
+
//# sourceMappingURL=test-collector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-collector.d.ts","sourceRoot":"","sources":["../../src/shared/test-collector.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAEvD,MAAM,MAAM,MAAM,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhD,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,uFAAuF;IACvF,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC3B,0BAA0B,GAC1B,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type TestResultStatus = 'passed' | 'failed' | 'skipped' | 'todo';
|
|
2
|
+
export type SerializedError = {
|
|
3
|
+
name: string;
|
|
4
|
+
message: string;
|
|
5
|
+
stack?: string;
|
|
6
|
+
};
|
|
7
|
+
export type TestRunnerFileStartedEvent = {
|
|
8
|
+
type: 'file-started';
|
|
9
|
+
file: string;
|
|
10
|
+
};
|
|
11
|
+
export type TestRunnerFileFinishedEvent = {
|
|
12
|
+
type: 'file-finished';
|
|
13
|
+
file: string;
|
|
14
|
+
duration: number;
|
|
15
|
+
};
|
|
16
|
+
export type TestRunnerSuiteStartedEvent = {
|
|
17
|
+
type: 'suite-started';
|
|
18
|
+
name: string;
|
|
19
|
+
file: string;
|
|
20
|
+
};
|
|
21
|
+
export type TestRunnerTestStartedEvent = {
|
|
22
|
+
type: 'test-started';
|
|
23
|
+
name: string;
|
|
24
|
+
suite: string;
|
|
25
|
+
file: string;
|
|
26
|
+
};
|
|
27
|
+
export type TestRunnerTestFinishedEvent = {
|
|
28
|
+
type: 'test-finished';
|
|
29
|
+
name: string;
|
|
30
|
+
suite: string;
|
|
31
|
+
file: string;
|
|
32
|
+
duration: number;
|
|
33
|
+
error?: SerializedError;
|
|
34
|
+
status: TestResultStatus;
|
|
35
|
+
};
|
|
36
|
+
export type TestRunnerSuiteFinishedEvent = {
|
|
37
|
+
type: 'suite-finished';
|
|
38
|
+
name: string;
|
|
39
|
+
file: string;
|
|
40
|
+
duration: number;
|
|
41
|
+
error?: SerializedError;
|
|
42
|
+
status: TestResultStatus;
|
|
43
|
+
};
|
|
44
|
+
export type TestRunnerEvents = TestRunnerFileStartedEvent | TestRunnerFileFinishedEvent | TestRunnerTestStartedEvent | TestRunnerTestFinishedEvent | TestRunnerSuiteStartedEvent | TestRunnerSuiteFinishedEvent;
|
|
45
|
+
export type TestResult = {
|
|
46
|
+
name: string;
|
|
47
|
+
status: TestResultStatus;
|
|
48
|
+
error?: SerializedError;
|
|
49
|
+
duration: number;
|
|
50
|
+
};
|
|
51
|
+
export type TestSuiteResult = {
|
|
52
|
+
name: string;
|
|
53
|
+
tests: TestResult[];
|
|
54
|
+
suites: TestSuiteResult[];
|
|
55
|
+
status: TestResultStatus;
|
|
56
|
+
error?: SerializedError;
|
|
57
|
+
duration: number;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=test-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-runner.d.ts","sourceRoot":"","sources":["../../src/shared/test-runner.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAExE,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GACxB,0BAA0B,GAC1B,2BAA2B,GAC3B,0BAA0B,GAC1B,2BAA2B,GAC3B,2BAA2B,GAC3B,4BAA4B,CAAC;AAEjC,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/shared.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { TestRunnerEvents, TestSuiteResult } from './shared/test-runner.js';
|
|
2
|
+
import type { TestCollectorEvents } from './shared/test-collector.js';
|
|
3
|
+
export type { TestCollectorEvents, TestCollectionStartedEvent, TestCollectionFinishedEvent, TestSuite, TestCase, CollectionResult, } from './shared/test-collector.js';
|
|
4
|
+
export type { TestRunnerEvents, TestRunnerFileStartedEvent, TestRunnerFileFinishedEvent, TestRunnerSuiteStartedEvent, TestRunnerTestStartedEvent, TestRunnerTestFinishedEvent, TestRunnerSuiteFinishedEvent, TestSuiteResult, TestResult, TestResultStatus, SerializedError, } from './shared/test-runner.js';
|
|
5
|
+
export type DeviceDescriptor = {
|
|
6
|
+
platform: 'ios' | 'android';
|
|
7
|
+
manufacturer: string;
|
|
8
|
+
model: string;
|
|
9
|
+
osVersion: string;
|
|
10
|
+
};
|
|
11
|
+
export type BridgeEvents = TestCollectorEvents | TestRunnerEvents;
|
|
12
|
+
export type BridgeEventsMap = {
|
|
13
|
+
[K in BridgeEvents['type']]: (event: Extract<BridgeEvents, {
|
|
14
|
+
type: K;
|
|
15
|
+
}>) => void;
|
|
16
|
+
};
|
|
17
|
+
export type BridgeClientFunctions = {
|
|
18
|
+
runTests: (path: string) => Promise<TestSuiteResult>;
|
|
19
|
+
};
|
|
20
|
+
export type BridgeServerFunctions = {
|
|
21
|
+
reportReady: (device: DeviceDescriptor) => void;
|
|
22
|
+
emitEvent: <TEvent extends BridgeEvents>(event: TEvent['type'], data: TEvent) => void;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAChB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,2BAA2B,EAC3B,SAAS,EACT,QAAQ,EACR,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,gBAAgB,EAChB,0BAA0B,EAC1B,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,gBAAgB,CAAC;AAElE,MAAM,MAAM,eAAe,GAAG;KAC3B,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,GAAG,CAC3B,KAAK,EAAE,OAAO,CAAC,YAAY,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,KACtC,IAAI;CACV,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAChD,SAAS,EAAE,CAAC,MAAM,SAAS,YAAY,EACrC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EACrB,IAAI,EAAE,MAAM,KACT,IAAI,CAAC;CACX,CAAC"}
|
package/dist/shared.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../node_modules/tslib/tslib.d.ts","../../../node_modules/tslib/modules/index.d.ts","../../../node_modules/partysocket/ws.d.ts","../../../node_modules/partysocket/index.d.ts","../../../node_modules/birpc/dist/index.d.ts","../src/shared/test-runner.ts","../src/shared/test-collector.ts","../src/shared.ts","../src/client.ts","../src/index.ts","../../../node_modules/@types/node/assert.d.ts","../../../node_modules/@types/node/assert/strict.d.ts","../../../node_modules/@types/node/globals.d.ts","../../../node_modules/@types/node/async_hooks.d.ts","../../../node_modules/@types/node/buffer.d.ts","../../../node_modules/@types/node/child_process.d.ts","../../../node_modules/@types/node/cluster.d.ts","../../../node_modules/@types/node/console.d.ts","../../../node_modules/@types/node/constants.d.ts","../../../node_modules/@types/node/crypto.d.ts","../../../node_modules/@types/node/dgram.d.ts","../../../node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/@types/node/dns.d.ts","../../../node_modules/@types/node/dns/promises.d.ts","../../../node_modules/@types/node/domain.d.ts","../../../node_modules/@types/node/dom-events.d.ts","../../../node_modules/@types/node/events.d.ts","../../../node_modules/@types/node/fs.d.ts","../../../node_modules/@types/node/fs/promises.d.ts","../../../node_modules/@types/node/http.d.ts","../../../node_modules/@types/node/http2.d.ts","../../../node_modules/@types/node/https.d.ts","../../../node_modules/@types/node/inspector.d.ts","../../../node_modules/@types/node/module.d.ts","../../../node_modules/@types/node/net.d.ts","../../../node_modules/@types/node/os.d.ts","../../../node_modules/@types/node/path.d.ts","../../../node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/@types/node/process.d.ts","../../../node_modules/@types/node/punycode.d.ts","../../../node_modules/@types/node/querystring.d.ts","../../../node_modules/@types/node/readline.d.ts","../../../node_modules/@types/node/readline/promises.d.ts","../../../node_modules/@types/node/repl.d.ts","../../../node_modules/@types/node/stream.d.ts","../../../node_modules/@types/node/stream/promises.d.ts","../../../node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/@types/node/stream/web.d.ts","../../../node_modules/@types/node/string_decoder.d.ts","../../../node_modules/@types/node/test.d.ts","../../../node_modules/@types/node/timers.d.ts","../../../node_modules/@types/node/timers/promises.d.ts","../../../node_modules/@types/node/tls.d.ts","../../../node_modules/@types/node/trace_events.d.ts","../../../node_modules/@types/node/tty.d.ts","../../../node_modules/@types/node/url.d.ts","../../../node_modules/@types/node/util.d.ts","../../../node_modules/@types/node/v8.d.ts","../../../node_modules/@types/node/vm.d.ts","../../../node_modules/@types/node/wasi.d.ts","../../../node_modules/@types/node/worker_threads.d.ts","../../../node_modules/@types/node/zlib.d.ts","../../../node_modules/@types/node/globals.global.d.ts","../../../node_modules/@types/node/index.d.ts","../../../node_modules/@types/ws/index.d.mts","../../tools/dist/abort.d.ts","../../../node_modules/picocolors/types.d.ts","../../../node_modules/picocolors/picocolors.d.ts","../../tools/dist/color.d.ts","../../tools/dist/logger.d.ts","../../../node_modules/@clack/core/dist/index.d.mts","../../../node_modules/@clack/prompts/dist/index.d.mts","../../tools/dist/prompts.d.ts","../../../node_modules/nano-spawn/source/index.d.ts","../../tools/dist/spawn.d.ts","../../tools/dist/react-native.d.ts","../../tools/dist/index.d.ts","../src/server.ts"],"fileIdsList":[[89,92,104],[92,104,118],[58,104],[61,104],[62,67,95,104],[63,74,75,82,92,103,104],[63,64,74,82,104],[65,104],[66,67,75,83,104],[67,92,100,104],[68,70,74,82,104],[69,104],[70,71,104],[74,104],[72,74,104],[74,75,76,92,103,104],[74,75,76,89,92,95,104],[104,108],[104],[70,74,77,82,92,103,104],[74,75,77,78,82,92,100,103,104],[77,79,92,100,103,104],[58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110],[74,80,104],[81,103,104],[70,74,82,92,104],[83,104],[84,104],[61,85,104],[86,102,104,108],[87,104],[88,104],[74,89,90,104],[89,91,104,106],[62,74,92,93,94,95,104],[62,92,94,104],[92,93,104],[95,104],[96,104],[74,98,99,104],[98,99,104],[67,82,92,100,104],[101,104],[82,102,104],[62,77,88,103,104],[67,104],[92,104,105],[104,106],[104,107],[62,67,74,76,85,92,103,104,106,108],[92,104,109],[74,77,79,82,92,100,103,104,109,111],[63,104],[50,104],[104,114],[48,104],[49,51,52,55,104],[49,55,104],[49,52,55,74,104,112,124],[49,53,54,104],[49,104],[104,115],[104,113,116,117,120,122,123],[104,119],[104,121]],"fileInfos":[{"version":"69684132aeb9b5642cbcd9e22dff7818ff0ee1aa831728af0ecf97d3364d5546","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"092c2bfe125ce69dbb1223c85d68d4d2397d7d8411867b5cc03cec902c233763","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6a5253138c5432c68a1510c70fe78a644fe2e632111ba778e1978010d6edfec","impliedFormat":1},{"version":"b8f34dd1757f68e03262b1ca3ddfa668a855b872f8bdd5224d6f993a7b37dc2c","impliedFormat":99},{"version":"269658e7a0ee3ddc32320370f336fc6a51232f42f06e7f703d18aca6aeed8bfc","impliedFormat":1},{"version":"7c2fbbc70bc773f521aa8fa216186f7b73ea0faa4cbff2a88f7385fd4953f461","impliedFormat":1},{"version":"f2ee9c0f4e3e40fa79743b5bad3d085d41cf6854c68687737c00d3f6d0ed7941","impliedFormat":99},{"version":"4457df3f99740d38767d2842cb6df8eb684a129f0cbff5e5f0cfe092993c49c4","signature":"be389ee0d0f5e70329ea4c2fb44b7716e7ceda3680fa0ee32c22329ef8ef7e60","impliedFormat":99},{"version":"c7e2f93c8dc02ea5819fef27dd724c64090276077c56de6fba18ab923b060b80","signature":"402ac3b4c96c5718d18c00339c6e4c66ff0b1a0d8a166570107472342fd57e7a","impliedFormat":99},{"version":"1fc644692defa56153623d6fbdfac66a78e209fb8c4804af1184d163f02784fe","signature":"0df9e64851cbe9801f868551cae57fffd2d4339ac98b4d6ff00aad10a5cd8f33","impliedFormat":99},{"version":"a07f6f12820ee781272ed2752c92fd3d316d8d5f381e365495ebe755fe25214e","signature":"b49462226b8bfbdbc25c8aa2a294d2052e9b273f39a094044492854dd6a7b515","impliedFormat":99},{"version":"a955c49e9dc38915d1a9860dc049a3b5fa46cb4e9b832ebcde89d96d6e68b8e3","impliedFormat":99},{"version":"7e771891adaa85b690266bc37bd6eb43bc57eecc4b54693ead36467e7369952a","impliedFormat":1},{"version":"a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a","impliedFormat":1},{"version":"f749812878fecfa53cfc13b36e5d35086fb6377983a9df44175da83ccc23af1f","affectsGlobalScope":true,"impliedFormat":1},{"version":"7d2e3fea24c712c99c03ad8f556abedbfe105f87f1be10b95dbd409d24bc05a3","impliedFormat":1},{"version":"211e3f15fbced4ab4be19f49ffa990b9ff20d749d33b65ff753be691e7616239","affectsGlobalScope":true,"impliedFormat":1},{"version":"3719525a8f6ab731e3dfd585d9f87df55ec7d50d461df84f74eb4d68bb165244","impliedFormat":1},{"version":"5a94487653355b56018122d92392beb2e5f4a6c63ba5cef83bbe1c99775ef713","impliedFormat":1},{"version":"d5135ad93b33adcce80b18f8065087934cdc1730d63db58562edcf017e1aad9b","affectsGlobalScope":true,"impliedFormat":1},{"version":"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","impliedFormat":1},{"version":"e596c9bb2f29a2699fdd4ae89139612652245192f67f45617c5a4b20832aaae9","impliedFormat":1},{"version":"bb9c4ffa5e6290c6980b63c815cdd1625876dadb2efaf77edbe82984be93e55e","impliedFormat":1},{"version":"1cdcfc1f624d6c08aa12c73935f6e13f095919cd99edf95752951796eb225729","impliedFormat":1},{"version":"4eaff3d8e10676fd7913d8c108890e71c688e1e7d52f6d1d55c39514f493dc47","impliedFormat":1},{"version":"14b5aa23c5d0ae1907bc696ac7b6915d88f7d85799cc0dc2dcf98fbce2c5a67c","impliedFormat":1},{"version":"5c439dafdc09abe4d6c260a96b822fa0ba5be7203c71a63ab1f1423cd9e838ea","impliedFormat":1},{"version":"6b526a5ec4a401ca7c26cfe6a48e641d8f30af76673bad3b06a1b4504594a960","affectsGlobalScope":true,"impliedFormat":1},{"version":"00dee7cdca8b8420c47ea4a31a34b8e8294013ebc4f463fd941e867e7bf05029","affectsGlobalScope":true,"impliedFormat":1},{"version":"3256f3cccd578f9e7fe3a28096c505634bebcee8afb738ffa99368e536ca3a0b","impliedFormat":1},{"version":"1c84b46267610a34028edfd0d035509341751262bac1062857f3c8df7aff7153","impliedFormat":1},{"version":"7f138842074d0a40681775af008c8452093b68c383c94de31759e853c6d06b5c","impliedFormat":1},{"version":"a3d541d303ee505053f5dcbf9fafb65cac3d5631037501cd616195863a6c5740","impliedFormat":1},{"version":"8d3c583a07e0c37e876908c2d5da575019f689df8d9fa4c081d99119d53dba22","impliedFormat":1},{"version":"2c828a5405191d006115ab34e191b8474bc6c86ffdc401d1a9864b1b6e088a58","impliedFormat":1},{"version":"e630e5528e899219ae319e83bef54bf3bcb91b01d76861ecf881e8e614b167f0","affectsGlobalScope":true,"impliedFormat":1},{"version":"bcebb922784739bdb34c18ee51095d25a92b560c78ccd2eaacd6bd00f7443d83","impliedFormat":1},{"version":"7ee6ed878c4528215c82b664fe0cfe80e8b4da6c0d4cc80869367868774db8b1","impliedFormat":1},{"version":"b0973c3cbcdc59b37bf477731d468696ecaf442593ec51bab497a613a580fe30","impliedFormat":1},{"version":"4989e92ba5b69b182d2caaea6295af52b7dc73a4f7a2e336a676722884e7139d","affectsGlobalScope":true,"impliedFormat":1},{"version":"0715e4cd28ad471b2a93f3e552ff51a3ae423417a01a10aa1d3bc7c6b95059d6","affectsGlobalScope":true,"impliedFormat":1},{"version":"5153a2fd150e46ce57bb3f8db1318d33f6ad3261ed70ceeff92281c0608c74a3","impliedFormat":1},{"version":"210d54cd652ec0fec8c8916e4af59bb341065576ecda039842f9ffb2e908507c","impliedFormat":1},{"version":"36b03690b628eab08703d63f04eaa89c5df202e5f1edf3989f13ad389cd2c091","impliedFormat":1},{"version":"0effadd232a20498b11308058e334d3339cc5bf8c4c858393e38d9d4c0013dcf","impliedFormat":1},{"version":"25846d43937c672bab7e8195f3d881f93495df712ee901860effc109918938cc","impliedFormat":1},{"version":"4f3fdeba4e28e21aa719c081b8dc8f91d47e12e773389b9d35679c08151c9d37","impliedFormat":1},{"version":"1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff","impliedFormat":1},{"version":"69ee23dd0d215b09907ad30d23f88b7790c93329d1faf31d7835552a10cf7cbf","impliedFormat":1},{"version":"44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","impliedFormat":1},{"version":"23b89798789dffbd437c0c423f5d02d11f9736aea73d6abf16db4f812ff36eda","impliedFormat":1},{"version":"f69ff39996a61a0dd10f4bce73272b52e8024a4d58b13ab32bf4712909d0a2b7","impliedFormat":1},{"version":"3c4ba1dd9b12ffa284b565063108f2f031d150ea15b8fafbdc17f5d2a07251f3","affectsGlobalScope":true,"impliedFormat":1},{"version":"e10177274a35a9d07c825615340b2fcde2f610f53f3fb40269fd196b4288dda6","impliedFormat":1},{"version":"1422cd9e705adcc09088fda85a900c2b70e3ad36ea85846f68bd1a884cdf4e2b","impliedFormat":1},{"version":"3c13ef48634e7b5012fcf7e8fce7496352c2d779a7201389ca96a2a81ee4314d","impliedFormat":1},{"version":"5d0a25ec910fa36595f85a67ac992d7a53dd4064a1ba6aea1c9f14ab73a023f2","impliedFormat":1},{"version":"a73ae8c0e62103bb9e21bb6538700881bf135b9a8b125b857ec68edfa0da4ed3","affectsGlobalScope":true,"impliedFormat":1},{"version":"e1c1b2fbe236bf7ee3e342eeae7e20efb8988a0ac7da1cbbfa2c1f66b76c3423","affectsGlobalScope":true,"impliedFormat":1},{"version":"868831cab82b65dfe1d68180e898af1f2101e89ba9b754d1db6fb8cc2fac1921","impliedFormat":1},{"version":"0fe8985a28f82c450a04a6edf1279d7181c0893f37da7d2a27f8efd4fd5edb03","impliedFormat":1},{"version":"e59a892d87e72733e2a9ca21611b9beb52977be2696c7ba4b216cbbb9a48f5aa","impliedFormat":1},{"version":"52120bb7e4583612225bdf08e7c12559548170f11e660d33a33623bae9bbdbba","affectsGlobalScope":true,"impliedFormat":1},{"version":"8a300fa9b698845a1f9c41ecbe2c5966634582a8e2020d51abcace9b55aa959e","impliedFormat":1},{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6dd3dba8e665ac43d279e0fdf5219edda0eed69b5e9a5061f46cd6a65c4f7a1","impliedFormat":1},{"version":"316f1486e15cbf7896425f0a16dfe12d447dd57cfb3244b8b119c77df870858f","impliedFormat":99},{"version":"3e442c402123b264ccdf7123c1366e1473d9c39f5db69373e938284fc01c49ce","impliedFormat":99},{"version":"590595c1230ebb7c43ebac51b2b2da956a719b213355b4358e2a6b16a8b5936c","impliedFormat":1},{"version":"8c5f0739f00f89f89b03a1fe6658c6d78000d7ebd7f556f0f8d6908fa679de35","impliedFormat":1},{"version":"a15c0df1ac9b2a4d833490522614fc57ae97d70a07bf4964a4d6bb73f3f56399","impliedFormat":99},{"version":"e4cead4a8596a6f051c36ef184f5fb6f117232eefdc1f98ef9847c9efc2c8911","impliedFormat":99},{"version":"e191585a6a460d89791b3d3d39a10607bbcefa7f7c9812af6ca5f11c33d398d1","impliedFormat":99},{"version":"24379e38ef6db808a7aed9b162dae44d16f84f63c04994efb8b0106bcc589909","impliedFormat":99},{"version":"8af66ec621033f41ccb2bcee775e883c2649fa0db71192fe863185b0281082a6","impliedFormat":99},{"version":"9d4af7bde3e345d3071b5fefbece2d3482971aae89ded50f302c8cb246e81581","impliedFormat":99},{"version":"f3eb748185038bca941a02994b1b0b5803c0a2ce818b8a7d72a24a6b814f5d3e","impliedFormat":99},{"version":"2ba26b5ab00dd3495eeb733cdb46d939a8eb755a395a91169158cdf962aff6c3","impliedFormat":99},{"version":"2e1c22b413f96fd388774b174588816f4bd787486ecfe74f5bcb361dd6bfce50","impliedFormat":99},{"version":"69434e84aa26b9375f0500bcbe84a6bc78f1108cc9866e993e116bc0da2fc5df","signature":"18b54e0f8a18bb6b39598a08fe20f310fe683c6e0421bd1d2cda71faeb36e630","impliedFormat":99}],"root":[[53,57],125],"options":{"composite":true,"declarationMap":true,"emitDeclarationOnly":false,"importHelpers":true,"module":199,"noEmitOnError":true,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noImplicitReturns":true,"noUnusedLocals":true,"outDir":"./","rootDir":"../src","skipLibCheck":true,"strict":true,"target":9,"tsBuildInfoFile":"./tsconfig.lib.tsbuildinfo"},"referencedMap":[[118,1],[119,2],[58,3],[59,3],[61,4],[62,5],[63,6],[64,7],[65,8],[66,9],[67,10],[68,11],[69,12],[70,13],[71,13],[73,14],[72,15],[74,14],[75,16],[76,17],[60,18],[110,19],[77,20],[78,21],[79,22],[111,23],[80,24],[81,25],[82,26],[83,27],[84,28],[85,29],[86,30],[87,31],[88,32],[89,33],[90,33],[91,34],[92,35],[94,36],[93,37],[95,38],[96,39],[97,19],[98,40],[99,41],[100,42],[101,43],[102,44],[103,45],[104,46],[105,47],[106,48],[107,49],[108,50],[109,51],[112,52],[52,19],[121,53],[51,54],[50,19],[115,55],[114,19],[49,56],[48,19],[46,19],[47,19],[8,19],[10,19],[9,19],[2,19],[11,19],[12,19],[13,19],[14,19],[15,19],[16,19],[17,19],[18,19],[3,19],[19,19],[20,19],[4,19],[21,19],[25,19],[22,19],[23,19],[24,19],[26,19],[27,19],[28,19],[5,19],[29,19],[30,19],[31,19],[32,19],[6,19],[36,19],[33,19],[34,19],[35,19],[37,19],[7,19],[38,19],[43,19],[44,19],[39,19],[40,19],[41,19],[42,19],[1,19],[45,19],[56,57],[57,58],[125,59],[55,60],[54,61],[53,61],[113,19],[116,62],[124,63],[117,19],[120,64],[123,19],[122,65]],"latestChangedDtsFile":"./server.d.ts","version":"5.8.3"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import baseConfig from '../../eslint.config.mjs';
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
...baseConfig,
|
|
5
|
+
{
|
|
6
|
+
files: ['**/*.json'],
|
|
7
|
+
rules: {
|
|
8
|
+
'@nx/dependency-checks': [
|
|
9
|
+
'error',
|
|
10
|
+
{
|
|
11
|
+
ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}'],
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
languageOptions: {
|
|
16
|
+
parser: await import('jsonc-eslint-parser'),
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@react-native-harness/bridge",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
"./package.json": "./package.json",
|
|
10
|
+
".": {
|
|
11
|
+
"development": "./src/index.ts",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./client": {
|
|
17
|
+
"development": "./src/client.ts",
|
|
18
|
+
"types": "./dist/client.d.ts",
|
|
19
|
+
"import": "./dist/client.js",
|
|
20
|
+
"default": "./dist/client.js"
|
|
21
|
+
},
|
|
22
|
+
"./server": {
|
|
23
|
+
"development": "./src/server.ts",
|
|
24
|
+
"types": "./dist/server.d.ts",
|
|
25
|
+
"import": "./dist/server.js",
|
|
26
|
+
"default": "./dist/server.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"birpc": "^2.4.0",
|
|
31
|
+
"partysocket": "^1.1.4",
|
|
32
|
+
"tslib": "^2.3.0",
|
|
33
|
+
"ws": "^8.18.2",
|
|
34
|
+
"@react-native-harness/tools": "1.0.0-alpha.1"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/ws": "^8.18.1"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { WebSocket } from 'partysocket';
|
|
2
|
+
import { BirpcReturn, createBirpc } from 'birpc';
|
|
3
|
+
import type { BridgeClientFunctions, BridgeServerFunctions } from './shared.js';
|
|
4
|
+
|
|
5
|
+
export type BridgeClient = {
|
|
6
|
+
rpc: BirpcReturn<BridgeServerFunctions, BridgeClientFunctions>;
|
|
7
|
+
disconnect: () => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const getBridgeClient = async (
|
|
11
|
+
url: string,
|
|
12
|
+
handlers: BridgeClientFunctions
|
|
13
|
+
): Promise<BridgeClient> => {
|
|
14
|
+
return new Promise((resolve) => {
|
|
15
|
+
const ws = new WebSocket(url);
|
|
16
|
+
|
|
17
|
+
const handleOpen = () => {
|
|
18
|
+
const rpc = createBirpc<BridgeServerFunctions, BridgeClientFunctions>(
|
|
19
|
+
handlers,
|
|
20
|
+
{
|
|
21
|
+
post: (data) => ws.send(data),
|
|
22
|
+
on: (handler) => {
|
|
23
|
+
ws.addEventListener('message', (event: any) => {
|
|
24
|
+
handler(event.data);
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
serialize: JSON.stringify,
|
|
28
|
+
deserialize: JSON.parse,
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const client: BridgeClient = {
|
|
33
|
+
rpc,
|
|
34
|
+
disconnect: () => {
|
|
35
|
+
ws.close();
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
resolve(client);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
ws.addEventListener('open', handleOpen, { once: true });
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { getBridgeClient };
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './shared.js';
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { WebSocketServer, type WebSocket } from 'ws';
|
|
2
|
+
import { type BirpcGroup, createBirpcGroup } from 'birpc';
|
|
3
|
+
import { logger } from '@react-native-harness/tools';
|
|
4
|
+
import { EventEmitter } from 'node:events';
|
|
5
|
+
import type {
|
|
6
|
+
BridgeServerFunctions,
|
|
7
|
+
BridgeClientFunctions,
|
|
8
|
+
DeviceDescriptor,
|
|
9
|
+
BridgeEventsMap,
|
|
10
|
+
} from './shared.js';
|
|
11
|
+
|
|
12
|
+
export type BridgeServerOptions = {
|
|
13
|
+
port: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type BridgeServerEvents = {
|
|
17
|
+
ready: (device: DeviceDescriptor) => void;
|
|
18
|
+
} & BridgeEventsMap;
|
|
19
|
+
|
|
20
|
+
export type BridgeServer = {
|
|
21
|
+
ws: WebSocketServer;
|
|
22
|
+
rpc: BirpcGroup<BridgeClientFunctions, BridgeServerFunctions>;
|
|
23
|
+
on: <T extends keyof BridgeServerEvents>(
|
|
24
|
+
event: T,
|
|
25
|
+
listener: BridgeServerEvents[T]
|
|
26
|
+
) => void;
|
|
27
|
+
once: <T extends keyof BridgeServerEvents>(
|
|
28
|
+
event: T,
|
|
29
|
+
listener: BridgeServerEvents[T]
|
|
30
|
+
) => void;
|
|
31
|
+
off: <T extends keyof BridgeServerEvents>(
|
|
32
|
+
event: T,
|
|
33
|
+
listener: BridgeServerEvents[T]
|
|
34
|
+
) => void;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const getBridgeServer = async ({
|
|
38
|
+
port,
|
|
39
|
+
}: BridgeServerOptions): Promise<BridgeServer> => {
|
|
40
|
+
const wss = await new Promise<WebSocketServer>((resolve) => {
|
|
41
|
+
const server = new WebSocketServer({ port, host: '0.0.0.0' }, () => {
|
|
42
|
+
resolve(server);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
const emitter = new EventEmitter();
|
|
46
|
+
const clients = new Set<WebSocket>();
|
|
47
|
+
|
|
48
|
+
const group = createBirpcGroup<BridgeClientFunctions, BridgeServerFunctions>(
|
|
49
|
+
{
|
|
50
|
+
reportReady: (device) => {
|
|
51
|
+
emitter.emit('ready', device);
|
|
52
|
+
},
|
|
53
|
+
emitEvent: (event, data) => {
|
|
54
|
+
emitter.emit(event, data);
|
|
55
|
+
},
|
|
56
|
+
} satisfies BridgeServerFunctions,
|
|
57
|
+
[]
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
wss.on('connection', (ws: WebSocket) => {
|
|
61
|
+
logger.debug('Client connected to the bridge');
|
|
62
|
+
ws.on('close', () => {
|
|
63
|
+
logger.debug('Client disconnected from the bridge');
|
|
64
|
+
|
|
65
|
+
// TODO: Remove channel when connection is closed.
|
|
66
|
+
clients.delete(ws);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
group.updateChannels((channels) => {
|
|
70
|
+
channels.push({
|
|
71
|
+
post: (data) => ws.send(data),
|
|
72
|
+
on: (handler) => {
|
|
73
|
+
ws.on('message', (event: Buffer | ArrayBuffer | Buffer[]) => {
|
|
74
|
+
const message = event.toString();
|
|
75
|
+
handler(message);
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
serialize: (data) => {
|
|
79
|
+
if (data.e) {
|
|
80
|
+
// Serialize error by hand (include message, stack and cause).
|
|
81
|
+
return JSON.stringify({
|
|
82
|
+
...data,
|
|
83
|
+
e: {
|
|
84
|
+
...data.e,
|
|
85
|
+
name: data.e.name,
|
|
86
|
+
message: data.e.message,
|
|
87
|
+
stack: data.e.stack,
|
|
88
|
+
cause: data.e.cause,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return JSON.stringify(data);
|
|
94
|
+
},
|
|
95
|
+
deserialize: JSON.parse,
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
ws: wss,
|
|
102
|
+
rpc: group,
|
|
103
|
+
on: emitter.on.bind(emitter),
|
|
104
|
+
once: emitter.once.bind(emitter),
|
|
105
|
+
off: emitter.off.bind(emitter),
|
|
106
|
+
};
|
|
107
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type TestStatus = 'active' | 'skipped' | 'todo';
|
|
2
|
+
|
|
3
|
+
export type TestFn = () => void | Promise<void>;
|
|
4
|
+
|
|
5
|
+
export type TestCase = {
|
|
6
|
+
name: string;
|
|
7
|
+
fn: TestFn;
|
|
8
|
+
status: TestStatus;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type TestSuite = {
|
|
12
|
+
name: string;
|
|
13
|
+
tests: TestCase[];
|
|
14
|
+
suites: TestSuite[];
|
|
15
|
+
parent?: TestSuite;
|
|
16
|
+
beforeAll: TestFn[];
|
|
17
|
+
afterAll: TestFn[];
|
|
18
|
+
beforeEach: TestFn[];
|
|
19
|
+
afterEach: TestFn[];
|
|
20
|
+
status?: TestStatus;
|
|
21
|
+
_hasFocused?: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type CollectionResult = {
|
|
25
|
+
testSuite: TestSuite;
|
|
26
|
+
/** Number of tests that will actually be executed (excludes skipped and todo tests) */
|
|
27
|
+
totalTests: number;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type TestCollectionStartedEvent = {
|
|
31
|
+
type: 'collection-started';
|
|
32
|
+
file: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type TestCollectionFinishedEvent = {
|
|
36
|
+
type: 'collection-finished';
|
|
37
|
+
file: string;
|
|
38
|
+
duration: number;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type TestCollectorEvents =
|
|
42
|
+
| TestCollectionStartedEvent
|
|
43
|
+
| TestCollectionFinishedEvent;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export type TestResultStatus = 'passed' | 'failed' | 'skipped' | 'todo';
|
|
2
|
+
|
|
3
|
+
export type SerializedError = {
|
|
4
|
+
name: string;
|
|
5
|
+
message: string;
|
|
6
|
+
stack?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type TestRunnerFileStartedEvent = {
|
|
10
|
+
type: 'file-started';
|
|
11
|
+
file: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type TestRunnerFileFinishedEvent = {
|
|
15
|
+
type: 'file-finished';
|
|
16
|
+
file: string;
|
|
17
|
+
duration: number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type TestRunnerSuiteStartedEvent = {
|
|
21
|
+
type: 'suite-started';
|
|
22
|
+
name: string;
|
|
23
|
+
file: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type TestRunnerTestStartedEvent = {
|
|
27
|
+
type: 'test-started';
|
|
28
|
+
name: string;
|
|
29
|
+
suite: string;
|
|
30
|
+
file: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type TestRunnerTestFinishedEvent = {
|
|
34
|
+
type: 'test-finished';
|
|
35
|
+
name: string;
|
|
36
|
+
suite: string;
|
|
37
|
+
file: string;
|
|
38
|
+
duration: number;
|
|
39
|
+
error?: SerializedError;
|
|
40
|
+
status: TestResultStatus;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type TestRunnerSuiteFinishedEvent = {
|
|
44
|
+
type: 'suite-finished';
|
|
45
|
+
name: string;
|
|
46
|
+
file: string;
|
|
47
|
+
duration: number;
|
|
48
|
+
error?: SerializedError;
|
|
49
|
+
status: TestResultStatus;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type TestRunnerEvents =
|
|
53
|
+
| TestRunnerFileStartedEvent
|
|
54
|
+
| TestRunnerFileFinishedEvent
|
|
55
|
+
| TestRunnerTestStartedEvent
|
|
56
|
+
| TestRunnerTestFinishedEvent
|
|
57
|
+
| TestRunnerSuiteStartedEvent
|
|
58
|
+
| TestRunnerSuiteFinishedEvent;
|
|
59
|
+
|
|
60
|
+
export type TestResult = {
|
|
61
|
+
name: string;
|
|
62
|
+
status: TestResultStatus;
|
|
63
|
+
error?: SerializedError;
|
|
64
|
+
duration: number;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type TestSuiteResult = {
|
|
68
|
+
name: string;
|
|
69
|
+
tests: TestResult[];
|
|
70
|
+
suites: TestSuiteResult[];
|
|
71
|
+
status: TestResultStatus;
|
|
72
|
+
error?: SerializedError;
|
|
73
|
+
duration: number;
|
|
74
|
+
};
|
package/src/shared.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
TestRunnerEvents,
|
|
3
|
+
TestSuiteResult,
|
|
4
|
+
} from './shared/test-runner.js';
|
|
5
|
+
import type { TestCollectorEvents } from './shared/test-collector.js';
|
|
6
|
+
|
|
7
|
+
export type {
|
|
8
|
+
TestCollectorEvents,
|
|
9
|
+
TestCollectionStartedEvent,
|
|
10
|
+
TestCollectionFinishedEvent,
|
|
11
|
+
TestSuite,
|
|
12
|
+
TestCase,
|
|
13
|
+
CollectionResult,
|
|
14
|
+
} from './shared/test-collector.js';
|
|
15
|
+
export type {
|
|
16
|
+
TestRunnerEvents,
|
|
17
|
+
TestRunnerFileStartedEvent,
|
|
18
|
+
TestRunnerFileFinishedEvent,
|
|
19
|
+
TestRunnerSuiteStartedEvent,
|
|
20
|
+
TestRunnerTestStartedEvent,
|
|
21
|
+
TestRunnerTestFinishedEvent,
|
|
22
|
+
TestRunnerSuiteFinishedEvent,
|
|
23
|
+
TestSuiteResult,
|
|
24
|
+
TestResult,
|
|
25
|
+
TestResultStatus,
|
|
26
|
+
SerializedError,
|
|
27
|
+
} from './shared/test-runner.js';
|
|
28
|
+
|
|
29
|
+
export type DeviceDescriptor = {
|
|
30
|
+
platform: 'ios' | 'android';
|
|
31
|
+
manufacturer: string;
|
|
32
|
+
model: string;
|
|
33
|
+
osVersion: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type BridgeEvents = TestCollectorEvents | TestRunnerEvents;
|
|
37
|
+
|
|
38
|
+
export type BridgeEventsMap = {
|
|
39
|
+
[K in BridgeEvents['type']]: (
|
|
40
|
+
event: Extract<BridgeEvents, { type: K }>
|
|
41
|
+
) => void;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type BridgeClientFunctions = {
|
|
45
|
+
runTests: (path: string) => Promise<TestSuiteResult>;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type BridgeServerFunctions = {
|
|
49
|
+
reportReady: (device: DeviceDescriptor) => void;
|
|
50
|
+
emitEvent: <TEvent extends BridgeEvents>(
|
|
51
|
+
event: TEvent['type'],
|
|
52
|
+
data: TEvent
|
|
53
|
+
) => void;
|
|
54
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"baseUrl": ".",
|
|
5
|
+
"rootDir": "src",
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
|
|
8
|
+
"emitDeclarationOnly": false,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"types": ["node"],
|
|
11
|
+
"lib": ["ES2020", "DOM"]
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*.ts"],
|
|
14
|
+
"references": [
|
|
15
|
+
{
|
|
16
|
+
"path": "../tools/tsconfig.lib.json"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|