mirror of
https://github.com/aaddrick/claude-desktop-debian.git
synced 2026-05-17 00:26:21 +03:00
Build out a Playwright-based regression-detection harness covering the compat-matrix surfaces (KDE-W, KDE-X, GNOME, Sway, i3, Niri, packaging formats). Adds: - Planning + decision docs under docs/testing/ — README, matrix, runbook, automation, cases/ (11 case files), quick-entry-closeout - Playwright scaffolding (config, tsconfig) - 78 spec runners under tools/test-harness/src/runners/ — T## case- doc runners and S## distribution/smoke runners - Substrate primitives in tools/test-harness/src/lib/: AX-tree loader (snapshotAx + waitForAxNode + axTreeToSnapshot), focus- shifter, eipc-registry, niri-native bridge, drag-drop bridge, electron-mocks, claudeai page-objects, inspector client S03 (DEB Depends declared) and S04 (RPM Requires declared) ship marked test.fail() — they're regression detectors for the case-doc gap (deb.sh emits no Depends:, rpm.sh sets AutoReqProv: no), and the expected-failure shape lets them report green on every host until upstream packaging starts declaring runtime deps. 127 files, no runtime changes; harness is opt-in via 'cd tools/test-harness && npx playwright test'. Co-authored-by: Claude <claude@anthropic.com>
198 lines
9.9 KiB
Markdown
198 lines
9.9 KiB
Markdown
# Code Tab — Foundations
|
|
|
|
Tests covering Code-tab availability on Linux (officially unsupported per upstream docs), sign-in flow, folder picker, drag-and-drop, and the basic editing surfaces (terminal, file pane). See [`../matrix.md`](../matrix.md) for status.
|
|
|
|
## T15 — Sign-in completes in the embedded webview
|
|
|
|
> **Drift in build 1.5354.0** — Sign-in is an in-app `mainView.webContents.loadURL` flow, not an `xdg-open` browser handoff. Claude.ai/login renders inside the embedded BrowserView; the resulting `sessionKey` cookie is then exchanged at `${apiHost}/v1/oauth/${org}/authorize` with redirect URI `https://claude.ai/desktop/callback`. No system browser is involved.
|
|
|
|
**Severity:** Smoke
|
|
**Surface:** Auth / embedded webview
|
|
**Applies to:** All rows
|
|
**Issues:** —
|
|
|
|
**Steps:**
|
|
1. Launch a fresh app instance (signed-out state).
|
|
2. Click **Sign in**. Observe claude.ai/login rendering inside the app.
|
|
3. Authenticate. Observe the in-app navigation completing back to the
|
|
workspace.
|
|
|
|
**Expected:** Sign-in stays inside the embedded webview (`will-navigate`
|
|
handler `Ihr` keeps `/login/` paths in-app). After auth the
|
|
`sessionKey` cookie is captured and silently exchanged for an OAuth
|
|
token via the `desktop/callback` redirect. Account dropdown populates;
|
|
no auth banner remains.
|
|
|
|
**Diagnostics on failure:** DevTools console for the `mainView`
|
|
BrowserView, network captures of the `/v1/oauth/{org}/authorize` and
|
|
`/v1/oauth/token` calls, launcher log, cookie jar inspection
|
|
(`sessionKey` on `.claude.ai`).
|
|
|
|
**References:** [Code tab auth troubleshooting](https://code.claude.com/docs/en/desktop#403-or-authentication-errors-in-the-code-tab)
|
|
|
|
**Code anchors:**
|
|
- `build-reference/app-extracted/.vite/build/index.js:141996` — desktop
|
|
OAuth redirect URI `https://claude.ai/desktop/callback`
|
|
- `build-reference/app-extracted/.vite/build/index.js:142431` — POST to
|
|
`${apiHost}/v1/oauth/${org}/authorize` with `Bearer ${sessionKey}`
|
|
- `build-reference/app-extracted/.vite/build/index.js:216565` — `Ihr`
|
|
treats `/login/` paths as in-app (not external)
|
|
- `build-reference/app-extracted/.vite/build/index.js:141316` —
|
|
`mainView.webContents.loadURL(...)` drives the embedded sign-in
|
|
|
|
## T16 — Code tab loads
|
|
|
|
**Severity:** Smoke
|
|
**Surface:** Code tab — top-level UI
|
|
**Applies to:** All rows
|
|
**Issues:** —
|
|
|
|
**Steps:**
|
|
1. After sign-in, click the **Code** tab at the top center.
|
|
2. Wait a few seconds.
|
|
|
|
**Expected:** Code tab renders the session UI (sidebar, prompt area, environment dropdown). Per upstream docs the Code tab is "not supported" on Linux — the patched build under this project should render the UI normally or surface a clear, actionable message. Not a blank screen, infinite spinner, or `Error 403: Forbidden`.
|
|
|
|
**Diagnostics on failure:** Screenshot, DevTools console, network captures (auth/feature-flag responses), launcher log, the active patch set in `scripts/patches/`.
|
|
|
|
**References:** [Use Claude Code Desktop](https://code.claude.com/docs/en/desktop), [Get started with the desktop app](https://code.claude.com/docs/en/desktop-quickstart)
|
|
|
|
**Code anchors:**
|
|
- `build-reference/app-extracted/.vite/build/index.js:525066` —
|
|
`sidebarMode === "code"` rewrites the BrowserView path to `/epitaxy`
|
|
- `build-reference/app-extracted/.vite/build/index.js:496066` — Code
|
|
deeplinks (`claude://code?...`) navigate to `/epitaxy?...`
|
|
- `build-reference/app-extracted/.vite/build/index.js:105273` — `IHi`
|
|
recognises `/epitaxy` and `/epitaxy/...` as the Code-tab path
|
|
- `build-reference/app-extracted/.vite/build/index.js:105346` —
|
|
`sidebarMode` enum contains `"code"`
|
|
|
|
**Inventory anchor:** `…tablist.tab-by-name.code` (role `tab`, label
|
|
`Code`) — confirms the Code tab is reachable from the new-chat tablist
|
|
in the captured idle state.
|
|
|
|
## T17 — Folder picker opens
|
|
|
|
**Severity:** Smoke
|
|
**Surface:** Code tab → Environment selection
|
|
**Applies to:** All rows
|
|
**Issues:** —
|
|
**Runner:** [`tools/test-harness/src/runners/T17_folder_picker.spec.ts`](../../../tools/test-harness/src/runners/T17_folder_picker.spec.ts) — runtime-attach via SIGUSR1 + main-process `dialog.showOpenDialog` mock + `webContents.executeJavaScript` to drive the renderer. Click chain to reach the folder-picker button awaits selector tuning
|
|
|
|
**Steps:**
|
|
1. In the Code tab, click the environment pill → **Local** → **Select folder**.
|
|
2. Choose a project directory.
|
|
|
|
**Expected:** Native file chooser opens. On Wayland sessions the chooser is `xdg-desktop-portal`-backed (verify with `busctl --user tree org.freedesktop.portal.Desktop`). On X11 sessions the GTK/Qt native picker fires. Selected path appears in the env pill.
|
|
|
|
**Diagnostics on failure:** `systemctl --user status xdg-desktop-portal`, `XDG_SESSION_TYPE`, the portal backend in use (`xdg-desktop-portal-kde`, `xdg-desktop-portal-gnome`, `xdg-desktop-portal-wlr`), launcher log.
|
|
|
|
**References:** [Local sessions](https://code.claude.com/docs/en/desktop#local-sessions)
|
|
|
|
**Code anchors:**
|
|
- `build-reference/app-extracted/.vite/build/index.js:66403` — IPC
|
|
channel `claude.web_FileSystem_browseFolder` (renderer → main)
|
|
- `build-reference/app-extracted/.vite/build/index.js:509188` —
|
|
`browseFolder` impl calls `dialog.showOpenDialog` with
|
|
`properties: ["openDirectory", "createDirectory"]`
|
|
- `build-reference/app-extracted/.vite/build/index.js:450534` —
|
|
`grantViaPicker` (Operon host-access folder grant) uses the same
|
|
`["openDirectory"]` shape
|
|
- `tools/test-harness/src/lib/claudeai.ts:122` — `installOpenDialogMock`
|
|
intercepts both `(opts)` and `(window, opts)` arities, matching the
|
|
call sites at index.js:509196 and :450534
|
|
|
|
**Inventory anchor:** `root.main.region.button-by-name.select-folder`
|
|
(role `button`, label `Select folder…`) — the persistent button the
|
|
T17 runner clicks before the dialog mock fires.
|
|
|
|
## T18 — Drag-and-drop files into prompt
|
|
|
|
**Severity:** Critical
|
|
**Surface:** Code tab → Prompt area
|
|
**Applies to:** All rows
|
|
**Issues:** —
|
|
|
|
**Steps:**
|
|
1. Open a Code-tab session.
|
|
2. From the system file manager, drag one or more files into the prompt area.
|
|
3. Repeat with multiple files at once.
|
|
|
|
**Expected:** Files attach to the prompt. The renderer resolves dropped
|
|
`File` objects to absolute paths via the preload-bridged
|
|
`claudeAppSettings.filePickers.getPathForFile` (Electron's
|
|
`webUtils.getPathForFile`). Multi-file drops attach each file. Works on
|
|
both Wayland and X11.
|
|
|
|
**Diagnostics on failure:** Screen recording, `wl-paste --list-types` (Wayland) or `xclip -selection clipboard -t TARGETS -o` (X11) during drag, DevTools console, launcher log.
|
|
|
|
**References:** [Add files and context](https://code.claude.com/docs/en/desktop#add-files-and-context-to-prompts)
|
|
|
|
**Code anchors:**
|
|
- `build-reference/app-extracted/.vite/build/mainView.js:9267` —
|
|
`filePickers.getPathForFile` wraps `webUtils.getPathForFile`
|
|
- `build-reference/app-extracted/.vite/build/mainView.js:9552` —
|
|
exposed to the renderer as `window.claudeAppSettings`
|
|
|
|
## T19 — Integrated terminal
|
|
|
|
**Severity:** Critical
|
|
**Surface:** Code tab → Terminal pane
|
|
**Applies to:** All rows
|
|
**Issues:** —
|
|
|
|
**Steps:**
|
|
1. In a Code-tab session, press `` Ctrl+` `` (or open via the Views menu).
|
|
2. Confirm the terminal opens in the session's working directory.
|
|
3. Run `git status`, `npm --version`, `gh auth status`.
|
|
|
|
**Expected:** Terminal pane opens in the session's working directory, inherits the same `PATH` Claude sees. Standard commands run cleanly. Terminal pane is local-session-only per docs.
|
|
|
|
**Diagnostics on failure:** Terminal pane content, `echo $PATH` from inside the pane, `pwd`, the shell binary in use, launcher log.
|
|
|
|
**References:** [Run commands in the terminal](https://code.claude.com/docs/en/desktop#run-commands-in-the-terminal)
|
|
|
|
**Code anchors:**
|
|
- `build-reference/app-extracted/.vite/build/index.js:69135` — IPC
|
|
channel `claude.web_LocalSessions_startShellPty` (also
|
|
`resizeShellPty`, `writeShellPty` at :69184, :69210)
|
|
- `build-reference/app-extracted/.vite/build/index.js:486438` —
|
|
`startShellPty` body: spawns `node-pty` in
|
|
`n.worktreePath ?? n.cwd` with `TERM=xterm-256color`
|
|
- `build-reference/app-extracted/.vite/build/index.js:486463` —
|
|
`node-pty` dynamic import (optional dep, `package.json` line 100)
|
|
- `build-reference/app-extracted/.vite/build/index.js:259306` —
|
|
`shell-path-worker/shellPathWorker.js` resolves the user's interactive
|
|
PATH; `FX()` (line 259311) returns it for the spawned PTY env
|
|
|
|
## T20 — File pane opens and saves
|
|
|
|
**Severity:** Critical
|
|
**Surface:** Code tab → File pane
|
|
**Applies to:** All rows
|
|
**Issues:** —
|
|
|
|
**Steps:**
|
|
1. In a Code-tab session, click a file path in chat or diff to open it in the file pane.
|
|
2. Make a small edit. Click **Save**.
|
|
3. Modify the file externally (e.g. `echo >> file`). Re-edit in the pane. Observe the on-disk-changed warning.
|
|
|
|
**Expected:** File opens in the editor pane. Edits write back to disk on Save. If the file changed on disk since opening, the pane shows the on-disk-changed warning and offers override or discard. (The conflict check is sha256-based, not mtime-based — `writeSessionFile` reads the current bytes, hashes them, and rejects with `Conflict` if the renderer-supplied `expectedHash` doesn't match.)
|
|
|
|
**Diagnostics on failure:** `sha256sum <file>` output (and stat mtime for cross-checking), launcher log, DevTools console, screen recording of the warning state.
|
|
|
|
**References:** [Open and edit files](https://code.claude.com/docs/en/desktop#open-and-edit-files)
|
|
|
|
**Code anchors:**
|
|
- `build-reference/app-extracted/.vite/build/index.js:68922` — IPC
|
|
channel `claude.web_LocalSessions_readSessionFile`
|
|
- `build-reference/app-extracted/.vite/build/index.js:69003` — IPC
|
|
channel `claude.web_LocalSessions_writeSessionFile` with
|
|
`expectedHash` argument at position 3
|
|
- `build-reference/app-extracted/.vite/build/index.js:492874` —
|
|
`readSessionFile` impl
|
|
- `build-reference/app-extracted/.vite/build/index.js:492954` —
|
|
`writeSessionFile` impl: sha256-hashes current on-disk bytes,
|
|
returns `{ status: nW.Conflict, currentHash }` when `expectedHash`
|
|
mismatches
|