From bd7b166fdaf17cda0084ed639bd227391c302d7f Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 7 May 2026 14:43:55 +0000 Subject: [PATCH] =?UTF-8?q?chore(nests):=20mv=20nestsClient-browser-intero?= =?UTF-8?q?p/=20=E2=86=92=20nestsClient/tests/browser-interop/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors the existing nestsClient/tests/hang-interop/ layout — all T16 cross-stack interop test infrastructure (Rust sidecars + bun browser harness) now lives under nestsClient/tests/. Updates: - nestsClient/build.gradle.kts: browserInteropDir path. - PlaywrightDriver.kt + BrowserInteropTest.kt: kdoc comments. - All plan docs in nestsClient/plans/ that referenced the old path. Compiles clean post-move. No CI changes (those jobs are intentionally not wired per 2026-05-07-cross-stack-interop-ci-gating.md; when re-added they'll reference the new path). --- nestsClient/build.gradle.kts | 4 ++-- ...-05-06-cross-stack-interop-test-results.md | 4 ++-- .../2026-05-06-cross-stack-interop-test.md | 14 +++++------ ...26-05-06-i4-stereo-cross-stack-scenario.md | 2 +- ...26-05-06-phase4-browser-harness-results.md | 2 +- .../2026-05-06-phase4-browser-harness.md | 24 +++++++++---------- ...026-05-07-cross-stack-interop-ci-gating.md | 12 +++++----- .../interop/native/BrowserInteropTest.kt | 2 +- .../interop/native/PlaywrightDriver.kt | 2 +- .../tests/browser-interop}/.gitignore | 0 .../tests/browser-interop}/REV | 0 .../tests/browser-interop}/bun.lock | 0 .../tests/browser-interop}/package.json | 0 .../browser-interop}/playwright.config.ts | 0 .../tests/browser-interop}/src/listen.html | 0 .../tests/browser-interop}/src/listen.ts | 0 .../tests/browser-interop}/src/publish.html | 0 .../tests/browser-interop}/src/publish.ts | 0 .../tests/browser-interop}/src/server.ts | 0 .../browser-interop}/tests/harness.spec.ts | 0 .../tests/browser-interop}/tsconfig.json | 0 21 files changed, 33 insertions(+), 33 deletions(-) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/.gitignore (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/REV (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/bun.lock (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/package.json (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/playwright.config.ts (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/src/listen.html (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/src/listen.ts (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/src/publish.html (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/src/publish.ts (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/src/server.ts (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/tests/harness.spec.ts (100%) rename {nestsClient-browser-interop => nestsClient/tests/browser-interop}/tsconfig.json (100%) diff --git a/nestsClient/build.gradle.kts b/nestsClient/build.gradle.kts index 68a9b94e2..d85e6a809 100644 --- a/nestsClient/build.gradle.kts +++ b/nestsClient/build.gradle.kts @@ -232,7 +232,7 @@ tasks.withType().configureEach { // ---- Cross-stack interop: BROWSER (Phase 4 of T16) -------------------------- // // Adds the bun + Playwright + headless Chromium harness at -// `nestsClient-browser-interop/`. Mirrors the hang-interop wiring above +// `nestsClient/tests/browser-interop/`. Mirrors the hang-interop wiring above // but with bun/npx subprocesses instead of cargo. Opt-in via // `-DnestsBrowserInterop=true`. See: // nestsClient/plans/2026-05-06-phase4-browser-harness.md @@ -249,7 +249,7 @@ tasks.withType().configureEach { // paths the agents/host runner ship with. val browserInteropDir = - rootProject.layout.projectDirectory.dir("nestsClient-browser-interop") + rootProject.layout.projectDirectory.dir("nestsClient/tests/browser-interop") // `bun` lives at `/root/.bun/bin/bun` on the agent runner. CI may put it // elsewhere; allow override via env / system property. Falls back to diff --git a/nestsClient/plans/2026-05-06-cross-stack-interop-test-results.md b/nestsClient/plans/2026-05-06-cross-stack-interop-test-results.md index 50e4e6d7b..e770c1907 100644 --- a/nestsClient/plans/2026-05-06-cross-stack-interop-test-results.md +++ b/nestsClient/plans/2026-05-06-cross-stack-interop-test-results.md @@ -379,7 +379,7 @@ adds an explicit goaway frame, the test would slot in here. Running in agent worktree (`feat/nests-browser-interop`). Adds: -- `nestsClient-browser-interop/` — TypeScript + Vite project shipping +- `nestsClient/tests/browser-interop/` — TypeScript + Vite project shipping the upstream `@kixelated/moq` and `@kixelated/hang-wasm` consumers/ publishers, bundled into static `listen.html` / `publish.html` pages. @@ -492,7 +492,7 @@ nestsClient/src/jvmTest/kotlin/com/vitorpamplona/nestsclient/ # In sister branches (not yet merged): # feat/nests-i6-multi-listener -> HangInteropMultiListenerTest.kt (I6) # feat/nests-i7-publisher-reconnect -> HangInteropReverseTest.kt (I7) -# feat/nests-browser-interop -> nestsClient-browser-interop/ + +# feat/nests-browser-interop -> nestsClient/tests/browser-interop/ + # BrowserInteropTest.kt (Phase 4) nestsClient/plans/2026-05-06-cross-stack-interop-test-results.md # this file diff --git a/nestsClient/plans/2026-05-06-cross-stack-interop-test.md b/nestsClient/plans/2026-05-06-cross-stack-interop-test.md index 0b4a2e3c4..56f7b1b48 100644 --- a/nestsClient/plans/2026-05-06-cross-stack-interop-test.md +++ b/nestsClient/plans/2026-05-06-cross-stack-interop-test.md @@ -196,10 +196,10 @@ Behaviour: standard tokio UDP relay. For each datagram received, ### Browser harness (bun + Playwright) -New module at `nestsClient-browser-interop/`. +New module at `nestsClient/tests/browser-interop/`. ``` -nestsClient-browser-interop/ +nestsClient/tests/browser-interop/ ├── package.json ├── tsconfig.json ├── src/ @@ -225,7 +225,7 @@ nestsClient-browser-interop/ ``` Pin to the same npm versions that `nostrnests/nests` `NestsUI-v2/package.json` -ships. Document the rev in `nestsClient-browser-interop/REV`. +ships. Document the rev in `nestsClient/tests/browser-interop/REV`. #### `listen.ts` Mirrors NostrNests' `transport/moq-transport.ts` `Watch.Broadcast` @@ -552,7 +552,7 @@ Total: ~5 days. P0 deliverable (1+2+4) is **3 days**. ### Phase 4 — Browser harness (1.5 days) -15. Bootstrap `nestsClient-browser-interop/`: bun init, install +15. Bootstrap `nestsClient/tests/browser-interop/`: bun init, install `@moq/lite` `@moq/watch` `@moq/publish` `@moq/hang` at pinned versions matching `nostrnests/nests` `NestsUI-v2`. Document rev. 16. Write `listen.ts` + `pcm-tap-worklet.ts` + `listen.html`. Mirror @@ -618,8 +618,8 @@ jobs: path: | ~/.cargo/registry ~/.cache/ms-playwright - nestsClient-browser-interop/node_modules - key: ${{ runner.os }}-browser-${{ hashFiles('nestsClient-browser-interop/bun.lockb', 'nestsClient/tests/hang-interop/Cargo.lock') }} + nestsClient/tests/browser-interop/node_modules + key: ${{ runner.os }}-browser-${{ hashFiles('nestsClient/tests/browser-interop/bun.lockb', 'nestsClient/tests/hang-interop/Cargo.lock') }} - run: ./gradlew :nestsClient:jvmTest -DnestsBrowserInterop=true ``` @@ -664,7 +664,7 @@ Acceptable for PR-level CI. committed at `nestsClient/plans/2026-05-06-cross-stack-interop-test-gap-matrix.md`. 6. Both `-DnestsHangInterop=true` and `-DnestsBrowserInterop=true` in the default PR-level GitHub Actions config. -7. `nestsClient/tests/hang-interop/REV` and `nestsClient-browser-interop/REV` +7. `nestsClient/tests/hang-interop/REV` and `nestsClient/tests/browser-interop/REV` document the pinned upstream revs. 8. New plan filed at `nestsClient/plans/2026-05-06-cross-stack-interop-test-results.md` diff --git a/nestsClient/plans/2026-05-06-i4-stereo-cross-stack-scenario.md b/nestsClient/plans/2026-05-06-i4-stereo-cross-stack-scenario.md index e62577e07..18cf40fd3 100644 --- a/nestsClient/plans/2026-05-06-i4-stereo-cross-stack-scenario.md +++ b/nestsClient/plans/2026-05-06-i4-stereo-cross-stack-scenario.md @@ -331,7 +331,7 @@ tests stay green. - **5.1 / spatial audio.** Catalog field is `numberOfChannels`, but the audio pipeline assumes interleaved planar — beyond stereo would need a separate plan. -- **Browser side I4.** `nestsClient-browser-interop/` doesn't +- **Browser side I4.** `nestsClient/tests/browser-interop/` doesn't exist yet (Phase 4 of the parent plan); when it lands the same I4 shape ports straight to a `BrowserInteropTest`. - **Per-channel mute.** The existing `setMuted(true)` mutes the diff --git a/nestsClient/plans/2026-05-06-phase4-browser-harness-results.md b/nestsClient/plans/2026-05-06-phase4-browser-harness-results.md index aba42caa8..e69c6861a 100644 --- a/nestsClient/plans/2026-05-06-phase4-browser-harness-results.md +++ b/nestsClient/plans/2026-05-06-phase4-browser-harness-results.md @@ -6,7 +6,7 @@ the spec at `nestsClient/plans/2026-05-06-phase4-browser-harness.md`. ## Where it landed -- New top-level `nestsClient-browser-interop/` workspace: +- New top-level `nestsClient/tests/browser-interop/` workspace: - `package.json` pins `@moq/lite@0.2.2`, `@moq/hang@0.2.4`, `@moq/watch@0.2.10`, `@moq/publish@0.2.6`, `@playwright/test@1.56.1`. - `REV` documents the pinned versions next to the diff --git a/nestsClient/plans/2026-05-06-phase4-browser-harness.md b/nestsClient/plans/2026-05-06-phase4-browser-harness.md index fbd58c859..06d2c1162 100644 --- a/nestsClient/plans/2026-05-06-phase4-browser-harness.md +++ b/nestsClient/plans/2026-05-06-phase4-browser-harness.md @@ -65,7 +65,7 @@ Phase 1 — no Docker, no second relay, no fake auth sidecar. ▼ ▼ ▼ ┌──────────────────────┐ ┌──────────────────┐ ┌─────────────────────────────┐ │ NativeMoqRelayHarness│ │ Kotlin in-proc │ │ Browser harness │ - │ (existing — Phase 1) │ │ speaker / listener│ │ nestsClient-browser-interop/│ + │ (existing — Phase 1) │ │ speaker / listener│ │ nestsClient/tests/browser-interop/│ │ moq-relay subprocess │ │ via │ │ - bun static + WS server │ │ 127.0.0.1: │ │ connectNestsSpeaker │ - listen.html + listen.ts │ │ --auth-public "" │ │ connectNestsListener │ - publish.html+publish.ts │ @@ -79,13 +79,13 @@ Phase 1 — no Docker, no second relay, no fake auth sidecar. ## Components -### 1. `nestsClient-browser-interop/` — bun + Playwright workspace +### 1. `nestsClient/tests/browser-interop/` — bun + Playwright workspace New top-level directory, mirrors the parent plan's specification. Contents: ``` -nestsClient-browser-interop/ +nestsClient/tests/browser-interop/ ├── package.json ├── tsconfig.json ├── bun.lockb # pinned via REV file @@ -103,7 +103,7 @@ nestsClient-browser-interop/ Pin all `@moq/*` deps to the same versions `nostrnests/nests` ships in `NestsUI-v2/package.json`. Document the rev in -`nestsClient-browser-interop/REV` (parallel to +`nestsClient/tests/browser-interop/REV` (parallel to `nestsClient/tests/hang-interop/REV`). ### 2. `listen.ts` — browser listener @@ -168,14 +168,14 @@ the relay's auto-generated cert without parsing). val interopBuildBrowserHarness by tasks.registering(Exec::class) { description = "bun install && bun build for the browser interop harness" group = "interop" - workingDir = file("nestsClient-browser-interop") + workingDir = file("nestsClient/tests/browser-interop") commandLine("bash", "-c", "bun install && bun build src/listen.ts src/publish.ts src/pcm-tap-worklet.ts --outdir dist --target browser") inputs.files( - fileTree("nestsClient-browser-interop") { + fileTree("nestsClient/tests/browser-interop") { include("package.json", "bun.lockb", "src/**/*") } ) - outputs.dir("nestsClient-browser-interop/dist") + outputs.dir("nestsClient/tests/browser-interop/dist") } ``` @@ -185,7 +185,7 @@ A second task installs Playwright's Chromium: val interopInstallPlaywrightChromium by tasks.registering(Exec::class) { description = "Install Playwright Chromium + dependencies" group = "interop" - workingDir = file("nestsClient-browser-interop") + workingDir = file("nestsClient/tests/browser-interop") commandLine("bash", "-c", "npx playwright install --with-deps chromium") onlyIf { // Skip if Chromium binary exists in the cache @@ -205,7 +205,7 @@ tasks.withType().configureEach { } systemProperty( "nestsBrowserInteropHarnessDir", - file("nestsClient-browser-interop").absolutePath, + file("nestsClient/tests/browser-interop").absolutePath, ) System.getProperty("nestsBrowserInterop")?.let { systemProperty("nestsBrowserInterop", it) @@ -288,7 +288,7 @@ Total: ~1.5 days. ### Phase 4.A — bun harness scaffold (~3 hr) -1. `bun init` in `nestsClient-browser-interop/`. Pin `@moq/lite`, +1. `bun init` in `nestsClient/tests/browser-interop/`. Pin `@moq/lite`, `@moq/watch`, `@moq/publish`, `@moq/hang` to the versions `nostrnests/nests` `NestsUI-v2/package.json` ships at the time of implementation. Document in `REV`. @@ -351,7 +351,7 @@ method). 13. Add `browser-interop` job to `.github/workflows/build.yml` parallel to `hang-interop`. Cache - `nestsClient-browser-interop/node_modules` and + `nestsClient/tests/browser-interop/node_modules` and `~/.cache/ms-playwright` on the bun.lockb hash. 14. Run `./gradlew :nestsClient:jvmTest -DnestsBrowserInterop=true` on Linux runners. macOS / Windows would double the matrix @@ -373,7 +373,7 @@ method). ## Definition of done -1. `nestsClient-browser-interop/` directory complete with +1. `nestsClient/tests/browser-interop/` directory complete with bun + Playwright + sources building cleanly via `interopBuildBrowserHarness`. 2. P0 scenarios green: I1 forward, I2, I3, I13, I14 (and I4 diff --git a/nestsClient/plans/2026-05-07-cross-stack-interop-ci-gating.md b/nestsClient/plans/2026-05-07-cross-stack-interop-ci-gating.md index 5f19f3168..e0bf068b2 100644 --- a/nestsClient/plans/2026-05-07-cross-stack-interop-ci-gating.md +++ b/nestsClient/plans/2026-05-07-cross-stack-interop-ci-gating.md @@ -73,13 +73,13 @@ browser-interop: - uses: actions/cache@v4 with: path: | - nestsClient-browser-interop/node_modules - nestsClient-browser-interop/dist - key: ${{ runner.os }}-bun-${{ hashFiles('nestsClient-browser-interop/package.json', 'nestsClient-browser-interop/bun.lock') }} + nestsClient/tests/browser-interop/node_modules + nestsClient/tests/browser-interop/dist + key: ${{ runner.os }}-bun-${{ hashFiles('nestsClient/tests/browser-interop/package.json', 'nestsClient/tests/browser-interop/bun.lock') }} - uses: actions/cache@v4 with: path: ~/.cache/ms-playwright - key: ${{ runner.os }}-playwright-${{ hashFiles('nestsClient-browser-interop/package.json') }} + key: ${{ runner.os }}-playwright-${{ hashFiles('nestsClient/tests/browser-interop/package.json') }} - name: Run browser cross-stack interop suite run: | ./gradlew :nestsClient:jvmTest \ @@ -92,8 +92,8 @@ browser-interop: name: Browser Interop Test Reports path: | nestsClient/build/reports/tests/jvmTest/ - nestsClient-browser-interop/test-results/ - nestsClient-browser-interop/playwright-report/ + nestsClient/tests/browser-interop/test-results/ + nestsClient/tests/browser-interop/playwright-report/ ``` Same `git show b94737de7 -- .github/workflows/build.yml` reverse diff --git a/nestsClient/src/jvmTest/kotlin/com/vitorpamplona/nestsclient/interop/native/BrowserInteropTest.kt b/nestsClient/src/jvmTest/kotlin/com/vitorpamplona/nestsclient/interop/native/BrowserInteropTest.kt index 5eb406d89..834b8fe99 100644 --- a/nestsClient/src/jvmTest/kotlin/com/vitorpamplona/nestsclient/interop/native/BrowserInteropTest.kt +++ b/nestsClient/src/jvmTest/kotlin/com/vitorpamplona/nestsclient/interop/native/BrowserInteropTest.kt @@ -138,7 +138,7 @@ class BrowserInteropTest { * `Container.Consumer`", but two constraints reshape this here: * * 1. `@moq/hang` 0.2.4 (the published version pinned in - * `nestsClient-browser-interop/package.json`) does not export + * `nestsClient/tests/browser-interop/package.json`) does not export * the high-level `Container.Consumer` / `Format` API. Phase 4 * uses `Container.Legacy.Consumer` directly — same data path * `@moq/watch` uses internally for `container.kind = "legacy"`. diff --git a/nestsClient/src/jvmTest/kotlin/com/vitorpamplona/nestsclient/interop/native/PlaywrightDriver.kt b/nestsClient/src/jvmTest/kotlin/com/vitorpamplona/nestsclient/interop/native/PlaywrightDriver.kt index 5f7ae6edb..143124825 100644 --- a/nestsClient/src/jvmTest/kotlin/com/vitorpamplona/nestsclient/interop/native/PlaywrightDriver.kt +++ b/nestsClient/src/jvmTest/kotlin/com/vitorpamplona/nestsclient/interop/native/PlaywrightDriver.kt @@ -52,7 +52,7 @@ internal object PlaywrightDriver { const val ENABLE_PROPERTY = "nestsBrowserInterop" /** - * Forwarded by Gradle: absolute path to `nestsClient-browser-interop/`. + * Forwarded by Gradle: absolute path to `nestsClient/tests/browser-interop/`. */ const val HARNESS_DIR_PROPERTY = "nestsBrowserInteropHarnessDir" diff --git a/nestsClient-browser-interop/.gitignore b/nestsClient/tests/browser-interop/.gitignore similarity index 100% rename from nestsClient-browser-interop/.gitignore rename to nestsClient/tests/browser-interop/.gitignore diff --git a/nestsClient-browser-interop/REV b/nestsClient/tests/browser-interop/REV similarity index 100% rename from nestsClient-browser-interop/REV rename to nestsClient/tests/browser-interop/REV diff --git a/nestsClient-browser-interop/bun.lock b/nestsClient/tests/browser-interop/bun.lock similarity index 100% rename from nestsClient-browser-interop/bun.lock rename to nestsClient/tests/browser-interop/bun.lock diff --git a/nestsClient-browser-interop/package.json b/nestsClient/tests/browser-interop/package.json similarity index 100% rename from nestsClient-browser-interop/package.json rename to nestsClient/tests/browser-interop/package.json diff --git a/nestsClient-browser-interop/playwright.config.ts b/nestsClient/tests/browser-interop/playwright.config.ts similarity index 100% rename from nestsClient-browser-interop/playwright.config.ts rename to nestsClient/tests/browser-interop/playwright.config.ts diff --git a/nestsClient-browser-interop/src/listen.html b/nestsClient/tests/browser-interop/src/listen.html similarity index 100% rename from nestsClient-browser-interop/src/listen.html rename to nestsClient/tests/browser-interop/src/listen.html diff --git a/nestsClient-browser-interop/src/listen.ts b/nestsClient/tests/browser-interop/src/listen.ts similarity index 100% rename from nestsClient-browser-interop/src/listen.ts rename to nestsClient/tests/browser-interop/src/listen.ts diff --git a/nestsClient-browser-interop/src/publish.html b/nestsClient/tests/browser-interop/src/publish.html similarity index 100% rename from nestsClient-browser-interop/src/publish.html rename to nestsClient/tests/browser-interop/src/publish.html diff --git a/nestsClient-browser-interop/src/publish.ts b/nestsClient/tests/browser-interop/src/publish.ts similarity index 100% rename from nestsClient-browser-interop/src/publish.ts rename to nestsClient/tests/browser-interop/src/publish.ts diff --git a/nestsClient-browser-interop/src/server.ts b/nestsClient/tests/browser-interop/src/server.ts similarity index 100% rename from nestsClient-browser-interop/src/server.ts rename to nestsClient/tests/browser-interop/src/server.ts diff --git a/nestsClient-browser-interop/tests/harness.spec.ts b/nestsClient/tests/browser-interop/tests/harness.spec.ts similarity index 100% rename from nestsClient-browser-interop/tests/harness.spec.ts rename to nestsClient/tests/browser-interop/tests/harness.spec.ts diff --git a/nestsClient-browser-interop/tsconfig.json b/nestsClient/tests/browser-interop/tsconfig.json similarity index 100% rename from nestsClient-browser-interop/tsconfig.json rename to nestsClient/tests/browser-interop/tsconfig.json