@rightkit/qa 0.4.0 → 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.
Files changed (2) hide show
  1. package/README.md +24 -50
  2. package/package.json +4 -4
package/README.md CHANGED
@@ -1,73 +1,47 @@
1
- # `@rightkit/qa`
1
+ # @rightkit/qa
2
2
 
3
- > **Which QA tool?** To drive a Right Suite desktop app under test, use the Rust **`rightkit-qa`** crate with **`rightkit-control`**; that is the one supported engine. For a test browser only, use the zero-dependency **`@rightkit/qa-chrome`**. For an agent driving an installed app, use **`right-ctl`**. This package's WebdriverIO native lane & `right-qa` CLI were removed in 0.3.0.
3
+ Shared browser and QA primitives for Right Suite apps: run storage and evidence bundles, bearer-authenticated loopback control, owned-process cleanup, pane and frame checks, paint checks, workspace environment, a raw Chrome DevTools Protocol page driver, and the Chrome for Testing re-export.
4
4
 
5
- Shared QA primitives for Right Suite desktop apps. The package owns run locking, bearer-authenticated loopback control, deterministic evidence bundles, exact owned-process cleanup, and the guard that keeps development WebDriver access out of production builds.
6
-
7
- This package is intentionally private until the Windows and macOS phase gate passes. App repositories must never consume it through a Git, path, `file:`, `link:`, or `workspace:` dependency; adoption happens only after a registry version is published.
8
-
9
- ## Run storage
10
-
11
- Run roots, harness evidence, captures & summaries remain under `<managed>/runs/<app>/<run-id>`. App homes, profiles, service/port files, live logs & app-provided output paths use an owned internal system-temp companion recorded as `appRoot` in `.rightkit-run.json`. On macOS, companions always use `/private/tmp/rightkit-qa/<app-prefix>-<random>` with short names so launchd can open app files & control socket paths fit `sockaddr_un`.
12
-
13
- Finish copies app logs to managed `evidence/`, app-written evidence to `evidence/app/` & app captures to `captures/` before releasing ownership. Disposal removes temp companions; failed copies or cleanup preserve ownership metadata for recovery. Retention & orphan pruning validate companion bindings & protect live runs.
14
-
15
- Workspace env sets `RIGHTKIT_RUN_ROOT`, `HOME` & `USERPROFILE` to `home`; `RIGHTKIT_SUITE_ROOT` to `home/suite`; data/profile keys to `home/data`; `XDG_CACHE_HOME` to `home/cache`; `TMPDIR`, `TMP` & `TEMP` to `home/tmp`. `RIGHTKIT_QA_EVIDENCE_DIR` & `RIGHTKIT_QA_CAPTURE_DIR` use `home/evidence` & `home/captures`. The JS package supplies workspace env; native UI bundle staging & unique per-launch suite/service identity belong to Rust `control::launch`.
5
+ | Item | Value |
6
+ |---|---|
7
+ | Where it runs | Dev and test tooling (Node, and browser-driven test harnesses) |
8
+ | Rust pair | None declared. For native desktop QA use the Rust `rightkit-qa` crate with `rightkit-control`. |
9
+ | Version | see INDEX.md |
10
+ | License | MIT OR Apache-2.0 |
16
11
 
17
- ## Chrome for Testing (`@rightkit/qa/chrome`)
12
+ ## Entry points
18
13
 
19
- Web/CDP harnesses launch Chrome for Testing, never regular Google Chrome: on macOS each regular Chrome instance clones its app bundle under `<DARWIN_USER_TEMP_DIR>/../X/com.google.Chrome.code_sign_clone/`, and a killed instance leaks that clone.
14
+ | Import | Contents |
15
+ |---|---|
16
+ | `@rightkit/qa` | `export *` from evidence, frames, guard, loopback, ownership, paint, panes, process, workspace, storage, page and chrome modules. Includes `QaBrowserSession`, `QaPage`, `QaElement`, `QaKeyboard`, `TimeoutError`. |
17
+ | `@rightkit/qa/chrome` | Re-export of `@rightkit/qa-chrome` |
20
18
 
21
- - `resolveChromeForTesting({ executablePath? })` resolves the explicit option, then `RIGHTKIT_CHROME_FOR_TESTING`, then `/Applications` and `~/Applications` app installs, then the newest Puppeteer (`~/.cache/puppeteer`, `PUPPETEER_CACHE_DIR`) and Playwright (`~/Library/Caches/ms-playwright`, `PLAYWRIGHT_BROWSERS_PATH`) builds. It throws `ChromeForTestingNotFoundError` with install instructions; it never falls back. `findChromeForTesting()` returns `{ path }` or `{ reason }` for test skips.
22
- - `launchChromeForTesting(options)` starts it in its own process group with a temp profile and returns `{ wsEndpoint, port, pid, profileDir, close() }`. Launch one browser per suite and open targets per test.
23
- - `close()` / `closeChromeGracefully()` sends CDP `Browser.close`, waits up to 5 s, sends SIGTERM to the process group (`taskkill /T` on Windows), waits again, sends SIGKILL only last, then removes the profile. It reports the step that ended the tree.
24
- - `codeSignCloneEntries()` lists the macOS clone entries so tests can assert that none appear.
19
+ Dependency: `@rightkit/qa-chrome` (exact `0.1.3`).
25
20
 
26
- ## Raw CDP page driver (Node 26)
21
+ Peer dependencies: none.
27
22
 
28
- `QaBrowserSession`, `QaPage`, `QaElement`, `QaKeyboard` & `TimeoutError` are exported from `@rightkit/qa`. Transport uses Node's built-in `WebSocket` directly; no Puppeteer, Playwright, or CDP wrapper dependency.
23
+ ## Example
29
24
 
30
25
  ```ts
31
- import { launchChromeForTesting, QaBrowserSession } from '@rightkit/qa';
26
+ import { launchChromeForTesting, QaBrowserSession } from "@rightkit/qa";
32
27
 
33
28
  const chrome = await launchChromeForTesting();
34
29
  const browser = await QaBrowserSession.connect(chrome.wsEndpoint);
35
30
  try {
36
31
  const page = await browser.newPage();
37
32
  await page.setViewport({ width: 1280, height: 720, deviceScaleFactor: 1 });
38
- await page.evaluateOnNewDocument(() => { window.localStorage.setItem('qa', '1'); });
39
- await page.goto('http://127.0.0.1:3000', { waitUntil: 'networkidle0', timeout: 10_000 });
40
- const button = await page.waitForSelector('button', { visible: true });
33
+ await page.goto("http://127.0.0.1:3000", { waitUntil: "networkidle0", timeout: 10_000 });
34
+ const button = await page.waitForSelector("button", { visible: true });
41
35
  await button?.click();
42
- await button?.dispose();
43
- await page.screenshot({ path: 'viewport.png', type: 'png', captureBeyondViewport: false });
36
+ await page.screenshot({ path: "viewport.png" });
44
37
  } finally {
45
38
  try { await browser.close(); } finally { await chrome.close(); }
46
39
  }
47
40
  ```
48
41
 
49
- Session owns targets it creates; launcher owns browser process & profile. `connect(endpoint, { timeout, debug })` defaults to 30,000 ms per connection/command, with logging off. Positive finite deadlines apply to navigation & waits; failures use typed `TimeoutError`. `page.on(cdpMethod, listener)` subscribes to page-session events & returns an unsubscribe function. Debug callbacks receive method names only. Throwing event subscribers are isolated from transport state.
50
-
51
- Evaluation uses main frame's default execution context, awaits promises & returns values by JSON. Functions run in Chrome, so pass external values as arguments rather than closing over Node variables. JavaScript exceptions become `Error` with Chrome's message. `evaluateOnNewDocument` accepts function + arguments or source text & runs before document scripts, including subsequent reloads.
52
-
53
- `goto`/`reload` support `load`, `domcontentloaded` & `networkidle0` (zero outstanding requests for 500 ms). `waitForSelector` supports present/visible/hidden states; hidden waits return `null`. `waitForFunction` supports animation-frame or positive millisecond polling & resolves when predicate is truthy. Both name selector/predicate in timeout errors. `$`/`$$` return remote element handles, released by `dispose()`, navigation, or page closure.
42
+ The page driver uses Node's built-in `WebSocket`. It has no Puppeteer or Playwright dependency. Method names mirror Puppeteer's for the common calls (`goto`, `click`, `evaluate`, `waitForSelector`, `screenshot`).
54
43
 
55
- Click/hover scroll elements into view & use box centres. Mouse, keyboard & text input use CDP `Input` commands; `select` dispatches DOM `input`/`change` after selecting values. Keyboard supports required navigation/editing keys, letters/digits & modifier chords such as `Control+A`, `Meta+A`, or `Shift+ArrowLeft`. Screenshots return `Buffer`, optionally write `path`, & capture viewport PNG at configured DPR; `fullPage` & `captureBeyondViewport` support `false` only.
56
-
57
- | Puppeteer | QaPage equivalent |
58
- |---|---|
59
- | `puppeteer.connect({ browserWSEndpoint })` | `QaBrowserSession.connect(wsEndpoint)` |
60
- | `browser.newPage()` / `browser.close()` | Same calls; session closes owned targets |
61
- | `page.goto()` / `reload()` / `close()` | Same calls & navigation options |
62
- | `page.setViewport()` | Same call; CDP device metrics |
63
- | `page.evaluateOnNewDocument()` | Same call; function or source |
64
- | `page.evaluate()` / `$eval()` / `$$eval()` | Same calls; JSON results & awaited promises |
65
- | `page.waitForSelector()` | Same options; `QaElement` or `null` |
66
- | `page.waitForFunction()` | Same predicate/options/arguments; returns `void` |
67
- | `page.$()` / `page.$$()` | `QaElement` / `QaElement[]` |
68
- | `element.click/type/hover/focus/boundingBox/evaluate/dispose()` | Same calls on `QaElement` |
69
- | `page.click/type/hover/focus/select()` | Same calls; click accepts selector or handle |
70
- | `page.keyboard.press()` | Same call; named key or modifier chord |
71
- | `page.screenshot()` | Viewport PNG `Buffer`; optional `path` |
44
+ ## Known issues
72
45
 
73
- `pnpm --dir packages/qa test` runs mock-WebSocket unit tests & real Chrome for Testing integration against local static fixture. Install Chrome through `@rightkit/qa-chrome` or set `RIGHTKIT_CHROME_FOR_TESTING`; integration requires Chrome & does not silently skip.
46
+ - `@rightkit/qa-chrome` is pinned exactly to `0.1.3`. A qa-chrome release therefore needs a `@rightkit/qa` republish to reach consumers (npm audit 2026-10-08, qa finding).
47
+ - Three consumers pin three different versions of `@rightkit/qa-chrome` as dev dependencies (npm audit 2026-10-08).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rightkit/qa",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Shared QA evidence, ownership, browser helpers, and release-backdoor guards for Right Suite apps.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "type": "module",
@@ -37,12 +37,12 @@
37
37
  },
38
38
  "repository": {
39
39
  "type": "git",
40
- "url": "git+https://github.com/bogusyogi/claude.git",
41
- "directory": "tools/rightkit/packages/qa"
40
+ "url": "git+https://github.com/bogusyogi/rightkit.git",
41
+ "directory": "packages/qa"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc -p tsconfig.json",
45
45
  "typecheck": "tsc -p tsconfig.json --noEmit",
46
- "test": "vitest run && node --test public-storage.test.mjs"
46
+ "test": "pnpm --filter @rightkit/qa-chrome build && pnpm run build && vitest run && node --test public-storage.test.mjs"
47
47
  }
48
48
  }