gestament 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -5
- package/dist/displaySession.d.ts +2 -2
- package/dist/displaySession.d.ts.map +1 -1
- package/dist/element.d.ts +2 -2
- package/dist/element.d.ts.map +1 -1
- package/dist/errors.d.ts +2 -2
- package/dist/generated/packageMetadata.d.ts +4 -4
- package/dist/gestament-config.d.ts +2 -2
- package/dist/gestament-launcher-driver.cjs +118 -5
- package/dist/gestament-launcher-driver.cjs.map +1 -1
- package/dist/gestament-launcher-driver.d.ts +2 -2
- package/dist/gestament-launcher-driver.mjs +118 -5
- package/dist/gestament-launcher-driver.mjs.map +1 -1
- package/dist/gestament-tray-host.cjs +9 -1
- package/dist/gestament-tray-host.cjs.map +1 -1
- package/dist/gestament-tray-host.d.ts +2 -2
- package/dist/gestament-tray-host.mjs +9 -1
- package/dist/gestament-tray-host.mjs.map +1 -1
- package/dist/gestament-xvfb-pool-probe.cjs +1 -1
- package/dist/gestament-xvfb-pool-probe.d.ts +2 -2
- package/dist/gestament-xvfb-pool-probe.mjs +1 -1
- package/dist/gestament-xvfb-worker.d.ts +2 -2
- package/dist/gestament-xvfb.cjs +7 -2
- package/dist/gestament-xvfb.cjs.map +1 -1
- package/dist/gestament-xvfb.d.ts +2 -2
- package/dist/gestament-xvfb.mjs +7 -2
- package/dist/gestament-xvfb.mjs.map +1 -1
- package/dist/gestament.cjs +279 -0
- package/dist/gestament.cjs.map +1 -0
- package/dist/gestament.d.ts +29 -0
- package/dist/gestament.d.ts.map +1 -0
- package/dist/gestament.mjs +278 -0
- package/dist/gestament.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{launchGtkApp-BIO_5Xjn.cjs → launchGtkApp-CzYcrc9f.cjs} +794 -89
- package/dist/launchGtkApp-CzYcrc9f.cjs.map +1 -0
- package/dist/{launchGtkApp-qi1qm5G4.js → launchGtkApp-EI6OIpPI.js} +792 -87
- package/dist/launchGtkApp-EI6OIpPI.js.map +1 -0
- package/dist/launchGtkApp.d.ts +2 -2
- package/dist/launchGtkApp.d.ts.map +1 -1
- package/dist/launcherDriverProtocol.d.ts +29 -4
- package/dist/launcherDriverProtocol.d.ts.map +1 -1
- package/dist/{native-CWdUmdty.js → native-DlCBBWlV.js} +16 -10
- package/dist/native-DlCBBWlV.js.map +1 -0
- package/dist/{native-CBXaFWP-.cjs → native-Kfm95Uxw.cjs} +12 -6
- package/dist/native-Kfm95Uxw.cjs.map +1 -0
- package/dist/native.d.ts +23 -2
- package/dist/native.d.ts.map +1 -1
- package/dist/output.d.ts +27 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/packageMetadata-CewXH0iF.cjs +4 -0
- package/dist/packageMetadata-CewXH0iF.cjs.map +1 -0
- package/dist/packageMetadata-DjxyJCJm.js +5 -0
- package/dist/packageMetadata-DjxyJCJm.js.map +1 -0
- package/dist/prerequisites.d.ts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/tray.d.ts +2 -2
- package/dist/types.d.ts +277 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/wait.d.ts +2 -2
- package/package.json +8 -7
- package/prebuilds/linux-arm/gtk3/node.napi.armv7.glibc.node +0 -0
- package/prebuilds/linux-arm/gtk4/node.napi.armv7.glibc.node +0 -0
- package/prebuilds/linux-arm64/gtk3/node.napi.glibc.node +0 -0
- package/prebuilds/linux-arm64/gtk4/node.napi.glibc.node +0 -0
- package/prebuilds/linux-ia32/gtk3/node.napi.glibc.node +0 -0
- package/prebuilds/linux-ia32/gtk4/node.napi.glibc.node +0 -0
- package/prebuilds/linux-riscv64/gtk3/node.napi.glibc.node +0 -0
- package/prebuilds/linux-riscv64/gtk4/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/gtk3/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/gtk4/node.napi.glibc.node +0 -0
- package/dist/launchGtkApp-BIO_5Xjn.cjs.map +0 -1
- package/dist/launchGtkApp-qi1qm5G4.js.map +0 -1
- package/dist/native-CBXaFWP-.cjs.map +0 -1
- package/dist/native-CWdUmdty.js.map +0 -1
package/README.md
CHANGED
|
@@ -65,8 +65,10 @@ describe('sample GTK app', () => {
|
|
|
65
65
|
- Provides APIs for identifying GTK application windows and widgets within those windows.
|
|
66
66
|
- These APIs can be used to check and manipulate widget states.
|
|
67
67
|
- Captures the rendering output of GTK applications to verify the display area and clip state.
|
|
68
|
+
- Exposes top-level window bounds, resize hints, and X11 metadata without requiring helper tools.
|
|
68
69
|
- Detects StatusNotifierItem-based tray icons and allows you to click them, retrieve metadata, and capture screenshots.
|
|
69
70
|
- Runs GTK applications on launcher-scoped `xvfb` sessions to enable stable testing in headless and concurrent environments.
|
|
71
|
+
- Exposes the final GTK session environment so helper processes can join the same Xvfb and DBus session.
|
|
70
72
|
|
|
71
73
|
### Environment
|
|
72
74
|
|
|
@@ -96,19 +98,34 @@ sudo apt-get install -y \
|
|
|
96
98
|
This completes the native environment setup.
|
|
97
99
|
|
|
98
100
|
NPM projects can choose from many test frameworks.
|
|
99
|
-
gestament does not depend on a specific test framework, but
|
|
101
|
+
gestament does not depend on a specific test framework, but it provides a minimal initializer for Vitest-based GTK test projects.
|
|
102
|
+
The initializer creates only the Node/Vitest test harness files.
|
|
103
|
+
It does not generate Vite web pages, static web assets, or GTK/C/C++ build files.
|
|
100
104
|
|
|
101
105
|
```bash
|
|
102
|
-
# Generate a
|
|
103
|
-
|
|
106
|
+
# Generate a minimal gestament test project.
|
|
107
|
+
npx gestament init gestament-tests
|
|
104
108
|
|
|
105
109
|
cd gestament-tests
|
|
106
110
|
|
|
107
|
-
# Install the
|
|
111
|
+
# Install the generated project dependencies.
|
|
108
112
|
npm install
|
|
109
|
-
npm install -D vitest @types/node gestament
|
|
110
113
|
```
|
|
111
114
|
|
|
115
|
+
This creates the following files:
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
gestament-tests/
|
|
119
|
+
├── .gitignore.gestament-example
|
|
120
|
+
├── package.json
|
|
121
|
+
├── tests/
|
|
122
|
+
├── tsconfig.json
|
|
123
|
+
└── vitest.config.ts
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The initializer does not modify an existing `.gitignore`.
|
|
127
|
+
If needed, merge the entries from `.gitignore.gestament-example` into the GTK application project's `.gitignore`.
|
|
128
|
+
|
|
112
129
|
---
|
|
113
130
|
|
|
114
131
|
## Documentation
|
package/dist/displaySession.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* name: gestament
|
|
3
|
-
* version: 0.
|
|
3
|
+
* version: 0.5.0
|
|
4
4
|
* description: TypeScript based test driver for GTK
|
|
5
5
|
* author: Kouji Matsui (@kekyo@mi.kekyo.net)
|
|
6
6
|
* license: MIT
|
|
7
7
|
* repository.url: https://github.com/kekyo/gestament.git
|
|
8
|
-
* git.commit.hash:
|
|
8
|
+
* git.commit.hash: 368fd995a6a10f20aea97cb0389ac3e12cfbedb3
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { GtkAppLauncher, GtkAppLauncherOptions } from './types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"displaySession.d.ts","sourceRoot":"","sources":["../src/displaySession.ts"],"names":[],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"displaySession.d.ts","sourceRoot":"","sources":["../src/displaySession.ts"],"names":[],"mappings":";;;;;;;;;AAqDA,OAAO,KAAK,EAIV,cAAc,EAEd,qBAAqB,EAiBtB,MAAM,SAAS,CAAC;AA8zEjB;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,GAC3C,SAAS,qBAAqB,KAC7B,cAoHF,CAAC"}
|
package/dist/element.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* name: gestament
|
|
3
|
-
* version: 0.
|
|
3
|
+
* version: 0.5.0
|
|
4
4
|
* description: TypeScript based test driver for GTK
|
|
5
5
|
* author: Kouji Matsui (@kekyo@mi.kekyo.net)
|
|
6
6
|
* license: MIT
|
|
7
7
|
* repository.url: https://github.com/kekyo/gestament.git
|
|
8
|
-
* git.commit.hash:
|
|
8
|
+
* git.commit.hash: 368fd995a6a10f20aea97cb0389ac3e12cfbedb3
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { NativeElementHandle } from './native.js';
|
package/dist/element.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":";;;;;;;;;AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":";;;;;;;;;AAKA,OAAO,EAmCL,KAAK,mBAAmB,EAEzB,MAAM,UAAU,CAAC;AAMlB,OAAO,KAAK,EAWV,gBAAgB,EAIjB,MAAM,YAAS,CAAC;AAq3BjB,yEAAsE;AACtE,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,mBAAmB,KAC1B,gBA2IF,CAAC"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* name: gestament
|
|
3
|
-
* version: 0.
|
|
3
|
+
* version: 0.5.0
|
|
4
4
|
* description: TypeScript based test driver for GTK
|
|
5
5
|
* author: Kouji Matsui (@kekyo@mi.kekyo.net)
|
|
6
6
|
* license: MIT
|
|
7
7
|
* repository.url: https://github.com/kekyo/gestament.git
|
|
8
|
-
* git.commit.hash:
|
|
8
|
+
* git.commit.hash: 368fd995a6a10f20aea97cb0389ac3e12cfbedb3
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { GtkAutomationError } from './types.js';
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* name: gestament
|
|
3
|
-
* version: 0.
|
|
3
|
+
* version: 0.5.0
|
|
4
4
|
* description: TypeScript based test driver for GTK
|
|
5
5
|
* author: Kouji Matsui (@kekyo@mi.kekyo.net)
|
|
6
6
|
* license: MIT
|
|
7
7
|
* repository.url: https://github.com/kekyo/gestament.git
|
|
8
|
-
* git.commit.hash:
|
|
8
|
+
* git.commit.hash: 368fd995a6a10f20aea97cb0389ac3e12cfbedb3
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
export declare const name = "gestament";
|
|
12
|
-
export declare const version = "0.
|
|
12
|
+
export declare const version = "0.5.0";
|
|
13
13
|
export declare const description = "TypeScript based test driver for GTK";
|
|
14
14
|
export declare const author = "Kouji Matsui (@kekyo@mi.kekyo.net)";
|
|
15
15
|
export declare const license = "MIT";
|
|
16
16
|
export declare const repository_url = "https://github.com/kekyo/gestament.git";
|
|
17
|
-
export declare const git_commit_hash = "
|
|
17
|
+
export declare const git_commit_hash = "368fd995a6a10f20aea97cb0389ac3e12cfbedb3";
|
|
18
18
|
//# sourceMappingURL=packageMetadata.d.ts.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/*!
|
|
3
3
|
* name: gestament
|
|
4
|
-
* version: 0.
|
|
4
|
+
* version: 0.5.0
|
|
5
5
|
* description: TypeScript based test driver for GTK
|
|
6
6
|
* author: Kouji Matsui (@kekyo@mi.kekyo.net)
|
|
7
7
|
* license: MIT
|
|
8
8
|
* repository.url: https://github.com/kekyo/gestament.git
|
|
9
|
-
* git.commit.hash:
|
|
9
|
+
* git.commit.hash: 368fd995a6a10f20aea97cb0389ac3e12cfbedb3
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
export interface GestamentConfigOutput {
|
|
@@ -5,7 +5,7 @@ const node_net = require("node:net");
|
|
|
5
5
|
const node_fs = require("node:fs");
|
|
6
6
|
const node_path = require("node:path");
|
|
7
7
|
const errors = require("./errors-6gj5YuLw.cjs");
|
|
8
|
-
const launchGtkApp = require("./launchGtkApp-
|
|
8
|
+
const launchGtkApp = require("./launchGtkApp-CzYcrc9f.cjs");
|
|
9
9
|
const wait = require("./wait-eOIz4nZm.cjs");
|
|
10
10
|
const trayHostReadyLine = "gestament-tray-host-ready";
|
|
11
11
|
const trayHostReadyTimeoutMs = 3e4;
|
|
@@ -20,6 +20,7 @@ let nextAppId = 1;
|
|
|
20
20
|
let nextElementId = 1;
|
|
21
21
|
let nextTrayItemId = 1;
|
|
22
22
|
let nextImageInfoId = 1;
|
|
23
|
+
let parentSocket;
|
|
23
24
|
let shuttingDown = false;
|
|
24
25
|
let trayHostProcess;
|
|
25
26
|
const parseArguments = (args) => {
|
|
@@ -65,16 +66,40 @@ const waitForTrayHostReady = (host) => new Promise((resolveReady, rejectReady) =
|
|
|
65
66
|
host.stdout.on("data", (chunk) => {
|
|
66
67
|
const text = chunk.toString("utf8");
|
|
67
68
|
output += text;
|
|
68
|
-
|
|
69
|
+
const readyIndex = output.indexOf(trayHostReadyLine);
|
|
70
|
+
if (!settled && readyIndex >= 0) {
|
|
69
71
|
settled = true;
|
|
70
72
|
clearTimeout(timeout);
|
|
73
|
+
const beforeReady = output.slice(0, readyIndex);
|
|
74
|
+
if (beforeReady.length > 0) {
|
|
75
|
+
writeSystemOutputChunk("stdout", Buffer.from(beforeReady));
|
|
76
|
+
}
|
|
77
|
+
let afterReadyIndex = readyIndex + trayHostReadyLine.length;
|
|
78
|
+
if (output.slice(afterReadyIndex, afterReadyIndex + 2) === "\r\n") {
|
|
79
|
+
afterReadyIndex += 2;
|
|
80
|
+
} else if (output[afterReadyIndex] === "\n") {
|
|
81
|
+
afterReadyIndex += 1;
|
|
82
|
+
}
|
|
83
|
+
const afterReady = output.slice(afterReadyIndex);
|
|
84
|
+
if (afterReady.length > 0) {
|
|
85
|
+
writeSystemOutputChunk("stdout", Buffer.from(afterReady));
|
|
86
|
+
}
|
|
71
87
|
resolveReady();
|
|
72
88
|
return;
|
|
73
89
|
}
|
|
74
90
|
if (settled) {
|
|
75
|
-
|
|
91
|
+
writeSystemOutputChunk("stdout", chunk);
|
|
76
92
|
}
|
|
77
93
|
});
|
|
94
|
+
host.stdout.once("end", () => {
|
|
95
|
+
writeSystemOutputFlush("stdout");
|
|
96
|
+
});
|
|
97
|
+
host.stderr?.on("data", (chunk) => {
|
|
98
|
+
writeSystemOutputChunk("stderr", chunk);
|
|
99
|
+
});
|
|
100
|
+
host.stderr?.once("end", () => {
|
|
101
|
+
writeSystemOutputFlush("stderr");
|
|
102
|
+
});
|
|
78
103
|
host.once("exit", (code, signal) => {
|
|
79
104
|
if (!settled) {
|
|
80
105
|
settled = true;
|
|
@@ -107,7 +132,7 @@ const startTrayHost = async () => {
|
|
|
107
132
|
);
|
|
108
133
|
const host = node_child_process.spawn(process.execPath, [hostPath], {
|
|
109
134
|
env: process.env,
|
|
110
|
-
stdio: ["ignore", "pipe", "
|
|
135
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
111
136
|
});
|
|
112
137
|
try {
|
|
113
138
|
await waitForTrayHostReady(host);
|
|
@@ -137,6 +162,52 @@ const writeReady = (socket) => {
|
|
|
137
162
|
socket.write(`${JSON.stringify(ready)}
|
|
138
163
|
`);
|
|
139
164
|
};
|
|
165
|
+
const writeInternalTestOutput = () => {
|
|
166
|
+
const stdout = process.env.GESTAMENT_TEST_DRIVER_SYSTEM_STDOUT;
|
|
167
|
+
if (stdout !== void 0) {
|
|
168
|
+
process.stdout.write(stdout);
|
|
169
|
+
}
|
|
170
|
+
const stderr = process.env.GESTAMENT_TEST_DRIVER_SYSTEM_STDERR;
|
|
171
|
+
if (stderr !== void 0) {
|
|
172
|
+
process.stderr.write(stderr);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const writePayloadInternalTestOutput = (env) => {
|
|
176
|
+
const stdout = env.GESTAMENT_TEST_DRIVER_COMMAND_SYSTEM_STDOUT;
|
|
177
|
+
if (stdout !== null && stdout !== void 0) {
|
|
178
|
+
process.stdout.write(stdout);
|
|
179
|
+
}
|
|
180
|
+
const stderr = env.GESTAMENT_TEST_DRIVER_COMMAND_SYSTEM_STDERR;
|
|
181
|
+
if (stderr !== null && stderr !== void 0) {
|
|
182
|
+
process.stderr.write(stderr);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
const writeDriverEvent = (channel, scopeId, value) => {
|
|
186
|
+
try {
|
|
187
|
+
parentSocket?.write(
|
|
188
|
+
`${JSON.stringify({ channel, scopeId, type: "event", value })}
|
|
189
|
+
`
|
|
190
|
+
);
|
|
191
|
+
} catch {
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const writeSystemOutputChunk = (stream, chunk) => {
|
|
195
|
+
const value = {
|
|
196
|
+
chunkBase64: chunk.toString("base64"),
|
|
197
|
+
source: "tray-host",
|
|
198
|
+
stream,
|
|
199
|
+
type: "chunk"
|
|
200
|
+
};
|
|
201
|
+
writeDriverEvent("system.output", "system", value);
|
|
202
|
+
};
|
|
203
|
+
const writeSystemOutputFlush = (stream) => {
|
|
204
|
+
const value = {
|
|
205
|
+
source: "tray-host",
|
|
206
|
+
stream,
|
|
207
|
+
type: "flush"
|
|
208
|
+
};
|
|
209
|
+
writeDriverEvent("system.output", "system", value);
|
|
210
|
+
};
|
|
140
211
|
const wireEnvironmentToGtkAppEnvironment = (env) => {
|
|
141
212
|
const appEnv = {};
|
|
142
213
|
for (const [key, value] of Object.entries(env)) {
|
|
@@ -144,6 +215,13 @@ const wireEnvironmentToGtkAppEnvironment = (env) => {
|
|
|
144
215
|
}
|
|
145
216
|
return appEnv;
|
|
146
217
|
};
|
|
218
|
+
const gtkAppEnvironmentToWireEnvironment = (env) => {
|
|
219
|
+
const wireEnv = {};
|
|
220
|
+
for (const [key, value] of Object.entries(env)) {
|
|
221
|
+
wireEnv[key] = value ?? null;
|
|
222
|
+
}
|
|
223
|
+
return wireEnv;
|
|
224
|
+
};
|
|
147
225
|
const toWireCapture = (capture) => ({
|
|
148
226
|
bounds: capture.bounds,
|
|
149
227
|
clipped: capture.clipped,
|
|
@@ -310,10 +388,28 @@ const optionalElementRef = (appId, element) => element === void 0 ? null : regis
|
|
|
310
388
|
const optionalTrayItemRef = (appId, trayItem) => trayItem === void 0 ? null : registerTrayItem(appId, trayItem);
|
|
311
389
|
const handleLauncherCommand = async (command, payload) => {
|
|
312
390
|
switch (command) {
|
|
391
|
+
case "launcher.environment": {
|
|
392
|
+
const environmentPayload = payload;
|
|
393
|
+
writePayloadInternalTestOutput(environmentPayload.env);
|
|
394
|
+
return gtkAppEnvironmentToWireEnvironment(
|
|
395
|
+
launchGtkApp.createGtkAppEnvironment(
|
|
396
|
+
process.env,
|
|
397
|
+
wireEnvironmentToGtkAppEnvironment(environmentPayload.env)
|
|
398
|
+
)
|
|
399
|
+
);
|
|
400
|
+
}
|
|
313
401
|
case "launcher.launch": {
|
|
314
402
|
const launchPayload = payload;
|
|
403
|
+
writePayloadInternalTestOutput(launchPayload.env);
|
|
404
|
+
const outputScopeId = launchPayload.outputScopeId;
|
|
315
405
|
const launchOptions = {
|
|
316
406
|
env: wireEnvironmentToGtkAppEnvironment(launchPayload.env),
|
|
407
|
+
...launchPayload.outputBufferBytes === null ? {} : { outputBufferBytes: launchPayload.outputBufferBytes },
|
|
408
|
+
...outputScopeId === null ? {} : {
|
|
409
|
+
onOutput: (event) => {
|
|
410
|
+
writeDriverEvent("app.output", outputScopeId, event);
|
|
411
|
+
}
|
|
412
|
+
},
|
|
317
413
|
...launchPayload.timeoutMs === null ? {} : { timeoutMs: launchPayload.timeoutMs }
|
|
318
414
|
};
|
|
319
415
|
const app = await launchGtkApp.launchGtkApp(
|
|
@@ -342,6 +438,10 @@ const handleAppCommand = async (command, payload) => {
|
|
|
342
438
|
const { appId } = appPayload(payload);
|
|
343
439
|
const app = resolveApp(appId);
|
|
344
440
|
switch (command) {
|
|
441
|
+
case "app.environment":
|
|
442
|
+
return gtkAppEnvironmentToWireEnvironment(await app.environment());
|
|
443
|
+
case "app.output":
|
|
444
|
+
return await app.output();
|
|
345
445
|
case "app.release":
|
|
346
446
|
await releaseApp(appId);
|
|
347
447
|
return null;
|
|
@@ -397,6 +497,12 @@ const handleElementCommand = async (command, payload) => {
|
|
|
397
497
|
return entry.element.info();
|
|
398
498
|
case "element.capture":
|
|
399
499
|
return toWireCapture(await entry.element.capture());
|
|
500
|
+
case "element.bounds":
|
|
501
|
+
return callElementMethod(entry, "bounds");
|
|
502
|
+
case "window.resizeHints":
|
|
503
|
+
return callElementMethod(entry, "resizeHints");
|
|
504
|
+
case "window.x11Info":
|
|
505
|
+
return callElementMethod(entry, "x11Info");
|
|
400
506
|
case "element.childAt": {
|
|
401
507
|
const { index } = payload;
|
|
402
508
|
return optionalElementRef(
|
|
@@ -572,6 +678,9 @@ const handleRequest = async (request) => {
|
|
|
572
678
|
if (request.command.startsWith("element.")) {
|
|
573
679
|
return handleElementCommand(request.command, request.payload);
|
|
574
680
|
}
|
|
681
|
+
if (request.command.startsWith("window.")) {
|
|
682
|
+
return handleElementCommand(request.command, request.payload);
|
|
683
|
+
}
|
|
575
684
|
if (request.command.startsWith("imageInfo.")) {
|
|
576
685
|
return handleImageInfoCommand(request.command, request.payload);
|
|
577
686
|
}
|
|
@@ -605,6 +714,7 @@ const handleRequestLine = async (socket, line) => {
|
|
|
605
714
|
}
|
|
606
715
|
};
|
|
607
716
|
const installSocketProtocol = (socket) => {
|
|
717
|
+
parentSocket = socket;
|
|
608
718
|
let input = "";
|
|
609
719
|
socket.on("data", (chunk) => {
|
|
610
720
|
input += chunk.toString("utf8");
|
|
@@ -617,9 +727,11 @@ const installSocketProtocol = (socket) => {
|
|
|
617
727
|
}
|
|
618
728
|
});
|
|
619
729
|
socket.once("close", () => {
|
|
730
|
+
parentSocket = void 0;
|
|
620
731
|
void shutdown(0);
|
|
621
732
|
});
|
|
622
733
|
socket.once("error", () => {
|
|
734
|
+
parentSocket = void 0;
|
|
623
735
|
void shutdown(1);
|
|
624
736
|
});
|
|
625
737
|
};
|
|
@@ -636,9 +748,10 @@ const shutdown = async (exitCode) => {
|
|
|
636
748
|
};
|
|
637
749
|
const run = async () => {
|
|
638
750
|
const parsed = parseArguments(process.argv.slice(2));
|
|
639
|
-
trayHostProcess = parsed.withTrayHost ? await startTrayHost() : void 0;
|
|
640
751
|
const socket = await connectToParent(parsed.socketPath);
|
|
641
752
|
installSocketProtocol(socket);
|
|
753
|
+
writeInternalTestOutput();
|
|
754
|
+
trayHostProcess = parsed.withTrayHost ? await startTrayHost() : void 0;
|
|
642
755
|
writeReady(socket);
|
|
643
756
|
process.once("SIGINT", () => {
|
|
644
757
|
void shutdown(130);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gestament-launcher-driver.cjs","sources":["../src/gestament-launcher-driver.ts"],"sourcesContent":["#!/usr/bin/env node\n// gestament - TypeScript based test driver for GTK.\n// Copyright (c) Kouji Matsui. (@kekyo@mi.kekyo.net)\n// Under MIT.\n// https://github.com/kekyo/gestament\n\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { createConnection, type Socket } from 'node:net';\nimport { realpathSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\n\nimport {\n createGtkAppExitedError,\n createGtkOperationFailedError,\n createGtkStaleElementError,\n createGtkUnsupportedInterfaceError,\n} from './errors';\nimport { launchGtkApp } from './launchGtkApp';\nimport { runWithWaitDeadline } from './wait';\nimport type {\n DriverAppPayload,\n DriverAppRef,\n DriverCommand,\n DriverElementPayload,\n DriverElementRef,\n DriverIdPayload,\n DriverImageInfoPayload,\n DriverIndexPayload,\n DriverLaunchPayload,\n DriverPathPayload,\n DriverReadyMessage,\n DriverRequest,\n DriverSelectedIndexPayload,\n DriverTableCellPayload,\n DriverTextPayload,\n DriverTrayItemRef,\n DriverTrayPayload,\n DriverTraySelectorPayload,\n DriverValuePayload,\n SerializedDriverError,\n WireCapture,\n WireGtkAppEnvironment,\n WireImageInfo,\n} from './launcherDriverProtocol';\nimport type {\n GtkApp,\n GtkAppEnvironment,\n GtkCapture,\n GtkImageInfo,\n GtkTrayItem,\n GtkWidgetElement,\n} from './types';\n\n/////////////////////////////////////////////////////////////////////////////////////////\n\ninterface DriverArguments {\n readonly socketPath: string;\n readonly withTrayHost: boolean;\n}\n\ninterface ElementEntry {\n readonly appId: string;\n readonly element: GtkWidgetElement;\n}\n\ninterface TrayItemEntry {\n readonly appId: string;\n readonly trayItem: GtkTrayItem;\n}\n\ninterface ImageInfoEntry {\n readonly appId: string;\n readonly capture: () => Promise<GtkCapture>;\n}\n\ntype AsyncMethod = (...args: unknown[]) => Promise<unknown>;\n\nconst trayHostReadyLine = 'gestament-tray-host-ready';\nconst trayHostReadyTimeoutMs = 30_000;\n\nconst apps = new Map<string, GtkApp>();\nconst elements = new Map<string, ElementEntry>();\nconst trayItems = new Map<string, TrayItemEntry>();\nconst imageInfos = new Map<string, ImageInfoEntry>();\nconst staleElementIds = new Set<string>();\nconst staleTrayItemIds = new Set<string>();\nconst staleImageInfoIds = new Set<string>();\n\nlet nextAppId = 1;\nlet nextElementId = 1;\nlet nextTrayItemId = 1;\nlet nextImageInfoId = 1;\nlet shuttingDown = false;\nlet trayHostProcess: ChildProcess | undefined;\n\nconst parseArguments = (args: readonly string[]): DriverArguments => {\n let socketPath: string | undefined;\n let withTrayHost = false;\n let index = 0;\n\n while (index < args.length) {\n const argument = args[index];\n\n if (argument === '--socket') {\n const value = args[index + 1];\n if (value === undefined || value.length === 0) {\n throw new Error('--socket requires a Unix socket path.');\n }\n socketPath = value;\n index += 2;\n continue;\n }\n\n if (argument === '--with-tray-host') {\n withTrayHost = true;\n index += 1;\n continue;\n }\n\n throw new Error(`Unknown gestament launcher driver option: ${argument}`);\n }\n\n if (socketPath === undefined) {\n throw new Error('Missing --socket option.');\n }\n\n return { socketPath, withTrayHost };\n};\n\nconst waitForTrayHostReady = (host: ChildProcess): Promise<void> =>\n new Promise<void>((resolveReady, rejectReady) => {\n if (host.stdout === null) {\n rejectReady(new Error('gestament tray host did not expose stdout.'));\n return;\n }\n\n let output = '';\n let settled = false;\n\n const timeout = setTimeout(() => {\n if (!settled) {\n settled = true;\n rejectReady(new Error('Timed out waiting for gestament tray host.'));\n }\n }, trayHostReadyTimeoutMs);\n\n host.stdout.on('data', (chunk: Buffer) => {\n const text = chunk.toString('utf8');\n output += text;\n if (!settled && output.includes(trayHostReadyLine)) {\n settled = true;\n clearTimeout(timeout);\n resolveReady();\n return;\n }\n if (settled) {\n process.stdout.write(text);\n }\n });\n\n host.once('exit', (code, signal) => {\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n rejectReady(\n new Error(\n `gestament tray host exited before ready: code=${String(\n code\n )}, signal=${String(signal)}`\n )\n );\n }\n });\n\n host.once('error', (error) => {\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n rejectReady(error);\n }\n });\n });\n\nconst startTrayHost = async (): Promise<ChildProcess> => {\n const executablePath = process.argv[1];\n if (executablePath === undefined) {\n throw new Error('Missing executable path.');\n }\n\n const hostPath = resolve(\n dirname(realpathSync(executablePath)),\n 'gestament-tray-host.cjs'\n );\n const host = spawn(process.execPath, [hostPath], {\n env: process.env,\n stdio: ['ignore', 'pipe', 'inherit'],\n });\n try {\n await waitForTrayHostReady(host);\n return host;\n } catch (error) {\n if (host.exitCode === null && host.signalCode === null) {\n host.kill('SIGTERM');\n }\n throw error;\n }\n};\n\nconst connectToParent = (socketPath: string): Promise<Socket> =>\n new Promise<Socket>((resolveConnect, rejectConnect) => {\n const socket = createConnection(socketPath);\n\n const rejectFromError = (error: Error): void => {\n socket.removeListener('connect', resolveFromConnect);\n rejectConnect(error);\n };\n const resolveFromConnect = (): void => {\n socket.removeListener('error', rejectFromError);\n resolveConnect(socket);\n };\n\n socket.once('error', rejectFromError);\n socket.once('connect', resolveFromConnect);\n });\n\nconst writeReady = (socket: Socket): void => {\n const ready: DriverReadyMessage = { type: 'ready' };\n socket.write(`${JSON.stringify(ready)}\\n`);\n};\n\nconst wireEnvironmentToGtkAppEnvironment = (\n env: WireGtkAppEnvironment\n): GtkAppEnvironment => {\n const appEnv: Record<string, string | undefined> = {};\n for (const [key, value] of Object.entries(env)) {\n appEnv[key] = value === null ? undefined : value;\n }\n return appEnv;\n};\n\nconst toWireCapture = (capture: GtkCapture): WireCapture => ({\n bounds: capture.bounds,\n clipped: capture.clipped,\n imageBase64: capture.image.toString('base64'),\n visibleBounds: capture.visibleBounds,\n});\n\nconst registerApp = (app: GtkApp): DriverAppRef => {\n const appId = `app-${nextAppId}`;\n nextAppId += 1;\n apps.set(appId, app);\n return { appId };\n};\n\nconst registerElement = (\n appId: string,\n element: GtkWidgetElement\n): DriverElementRef => {\n const elementId = `element-${nextElementId}`;\n nextElementId += 1;\n elements.set(elementId, { appId, element });\n return { elementId, kind: element.kind };\n};\n\nconst registerTrayItem = (\n appId: string,\n trayItem: GtkTrayItem\n): DriverTrayItemRef => {\n const trayItemId = `tray-${nextTrayItemId}`;\n nextTrayItemId += 1;\n trayItems.set(trayItemId, { appId, trayItem });\n return { trayItemId };\n};\n\nconst registerImageInfo = (\n appId: string,\n info: GtkImageInfo\n): WireImageInfo => {\n const imageInfoId = `image-info-${nextImageInfoId}`;\n nextImageInfoId += 1;\n imageInfos.set(imageInfoId, { appId, capture: info.capture });\n return {\n bounds: info.bounds,\n description: info.description,\n imageInfoId,\n locale: info.locale,\n position: info.position,\n size: info.size,\n };\n};\n\nconst resolveApp = (appId: string): GtkApp => {\n const app = apps.get(appId);\n if (app === undefined) {\n throw createGtkAppExitedError(\n 'GTK application has exited or was released.'\n );\n }\n return app;\n};\n\nconst resolveElementEntry = (elementId: string): ElementEntry => {\n const entry = elements.get(elementId);\n if (entry === undefined) {\n if (staleElementIds.has(elementId)) {\n throw createGtkStaleElementError('GTK element is no longer available.');\n }\n throw createGtkAppExitedError('GTK element is not registered.');\n }\n if (!apps.has(entry.appId)) {\n throw createGtkStaleElementError('GTK element is no longer available.');\n }\n return entry;\n};\n\nconst resolveTrayItemEntry = (trayItemId: string): TrayItemEntry => {\n const entry = trayItems.get(trayItemId);\n if (entry === undefined) {\n if (staleTrayItemIds.has(trayItemId)) {\n throw createGtkStaleElementError('Tray item is no longer registered.');\n }\n throw createGtkAppExitedError('GTK tray item is not registered.');\n }\n if (!apps.has(entry.appId)) {\n throw createGtkStaleElementError('Tray item is no longer registered.');\n }\n return entry;\n};\n\nconst resolveImageInfoEntry = (imageInfoId: string): ImageInfoEntry => {\n const entry = imageInfos.get(imageInfoId);\n if (entry === undefined) {\n if (staleImageInfoIds.has(imageInfoId)) {\n throw createGtkStaleElementError(\n 'GTK image info is no longer available.'\n );\n }\n throw createGtkAppExitedError('GTK image info is not registered.');\n }\n if (!apps.has(entry.appId)) {\n throw createGtkStaleElementError('GTK image info is no longer available.');\n }\n return entry;\n};\n\nconst removeAppRefs = (appId: string): void => {\n for (const [elementId, entry] of elements) {\n if (entry.appId === appId) {\n staleElementIds.add(elementId);\n elements.delete(elementId);\n }\n }\n for (const [trayItemId, entry] of trayItems) {\n if (entry.appId === appId) {\n staleTrayItemIds.add(trayItemId);\n trayItems.delete(trayItemId);\n }\n }\n for (const [imageInfoId, entry] of imageInfos) {\n if (entry.appId === appId) {\n staleImageInfoIds.add(imageInfoId);\n imageInfos.delete(imageInfoId);\n }\n }\n};\n\nconst releaseApp = async (appId: string): Promise<void> => {\n const app = apps.get(appId);\n if (app === undefined) {\n return;\n }\n\n apps.delete(appId);\n removeAppRefs(appId);\n await app.release();\n};\n\nconst releaseApps = async (): Promise<void> => {\n const appIds = [...apps.keys()];\n await Promise.all(appIds.map((appId) => releaseApp(appId)));\n};\n\nconst stopTrayHost = (): void => {\n if (\n trayHostProcess !== undefined &&\n trayHostProcess.exitCode === null &&\n trayHostProcess.signalCode === null\n ) {\n trayHostProcess.kill('SIGTERM');\n }\n};\n\nconst releaseAll = async (): Promise<void> => {\n await releaseApps();\n stopTrayHost();\n};\n\nconst asMethod = (\n target: unknown,\n methodName: string,\n kindLabel: string\n): AsyncMethod => {\n const value = (target as Record<string, unknown>)[methodName];\n if (typeof value !== 'function') {\n throw createGtkUnsupportedInterfaceError(\n `${kindLabel} does not support ${methodName}().`\n );\n }\n return value as AsyncMethod;\n};\n\nconst callElementMethod = (\n entry: ElementEntry,\n methodName: string,\n args: unknown[] = []\n): Promise<unknown> =>\n asMethod(\n entry.element,\n methodName,\n `GTK ${entry.element.kind} element`\n )(...args);\n\nconst callTrayItemMethod = (\n entry: TrayItemEntry,\n methodName: string,\n args: unknown[] = []\n): Promise<unknown> =>\n asMethod(entry.trayItem, methodName, 'GTK tray item')(...args);\n\nconst serializeError = (error: unknown): SerializedDriverError => {\n if (error instanceof Error) {\n const maybeCode = (error as { code?: unknown }).code;\n const base = {\n message: error.message,\n name: error.name,\n };\n const withStack =\n error.stack === undefined ? base : { ...base, stack: error.stack };\n return typeof maybeCode === 'string'\n ? { ...withStack, code: maybeCode }\n : withStack;\n }\n\n return {\n message: String(error),\n name: 'Error',\n };\n};\n\nconst appPayload = (payload: unknown): DriverAppPayload =>\n payload as DriverAppPayload;\n\nconst elementPayload = (payload: unknown): DriverElementPayload =>\n payload as DriverElementPayload;\n\nconst trayPayload = (payload: unknown): DriverTrayPayload =>\n payload as DriverTrayPayload;\n\nconst optionalElementRef = (\n appId: string,\n element: GtkWidgetElement | undefined\n): DriverElementRef | null =>\n element === undefined ? null : registerElement(appId, element);\n\nconst optionalTrayItemRef = (\n appId: string,\n trayItem: GtkTrayItem | undefined\n): DriverTrayItemRef | null =>\n trayItem === undefined ? null : registerTrayItem(appId, trayItem);\n\nconst handleLauncherCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n switch (command) {\n case 'launcher.launch': {\n const launchPayload = payload as DriverLaunchPayload;\n const launchOptions = {\n env: wireEnvironmentToGtkAppEnvironment(launchPayload.env),\n ...(launchPayload.timeoutMs === null\n ? {}\n : { timeoutMs: launchPayload.timeoutMs }),\n };\n const app = await launchGtkApp(\n launchPayload.appPath,\n launchPayload.args,\n launchOptions\n );\n return registerApp(app);\n }\n case 'launcher.release':\n await releaseAll();\n return null;\n case 'launcher.reset':\n await releaseApps();\n return {\n appCount: apps.size,\n elementCount: elements.size,\n imageInfoCount: imageInfos.size,\n trayItemCount: trayItems.size,\n };\n default:\n throw createGtkOperationFailedError(`Unsupported command: ${command}`);\n }\n};\n\nconst handleAppCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n const { appId } = appPayload(payload);\n const app = resolveApp(appId);\n\n switch (command) {\n case 'app.release':\n await releaseApp(appId);\n return null;\n case 'app.capture':\n return toWireCapture(await app.capture());\n case 'app.findById': {\n const { id } = payload as DriverAppPayload & DriverIdPayload;\n return optionalElementRef(appId, await app.findById(id));\n }\n case 'app.getById': {\n const { id } = payload as DriverAppPayload & DriverIdPayload;\n return registerElement(appId, await app.getById(id));\n }\n case 'app.findByPath': {\n const { path } = payload as DriverAppPayload & DriverPathPayload;\n return optionalElementRef(appId, await app.findByPath(path));\n }\n case 'app.getByPath': {\n const { path } = payload as DriverAppPayload & DriverPathPayload;\n return registerElement(appId, await app.getByPath(path));\n }\n case 'app.windowAt': {\n const { index } = payload as DriverAppPayload & DriverIndexPayload;\n return optionalElementRef(appId, await app.windowAt(index));\n }\n case 'app.getWindowCount':\n return app.getWindowCount();\n case 'app.findTrayItem': {\n const { selector } = payload as DriverAppPayload &\n DriverTraySelectorPayload;\n return optionalTrayItemRef(appId, await app.findTrayItem(selector));\n }\n case 'app.getTrayItem': {\n const { selector } = payload as DriverAppPayload &\n DriverTraySelectorPayload;\n return registerTrayItem(appId, await app.getTrayItem(selector));\n }\n case 'app.trayItemAt': {\n const { index } = payload as DriverAppPayload & DriverIndexPayload;\n return optionalTrayItemRef(appId, await app.trayItemAt(index));\n }\n case 'app.getTrayItemCount':\n return app.getTrayItemCount();\n default:\n throw createGtkOperationFailedError(\n `Unsupported app command: ${command}`\n );\n }\n};\n\nconst handleElementCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n const { elementId } = elementPayload(payload);\n const entry = resolveElementEntry(elementId);\n\n switch (command) {\n case 'element.info':\n return entry.element.info();\n case 'element.capture':\n return toWireCapture(await entry.element.capture());\n case 'element.childAt': {\n const { index } = payload as DriverElementPayload & DriverIndexPayload;\n return optionalElementRef(\n entry.appId,\n (await callElementMethod(entry, 'childAt', [index])) as\n | GtkWidgetElement\n | undefined\n );\n }\n case 'element.getChildCount':\n return callElementMethod(entry, 'getChildCount');\n case 'element.click':\n await callElementMethod(entry, 'click');\n return null;\n case 'element.text':\n return callElementMethod(entry, 'text');\n case 'element.setText': {\n const { text } = payload as DriverElementPayload & DriverTextPayload;\n await callElementMethod(entry, 'setText', [text]);\n return null;\n }\n case 'element.isChecked':\n return callElementMethod(entry, 'isChecked');\n case 'element.toggle':\n await callElementMethod(entry, 'toggle');\n return null;\n case 'element.value':\n return callElementMethod(entry, 'value');\n case 'element.valueInfo':\n return callElementMethod(entry, 'valueInfo');\n case 'element.setValue': {\n const { value } = payload as DriverElementPayload & DriverValuePayload;\n await callElementMethod(entry, 'setValue', [value]);\n return null;\n }\n case 'element.increment':\n await callElementMethod(entry, 'increment');\n return null;\n case 'element.decrement':\n await callElementMethod(entry, 'decrement');\n return null;\n case 'element.getSelectedChildCount':\n return callElementMethod(entry, 'getSelectedChildCount');\n case 'element.selectedChildAt': {\n const { selectedIndex } = payload as DriverElementPayload &\n DriverSelectedIndexPayload;\n return optionalElementRef(\n entry.appId,\n (await callElementMethod(entry, 'selectedChildAt', [selectedIndex])) as\n | GtkWidgetElement\n | undefined\n );\n }\n case 'element.isChildSelected': {\n const { index } = payload as DriverElementPayload & DriverIndexPayload;\n return callElementMethod(entry, 'isChildSelected', [index]);\n }\n case 'element.selectChildAt': {\n const { index } = payload as DriverElementPayload & DriverIndexPayload;\n await callElementMethod(entry, 'selectChildAt', [index]);\n return null;\n }\n case 'element.deselectChildAt': {\n const { index } = payload as DriverElementPayload & DriverIndexPayload;\n await callElementMethod(entry, 'deselectChildAt', [index]);\n return null;\n }\n case 'element.selectAllChildren':\n await callElementMethod(entry, 'selectAllChildren');\n return null;\n case 'element.clearSelection':\n await callElementMethod(entry, 'clearSelection');\n return null;\n case 'element.getRowCount':\n return callElementMethod(entry, 'getRowCount');\n case 'element.getColumnCount':\n return callElementMethod(entry, 'getColumnCount');\n case 'element.cellAt': {\n const { column, row } = payload as DriverElementPayload &\n DriverTableCellPayload;\n return optionalElementRef(\n entry.appId,\n (await callElementMethod(entry, 'cellAt', [row, column])) as\n | GtkWidgetElement\n | undefined\n );\n }\n case 'element.selectedRows':\n return callElementMethod(entry, 'selectedRows');\n case 'element.selectedColumns':\n return callElementMethod(entry, 'selectedColumns');\n case 'element.isRowSelected': {\n const { row } = payload as DriverElementPayload & DriverTableCellPayload;\n return callElementMethod(entry, 'isRowSelected', [row]);\n }\n case 'element.isColumnSelected': {\n const { column } = payload as DriverElementPayload &\n DriverTableCellPayload;\n return callElementMethod(entry, 'isColumnSelected', [column]);\n }\n case 'element.isCellSelected': {\n const { column, row } = payload as DriverElementPayload &\n DriverTableCellPayload;\n return callElementMethod(entry, 'isCellSelected', [row, column]);\n }\n case 'element.selectRow': {\n const { row } = payload as DriverElementPayload & DriverTableCellPayload;\n await callElementMethod(entry, 'selectRow', [row]);\n return null;\n }\n case 'element.deselectRow': {\n const { row } = payload as DriverElementPayload & DriverTableCellPayload;\n await callElementMethod(entry, 'deselectRow', [row]);\n return null;\n }\n case 'element.selectColumn': {\n const { column } = payload as DriverElementPayload &\n DriverTableCellPayload;\n await callElementMethod(entry, 'selectColumn', [column]);\n return null;\n }\n case 'element.deselectColumn': {\n const { column } = payload as DriverElementPayload &\n DriverTableCellPayload;\n await callElementMethod(entry, 'deselectColumn', [column]);\n return null;\n }\n case 'element.imageInfo': {\n const info = (await callElementMethod(\n entry,\n 'imageInfo'\n )) as GtkImageInfo;\n return registerImageInfo(entry.appId, info);\n }\n default:\n throw createGtkOperationFailedError(\n `Unsupported element command: ${command}`\n );\n }\n};\n\nconst handleImageInfoCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n if (command !== 'imageInfo.capture') {\n throw createGtkOperationFailedError(\n `Unsupported image info command: ${command}`\n );\n }\n const { imageInfoId } = payload as DriverImageInfoPayload;\n const entry = resolveImageInfoEntry(imageInfoId);\n return toWireCapture(await entry.capture());\n};\n\nconst handleTrayCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n const { trayItemId } = trayPayload(payload);\n const entry = resolveTrayItemEntry(trayItemId);\n\n switch (command) {\n case 'tray.metadata':\n return entry.trayItem.metadata();\n case 'tray.element':\n return optionalElementRef(\n entry.appId,\n (await callTrayItemMethod(entry, 'element')) as\n | GtkWidgetElement\n | undefined\n );\n case 'tray.capture':\n return toWireCapture(await entry.trayItem.capture());\n case 'tray.click':\n await entry.trayItem.click();\n return null;\n case 'tray.openMenu':\n return optionalElementRef(\n entry.appId,\n (await callTrayItemMethod(entry, 'openMenu')) as\n | GtkWidgetElement\n | undefined\n );\n default:\n throw createGtkOperationFailedError(\n `Unsupported tray command: ${command}`\n );\n }\n};\n\nconst handleRequest = async (request: DriverRequest): Promise<unknown> => {\n if (request.command.startsWith('launcher.')) {\n return handleLauncherCommand(request.command, request.payload);\n }\n if (request.command.startsWith('app.')) {\n return handleAppCommand(request.command, request.payload);\n }\n if (request.command.startsWith('element.')) {\n return handleElementCommand(request.command, request.payload);\n }\n if (request.command.startsWith('imageInfo.')) {\n return handleImageInfoCommand(request.command, request.payload);\n }\n if (request.command.startsWith('tray.')) {\n return handleTrayCommand(request.command, request.payload);\n }\n throw createGtkOperationFailedError(\n `Unsupported launcher driver command: ${request.command}`\n );\n};\n\nconst writeResponse = (\n socket: Socket,\n id: number,\n response:\n | {\n readonly ok: true;\n readonly value: unknown;\n }\n | {\n readonly error: SerializedDriverError;\n readonly ok: false;\n }\n): void => {\n socket.write(`${JSON.stringify({ id, ...response })}\\n`);\n};\n\nconst handleRequestLine = async (\n socket: Socket,\n line: string\n): Promise<void> => {\n const request = JSON.parse(line) as DriverRequest;\n try {\n const value =\n request.deadlineMs === undefined || request.deadlineMs === null\n ? await handleRequest(request)\n : await runWithWaitDeadline(request.deadlineMs, () =>\n handleRequest(request)\n );\n writeResponse(socket, request.id, { ok: true, value });\n if (request.command === 'launcher.release') {\n socket.end();\n }\n } catch (error) {\n writeResponse(socket, request.id, {\n error: serializeError(error),\n ok: false,\n });\n }\n};\n\nconst installSocketProtocol = (socket: Socket): void => {\n let input = '';\n\n socket.on('data', (chunk: Buffer) => {\n input += chunk.toString('utf8');\n let newlineIndex = input.indexOf('\\n');\n while (newlineIndex >= 0) {\n const line = input.slice(0, newlineIndex);\n input = input.slice(newlineIndex + 1);\n void handleRequestLine(socket, line);\n newlineIndex = input.indexOf('\\n');\n }\n });\n\n socket.once('close', () => {\n void shutdown(0);\n });\n socket.once('error', () => {\n void shutdown(1);\n });\n};\n\nconst shutdown = async (exitCode: number): Promise<void> => {\n if (shuttingDown) {\n return;\n }\n shuttingDown = true;\n await releaseAll();\n process.exitCode = exitCode;\n setImmediate(() => {\n process.exit(exitCode);\n });\n};\n\nconst run = async (): Promise<void> => {\n const parsed = parseArguments(process.argv.slice(2));\n trayHostProcess = parsed.withTrayHost ? await startTrayHost() : undefined;\n\n const socket = await connectToParent(parsed.socketPath);\n installSocketProtocol(socket);\n writeReady(socket);\n\n process.once('SIGINT', () => {\n void shutdown(130);\n });\n process.once('SIGTERM', () => {\n void shutdown(143);\n });\n};\n\n/////////////////////////////////////////////////////////////////////////////////////////\n\nrun().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`gestament launcher driver: ${message}\\n`);\n process.exitCode = 2;\n});\n"],"names":["resolve","dirname","realpathSync","spawn","createConnection","createGtkAppExitedError","createGtkStaleElementError","createGtkUnsupportedInterfaceError","launchGtkApp","createGtkOperationFailedError","runWithWaitDeadline"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gestament-launcher-driver.cjs","sources":["../src/gestament-launcher-driver.ts"],"sourcesContent":["#!/usr/bin/env node\n// gestament - TypeScript based test driver for GTK.\n// Copyright (c) Kouji Matsui. (@kekyo@mi.kekyo.net)\n// Under MIT.\n// https://github.com/kekyo/gestament\n\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { createConnection, type Socket } from 'node:net';\nimport { realpathSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\n\nimport {\n createGtkAppExitedError,\n createGtkOperationFailedError,\n createGtkStaleElementError,\n createGtkUnsupportedInterfaceError,\n} from './errors';\nimport { createGtkAppEnvironment, launchGtkApp } from './launchGtkApp';\nimport { runWithWaitDeadline } from './wait';\nimport type {\n DriverEnvironmentPayload,\n DriverAppPayload,\n DriverAppRef,\n DriverCommand,\n DriverEventChannel,\n DriverElementPayload,\n DriverElementRef,\n DriverIdPayload,\n DriverImageInfoPayload,\n DriverIndexPayload,\n DriverLaunchPayload,\n DriverPathPayload,\n DriverReadyMessage,\n DriverRequest,\n DriverSelectedIndexPayload,\n DriverTableCellPayload,\n DriverTextPayload,\n DriverTrayItemRef,\n DriverTrayPayload,\n DriverTraySelectorPayload,\n DriverValuePayload,\n SerializedDriverError,\n WireCapture,\n WireGtkAppEnvironment,\n WireGtkAppOutput,\n WireGtkAppOutputEvent,\n WireGtkSystemOutput,\n WireImageInfo,\n} from './launcherDriverProtocol';\nimport type {\n GtkApp,\n GtkAppEnvironment,\n GtkCapture,\n GtkImageInfo,\n GtkTrayItem,\n GtkWidgetElement,\n LaunchGtkAppOptions,\n} from './types';\n\n/////////////////////////////////////////////////////////////////////////////////////////\n\ninterface DriverArguments {\n readonly socketPath: string;\n readonly withTrayHost: boolean;\n}\n\ninterface ElementEntry {\n readonly appId: string;\n readonly element: GtkWidgetElement;\n}\n\ninterface TrayItemEntry {\n readonly appId: string;\n readonly trayItem: GtkTrayItem;\n}\n\ninterface ImageInfoEntry {\n readonly appId: string;\n readonly capture: () => Promise<GtkCapture>;\n}\n\ntype AsyncMethod = (...args: unknown[]) => Promise<unknown>;\n\nconst trayHostReadyLine = 'gestament-tray-host-ready';\nconst trayHostReadyTimeoutMs = 30_000;\n\nconst apps = new Map<string, GtkApp>();\nconst elements = new Map<string, ElementEntry>();\nconst trayItems = new Map<string, TrayItemEntry>();\nconst imageInfos = new Map<string, ImageInfoEntry>();\nconst staleElementIds = new Set<string>();\nconst staleTrayItemIds = new Set<string>();\nconst staleImageInfoIds = new Set<string>();\n\nlet nextAppId = 1;\nlet nextElementId = 1;\nlet nextTrayItemId = 1;\nlet nextImageInfoId = 1;\nlet parentSocket: Socket | undefined;\nlet shuttingDown = false;\nlet trayHostProcess: ChildProcess | undefined;\n\nconst parseArguments = (args: readonly string[]): DriverArguments => {\n let socketPath: string | undefined;\n let withTrayHost = false;\n let index = 0;\n\n while (index < args.length) {\n const argument = args[index];\n\n if (argument === '--socket') {\n const value = args[index + 1];\n if (value === undefined || value.length === 0) {\n throw new Error('--socket requires a Unix socket path.');\n }\n socketPath = value;\n index += 2;\n continue;\n }\n\n if (argument === '--with-tray-host') {\n withTrayHost = true;\n index += 1;\n continue;\n }\n\n throw new Error(`Unknown gestament launcher driver option: ${argument}`);\n }\n\n if (socketPath === undefined) {\n throw new Error('Missing --socket option.');\n }\n\n return { socketPath, withTrayHost };\n};\n\nconst waitForTrayHostReady = (host: ChildProcess): Promise<void> =>\n new Promise<void>((resolveReady, rejectReady) => {\n if (host.stdout === null) {\n rejectReady(new Error('gestament tray host did not expose stdout.'));\n return;\n }\n\n let output = '';\n let settled = false;\n\n const timeout = setTimeout(() => {\n if (!settled) {\n settled = true;\n rejectReady(new Error('Timed out waiting for gestament tray host.'));\n }\n }, trayHostReadyTimeoutMs);\n\n host.stdout.on('data', (chunk: Buffer) => {\n const text = chunk.toString('utf8');\n output += text;\n const readyIndex = output.indexOf(trayHostReadyLine);\n if (!settled && readyIndex >= 0) {\n settled = true;\n clearTimeout(timeout);\n const beforeReady = output.slice(0, readyIndex);\n if (beforeReady.length > 0) {\n writeSystemOutputChunk('stdout', Buffer.from(beforeReady));\n }\n let afterReadyIndex = readyIndex + trayHostReadyLine.length;\n if (output.slice(afterReadyIndex, afterReadyIndex + 2) === '\\r\\n') {\n afterReadyIndex += 2;\n } else if (output[afterReadyIndex] === '\\n') {\n afterReadyIndex += 1;\n }\n const afterReady = output.slice(afterReadyIndex);\n if (afterReady.length > 0) {\n writeSystemOutputChunk('stdout', Buffer.from(afterReady));\n }\n resolveReady();\n return;\n }\n if (settled) {\n writeSystemOutputChunk('stdout', chunk);\n }\n });\n host.stdout.once('end', () => {\n writeSystemOutputFlush('stdout');\n });\n host.stderr?.on('data', (chunk: Buffer) => {\n writeSystemOutputChunk('stderr', chunk);\n });\n host.stderr?.once('end', () => {\n writeSystemOutputFlush('stderr');\n });\n\n host.once('exit', (code, signal) => {\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n rejectReady(\n new Error(\n `gestament tray host exited before ready: code=${String(\n code\n )}, signal=${String(signal)}`\n )\n );\n }\n });\n\n host.once('error', (error) => {\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n rejectReady(error);\n }\n });\n });\n\nconst startTrayHost = async (): Promise<ChildProcess> => {\n const executablePath = process.argv[1];\n if (executablePath === undefined) {\n throw new Error('Missing executable path.');\n }\n\n const hostPath = resolve(\n dirname(realpathSync(executablePath)),\n 'gestament-tray-host.cjs'\n );\n const host = spawn(process.execPath, [hostPath], {\n env: process.env,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n try {\n await waitForTrayHostReady(host);\n return host;\n } catch (error) {\n if (host.exitCode === null && host.signalCode === null) {\n host.kill('SIGTERM');\n }\n throw error;\n }\n};\n\nconst connectToParent = (socketPath: string): Promise<Socket> =>\n new Promise<Socket>((resolveConnect, rejectConnect) => {\n const socket = createConnection(socketPath);\n\n const rejectFromError = (error: Error): void => {\n socket.removeListener('connect', resolveFromConnect);\n rejectConnect(error);\n };\n const resolveFromConnect = (): void => {\n socket.removeListener('error', rejectFromError);\n resolveConnect(socket);\n };\n\n socket.once('error', rejectFromError);\n socket.once('connect', resolveFromConnect);\n });\n\nconst writeReady = (socket: Socket): void => {\n const ready: DriverReadyMessage = { type: 'ready' };\n socket.write(`${JSON.stringify(ready)}\\n`);\n};\n\nconst writeInternalTestOutput = (): void => {\n const stdout = process.env.GESTAMENT_TEST_DRIVER_SYSTEM_STDOUT;\n if (stdout !== undefined) {\n process.stdout.write(stdout);\n }\n const stderr = process.env.GESTAMENT_TEST_DRIVER_SYSTEM_STDERR;\n if (stderr !== undefined) {\n process.stderr.write(stderr);\n }\n};\n\nconst writePayloadInternalTestOutput = (env: WireGtkAppEnvironment): void => {\n const stdout = env.GESTAMENT_TEST_DRIVER_COMMAND_SYSTEM_STDOUT;\n if (stdout !== null && stdout !== undefined) {\n process.stdout.write(stdout);\n }\n const stderr = env.GESTAMENT_TEST_DRIVER_COMMAND_SYSTEM_STDERR;\n if (stderr !== null && stderr !== undefined) {\n process.stderr.write(stderr);\n }\n};\n\nconst writeDriverEvent = (\n channel: DriverEventChannel,\n scopeId: string,\n value: unknown\n): void => {\n try {\n parentSocket?.write(\n `${JSON.stringify({ channel, scopeId, type: 'event', value })}\\n`\n );\n } catch {\n // The parent process owns event delivery; ignore writes after disconnect.\n }\n};\n\nconst writeSystemOutputChunk = (\n stream: 'stdout' | 'stderr',\n chunk: Buffer\n): void => {\n const value: WireGtkSystemOutput = {\n chunkBase64: chunk.toString('base64'),\n source: 'tray-host',\n stream,\n type: 'chunk',\n };\n writeDriverEvent('system.output', 'system', value);\n};\n\nconst writeSystemOutputFlush = (stream: 'stdout' | 'stderr'): void => {\n const value: WireGtkSystemOutput = {\n source: 'tray-host',\n stream,\n type: 'flush',\n };\n writeDriverEvent('system.output', 'system', value);\n};\n\nconst wireEnvironmentToGtkAppEnvironment = (\n env: WireGtkAppEnvironment\n): GtkAppEnvironment => {\n const appEnv: Record<string, string | undefined> = {};\n for (const [key, value] of Object.entries(env)) {\n appEnv[key] = value === null ? undefined : value;\n }\n return appEnv;\n};\n\nconst gtkAppEnvironmentToWireEnvironment = (\n env: GtkAppEnvironment\n): WireGtkAppEnvironment => {\n const wireEnv: Record<string, string | null> = {};\n for (const [key, value] of Object.entries(env)) {\n wireEnv[key] = value ?? null;\n }\n return wireEnv;\n};\n\nconst toWireCapture = (capture: GtkCapture): WireCapture => ({\n bounds: capture.bounds,\n clipped: capture.clipped,\n imageBase64: capture.image.toString('base64'),\n visibleBounds: capture.visibleBounds,\n});\n\nconst registerApp = (app: GtkApp): DriverAppRef => {\n const appId = `app-${nextAppId}`;\n nextAppId += 1;\n apps.set(appId, app);\n return { appId };\n};\n\nconst registerElement = (\n appId: string,\n element: GtkWidgetElement\n): DriverElementRef => {\n const elementId = `element-${nextElementId}`;\n nextElementId += 1;\n elements.set(elementId, { appId, element });\n return { elementId, kind: element.kind };\n};\n\nconst registerTrayItem = (\n appId: string,\n trayItem: GtkTrayItem\n): DriverTrayItemRef => {\n const trayItemId = `tray-${nextTrayItemId}`;\n nextTrayItemId += 1;\n trayItems.set(trayItemId, { appId, trayItem });\n return { trayItemId };\n};\n\nconst registerImageInfo = (\n appId: string,\n info: GtkImageInfo\n): WireImageInfo => {\n const imageInfoId = `image-info-${nextImageInfoId}`;\n nextImageInfoId += 1;\n imageInfos.set(imageInfoId, { appId, capture: info.capture });\n return {\n bounds: info.bounds,\n description: info.description,\n imageInfoId,\n locale: info.locale,\n position: info.position,\n size: info.size,\n };\n};\n\nconst resolveApp = (appId: string): GtkApp => {\n const app = apps.get(appId);\n if (app === undefined) {\n throw createGtkAppExitedError(\n 'GTK application has exited or was released.'\n );\n }\n return app;\n};\n\nconst resolveElementEntry = (elementId: string): ElementEntry => {\n const entry = elements.get(elementId);\n if (entry === undefined) {\n if (staleElementIds.has(elementId)) {\n throw createGtkStaleElementError('GTK element is no longer available.');\n }\n throw createGtkAppExitedError('GTK element is not registered.');\n }\n if (!apps.has(entry.appId)) {\n throw createGtkStaleElementError('GTK element is no longer available.');\n }\n return entry;\n};\n\nconst resolveTrayItemEntry = (trayItemId: string): TrayItemEntry => {\n const entry = trayItems.get(trayItemId);\n if (entry === undefined) {\n if (staleTrayItemIds.has(trayItemId)) {\n throw createGtkStaleElementError('Tray item is no longer registered.');\n }\n throw createGtkAppExitedError('GTK tray item is not registered.');\n }\n if (!apps.has(entry.appId)) {\n throw createGtkStaleElementError('Tray item is no longer registered.');\n }\n return entry;\n};\n\nconst resolveImageInfoEntry = (imageInfoId: string): ImageInfoEntry => {\n const entry = imageInfos.get(imageInfoId);\n if (entry === undefined) {\n if (staleImageInfoIds.has(imageInfoId)) {\n throw createGtkStaleElementError(\n 'GTK image info is no longer available.'\n );\n }\n throw createGtkAppExitedError('GTK image info is not registered.');\n }\n if (!apps.has(entry.appId)) {\n throw createGtkStaleElementError('GTK image info is no longer available.');\n }\n return entry;\n};\n\nconst removeAppRefs = (appId: string): void => {\n for (const [elementId, entry] of elements) {\n if (entry.appId === appId) {\n staleElementIds.add(elementId);\n elements.delete(elementId);\n }\n }\n for (const [trayItemId, entry] of trayItems) {\n if (entry.appId === appId) {\n staleTrayItemIds.add(trayItemId);\n trayItems.delete(trayItemId);\n }\n }\n for (const [imageInfoId, entry] of imageInfos) {\n if (entry.appId === appId) {\n staleImageInfoIds.add(imageInfoId);\n imageInfos.delete(imageInfoId);\n }\n }\n};\n\nconst releaseApp = async (appId: string): Promise<void> => {\n const app = apps.get(appId);\n if (app === undefined) {\n return;\n }\n\n apps.delete(appId);\n removeAppRefs(appId);\n await app.release();\n};\n\nconst releaseApps = async (): Promise<void> => {\n const appIds = [...apps.keys()];\n await Promise.all(appIds.map((appId) => releaseApp(appId)));\n};\n\nconst stopTrayHost = (): void => {\n if (\n trayHostProcess !== undefined &&\n trayHostProcess.exitCode === null &&\n trayHostProcess.signalCode === null\n ) {\n trayHostProcess.kill('SIGTERM');\n }\n};\n\nconst releaseAll = async (): Promise<void> => {\n await releaseApps();\n stopTrayHost();\n};\n\nconst asMethod = (\n target: unknown,\n methodName: string,\n kindLabel: string\n): AsyncMethod => {\n const value = (target as Record<string, unknown>)[methodName];\n if (typeof value !== 'function') {\n throw createGtkUnsupportedInterfaceError(\n `${kindLabel} does not support ${methodName}().`\n );\n }\n return value as AsyncMethod;\n};\n\nconst callElementMethod = (\n entry: ElementEntry,\n methodName: string,\n args: unknown[] = []\n): Promise<unknown> =>\n asMethod(\n entry.element,\n methodName,\n `GTK ${entry.element.kind} element`\n )(...args);\n\nconst callTrayItemMethod = (\n entry: TrayItemEntry,\n methodName: string,\n args: unknown[] = []\n): Promise<unknown> =>\n asMethod(entry.trayItem, methodName, 'GTK tray item')(...args);\n\nconst serializeError = (error: unknown): SerializedDriverError => {\n if (error instanceof Error) {\n const maybeCode = (error as { code?: unknown }).code;\n const base = {\n message: error.message,\n name: error.name,\n };\n const withStack =\n error.stack === undefined ? base : { ...base, stack: error.stack };\n return typeof maybeCode === 'string'\n ? { ...withStack, code: maybeCode }\n : withStack;\n }\n\n return {\n message: String(error),\n name: 'Error',\n };\n};\n\nconst appPayload = (payload: unknown): DriverAppPayload =>\n payload as DriverAppPayload;\n\nconst elementPayload = (payload: unknown): DriverElementPayload =>\n payload as DriverElementPayload;\n\nconst trayPayload = (payload: unknown): DriverTrayPayload =>\n payload as DriverTrayPayload;\n\nconst optionalElementRef = (\n appId: string,\n element: GtkWidgetElement | undefined\n): DriverElementRef | null =>\n element === undefined ? null : registerElement(appId, element);\n\nconst optionalTrayItemRef = (\n appId: string,\n trayItem: GtkTrayItem | undefined\n): DriverTrayItemRef | null =>\n trayItem === undefined ? null : registerTrayItem(appId, trayItem);\n\nconst handleLauncherCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n switch (command) {\n case 'launcher.environment': {\n const environmentPayload = payload as DriverEnvironmentPayload;\n writePayloadInternalTestOutput(environmentPayload.env);\n return gtkAppEnvironmentToWireEnvironment(\n createGtkAppEnvironment(\n process.env,\n wireEnvironmentToGtkAppEnvironment(environmentPayload.env)\n )\n );\n }\n case 'launcher.launch': {\n const launchPayload = payload as DriverLaunchPayload;\n writePayloadInternalTestOutput(launchPayload.env);\n const outputScopeId = launchPayload.outputScopeId;\n const launchOptions: LaunchGtkAppOptions = {\n env: wireEnvironmentToGtkAppEnvironment(launchPayload.env),\n ...(launchPayload.outputBufferBytes === null\n ? {}\n : { outputBufferBytes: launchPayload.outputBufferBytes }),\n ...(outputScopeId === null\n ? {}\n : {\n onOutput: (event: WireGtkAppOutputEvent): void => {\n writeDriverEvent('app.output', outputScopeId, event);\n },\n }),\n ...(launchPayload.timeoutMs === null\n ? {}\n : { timeoutMs: launchPayload.timeoutMs }),\n };\n const app = await launchGtkApp(\n launchPayload.appPath,\n launchPayload.args,\n launchOptions\n );\n return registerApp(app);\n }\n case 'launcher.release':\n await releaseAll();\n return null;\n case 'launcher.reset':\n await releaseApps();\n return {\n appCount: apps.size,\n elementCount: elements.size,\n imageInfoCount: imageInfos.size,\n trayItemCount: trayItems.size,\n };\n default:\n throw createGtkOperationFailedError(`Unsupported command: ${command}`);\n }\n};\n\nconst handleAppCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n const { appId } = appPayload(payload);\n const app = resolveApp(appId);\n\n switch (command) {\n case 'app.environment':\n return gtkAppEnvironmentToWireEnvironment(await app.environment());\n case 'app.output':\n return (await app.output()) satisfies WireGtkAppOutput;\n case 'app.release':\n await releaseApp(appId);\n return null;\n case 'app.capture':\n return toWireCapture(await app.capture());\n case 'app.findById': {\n const { id } = payload as DriverAppPayload & DriverIdPayload;\n return optionalElementRef(appId, await app.findById(id));\n }\n case 'app.getById': {\n const { id } = payload as DriverAppPayload & DriverIdPayload;\n return registerElement(appId, await app.getById(id));\n }\n case 'app.findByPath': {\n const { path } = payload as DriverAppPayload & DriverPathPayload;\n return optionalElementRef(appId, await app.findByPath(path));\n }\n case 'app.getByPath': {\n const { path } = payload as DriverAppPayload & DriverPathPayload;\n return registerElement(appId, await app.getByPath(path));\n }\n case 'app.windowAt': {\n const { index } = payload as DriverAppPayload & DriverIndexPayload;\n return optionalElementRef(appId, await app.windowAt(index));\n }\n case 'app.getWindowCount':\n return app.getWindowCount();\n case 'app.findTrayItem': {\n const { selector } = payload as DriverAppPayload &\n DriverTraySelectorPayload;\n return optionalTrayItemRef(appId, await app.findTrayItem(selector));\n }\n case 'app.getTrayItem': {\n const { selector } = payload as DriverAppPayload &\n DriverTraySelectorPayload;\n return registerTrayItem(appId, await app.getTrayItem(selector));\n }\n case 'app.trayItemAt': {\n const { index } = payload as DriverAppPayload & DriverIndexPayload;\n return optionalTrayItemRef(appId, await app.trayItemAt(index));\n }\n case 'app.getTrayItemCount':\n return app.getTrayItemCount();\n default:\n throw createGtkOperationFailedError(\n `Unsupported app command: ${command}`\n );\n }\n};\n\nconst handleElementCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n const { elementId } = elementPayload(payload);\n const entry = resolveElementEntry(elementId);\n\n switch (command) {\n case 'element.info':\n return entry.element.info();\n case 'element.capture':\n return toWireCapture(await entry.element.capture());\n case 'element.bounds':\n return callElementMethod(entry, 'bounds');\n case 'window.resizeHints':\n return callElementMethod(entry, 'resizeHints');\n case 'window.x11Info':\n return callElementMethod(entry, 'x11Info');\n case 'element.childAt': {\n const { index } = payload as DriverElementPayload & DriverIndexPayload;\n return optionalElementRef(\n entry.appId,\n (await callElementMethod(entry, 'childAt', [index])) as\n | GtkWidgetElement\n | undefined\n );\n }\n case 'element.getChildCount':\n return callElementMethod(entry, 'getChildCount');\n case 'element.click':\n await callElementMethod(entry, 'click');\n return null;\n case 'element.text':\n return callElementMethod(entry, 'text');\n case 'element.setText': {\n const { text } = payload as DriverElementPayload & DriverTextPayload;\n await callElementMethod(entry, 'setText', [text]);\n return null;\n }\n case 'element.isChecked':\n return callElementMethod(entry, 'isChecked');\n case 'element.toggle':\n await callElementMethod(entry, 'toggle');\n return null;\n case 'element.value':\n return callElementMethod(entry, 'value');\n case 'element.valueInfo':\n return callElementMethod(entry, 'valueInfo');\n case 'element.setValue': {\n const { value } = payload as DriverElementPayload & DriverValuePayload;\n await callElementMethod(entry, 'setValue', [value]);\n return null;\n }\n case 'element.increment':\n await callElementMethod(entry, 'increment');\n return null;\n case 'element.decrement':\n await callElementMethod(entry, 'decrement');\n return null;\n case 'element.getSelectedChildCount':\n return callElementMethod(entry, 'getSelectedChildCount');\n case 'element.selectedChildAt': {\n const { selectedIndex } = payload as DriverElementPayload &\n DriverSelectedIndexPayload;\n return optionalElementRef(\n entry.appId,\n (await callElementMethod(entry, 'selectedChildAt', [selectedIndex])) as\n | GtkWidgetElement\n | undefined\n );\n }\n case 'element.isChildSelected': {\n const { index } = payload as DriverElementPayload & DriverIndexPayload;\n return callElementMethod(entry, 'isChildSelected', [index]);\n }\n case 'element.selectChildAt': {\n const { index } = payload as DriverElementPayload & DriverIndexPayload;\n await callElementMethod(entry, 'selectChildAt', [index]);\n return null;\n }\n case 'element.deselectChildAt': {\n const { index } = payload as DriverElementPayload & DriverIndexPayload;\n await callElementMethod(entry, 'deselectChildAt', [index]);\n return null;\n }\n case 'element.selectAllChildren':\n await callElementMethod(entry, 'selectAllChildren');\n return null;\n case 'element.clearSelection':\n await callElementMethod(entry, 'clearSelection');\n return null;\n case 'element.getRowCount':\n return callElementMethod(entry, 'getRowCount');\n case 'element.getColumnCount':\n return callElementMethod(entry, 'getColumnCount');\n case 'element.cellAt': {\n const { column, row } = payload as DriverElementPayload &\n DriverTableCellPayload;\n return optionalElementRef(\n entry.appId,\n (await callElementMethod(entry, 'cellAt', [row, column])) as\n | GtkWidgetElement\n | undefined\n );\n }\n case 'element.selectedRows':\n return callElementMethod(entry, 'selectedRows');\n case 'element.selectedColumns':\n return callElementMethod(entry, 'selectedColumns');\n case 'element.isRowSelected': {\n const { row } = payload as DriverElementPayload & DriverTableCellPayload;\n return callElementMethod(entry, 'isRowSelected', [row]);\n }\n case 'element.isColumnSelected': {\n const { column } = payload as DriverElementPayload &\n DriverTableCellPayload;\n return callElementMethod(entry, 'isColumnSelected', [column]);\n }\n case 'element.isCellSelected': {\n const { column, row } = payload as DriverElementPayload &\n DriverTableCellPayload;\n return callElementMethod(entry, 'isCellSelected', [row, column]);\n }\n case 'element.selectRow': {\n const { row } = payload as DriverElementPayload & DriverTableCellPayload;\n await callElementMethod(entry, 'selectRow', [row]);\n return null;\n }\n case 'element.deselectRow': {\n const { row } = payload as DriverElementPayload & DriverTableCellPayload;\n await callElementMethod(entry, 'deselectRow', [row]);\n return null;\n }\n case 'element.selectColumn': {\n const { column } = payload as DriverElementPayload &\n DriverTableCellPayload;\n await callElementMethod(entry, 'selectColumn', [column]);\n return null;\n }\n case 'element.deselectColumn': {\n const { column } = payload as DriverElementPayload &\n DriverTableCellPayload;\n await callElementMethod(entry, 'deselectColumn', [column]);\n return null;\n }\n case 'element.imageInfo': {\n const info = (await callElementMethod(\n entry,\n 'imageInfo'\n )) as GtkImageInfo;\n return registerImageInfo(entry.appId, info);\n }\n default:\n throw createGtkOperationFailedError(\n `Unsupported element command: ${command}`\n );\n }\n};\n\nconst handleImageInfoCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n if (command !== 'imageInfo.capture') {\n throw createGtkOperationFailedError(\n `Unsupported image info command: ${command}`\n );\n }\n const { imageInfoId } = payload as DriverImageInfoPayload;\n const entry = resolveImageInfoEntry(imageInfoId);\n return toWireCapture(await entry.capture());\n};\n\nconst handleTrayCommand = async (\n command: DriverCommand,\n payload: unknown\n): Promise<unknown> => {\n const { trayItemId } = trayPayload(payload);\n const entry = resolveTrayItemEntry(trayItemId);\n\n switch (command) {\n case 'tray.metadata':\n return entry.trayItem.metadata();\n case 'tray.element':\n return optionalElementRef(\n entry.appId,\n (await callTrayItemMethod(entry, 'element')) as\n | GtkWidgetElement\n | undefined\n );\n case 'tray.capture':\n return toWireCapture(await entry.trayItem.capture());\n case 'tray.click':\n await entry.trayItem.click();\n return null;\n case 'tray.openMenu':\n return optionalElementRef(\n entry.appId,\n (await callTrayItemMethod(entry, 'openMenu')) as\n | GtkWidgetElement\n | undefined\n );\n default:\n throw createGtkOperationFailedError(\n `Unsupported tray command: ${command}`\n );\n }\n};\n\nconst handleRequest = async (request: DriverRequest): Promise<unknown> => {\n if (request.command.startsWith('launcher.')) {\n return handleLauncherCommand(request.command, request.payload);\n }\n if (request.command.startsWith('app.')) {\n return handleAppCommand(request.command, request.payload);\n }\n if (request.command.startsWith('element.')) {\n return handleElementCommand(request.command, request.payload);\n }\n if (request.command.startsWith('window.')) {\n return handleElementCommand(request.command, request.payload);\n }\n if (request.command.startsWith('imageInfo.')) {\n return handleImageInfoCommand(request.command, request.payload);\n }\n if (request.command.startsWith('tray.')) {\n return handleTrayCommand(request.command, request.payload);\n }\n throw createGtkOperationFailedError(\n `Unsupported launcher driver command: ${request.command}`\n );\n};\n\nconst writeResponse = (\n socket: Socket,\n id: number,\n response:\n | {\n readonly ok: true;\n readonly value: unknown;\n }\n | {\n readonly error: SerializedDriverError;\n readonly ok: false;\n }\n): void => {\n socket.write(`${JSON.stringify({ id, ...response })}\\n`);\n};\n\nconst handleRequestLine = async (\n socket: Socket,\n line: string\n): Promise<void> => {\n const request = JSON.parse(line) as DriverRequest;\n try {\n const value =\n request.deadlineMs === undefined || request.deadlineMs === null\n ? await handleRequest(request)\n : await runWithWaitDeadline(request.deadlineMs, () =>\n handleRequest(request)\n );\n writeResponse(socket, request.id, { ok: true, value });\n if (request.command === 'launcher.release') {\n socket.end();\n }\n } catch (error) {\n writeResponse(socket, request.id, {\n error: serializeError(error),\n ok: false,\n });\n }\n};\n\nconst installSocketProtocol = (socket: Socket): void => {\n parentSocket = socket;\n let input = '';\n\n socket.on('data', (chunk: Buffer) => {\n input += chunk.toString('utf8');\n let newlineIndex = input.indexOf('\\n');\n while (newlineIndex >= 0) {\n const line = input.slice(0, newlineIndex);\n input = input.slice(newlineIndex + 1);\n void handleRequestLine(socket, line);\n newlineIndex = input.indexOf('\\n');\n }\n });\n\n socket.once('close', () => {\n parentSocket = undefined;\n void shutdown(0);\n });\n socket.once('error', () => {\n parentSocket = undefined;\n void shutdown(1);\n });\n};\n\nconst shutdown = async (exitCode: number): Promise<void> => {\n if (shuttingDown) {\n return;\n }\n shuttingDown = true;\n await releaseAll();\n process.exitCode = exitCode;\n setImmediate(() => {\n process.exit(exitCode);\n });\n};\n\nconst run = async (): Promise<void> => {\n const parsed = parseArguments(process.argv.slice(2));\n const socket = await connectToParent(parsed.socketPath);\n installSocketProtocol(socket);\n writeInternalTestOutput();\n trayHostProcess = parsed.withTrayHost ? await startTrayHost() : undefined;\n writeReady(socket);\n\n process.once('SIGINT', () => {\n void shutdown(130);\n });\n process.once('SIGTERM', () => {\n void shutdown(143);\n });\n};\n\n/////////////////////////////////////////////////////////////////////////////////////////\n\nrun().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`gestament launcher driver: ${message}\\n`);\n process.exitCode = 2;\n});\n"],"names":["resolve","dirname","realpathSync","spawn","createConnection","createGtkAppExitedError","createGtkStaleElementError","createGtkUnsupportedInterfaceError","createGtkAppEnvironment","launchGtkApp","createGtkOperationFailedError","runWithWaitDeadline"],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/*!
|
|
3
3
|
* name: gestament
|
|
4
|
-
* version: 0.
|
|
4
|
+
* version: 0.5.0
|
|
5
5
|
* description: TypeScript based test driver for GTK
|
|
6
6
|
* author: Kouji Matsui (@kekyo@mi.kekyo.net)
|
|
7
7
|
* license: MIT
|
|
8
8
|
* repository.url: https://github.com/kekyo/gestament.git
|
|
9
|
-
* git.commit.hash:
|
|
9
|
+
* git.commit.hash: 368fd995a6a10f20aea97cb0389ac3e12cfbedb3
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
export {};
|