muggle-test-feature-local
Run a real-browser end-to-end (E2E) acceptance test against localhost to verify a feature works correctly — signup flows, checkout, form validation, UI interactions, or any user-facing behavior. Launches a browser that executes test steps and captures screenshots. Use this skill whenever the user asks to test, validate, or verify their web app, UI changes, user flows, or frontend behavior on localhost or a dev server — even if they don't mention 'muggle' or 'E2E' explicitly.
Muggle Test Feature Local
Goal: Run or generate an end-to-end test against a local URL using Muggle's Electron browser.
| Scope | MCP tools |
|---|---|
| Cloud (projects, cases, scripts, auth) | muggle-remote-* |
| Local (Electron run, publish, results) | muggle-local-* |
| Create new entities (preview / create) | muggle-remote-project-create, muggle-remote-use-case-prompt-preview, muggle-remote-use-case-create-from-prompts, muggle-remote-test-case-generate-from-prompt, muggle-remote-test-case-create |
The local URL only changes where the browser opens; it does not change the remote project or test definitions.
UX Guidelines — Minimize Typing
Every selection-based question MUST use the AskQuestion tool (or the platform's equivalent structured selection tool). Never ask the user to "reply with a number" in a plain text message — always present clickable options.
- Selections (project, use case, test case, script): Use
AskQuestionwith labeled options the user can click. - Free-text inputs (URLs, descriptions): Only use plain text prompts when there is no finite set of options. Even then, offer a detected/default value when possible.
Preferences
User preferences are available in the session context (injected at session start). Look for the line starting with Muggle Preferences — it contains key=value pairs like autoLogin=ask showElectronBrowser=always ....
If no preferences line is present, treat all preferences as "ask".
When you reach a decision gated by a preference:
always→ proceed without asking the usernever→ skip without asking the userask→ ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, callmuggle-local-preferences-setwith the key, their chosen value, and scopeglobal.
This skill uses these preferences:
| Preference | Decision it gates |
|---|---|
autoLogin | Reuse saved credentials when auth is required |
autoSelectProject | Reuse last-used Muggle project for this repo |
showElectronBrowser | Show Electron browser window during local E2E tests |
openTestResultsAfterRun | Open results page on Muggle dashboard after run |
Workflow
1. Auth
muggle-remote-auth-status- If authenticated: print the logged-in email and ask via
AskQuestion:"You're logged in as {email}. Continue with this account?"
- Option 1: "Yes, continue"
- Option 2: "No, switch account"
If the user picks "switch account", call
muggle-remote-auth-loginwithforceNewSession: truethenmuggle-remote-auth-poll.
- If not signed in or expired: call
muggle-remote-auth-loginthenmuggle-remote-auth-poll. Do not skip or assume auth.
2. Targets (user must confirm)
Ask the user to pick project, use case, and test case (do not infer).
muggle-remote-project-listmuggle-remote-use-case-list(withprojectId)muggle-remote-test-case-list-by-use-case(withuseCaseId)
Selection UI (mandatory): Every selection MUST use AskQuestion with clickable options. Never ask the user to "reply with the number" in plain text.
Project selection context: A project groups all your test results, use cases, and test scripts on the Muggle AI dashboard. Include the project URL in each option label so the user can identify the right one.
Prompt for projects: "Pick the project to group this test into:"
Relevance-first filtering (mandatory for project, use case, and test case lists):
- Do not dump the full list by default.
- Rank items by semantic relevance to the user's stated goal (title first, then description / user story / acceptance criteria).
- Show only the top 3-5 most relevant options via
AskQuestion, plus these fixed tail options:- "Show full list" — present the complete list in a new
AskQuestioncall. Skip this option if the API returned zero rows. - "Create new ..." — never omitted. Label per step: "Create new project", "Create new use case", or "Create new test case".
- "Show full list" — present the complete list in a new
Create new — tools and flow (use these MCP tools; preview before persist):
- Project — Create new project: Collect
projectName,description, andurl(may be the local app URL, e.g.http://localhost:3999). Callmuggle-remote-project-create. Use the returnedprojectIdand continue. - Use case — Create new use case: User provides a natural-language instruction (or you reuse their testing goal).
muggle-remote-use-case-prompt-previewwithprojectId,instruction— show preview; get confirmation viaAskQuestion.muggle-remote-use-case-create-from-promptswithprojectIdandinstructions: ["<the user's natural-language instruction>"]— persist. Use the created use case id and continue to test-case selection.
- Test case — Create new test case (requires a chosen
useCaseId): User provides an instruction describing what to test.muggle-remote-test-case-generate-from-promptwithprojectId,useCaseId,instruction— preview only (server test-case prompt preview); show the returned draft(s); get confirmation viaAskQuestion.- Persist the accepted draft with
muggle-remote-test-case-create, mapping preview fields into the required properties (title,description,goal,expectedResult,url, etc.). Then continue from section 5 with thattestCaseId.
3. Ensure Local Services Are Ready
Before detecting the local URL, verify that the services the user needs are actually running. Use the muggle:muggle-test-prepare integration contract:
- Check if
/tmp/muggle-test-prepare.jsonexists. - If it exists, verify tracked PIDs are alive with
kill -0. - If all live → services are ready, proceed to Step 4 (Local URL).
- If the file is missing or has stale PIDs → invoke the
muggle:muggle-test-prepareskill via theSkilltool to get services started. Once it completes, proceed to Step 4.
This step is especially important when the user's app depends on sibling services (a backend API, an auth service, etc.) that may not be running yet. The prepare skill handles discovery, startup, and cleanup so this skill doesn't have to.
4. Local URL
Try to auto-detect the dev server URL by checking running terminals or common ports (e.g., lsof -iTCP -sTCP:LISTEN -nP | grep -E ':(3000|3001|4200|5173|8080)'). If a likely URL is found, present it as a clickable default via AskQuestion:
- Option 1: "http://localhost:3000" (or whatever was detected)
- Option 2: "Other — let me type a URL"
If nothing detected, ask as free text: "Your local app should be running. What's the URL? (e.g., http://localhost:3000)"
Remind them: local URL is only the execution target, not tied to cloud project config.
5. Existing scripts vs new generation
muggle-remote-test-script-list with testCaseId.
- If any replayable/succeeded scripts exist: use
AskQuestionto present them as clickable options. Show: name, created/updated, step count per option. Include "Generate new script" as the last option. - If none: go straight to generation (no need to ask replay vs generate).
6. Load data for the chosen path
Determine freshSession
Before calling either execution tool, inspect the test case content (title, goal, instructions, preconditions) for signals that the test requires a clean browser state — no prior cookies, localStorage, or logged-in session. Pass freshSession: true when the test case involves any of:
- Registration / sign-up — creating a new account
- Login / authentication — verifying the login flow itself (not a test that merely uses login as a prerequisite)
- Cookie consent / GDPR banners — verifying first-visit consent prompts
- Onboarding flows — first-time user experiences that only appear on a fresh session
If none of the above apply, omit freshSession (defaults to false, preserving any existing session state).
Generate
muggle-remote-test-case-getmuggle-local-execute-test-generationwith that test case +localUrl(optional:showUi: falsefor headless — defaults to visible;freshSession— see above;timeoutMs— see below)
Replay
muggle-remote-test-script-get— noteactionScriptIdmuggle-remote-action-script-getwith that id — fullactionScriptUse the API response as-is. Do not edit, shorten, or rebuildactionScript; replay needs fulllabelpaths for element lookup.muggle-local-execute-replaywithtestScript,actionScript,localUrl(optional:showUi: falsefor headless — defaults to visible;freshSession— see above;timeoutMs— see below)
Local execution timeout (timeoutMs)
The MCP client often uses a default wait of 300000 ms (5 minutes) for muggle-local-execute-test-generation and muggle-local-execute-replay. Exploratory script generation (Auth0 login, dashboards, multi-step wizards, many LLM iterations) routinely runs longer than 5 minutes while Electron is still healthy.
- Always pass
timeoutMsfor flows that may be long — for example600000(10 min) or900000(15 min) — unless the user explicitly wants a short cap. - If the tool reports
Electron execution timed out after 300000ms(or similar) but Electron logs show the run still progressing (steps, screenshots, LLM calls), treat it as orchestration timeout, not an Electron app defect: increasetimeoutMsand retry. - Test case design: Preconditions like "a test run has already completed" on an empty account can force many steps (sign-up, new project, crawl). Prefer an account/project that already has the needed state, or narrow the test goal so generation does not try to create a full project from scratch unless that is intentional.
Interpreting failed / non-zero Electron exit
Electron execution timed out after 300000ms: Orchestration wait too short — seetimeoutMsabove.- Exit code 26 (and messages like LLM failed to generate / replay action script): Often corresponds to a completed exploration whose outcome was goal not achievable (
goal_not_achievable, summary withhalt) — e.g. verifying "view script after a successful run" when no run or script exists yet in the UI. Usemuggle-local-run-result-getand read the summary / structured summary; do not assume an Electron crash. Fix: choose a project that already has completed runs and scripts, or change the test case so preconditions match what localhost can satisfy (e.g. include steps to create and run a test first, or assert only empty-state UI when no runs exist).
7. Execute (no approval prompt)
Call muggle-local-execute-test-generation or muggle-local-execute-replay directly. Do not ask the user to re-approve the Electron launch — the user choosing this skill in the first place is the approval. The browser defaults to visible; only pass showUi: false if the user explicitly asked for headless.
8. After successful generation only
muggle-local-publish-test-script- Open returned
viewUrlfor the user (open "<viewUrl>"on macOS or OS equivalent).
9. Report
muggle-local-run-result-getwith the run id from execute.- Include: status, duration, pass/fail summary, per-step summary, artifact/screenshot paths, errors if failed, and script view URL when publishing ran.
10. Offer to post a visual walkthrough to the PR
After reporting results, gather the required input and hand off to the shared muggle:muggle-pr-visual-walkthrough skill, which renders the walkthrough via muggle build-pr-section and posts it to the current branch's open PR.
10a: Gather per-step screenshots
The shared skill takes an E2eReport JSON that includes per-step screenshot URLs. After step 8 has called muggle-local-publish-test-script and you have the testScriptId:
- Call
muggle-remote-test-script-getwith thetestScriptId. - Extract per step:
steps[].operation.actionandsteps[].operation.screenshotUrl. - Build the
stepsarray:[{ stepIndex: 0, action: "...", screenshotUrl: "..." }, ...]. - If the run failed, capture
failureStepIndex,error, and the localartifactsDirfrom the run result in step 9. - Populate
description(test case title/description) anduseCaseName(parent use case title) on the report entry — optional but strongly recommended; they drive the grouped overview and the per-test collapsible headers. Prefer values already in your conversation context from earlier steps (e.g. the test case you just created or selected, or the use case you confirmed); only callmuggle-remote-test-case-get/muggle-remote-use-case-getfor anything you don't already have.
Assemble the E2eReport:
{
"projectId": "<projectId from step 2 (Targets)>",
"tests": [
{
"name": "<test case title>",
"description": "<one-line description of what this test verifies (optional but recommended)>",
"useCaseName": "<parent use case title (optional but recommended)>",
"testCaseId": "<id>",
"testScriptId": "<id from publish>",
"runId": "<runId from execute>",
"viewUrl": "<viewUrl from publish>",
"status": "passed",
"steps": [{ "stepIndex": 0, "action": "...", "screenshotUrl": "..." }]
}
]
}
See the muggle:muggle-pr-visual-walkthrough skill for the full schema including the failed-test shape.
10b: Ask the user
Use AskQuestion:
"Post a visual walkthrough of this run to the PR? Reviewers can click the test case to see step-by-step screenshots on the Muggle AI dashboard."
- Option 1: "Yes, post to PR"
- Option 2: "Skip"
10c: Invoke the shared skill in Mode A
If the user chooses "Yes, post to PR", invoke the muggle:muggle-pr-visual-walkthrough skill via the Skill tool. With the E2eReport in context, the skill renders the markdown block via the CLI, finds the PR via gh pr view, posts body as a comment, posts the overflow comment only if the CLI emitted one, and confirms the PR URL to the user.
Always use Mode A (post to existing PR) from this skill. Never hand-write the walkthrough markdown or call gh pr comment directly — delegate to muggle:muggle-pr-visual-walkthrough.
Non-negotiables
- No silent auth skip.
- Never prompt for Electron launch approval before execution — invoking this skill is the approval. Just run.
- If replayable scripts exist, do not default to generation without user choice.
- No hiding failures: surface errors and artifact paths.
- Replay: never hand-built or simplified
actionScript— only frommuggle-remote-action-script-get. - Use
AskQuestionfor every selection — project, use case, test case, script. Never ask the user to type a number. - Project, use case, and test case selection lists must always include "Create new ...". Include "Show full list" whenever the API returned at least one row for that step; omit "Show full list" when the list is empty (offer "Create new ..." only). For creates, use preview tools (
muggle-remote-use-case-prompt-preview,muggle-remote-test-case-generate-from-prompt) before persisting. - PR posting is always optional and always delegated to the
muggle:muggle-pr-visual-walkthroughskill — never inline the walkthrough markdown or callgh pr commentdirectly from this skill.