Skip to content

test: E2E tests for version restore safety guards#373

Open
leotrs wants to merge 17 commits intomainfrom
std-qx6a
Open

test: E2E tests for version restore safety guards#373
leotrs wants to merge 17 commits intomainfrom
std-qx6a

Conversation

@leotrs
Copy link
Copy Markdown
Collaborator

@leotrs leotrs commented Apr 4, 2026

Summary

  • Unskipped and implemented 3 previously-skipped E2E tests: concurrent editor detection, read-only lock during restore, and in-progress restore guard
  • Added 3 new E2E tests: restore notification for connected users, network failure recovery (editor unlocks), and single-user restore (no concurrent warning)
  • Extracted shared helpers (registerSecondUser, shareFileWithUser, openVersionPreview, performRestore) to reduce duplication across tests

Dependencies

Test plan

  • E2E: npx playwright test --grep @version-restore --reporter=line
  • Verify existing "owner can restore" and "non-owner cannot restore" tests still pass
  • New safety guard tests expected to fail until dependency PRs merge

🤖 Generated with Claude Code

leotrs and others added 11 commits April 3, 2026 22:03
…sionRestore

Replace throwing stubs with real inject-based implementations for
useAwareness, useEditor, useYText, and useCurrentUser. Provide
readOnlyCompartment from Canvas.vue so useEditor can toggle read-only
state via the same Compartment that EditorCodeMirror uses.

Wire VersionPreviewModal to call useVersionRestore().restoreVersion()
instead of raw window.__cmView.dispatch(), gaining concurrent editor
detection, read-only locking, awareness broadcasting, and atomic Y.js
transactions with origin tagging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add useRestoreNotification composable that watches Y.js awareness states
for other users' 'restoring' field transitions. When another user starts
a restore, shows an info toast: "{name} restored a previous version".
Wired into Canvas.vue where awareness is provided.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
useVersionRestore called useYText/useAwareness/useEditor at setup time,
which threw when injected shallowRefs were null (editor not yet ready).
This crashed VersionPreviewModal on mount, causing 10 E2E failures.

Now uses lazy inject: inject() at setup (Vue requirement), .value access
deferred to restoreVersion(). Modal mounts safely; restore only needs
the editor when actually triggered.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Raw fetch('/api/...') hit Vite's SPA fallback in CI/Docker, returning
index.html instead of version content. Now uses the injected axios api
client (same as VersionPreviewModal) which has the correct baseURL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Unskip 3 previously-skipped tests and add 3 new tests for version
restore safety features: concurrent editor detection, read-only lock,
in-progress guard, restore notification, network failure recovery,
and single-user restore (no concurrent warning). Tests depend on
composable wiring (std-fku4) and restore notification (std-7oh1).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@netlify
Copy link
Copy Markdown

netlify bot commented Apr 4, 2026

Deploy Preview for rsm-studio-site canceled.

Name Link
🔨 Latest commit 152e451
🔍 Latest deploy log https://app.netlify.com/projects/rsm-studio-site/deploys/69d2c92bf227790008f8c103

@netlify
Copy link
Copy Markdown

netlify bot commented Apr 4, 2026

Deploy Preview for rsm-studio-frontend ready!

Name Link
🔨 Latest commit 152e451
🔍 Latest deploy log https://app.netlify.com/projects/rsm-studio-frontend/deploys/69d2c92b75469100081b45a9
😎 Deploy Preview https://deploy-preview-373--rsm-studio-frontend.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 4, 2026

Preview Deploy

Frontend: https://pr-373--rsm-studio-frontend.netlify.app
Backend: https://aris-backend-staging.fly.dev (staging)
API docs: https://aris-backend-staging.fly.dev/docs

Test user: preview-pr-373@aris.pub

This preview will be destroyed when the PR is closed.

leotrs and others added 4 commits April 4, 2026 20:31
1. useRestoreNotification.ts: Fix array destructuring bug — Y.js awareness
   emits (changes, origin) as separate args, not an array. Changed
   `([changes])` to `(changes)`.

2. version-restore.spec.js read-only test: Replace `view.state.readOnly`
   with `contentDOM.contentEditable` check. Remove route interceptor delay
   since lock happens after API returns, not during.

3. version-restore.spec.js notification test: Replace non-existent
   `[data-testid="restore-notification"]` with `.toast-container .toast-message`
   selector matching the actual Toast component.

4. version-restore.spec.js network failure test: Add dialog handler for
   browser alert, dismiss modal before testing editor editability.

Also fixed unit test mock to emit awareness changes as separate args
matching real Y.js behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three CI failures fixed:
1. Concurrent editor detection: composable uses native confirm(), not a DOM
   element. Switched to Playwright dialog handler to capture and verify the
   confirm message contains the concurrent editor's name.
2. Read-only during restore: polling contentEditable missed the 1s lock
   window. Replaced with MutationObserver that records whether
   contentEditable was ever set to 'false' during the restore.
3. Toast notification selector: use `.toast-message` directly (matching
   Toast.vue structure) and wait for awareness sync before restoring.
4. No-other-users test: verify no native dialog fires instead of checking
   for a non-existent DOM element.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@leotrs
Copy link
Copy Markdown
Collaborator Author

leotrs commented Apr 4, 2026

Stuck after 5 work cycles

Failing checks:

  • e2e-frontend (chromium, auth-content)

Last agent notes:

...r for toast
- `frontend/src/views/workspace/Canvas.vue` — provides awareness, readOnlyCompartment
- `frontend/src/views/workspace/EditorCodeMirror.vue` — writes readOnlyCompartment to parent ref

**Key insight:** PR description explicitly states these tests are expected to fail until dependency PRs merge: std-fku4 (#368) for composable wiring, std-7oh1 (#369) for restore notification. The composables are implemented but the E2E wiring (inject providers in the component tree) may not be complete.

Needs human intervention to unblock.

leotrs and others added 2 commits April 5, 2026 22:41
VersionPreviewModal lives in Sidebar→Drawer→DrawerVersions, which is a
sibling branch to Canvas.vue. The 3 collab refs (awareness, cmView,
readOnlyCompartment) were provided by Canvas.vue, making them invisible
to useVersionRestore when called from VersionPreviewModal. This caused
all 3 CI failures: no confirm() dialog, no read-only lock, no toast.

Hoist the provides to View.vue (matching existing ydoc pattern) so both
Canvas and Drawer branches can inject them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@leotrs
Copy link
Copy Markdown
Collaborator Author

leotrs commented Apr 5, 2026

Needs human review

What changed: Version restore now uses real composables instead of stubs — adds concurrent editor detection (confirm dialog), read-only editor lock during restore, and toast notifications to other connected users when a restore happens. Shared refs (awareness, cmView, readOnlyCompartment) hoisted from Canvas.vue to View.vue for cross-branch inject access.

Review checklist:

  1. Open the deploy preview: https://deploy-preview-373--rsm-studio-frontend.netlify.app
  2. Log in as the file owner, open a file with at least one saved version
  3. Open the versions drawer, click a version to preview, click "Restore" → confirm
  4. Verify the editor briefly becomes read-only during restore, then unlocks
  5. Verify content is replaced with the restored version
  6. Open the same file in a second browser/incognito as a collaborator (EDITOR role)
  7. With both users connected, have the owner restore a version
  8. Verify the collaborator sees a toast notification saying the owner restored a version
  9. Verify the collaborator's editor content updates to the restored version
  10. Test single-user restore (no second user) — no native confirm() dialog should appear
  11. Simulate network failure during restore (e.g., disconnect network before confirming) — editor should remain editable after error

What to look for:

  • Concurrent editor confirm dialog mentions the other user's name
  • Read-only lock is brief and editor unlocks after restore completes or fails
  • Toast notification appears promptly on the collaborator's screen with correct message
  • No regressions in the basic owner-restore and non-owner-blocked flows
  • Editor is not permanently locked if restore fails mid-way

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants