@nyssance/tauri-hasgard 0.2.1 → 0.4.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 CHANGED
@@ -29,6 +29,50 @@ export const { test, expect } = createHasgardTest({
29
29
 
30
30
  The fixture passes the selected socket to the application as `TAURI_HASGARD_SOCKET`, so each Playwright worker receives an isolated connection.
31
31
 
32
+ On macOS, a managed launch owns a detached process group. Teardown
33
+ waits for that group to exit, including children left behind by a launcher,
34
+ and escalates from SIGTERM to SIGKILL after five seconds. Startup failures also
35
+ clean up, and concurrent `stop()` calls share the same cleanup. A live endpoint
36
+ is rejected rather than unlinked; readiness requires a successful connection.
37
+ If cleanup fails, ownership is retained so `stop()` can be retried; another
38
+ launch is blocked until that cleanup succeeds.
39
+ Diagnostics retain the last 64 Ki characters per output stream with a truncation
40
+ marker. `await process.diagnostics()` exposes those tails and the actual exit
41
+ code or signal. Failed tests attach them; a failed screenshot does not replace
42
+ the original test error. Teardown removes the owned stale socket after its
43
+ process group exits, checking its identity and preserving live or replaced paths.
44
+
45
+ An independent supervisor owns the application and watches the worker's IPC
46
+ connection. If the worker is killed with SIGKILL, the supervisor still terminates
47
+ the application group and exits. Killing the supervisor itself or children that
48
+ deliberately create a new session or process group are outside this guarantee.
49
+ Attach-only fixtures do not terminate an application they did not launch.
50
+
51
+ `window.press(key)` uses native OS input and, by default, waits for a trusted
52
+ WebView keyup before the next press may switch windows. For OS shortcuts and
53
+ keys that navigate or close the document, explicitly use
54
+ `window.press(key, { completion: "native" })`; that mode confirms posting only.
55
+ Bare modifiers also use native posting completion. The active input method
56
+ remains in effect: use `fill` for exact text, and `Shift+m` for a shifted key.
57
+
58
+ To keep keyboard ownership until an application state is observable:
59
+
60
+ ```ts
61
+ await window.press("Tab", {
62
+ waitFor: "document.activeElement.id === 'save'",
63
+ timeoutMs: 1_000
64
+ })
65
+ ```
66
+
67
+ The postcondition timeout is capped at ten seconds. Failures retain their
68
+ `HasgardRpcError.data.phase` and `injected` status; never blindly retry an
69
+ already-injected or uncertain press. See [the wire contract](../../docs/protocol.md#native-keyboard-completion).
70
+
71
+ Requests are limited to 1,048,576 UTF-8 bytes including the trailing newline,
72
+ matching the plugin. Oversized requests fail before transmission. An explicit
73
+ null result is supported; malformed responses are rejected instead of returning
74
+ an invented value.
75
+
32
76
  ## Test
33
77
 
34
78
  ```ts
@@ -0,0 +1,31 @@
1
+ // src/process-group.js
2
+ import { setTimeout as delay } from "timers/promises";
3
+ function signalGroup(pid, signal) {
4
+ try {
5
+ process.kill(-pid, signal);
6
+ return true;
7
+ } catch (error) {
8
+ if (error.code === "ESRCH") return false;
9
+ if (signal === 0 && error.code === "EPERM") return true;
10
+ throw error;
11
+ }
12
+ }
13
+ async function waitForExit(pid, timeoutMs) {
14
+ const deadline = Date.now() + timeoutMs;
15
+ while (signalGroup(pid, 0)) {
16
+ if (Date.now() >= deadline) return false;
17
+ await delay(25);
18
+ }
19
+ return true;
20
+ }
21
+ async function stopProcessGroup(pid) {
22
+ signalGroup(pid, "SIGTERM");
23
+ if (!await waitForExit(pid, 5e3)) {
24
+ signalGroup(pid, "SIGKILL");
25
+ if (!await waitForExit(pid, 5e3)) throw new Error(`Hasgard process group ${pid} survived SIGKILL`);
26
+ }
27
+ }
28
+
29
+ export {
30
+ stopProcessGroup
31
+ };
package/dist/index.d.ts CHANGED
@@ -3,5 +3,5 @@ export { createHasgardExpect } from "./expect.js";
3
3
  export { createHasgardTest } from "./fixture.js";
4
4
  export { HasgardProcess } from "./process-manager.js";
5
5
  export { HasgardRpcClient, HasgardRpcError } from "./rpc-client.js";
6
- export type { BoundingBox, ConsoleLogEntry, ConsoleLogOptions, DialogListing, DialogPolicy, DialogRecord, DialogType, DiffChange, DiffOptions, DragOffset, DropFile, FileInput, FilterOptions, FormEntry, FormField, FormsDump, HasgardFixtures, HasgardLaunchConfig, HasgardTarget, HasgardTestConfig, HasgardWorkerFixtures, JsonPrimitive, JsonValue, NativeScreenshot, NativeScreenshotOptions, NetworkRequestEntry, NetworkRequestOptions, QueryDimension, RecorderEntry, RecorderResult, RecorderStatus, RoleQuery, ScrollOptions, Snapshot, SnapshotDiff, SnapshotElement, SnapshotOptions, StorageEntry, StorageListing, StorageOptions, TextQuery, WaitForFunctionOptions, WaitOptions, WatchChanges, WatchNode, WatchOptions, WindowInfo, WindowState } from "./types.js";
7
- export { byPoint, byRef, bySelector, HasgardApplication, HasgardLocator, HasgardWindow } from "./window.js";
6
+ export type { BoundingBox, ClickOptions, ConsoleLogEntry, ConsoleLogOptions, DialogListing, DialogPolicy, DialogRecord, DialogType, DiffChange, DiffOptions, DragOffset, DropFile, ElementPosition, FileInput, FilterOptions, FormEntry, FormField, FormsDump, FulfillOptions, HasgardFixtures, HasgardLaunchConfig, HasgardTarget, HasgardTestConfig, HasgardWorkerFixtures, InterceptedRequest, JsonPrimitive, JsonValue, KeyModifier, MouseButton, NativeScreenshot, NativeScreenshotOptions, NetworkRequestEntry, NetworkRequestOptions, PressOptions, QueryDimension, RecorderEntry, RecorderResult, RecorderStatus, RoleQuery, RouteListing, RouteOptions, RouteRule, ScrollOptions, Snapshot, SnapshotDiff, SnapshotElement, SnapshotOptions, StorageEntry, StorageListing, StorageOptions, TextQuery, WaitForFunctionOptions, WaitOptions, WatchChanges, WatchNode, WatchOptions, WindowInfo, WindowState } from "./types.js";
7
+ export { byPoint, byRef, bySelector, HasgardApplication, HasgardFrameLocator, HasgardLocator, HasgardWindow } from "./window.js";