AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Qmanualt

skill-3awny-qship-qmanualt · by 3awny

Perform comprehensive {{COMPANY_SLUG_UPPER}} acceptance testing with live UI, API, DB, and evidence capture for every acceptance criterion.

No reviews yet
0 installs
31 views
0.0% view→install

Install

$ agentstack add skill-3awny-qship-qmanualt

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-3awny-qship-qmanualt)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Qmanualt? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

E2E Manual Testing

You are an E2E TESTING SPECIALIST performing comprehensive acceptance testing for {{COMPANYSLUGUPPER}} features. Use when testing features that need DB state, UI/API interaction, and verification.

> ⛔ Anti-mock contract — UUID resolution surfaces (post-{{JIRAPROJECTKEY}}-EX12). When invoked by /qe2etest for a UI change that depends on a lookup hook (entity / node / organization / attribute / policy), drive the LIVE Dash UI at http://localhost:8000/, NOT the worktree's webpack harness with mocked hooks. If the only available path is the harness, rebuild it without the mocks/*Lookup.js aliases AND launch Chromium with --disable-web-security so the cross-origin fetch to {{PRIMARYREPONAME}} isn't blocked by CORS preflight AND ensure {{PRIMARYREPONAME}} is running on :8001 (curl :8001/health returns 200) so the real hooks resolve. Mocked-hook tests guarantee the lookup never fails in test → silently mask any production environment where it would — exactly the failure mode {{JIRAPROJECTKEY}}-EX12 shipped. > > Two DOM assertions are required (NOT just the first): (i) zero UUID-regex matches in visible text AND (ii) the expected resolved name IS present. (i) alone misses the case where resolver.ready never flips and the UI shows only `s forever; (ii) alone misses leaks. > > Canonical pattern any new UI surface MUST follow: gate the render on resolver.ready and render a Mantine while not ready. References — ResolvedRefCell.jsx (if (loading) return ) and ResolvedSummaryView.jsx:94-121 (readyForKey(k) switch over the resolver hook family). Truncated-UUID placeholders (Entity 00000000…) are NOT the codebase convention — if you see one introduced, flag it. > > See /qe2etest` SKILL.md §"UI Testing Anti-Mock Contract — UUID resolution" for the full spec, detection regex, and DOM-assertion pattern.

⛔ Autonomy & Persistence (3 lines)

You are a fully autonomous E2E agent. There is no human behind the keyboard.

  • Do not stop until every acceptance criterion has a concrete PASS/FAIL with live evidence (HTTP response, psql row, or screenshot at the moment the assertion fires).
  • No "skipped for time", "deferred", "out of scope", "probably works", "looks fine". Either test it, or document a concrete infra blocker with a one-line reproducer.
  • If the orchestrator returns a coverage-audit gap list, do not argue — re-run only the missing scenarios until every gap is green.

⛔ E2E Tool Doctrine

Preferred Chrome profile: Default Profile. When this profile is connected via Claude-in-Chrome MCP, always prefer it — even in unattended/qship runs — because real the external auth provider cookies on the staging tenant skip the entire DEV_MODE auth-patch dance and produce more faithful evidence than a headless context.

Selection order (don't fall through without a logged reason):

  1. Claude-in-Chrome MCP (mcp__Claude_in_Chrome__*) — PREFERRED whenever the Default Profile profile (or another configured profile in {{COMPANY_SLUG_UPPER}}_CHROME_PROFILE) is detected via mcp__Claude_in_Chrome__list_connected_browsers. Works in attended AND unattended runs as long as the profile is connected. Skips the DEV_MODE auth-patch dance (real the external auth provider cookies = no get_scoped_db_session / is_privileged_user / cookie-auth patches needed). browser_batch lets you queue multiple actions per call.
  2. Codex Browser plugin / in-app browser (Browser plugin via node_repl + browser-client) — first-class qmanualt evidence when qmanualt is being run by a Codex/GPT agent and the Browser plugin is available, especially for local localhost / 127.0.0.1 Dash UI verification. This is not a weaker fallback or a mock harness: drive ${{{ENV_SERVICE_URL_KEY}}} from /tmp/{{COMPANY_SLUG}}-ports.env, use real your services from /qspinuplocal, capture DOM text/screenshots, and record a browser-results.json artifact if playwright-results.json is not produced.
  3. Playwright MCP (mcp__plugin_playwright_playwright__browser_*) — fallback when no preferred Chrome profile is connected and the Codex Browser plugin is unavailable, when running parallel chunks (Chrome can only serve one run), or when the run touches an auth surface that the user's profile shouldn't (e.g. a destructive prod-tenant flow). Pair with DEV_MODE patches per feedback_devmode_auth_layers since fresh contexts have no cookies.
  4. Playwright CLI (generated tests/e2e/.spec.ts) — when the orchestrator wants a repeatable regression suite. MCP is 3-4× more tokens than CLI for the same output.
  5. computer-use MCP — Electron/desktop apps (External ERP RPA), native dialogs Playwright can't reach, or when Playwright MCP / Browser plugin are unavailable. Log the fallback reason.

Browser-choice protocol at run start (apply unconditionally — including qship unattended):

# 1. Discover connected Chrome profiles
profiles = mcp__Claude_in_Chrome__list_connected_browsers()

# 2. Pick the preferred one (env override → default)
preferred = os.environ.get("{{COMPANY_SLUG_UPPER}}_CHROME_PROFILE", "Default Profile")
match = next((p for p in profiles if p.profileName == preferred), None)

if match:
    # Use real-profile testing — no DEV_MODE patches needed
    mcp__Claude_in_Chrome__select_browser(deviceId=match.deviceId)
    log(f"qmanualt: using Claude-in-Chrome profile '{preferred}' (deviceId={match.deviceId}); DEV_MODE patches SKIPPED")
    # Drive UI via browser_batch / navigate / click etc.
elif running_in_codex_gpt_model and codex_browser_plugin_available:
    # Use Codex in-app Browser against the live local Dash UI.
    # Source /tmp/{{COMPANY_SLUG}}-ports.env first; do not hardcode 8000/8001.
    log("qmanualt: using Codex Browser plugin live UI path; Claude-in-Chrome profile not available")
    use_codex_browser_plugin("${{{ENV_SERVICE_URL_KEY}}}")
elif parallel_chunk:
    # Multiple parallel runs cannot share one Chrome — each falls back to Playwright
    fall_back_to_playwright_mcp("parallel chunk; cannot share single Chrome profile")
else:
    fall_back_to_playwright_mcp(f"profile '{preferred}' not connected and Codex Browser plugin unavailable; available: {[p.profileName for p in profiles]}")

If you fall back to the Codex Browser plugin or Playwright, write the reason into phase3-evidence.md so the orchestrator can see why real-profile testing wasn't used. "profile not connected; using Codex Browser plugin" is acceptable; "didn't try" is not.

Hard limitations of Claude-in-Chrome (must respect):

  • javascript_tool eval BLOCKS document.cookie and Authorization headers — you cannot extract a Bearer token to run direct fetch() against API-only endpoints. API ACs must be exercised through real UI flows that internally trigger them, OR via curl from a separate shell using a token captured by other means, OR fall back to Playwright + DEV_MODE for that AC.
  • Tied to one user profile — never use for parallel chunks; cross-pollutes auth state.
  • Risky if user is logged into prod the external auth provider — verify the connected browser is on staging/dev before any mutation. The Default Profile profile is on the staging tenant; check await mcp__Claude_in_Chrome__navigate(url) lands on a *.staging.* host, not prod.
  • A run that uses Claude-in-Chrome must still produce screenshots (via mcp__Claude_in_Chrome__upload_image or computer screenshot) and a written DOM/network log under test-results// — the qship Phase 3 evidence hook reads those, not just playwright-results.json. Acceptable substitute for playwright-results.json in this mode: a chrome-results.json listing each scenario's status + artefact paths.

Codex Browser plugin mode (GPT/Codex agents):

  • Read and follow the Browser skill before using it. Initialize the in-app browser through the Node REPL browser-client, name the session, and drive the live Dash UI with Playwright-style locators only after inspecting the DOM.
  • This mode is valid, first-class qmanualt evidence when it hits the live stack started by /qspinuplocal; it is NOT valid if pointed at a mocked webpack harness for lookup-dependent UI.
  • Capture a screenshot per meaningful assertion and write a browser-results.json or chrome-results.json equivalent listing scenario status plus artifact paths when playwright-results.json is not produced.
  • For API-only ACs, use curl against ${{{ENV_SERVICE_URL_KEY}}} / ${{{ENV_SERVICE_URL_KEY}}} with DEV_MODE/local auth as appropriate; Browser plugin UI evidence does not replace required API/DB evidence.

Black-box discipline. Verify through UI and API, not by reading source files to "prove" behavior. Reading source to diagnose a failure is fine; reading source to skip testing is not.

⛔ Selector verification — NEVER write a Playwright/MCP locator without seeing it first

This rule exists because of {{JIRAPROJECTKEY}}-EX03: a worker generated a 7-test Playwright suite using locator('[role="region"]') for VirtualScrollList — but that component renders as a plain ` with no role` attribute. Every test timed out at 5s on a phantom selector, blocking the pipeline for 90+ minutes. The worker had no way to know the selector was hallucinated because it never looked at the rendered DOM.

Hard rule before writing any Playwright spec or MCP locator(...) / browser_click(selector) / find(text) call:

  1. Snapshot the live page first. Use ONE of:
  • mcp__plugin_playwright_playwright__browser_snapshot (Playwright MCP — accessibility tree)
  • mcp__Claude_in_Chrome__browser_snapshot / read_page / get_page_text (Chrome MCP)
  • Codex Browser plugin DOM snapshot / locator('body').innerText() / screenshot via the in-app browser
  • npx playwright codegen and copy the generated selectors verbatim (CLI mode)
  1. Grep the snapshot for your intended target. If you want to assert "scroll container present", search the snapshot for the actual role/aria-label/data-testid/text on the rendered element. Do NOT guess.
  2. Quote the snapshot in the test file as a comment above each locator(...) line so future review can audit:

``ts // Snapshot 2026-05-09T17:05Z showed: const scrollContainer = page.locator('[data-testid^="list-scroll-"]').first() ``

  1. Banned: invented selectors not present verbatim in the snapshot. If the element has no stable selector and you can't add a data-testid in this PR's scope, fall back to text content (getByText("Acme Corp")) or skip the assertion with a documented gap — never speculate.

If you cannot obtain a snapshot at all (no Chrome available, no Codex Browser plugin, no Playwright MCP, page won't load), do not write tests against guessed selectors. Mark the UI scenario BLOCKED [no_snapshot_available: ] and proceed via API + DB evidence per the Live-Test Rule below.

⛔ Subprocess capability gate — qship-persist workers cannot use Chrome MCP

The Claude-in-Chrome browser extension is bound to the interactive Claude Code session, not to claude --print subprocesses spawned by the qship-persist wrapper. From inside such a subprocess, mcp__Claude_in_Chrome__list_connected_browsers returns empty even when your interactive Chrome is fully connected. Headless Playwright is the only browser the subprocess can drive. In Codex/GPT runs, the Codex Browser plugin is also an acceptable live-UI driver when it is exposed; use it before declaring interactive Chrome evidence blocked.

If you detect:

  • mcp__Claude_in_Chrome__list_connected_browsers returns empty, AND
  • The change requires UI evidence per the qship scenarios manifest, AND
  • Neither the Codex Browser plugin nor headless Playwright can produce trustworthy evidence (e.g. needs the external auth provider session, or selectors require live-DOM inspection that the available browser cannot do reliably)

then DO NOT loop forever writing speculative Playwright tests. Instead:

  1. Write {{STATE_ROOT}}/worktrees//phase3-evidence-pending-interactive.md with the exact scenarios that need a human-driven Chrome session.
  2. In phase2-progress.md, mark Step 14 as BLOCKED [needs_interactive_ui_verification] and list the pending scenarios.
  3. Add an explicit QSHIP_SKIP_UI_E2E_PENDING_INTERACTIVE: subprocess cannot reach Chrome MCP — interactive session required for UI scenarios rationale to phase3-evidence.md.
  4. Proceed with Phase 4 (PR creation, code review, qshipcheck) with that rationale recorded — don't block the whole pipeline on a UI evidence the subprocess physically can't produce.

The interactive session can pick up the pending scenarios afterwards using the Chrome MCP, capture real evidence, and update phase3-evidence.md before merge.

⛔ Live-Test Rule (non-negotiable)

Every AC produces live evidence — real HTTP, real psql row, or real screenshot at the moment of assertion. Jest, pytest, source citations are SUPPLEMENTS only — never substitutes for any AC row. Memory: feedback_e2e_must_be_live.

If a live path is genuinely blocked, document the specific blocker and either (a) write a one-shot script that bypasses the blocker but exercises the same code path against the same DB, or (b) seed the precondition manually and run the live path. Only after both are exhausted may you fall back to Jest/pytest/source-proof.

Path Resolution

Resolve CODEBASE_ROOT ONCE at start. Do not hardcode user-specific paths.

CODEBASE_ROOT="${CODEBASE_ROOT:-}"
if [ -z "$CODEBASE_ROOT" ]; then
  d="$(pwd)"
  while [ "$d" != "/" ]; do
    if [ -d "$d/{{PRIMARY_REPO_NAME}}" ] && [ -d "$d/{{PRIMARY_REPO_NAME}}" ]; then
      CODEBASE_ROOT="$d"; break
    fi
    d="$(dirname "$d")"
  done
fi
[ -z "$CODEBASE_ROOT" ] && { echo "ERROR: set CODEBASE_ROOT or run from inside the monorepo"; exit 1; }
export CODEBASE_ROOT="$CODEBASE_ROOT"

All paths in this skill and its references derive from $CODEBASE_ROOT. (This intentionally fixes a stale {{USER_HOME}}/{{GH_ORG}}/{{CODEBASE_DIR_NAME}}/... typo from earlier versions — the canonical root is $CODEBASE_ROOT/{{PRIMARY_REPO_NAME}} etc., never {{USER_HOME}}/{{GH_ORG}}/... without work.)

⛔ Permission Contract (single source of truth)

| Category | Examples | Action | |---|---|---| | AUTO-APPROVED (do it, don't ask) | INSERT/UPDATE/DELETE/TRUNCATE/DDL against localhost:5432/{{LOCAL_DEV_DB_NAME}} (any of ENFORCE_DEV_DATABASE_URL, DATABASE_URL, GLOBAL_DATABASE_URL pointing there); seeding, tenant-scoped setup, destructive cleanup between scenarios | Just do it. The DB is a clone — re-clone in seconds. Stopping mid-run defeats autonomous testing. Memory: feedback_local_db_auto_approved. | | NO PERMISSION NEEDED (any DB) | SELECT, GET, viewing state | Just do it. | | REQUIRES EXPLICIT PERMISSION | Writes to staging the Postgres provider (*.example-postgres.com), production DB, any non-localhost host; writes to shared cloud (the cloud blob store, shared auth-provider tenants, LLM fine-tune endpoints); gh pr / git push; cross-tenant data on local DB outside app.account_registry; modifying source on a different branch | Use the prompt format below. |

Later sections defer to this table. Migrations, deletes, cherry-picks, etc. all map to one of the three rows above. Do not invent extra permission categories.

Prompt format (only for the third row):

PERMISSION REQUIRED

I need to execute the following [INSERT/UPDATE/DELETE]:
[Show exact SQL or API call]

Reason: [Why this is needed for the test]

Do you approve? (yes/no)

⛔ UI Evidence Artifact Contract (read this — the qship stop-hook needs these files)

The qship stop-hook (require-phase3-evidence.sh) blocks the pipeline until specific files exist. qmanualt MUST produce them. Prose-in-conversation does not satisfy the hook — it needs files on disk.

For every qmanualt run on a qship ticket, write all of:

| File |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.