Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-2487Done

Story E2E (Playwright) — an admin authors a role, puts someone on it, watches it bite, then deletes it with a reassign; and records the acceptance video

The story's verification_recipe, automated in a browser, and the receipt a reviewer watches to accept it. A new spec beside tests/e2e/acceptance-roles-permissions.spec.ts, which covers the read-only screens and stays as it is.

The flow, in chapters

  1. Author. As a project admin: Project settings → Access → Roles & permissions → Create role. Start from Member, name it Contributor, untick two permissions, watch the pinned bar's count fall, save.
  2. Read it back. The list shows Contributor with its Custom chip, its N of M permissions and 0 members; drilling in shows Based on Member · −2.
  3. Assign. Project settings → Members: change a teammate to Contributor. The row's chip becomes Contributor, and the role list now shows 1 member.
  4. It bites. Sign in as that teammate and reach the surface one of the removed permissions governs: the control refuses. Then do something the role KEPT — edit a work item, comment — and it succeeds. Both halves matter: a role that takes everything away is not evidence the model works.
  5. Built-ins are safe. As the admin, open Admin: no Edit, no Delete, a lock instead.
  6. Delete with a reassign. Delete Contributor: the dialog names 1 member and requires a destination. Choose Viewer, confirm. The list no longer has Contributor, and the teammate's row reads Viewer — never blank.

Discipline

  • Wait on authoritative signals — the persisted row, the toast, the re-rendered chip — never a fixed timeout, and never a waitForTimeout standing in for a save.
  • Cover the states a happy path skips: the editor's empty name refusal and its duplicate-name refusal, and the role list at zero custom roles.
  • The video is watched by a person. Use the harness's paced chapter() so the clip is legible at human speed — a spec that races through meets the letter and produces a receipt nobody can review. The publish step refuses an unwatchable clip; the card says it so the pacing is planned rather than discovered from a red step.
  • Each of the three sign-ins uses the workspace-cookie pinning the shipped specs already do, so the run cannot drift onto another workspace's project.

Scope boundary

In: the spec, its fixtures, the recorded and published acceptance video, and any data-testid the surfaces need — added to the components in this PR. Out: unit and integration coverage, which the vitest gate owns; any production behaviour change — a failing step is a bug card, not an edited assertion; the shipped acceptance-roles-permissions.spec.ts, which keeps covering the read screens.

Acceptance criteria

  • tests/e2e/acceptance-custom-roles.spec.ts drives all six chapters above against a real server and a real database, and passes on a cold run.
  • Chapter 4 asserts both directions: the removed permission's control refuses, and a kept permission's action succeeds.
  • Chapter 6 asserts the teammate holds the destination role afterwards, read off the members surface — the criterion is that nobody is left without a role, so asserting the deletion alone does not discharge it.
  • The empty-name and duplicate-name refusals are covered, and the role list's zero-custom-roles state renders.
  • Every wait is on an authoritative signal; the spec contains no fixed-duration sleep.
  • The run records and publishes the acceptance video to the story, paced with chapter() so it is watchable, and the publish step accepts it.
  • The spec is deterministic across three consecutive runs and does not depend on data another spec leaves behind.

Context refs

  • tests/e2e/acceptance-roles-permissions.spec.ts — the sibling spec for the read screens: its sign-in helpers, workspace pinning and chapter pacing.
  • tests/e2e/per-domain-admin-permissions.spec.ts · tests/e2e/member-facing-permissions.spec.ts — the shipped multi-role permission specs and how they assert a refusal.
  • playwright.config.ts (testDir: 'tests/e2e') and the acceptance-video harness the shipped specs use.
  • motir-core/CLAUDE.md — the E2E discipline: authoritative waits, no fixed sleeps.
  • The story's verification_recipe, which this automates; the three surfaces it drives — the editor, the delete flow, the assignment.