Skip to content

tour: auto-start for first-time visitors#16

Merged
ryandmonk merged 1 commit into
mainfrom
feat/tour-first-run
Jul 21, 2026
Merged

tour: auto-start for first-time visitors#16
ryandmonk merged 1 commit into
mainfrom
feat/tour-first-run

Conversation

@ryandmonk

Copy link
Copy Markdown
Contributor

What

An eligible first-time visitor now lands in the guided tour automatically. Eligibility is strict: no dspack-studio-tour-done sentinel, no permalink hash (deep-linked visitors are never hijacked), and localStorage must accept writes — a write-probe precedes the auto-start, because a storage that reads fine but throws on write could never remember the dismissal and would re-launch the tour every visit. On any probe failure the behavior degrades to today's opt-in header button. Returning visitors are untouched; endTour already persisted the sentinel on finish/skip, so the loop was complete.

Owner-visible change: a first-time production visitor now starts in the tour (project-deletion, "argues back", event 3) instead of the auto-playing alive recipe recording. The alive first impression remains the returning-visitor experience. Universality later is a one-line pivot (drop the sentinel read).

The now-dead tourOffered state and the "first time here?" button label are removed; the button reads "guided tour".

Test strategy

Visitor history is now part of every e2e test's premise, so both Playwright configs split into two projects — no reliance on test.use override precedence, and zero edits to existing specs:

  • first-run — no storageState; runs only the new e2e/tour-first-run.spec.ts as a genuine first-time visitor.
  • studio — seeds dspack-studio-tour-done=1 via inline storageState (origin derived from the same baseURL expression, so a mismatch can't silently no-op); runs everything else as a returning visitor.

Fail-first evidence (new spec against the old build)

2 failed
  [first-run] › e2e/tour-first-run.spec.ts:10:1 › a first-time visitor lands in the tour, on a real recorded state
    Error: expect(locator).toBeVisible() failed
    Locator: getByTestId('tour-bar')  Expected: visible  Error: element(s) not found
  [first-run] › e2e/tour-first-run.spec.ts:20:1 › the tour never recurs after dismissal, and stays restartable
    Error: expect(locator).toBeVisible() failed
    Locator: getByTestId('tour-bar')  Expected: visible  Error: element(s) not found
1 passed (13.1s)

(The passing one is deep-link immunity — the old code never auto-started, exactly as expected.)

After the change

  • npx playwright test93 passed, 4 skipped, 0 failed across both projects.
  • pnpm -r typecheck and pnpm -r test green.
  • The three first-run tests cover: auto-start onto the real recorded gate-failure state, non-recurrence after skip + reload (manual button still present), and permalink immunity with fresh storage.

🤖 Generated with Claude Code

The tour is the studio's best explanation of itself, and first-run
detection already existed — it only relabeled the header button. Now an
eligible first visit (no tour-done sentinel, no permalink hash) starts
the tour directly on the recorded repair run. A write-probe guards the
auto-start: if localStorage can't persist the dismissal, we never
auto-launch (it would recur every visit) and the behavior degrades to
the manual button. tourOffered dies with the offer label.

Visitor history is now part of every e2e test's premise, so the
Playwright configs split into two projects: "first-run" (clean storage,
runs the new tour-first-run.spec.ts) and "studio" (seeded tour-done,
runs everything else as a returning visitor) — zero edits to existing
specs. Fail-first: auto-start and non-recurrence failed on the old
build ("element(s) not found" for tour-bar); deep-link immunity passed,
as the old code never auto-started. Full suite: 93 passed, 4 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 21, 2026 18:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the studio’s guided tour behavior so eligible first-time visitors automatically enter the tour on first load (while deep-linked visitors and returning visitors are not affected), and aligns Playwright test setup to make “visitor history” explicit via two separate projects.

Changes:

  • Auto-start the guided tour on first visit only when there’s no tour completion sentinel, no permalink hash, and localStorage writes succeed (write-probe gating).
  • Split Playwright configs into first-run (clean storage) vs studio (seeded dspack-studio-tour-done=1) projects to keep existing specs stable.
  • Add a dedicated first-run e2e spec covering auto-start, non-recurrence after dismissal, and deep-link immunity.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
playwright.production.config.ts Adds first-run/studio projects and seeds localStorage for returning-visitor behavior in production runs.
playwright.config.ts Mirrors the production project split locally, making visitor history explicit and avoiding per-test overrides.
e2e/tour-first-run.spec.ts New first-visit e2e coverage for tour auto-start, dismissal persistence, and deep-link immunity.
apps/web/app/studio.tsx Implements first-visit tour auto-start with a localStorage write-probe and simplifies the tour entry button copy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ryandmonk
ryandmonk merged commit b9b35bb into main Jul 21, 2026
2 checks passed
ryandmonk added a commit that referenced this pull request Jul 21, 2026
Conflict resolution keeps both halves: the first-run/studio project
isolation from #16, with support-triage.spec.ts added to the studio
project's production testMatch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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