@gtkx/vitest 0.20.0 → 1.0.0-rc.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/README.md +122 -55
- package/dist/headless-display.d.ts +30 -0
- package/dist/headless-display.d.ts.map +1 -0
- package/dist/headless-display.js +250 -0
- package/dist/headless-display.js.map +1 -0
- package/dist/index.d.ts +19 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +53 -1
- package/dist/index.js.map +1 -1
- package/dist/notification-service.d.ts +2 -0
- package/dist/notification-service.d.ts.map +1 -0
- package/dist/notification-service.js +47 -0
- package/dist/notification-service.js.map +1 -0
- package/dist/worker-preload.d.ts +2 -0
- package/dist/worker-preload.d.ts.map +1 -0
- package/dist/worker-preload.js +6 -0
- package/dist/worker-preload.js.map +1 -0
- package/dist/worker-setup.d.ts +6 -0
- package/dist/worker-setup.d.ts.map +1 -0
- package/dist/worker-setup.js +10 -0
- package/dist/worker-setup.js.map +1 -0
- package/package.json +16 -7
- package/src/dbus-native.d.ts +17 -0
- package/src/headless-display.ts +330 -0
- package/src/index.ts +69 -1
- package/src/notification-service.ts +54 -0
- package/src/worker-preload.ts +7 -0
- package/src/worker-setup.ts +15 -0
- package/dist/plugin.d.ts +0 -22
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -36
- package/dist/plugin.js.map +0 -1
- package/dist/setup.d.ts +0 -2
- package/dist/setup.d.ts.map +0 -1
- package/dist/setup.js +0 -44
- package/dist/setup.js.map +0 -1
- package/src/plugin.ts +0 -41
- package/src/setup.ts +0 -52
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { installGracefulShutdown } from "@gtkx/utils";
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
var gtkxHeadlessTeardown: (() => void) | undefined;
|
|
5
|
+
var gtkxHeadlessShutdownInstalled: boolean | undefined;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const installHeadlessShutdown = (): void => {
|
|
9
|
+
const teardown = globalThis.gtkxHeadlessTeardown;
|
|
10
|
+
if (teardown === undefined || globalThis.gtkxHeadlessShutdownInstalled === true) return;
|
|
11
|
+
globalThis.gtkxHeadlessShutdownInstalled = true;
|
|
12
|
+
installGracefulShutdown({ onSignal: teardown });
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
installHeadlessShutdown();
|
package/dist/plugin.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vitest/config";
|
|
2
|
-
/**
|
|
3
|
-
* Creates the GTKX Vitest plugin for running GTK tests.
|
|
4
|
-
*
|
|
5
|
-
* Each worker spawns its own Xvfb instance on a PID-based display number.
|
|
6
|
-
*
|
|
7
|
-
* @returns Vitest plugin configuration
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* // vitest.config.ts
|
|
12
|
-
* import { defineConfig } from "vitest/config";
|
|
13
|
-
* import gtkx from "@gtkx/vitest";
|
|
14
|
-
*
|
|
15
|
-
* export default defineConfig({
|
|
16
|
-
* plugins: [gtkx()],
|
|
17
|
-
* });
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
declare const gtkx: () => Plugin;
|
|
21
|
-
export default gtkx;
|
|
22
|
-
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,IAAI,QAAO,MAgBhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
package/dist/plugin.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
/**
|
|
3
|
-
* Creates the GTKX Vitest plugin for running GTK tests.
|
|
4
|
-
*
|
|
5
|
-
* Each worker spawns its own Xvfb instance on a PID-based display number.
|
|
6
|
-
*
|
|
7
|
-
* @returns Vitest plugin configuration
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* // vitest.config.ts
|
|
12
|
-
* import { defineConfig } from "vitest/config";
|
|
13
|
-
* import gtkx from "@gtkx/vitest";
|
|
14
|
-
*
|
|
15
|
-
* export default defineConfig({
|
|
16
|
-
* plugins: [gtkx()],
|
|
17
|
-
* });
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
const gtkx = () => {
|
|
21
|
-
const workerSetupPath = join(import.meta.dirname, "setup.js");
|
|
22
|
-
return {
|
|
23
|
-
name: "gtkx",
|
|
24
|
-
config(config) {
|
|
25
|
-
const setupFiles = config.test?.setupFiles ?? [];
|
|
26
|
-
return {
|
|
27
|
-
test: {
|
|
28
|
-
setupFiles: [workerSetupPath, ...(Array.isArray(setupFiles) ? setupFiles : [setupFiles])],
|
|
29
|
-
pool: "forks",
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
export default gtkx;
|
|
36
|
-
//# sourceMappingURL=plugin.js.map
|
package/dist/plugin.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,IAAI,GAAG,GAAW,EAAE;IACtB,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAE9D,OAAO;QACH,IAAI,EAAE,MAAM;QACZ,MAAM,CAAC,MAAM;YACT,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC;YAEjD,OAAO;gBACH,IAAI,EAAE;oBACF,UAAU,EAAE,CAAC,eAAe,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;oBACzF,IAAI,EAAE,OAAO;iBAChB;aACJ,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
package/dist/setup.d.ts
DELETED
package/dist/setup.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":""}
|
package/dist/setup.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
|
-
import { beforeAll } from "vitest";
|
|
4
|
-
const display = 100 + (process.pid % 5000);
|
|
5
|
-
const socketPath = `/tmp/.X11-unix/X${display}`;
|
|
6
|
-
const xvfb = spawn("Xvfb", [`:${display}`, "-screen", "0", "1024x768x24"], {
|
|
7
|
-
stdio: "ignore",
|
|
8
|
-
});
|
|
9
|
-
xvfb.unref();
|
|
10
|
-
process.env.GDK_BACKEND = "x11";
|
|
11
|
-
process.env.GSK_RENDERER = "cairo";
|
|
12
|
-
process.env.LIBGL_ALWAYS_SOFTWARE = "1";
|
|
13
|
-
process.env.DISPLAY = `:${display}`;
|
|
14
|
-
const killXvfb = () => {
|
|
15
|
-
if (xvfb.pid !== undefined) {
|
|
16
|
-
try {
|
|
17
|
-
process.kill(xvfb.pid, "SIGTERM");
|
|
18
|
-
}
|
|
19
|
-
catch { }
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
process.on("exit", killXvfb);
|
|
23
|
-
process.on("SIGTERM", () => {
|
|
24
|
-
killXvfb();
|
|
25
|
-
process.exit(143);
|
|
26
|
-
});
|
|
27
|
-
process.on("SIGINT", () => {
|
|
28
|
-
killXvfb();
|
|
29
|
-
process.exit(130);
|
|
30
|
-
});
|
|
31
|
-
const waitForDisplay = async (timeout = 5000) => {
|
|
32
|
-
const start = Date.now();
|
|
33
|
-
while (Date.now() - start < timeout) {
|
|
34
|
-
if (existsSync(socketPath)) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
38
|
-
}
|
|
39
|
-
throw new Error(`Xvfb display :${display} did not become available within ${timeout}ms`);
|
|
40
|
-
};
|
|
41
|
-
beforeAll(async () => {
|
|
42
|
-
await waitForDisplay();
|
|
43
|
-
});
|
|
44
|
-
//# sourceMappingURL=setup.js.map
|
package/dist/setup.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnC,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;AAC3C,MAAM,UAAU,GAAG,mBAAmB,OAAO,EAAE,CAAC;AAEhD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,OAAO,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,CAAC,EAAE;IACvE,KAAK,EAAE,QAAQ;CAClB,CAAC,CAAC;AAEH,IAAI,CAAC,KAAK,EAAE,CAAC;AAEb,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC;AAChC,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,OAAO,CAAC;AACnC,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,GAAG,CAAC;AACxC,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAEpC,MAAM,QAAQ,GAAG,GAAS,EAAE;IACxB,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACd,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAE7B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,QAAQ,EAAE,CAAC;IACX,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,QAAQ,EAAE,CAAC;IACX,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,KAAK,EAAE,OAAO,GAAG,IAAI,EAAiB,EAAE;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,OAAO,EAAE,CAAC;QAClC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACzB,OAAO;QACX,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iBAAiB,OAAO,oCAAoC,OAAO,IAAI,CAAC,CAAC;AAC7F,CAAC,CAAC;AAEF,SAAS,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,cAAc,EAAE,CAAC;AAC3B,CAAC,CAAC,CAAC"}
|
package/src/plugin.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
|
|
3
|
-
import type { Plugin } from "vitest/config";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Creates the GTKX Vitest plugin for running GTK tests.
|
|
7
|
-
*
|
|
8
|
-
* Each worker spawns its own Xvfb instance on a PID-based display number.
|
|
9
|
-
*
|
|
10
|
-
* @returns Vitest plugin configuration
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* // vitest.config.ts
|
|
15
|
-
* import { defineConfig } from "vitest/config";
|
|
16
|
-
* import gtkx from "@gtkx/vitest";
|
|
17
|
-
*
|
|
18
|
-
* export default defineConfig({
|
|
19
|
-
* plugins: [gtkx()],
|
|
20
|
-
* });
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
const gtkx = (): Plugin => {
|
|
24
|
-
const workerSetupPath = join(import.meta.dirname, "setup.js");
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
name: "gtkx",
|
|
28
|
-
config(config) {
|
|
29
|
-
const setupFiles = config.test?.setupFiles ?? [];
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
test: {
|
|
33
|
-
setupFiles: [workerSetupPath, ...(Array.isArray(setupFiles) ? setupFiles : [setupFiles])],
|
|
34
|
-
pool: "forks",
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export default gtkx;
|
package/src/setup.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
|
-
import { beforeAll } from "vitest";
|
|
4
|
-
|
|
5
|
-
const display = 100 + (process.pid % 5000);
|
|
6
|
-
const socketPath = `/tmp/.X11-unix/X${display}`;
|
|
7
|
-
|
|
8
|
-
const xvfb = spawn("Xvfb", [`:${display}`, "-screen", "0", "1024x768x24"], {
|
|
9
|
-
stdio: "ignore",
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
xvfb.unref();
|
|
13
|
-
|
|
14
|
-
process.env.GDK_BACKEND = "x11";
|
|
15
|
-
process.env.GSK_RENDERER = "cairo";
|
|
16
|
-
process.env.LIBGL_ALWAYS_SOFTWARE = "1";
|
|
17
|
-
process.env.DISPLAY = `:${display}`;
|
|
18
|
-
|
|
19
|
-
const killXvfb = (): void => {
|
|
20
|
-
if (xvfb.pid !== undefined) {
|
|
21
|
-
try {
|
|
22
|
-
process.kill(xvfb.pid, "SIGTERM");
|
|
23
|
-
} catch {}
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
process.on("exit", killXvfb);
|
|
28
|
-
|
|
29
|
-
process.on("SIGTERM", () => {
|
|
30
|
-
killXvfb();
|
|
31
|
-
process.exit(143);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
process.on("SIGINT", () => {
|
|
35
|
-
killXvfb();
|
|
36
|
-
process.exit(130);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
const waitForDisplay = async (timeout = 5000): Promise<void> => {
|
|
40
|
-
const start = Date.now();
|
|
41
|
-
while (Date.now() - start < timeout) {
|
|
42
|
-
if (existsSync(socketPath)) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
46
|
-
}
|
|
47
|
-
throw new Error(`Xvfb display :${display} did not become available within ${timeout}ms`);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
beforeAll(async () => {
|
|
51
|
-
await waitForDisplay();
|
|
52
|
-
});
|