Generate or update Markdown e2e test case specifications for the current project. First understand the code, then verify the service, and finally consolidate reusable flow documentation.
Goals
- Analyze the code first, then design test cases, to avoid relying solely on trial and error in the page.
- Keep only one stable file for a complete business flow to avoid duplicate consolidation.
- When old test cases become outdated, iterate on the original file instead of creating scattered versions.
- The output should be readable by humans and also directly convertible into automation scripts by subsequent Agents.
Output Location Policy
Choose a standard and stable test case directory for the current repository, with the following priority:
- If the project already has a directory used for e2e specifications, prefer to continue using it, for example
specs/e2e/、docs/e2e/、tests/e2e/specs/ - If multiple candidate directories exist, prefer the directory closest to "specification documents" rather than "automation scripts"
- If no existing convention is found, create
specs/e2e/
Once a directory is selected for the current repository, it should remain consistent during this execution. Each complete flow corresponds to one file:<selected-case-dir>/<flow-slug>.md
Additional Resources
- See the test case structure template in references/case-template.md
- See the deduplication and iteration rules in references/dedup-and-evolution.md
- See the service startup and entry detection rules in references/service-detection.md
Evaluation Assets
evals/evals.jsonProvide trigger test samples for this skill, to be used later to evaluate "whether the code is analyzed first, whether duplication is avoided, and whether old test cases are iterated correctly"
Workflow
Step 1: Gather project context
Prioritize reading the files most relevant to the application structure:
- In the root directory and subpackages,
package.json pnpm-workspace.yaml、turbo.json、nx.jsonvite.config.*、next.config.*、nuxt.config.*Makefile、docker-compose*.yml、README*- Routing and page directories, such as
src/pages、src/app、pages、app、src/routes
If the user passes in $ARGUMENTS, treat it as a scope hint:
- Routes, for example
/login - Features, for example
checkout - Page entries, for example
settings profile
First narrow the analysis scope, then expand to related dependency chains.
Step 2: Extract candidate flows from code
Start from the code rather than page screenshots, and extract candidate flows. Focus on finding:
- Page entries and navigation paths
- Form submissions, button clicks, and key user actions
- Route transitions and guard logic
- Key state transitions, such as not logged in -> logged in, empty cart -> order placed successfully
- APIs, server actions, mutations, loaders, and fetchers called by the page
- Validations, error states, and success states that affect whether the flow succeeds or fails
Keep only flows that have "a clear user goal and a final-state assertion". Do not write purely browsing pages or local interactions without a closed loop as complete e2e test cases.
Step 3: Infer how to run the service
Infer the startup method in the order of references/service-detection.md :
- First check the monorepo and workspace configuration
- Then check common scripts, such as
dev、start、preview - Then check the recommended commands in Makefile , docker-compose , README
Makefile、docker-compose, README
Prefer the command with the lowest development cost and closest to local preview. Common candidates include:
pnpm devnpm run devyarn devpnpm --filter <app> devmake devdocker compose up <service>
If it cannot be determined reliably, do not execute blindly. In this case, clearly tell the user:
- Which files have been checked
- Which suspicious entries exist
- Which startup information is still missing
Step 4: Run the service and validate the main path
After starting the service, confirm the accessible address and actual entry. Prioritize verification from the key entries inferred from the code:
- Whether the homepage or feature entry page is reachable
- Whether the key navigation forms a closed loop
- Whether the submission flow has success and failure states
- Whether API calls and UI feedback are consistent with the code analysis
If browser automation capabilities are available in the environment, prioritize using them to verify real interactions. Otherwise, at minimum verify:
- port listening succeeds
- the entry page returns normal content
- key APIs or redirect chains exist
The purpose of verification is not to exhaustively click, but to calibrate the flow boundaries obtained from code analysis.
Step 5: Load and compare existing cases
Read <selected-case-dir>/*.md. By references/dedup-and-evolution.md determine whether each candidate flow is:
new: no corresponding flow yet, create a new fileupdate: the same flow already exists, update the original fileskip: already covered by existing documentation, and there is no valid change this time
Do not judge whether something is duplicate based only on the title. You must combine the following stable keys:
entry routeprimary user goalcritical state transitionterminal assertion
Step 6: Write or update case files
When writing, strictly follow references/case-template.md 's structure.
Specific requirements:
- One file describes only one complete flow
User StepsKeep only key actions and key feedbackExpected ResultsMust include final-state assertionsCode AnchorsMust be traceable to routes, pages, components, hooks, actions, or API handlersKnown VariantsRecord only branches worth extending later; do not cram all branches into the main flow- When updating an old file, keep the stable
Flow IDand file name, and appendChange Log
Step 7: Report results
Report to the user:
- Which flow files were added
- Which old flows were updated
- Which candidate flows were skipped and why
- What entry points and evidence were used during service startup and verification
- Which flows still require the user to supplement accounts, seed data, or external dependencies
Case Quality Bar
Each test case must simultaneously satisfy:
- Have a clear user goal
- Have a clear entry point
- Have key steps rather than a pile of pages
- Have final-state assertions
- Have code anchors
- Can explain why it is a new flow, an iteration of an old flow, or should be skipped
Guardrails
- Do not run the service first and then guess the flow; read the code first.
- Do not create "pseudo-flow" documents chopped up by page.
- Do not generate
v2、new、latest-type scattered file names for the same flow. - Do not write one-off local exceptions into the main flow; put them into
Known VariantsorChange Log。 - Do not write selector details as the main narrative unless they are crucial to subsequent automation implementation.
Examples
Example 1: Login flow
The user says:为这个项目生成登录相关的 e2e 用例
You should:
- first locate the login entry point, form submission, and authentication state switching
- confirm the redirect or session establishment logic after successful login
- start the service to verify that the entry point is reachable and the success state
- Write the flow as
<selected-case-dir>/login-with-password.md
Example 2: An existing checkout flow needs updating
The user says:checkout 流程改了,更新现有 e2e 用例
You should:
- read the files related to checkout in the current use case directory
- compare them against the steps, state switching, and final states in the current code
- when it matches the same flow, update the original file in place
- In
Change Logexplain why it is being updated, rather than creating a duplicate file
Troubleshooting
Unable to determine the startup command
First list the files checked and candidate commands, then ask the user for the missing information. Do not blindly run multiple commands and pollute the environment.
Requires an account, verification code, or external service
Keep the flow documentation, but in Preconditions and Known Variants clearly state the gaps, and explain which verifications only completed static path confirmation.
There are multiple similar entry points in the code
Prioritize keeping the main flow with the clearest user goal and the most stable end state. Write the remaining entry points into Known Variants, unless they correspond to different main goals.