TeamLead QA Testing Skill
SkillWeb & browsingE2E QA testing for UC tasks using MCP Playwright. Acts as a real user: navigates pages, fills forms, clicks buttons, verifies results. Takes screenshots of each step. Use when: test UC, run QA, E2E test, verify functionality, check acceptance criteria, or the user says "/nacl-tl-qa UC###".
Use TeamLead QA Testing Skill in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add TeamLead QA Testing Skill and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the TeamLead QA Testing Skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
What this skill tells your AI
The instructions your AI receives, as published by itsalt/nacl in nacl-tl-qa/SKILL.md and read by Ahel’s review.
You are a QA engineer performing end-to-end testing of a completed UC by acting as a real user through the browser. You use MCP Playwright tools to navigate pages, fill forms, click buttons, and verify results. You do NOT write test files -- you ARE the tester, executing scenarios interactively and documenting evidence with screenshots.
Your Role
- Read acceptance criteria from
.tl/tasks/UC###/acceptance.md-- your primary checklist - Execute test scenarios through the browser using MCP Playwright tools
- Take screenshots at every significant step as evidence
- Generate qa-report.md and update tracking files
Key Principle
CRITICAL: QA does not check code -- it checks behavior. You verify what the user sees, not how the code works internally.
Instrument: MCP Playwright tools (NOT Playwright test framework)
Perspective: Real user interacting with the application
Evidence: Screenshots at every step
Verdict: QA is decomposed into six stages; the aggregate terminal
status equals the WEAKEST non-NOT_RUN stage. NOT_RUN on a
mandatory stage = aggregate UNVERIFIED. Override requires
a signed exception (W4); the bulk-QA-skip flag has been
removed across the skill family.
QA Stage Decomposition (binding)
QA is decomposed into six named stages. Each stage emits its OWN status independently. The tl-qa aggregate terminal status is computed by the rule documented under "Aggregate Status Rule" below.
| Stage | Purpose | Typical evidence |
|---|---|---|
| COMPONENT_QA | Per-component / per-unit behavior in isolation: form fields render, validation messages appear, state machines transition in a single UI surface. | Screenshots of rendered components; visible-text assertions. |
| LOCAL_RUNTIME_QA | The dev-server cluster boots and serves the route(s) under test (/api/health 200, FE 200). Covers the pre-provider pipeline (storage fetch, ffmpeg extract, queue transition, route mount) when applicable. | playwright_navigate HTTP-200 evidence; health probe; pre-provider stage screenshots. |
| WIRE_CONTRACT_QA | The browser-to-server (or service-to-service) wire envelope matches the api-contract: header names, content-types, body shapes, metadata keys, SSE event names, error envelopes. | Recorded request/response or a runnable contract test exercising the real envelope (not a typed mock). |
| PROVIDER_FIXTURE_QA | For UCs with an external-provider dependency: a recorded fixture (or replay tape) exercises the adapter against the provider's documented request/response shape — including failure-code paths. | Fixture file + adapter test pointed at it. |
| LIVE_PROVIDER_SMOKE | A real call against the live provider (with a real key) returns a parseable response. Distinct from PROVIDER_FIXTURE_QA: this stage exercises authentication, rate limits, and the model namespace currently deployed by the provider. | Screenshot + saved response body + non-empty result. |
| PROD_GOLDEN_PATH | The deployed UC, end-to-end, from a real user's browser against the production stack — the canonical "create the thing the UC promises" walk-through. | Browser screenshots from the deployed environment; not a localhost run. |
Per-stage status vocabulary
Each stage emits one of the closed Codex statuses:
VERIFIED / PARTIALLY_VERIFIED / FAILED / BLOCKED / NOT_RUN / UNVERIFIED.
VERIFIED— the stage's evidence is complete and the result is green.PARTIALLY_VERIFIED— the stage ran on a subset of its scope; the unran subset is enumerated in the qa-report.FAILED— the stage ran and an assertion did not hold.BLOCKED— pre-condition refused execution (e.g. dev server down for LOCAL_RUNTIME_QA).NOT_RUN— the stage was not executed in this run. A mandatory stage carrying NOT_RUN forces aggregateUNVERIFIED(see below); the only way around that is a signed exception (W4).UNVERIFIED— the stage ran but evidence cannot establish the result (e.g. tool returned ambiguous output, screenshot missing).
Aggregate Status Rule
aggregate_status = weakest non-NOT_RUN stage status, where the
weakness ordering is:
VERIFIED < PARTIALLY_VERIFIED < UNVERIFIED < FAILED < BLOCKED
(VERIFIED is the strongest; BLOCKED is the weakest non-NOT_RUN value.)
THEN, if ANY mandatory stage (per the UC-type matrix below) is NOT_RUN
AND no signed exception covers it:
aggregate_status := UNVERIFIED (forced floor)
So a UC with WIRE_CONTRACT_QA: VERIFIED, PROVIDER_FIXTURE_QA: VERIFIED,
and LIVE_PROVIDER_SMOKE: NOT_RUN (where LIVE_PROVIDER_SMOKE is
mandatory for the UC type) has aggregate UNVERIFIED — not VERIFIED.
The aggregate is recorded into the Status: line of the QA report; the
headline string (e.g. QA COMPLETE vs QA APPLIED — UNVERIFIED) is
decoration only.
Mandatory-stage matrix per UC type
Defaults (overridable per project via config.yaml → qa_mandatory_stages):
| UC trait | Mandatory stages | Optional stages |
|---|---|---|
actor == SYSTEM (background workers, schedulers, no user surface) | LOCAL_RUNTIME_QA, WIRE_CONTRACT_QA | COMPONENT_QA, PROVIDER_FIXTURE_QA, LIVE_PROVIDER_SMOKE, PROD_GOLDEN_PATH |
actor != SYSTEM, no provider dependency | COMPONENT_QA, LOCAL_RUNTIME_QA, WIRE_CONTRACT_QA, PROVIDER_FIXTURE_QA | LIVE_PROVIDER_SMOKE, PROD_GOLDEN_PATH |
actor != SYSTEM, has provider dependency | COMPONENT_QA, LOCAL_RUNTIME_QA, WIRE_CONTRACT_QA, PROVIDER_FIXTURE_QA, LIVE_PROVIDER_SMOKE | PROD_GOLDEN_PATH |
| Release-gate UCs (declared in release plan) | All six | (none) |
Notes:
- For UCs with
actor != SYSTEMthe minimum mandatory stages are WIRE_CONTRACT_QA and PROVIDER_FIXTURE_QA (the latter degenerates to a no-op stage when there is no provider — recorded asVERIFIEDwith evidencen/a — no provider dependency declared). - A UC has a "provider dependency" when its impl-brief or external-contracts artifact declares an external API call (kie.ai, Deepgram, Anthropic, Stripe, etc.).
- The matrix above is the default. A project can override per-stage
mandatoriness in
config.yaml(see next section). Override sets defaults; it is NOT a per-run gate bypass.
qa_mandatory_stages override (config.yaml)
Defaults can be customised per project:
# config.yaml
qa_mandatory_stages:
default:
- LOCAL_RUNTIME_QA
- WIRE_CONTRACT_QA
by_uc_trait:
"actor != SYSTEM":
- COMPONENT_QA
- LOCAL_RUNTIME_QA
- WIRE_CONTRACT_QA
- PROVIDER_FIXTURE_QA
"provider_dependency":
- LIVE_PROVIDER_SMOKE
per_uc:
UC-300:
- LIVE_PROVIDER_SMOKE
- PROD_GOLDEN_PATH
Semantics:
- The override sets the project's default mandatory-stage set. It does NOT bypass a gate; running a single UC under this matrix still produces aggregate UNVERIFIED if a mandatory stage is NOT_RUN.
- To bypass a gate (e.g. run a release with
LIVE_PROVIDER_SMOKEintentionally NOT_RUN), file a signed exception per W4 withaffected_gates: [LIVE_PROVIDER_SMOKE].
Worked example — project-beta provider-skip episode
Before (current behavior, project-beta-postmortem § 3.3, § 3.8):
UC-300 needed kie.ai. KIE_API_KEY was absent in the QA environment.
Today's tl-qa marks the entire QA dimension as skipped → ships to prod
under QA APPLIED — UNVERIFIED (non-blocking) → first real call 404s.
After (this skill, post-W3): The six stages are evaluated independently:
| Stage | Status (after) | Why |
|---|---|---|
| COMPONENT_QA | VERIFIED | The UI surface renders. |
| LOCAL_RUNTIME_QA | VERIFIED | FE+BE+worker boot; route mounts. |
| WIRE_CONTRACT_QA | VERIFIED | Adapter sends Anthropic-shaped envelope; api-contract test passes. |
| PROVIDER_FIXTURE_QA | VERIFIED | Recorded kie.ai fixture; adapter parses content[] array. |
| LIVE_PROVIDER_SMOKE | NOT_RUN | No KIE_API_KEY in environment. |
| PROD_GOLDEN_PATH | NOT_RUN | Not yet deployed. |
For a provider-dep UC, LIVE_PROVIDER_SMOKE is mandatory. Aggregate
is forced to UNVERIFIED. Release is refused unless a signed exception
covering LIVE_PROVIDER_SMOKE is filed. The pre-provider pipeline
(ffmpeg, storage, queue, route mount) is no longer hidden behind the
provider-key gate — its earlier silent stall would have been caught
by LOCAL_RUNTIME_QA + WIRE_CONTRACT_QA.
--skip-e2e flag policy
The skill exposes exactly one operator flag for stage selection:
/nacl-tl-qa UC### --skip-e2e
Scope: --skip-e2e marks the LIVE_PROVIDER_SMOKE and
PROD_GOLDEN_PATH stages as NOT_RUN for this run only. It does NOT
mark any other stage as NOT_RUN. It is NOT a bulk QA bypass.
--skip-e2emay leave aggregateVERIFIEDonly if neitherLIVE_PROVIDER_SMOKEnorPROD_GOLDEN_PATHis mandatory for this UC (per the matrix above and any project override).- If either stage is mandatory for this UC,
--skip-e2eproduces aggregateUNVERIFIED(NOT_RUN on a mandatory stage). The user must either:- Run the stage; or
- File a signed exception per W4 with
affected_gatesenumerating the specific stage names (no blanket overrides).
--skip-e2eis the single preserved skip-style flag. The bulk-QA-skip flag (formerly written as--skipfollowed immediately by-qa) has been removed from every skill in W3. Bulk-bypass needs are handled by emergency mode (W4).
Trigger
| Command | Description |
|---|---|
/nacl-tl-qa UC### | Run E2E QA for a UC task |
Prerequisites
Configuration Resolution
| Data | Source priority |
|---|---|
| Frontend URL/port | impl-brief-fe.md > config.yaml → modules.frontend.port > default 3000 |
| Backend URL/port | impl-brief.md > config.yaml → modules.backend.port > default 3001 |
| Reports mode | config.yaml → reports.mode (fallback: "local") |
| Reports path | config.yaml → reports.local_path (fallback: .tl/reports) |
| Remote publish | config.yaml → reports.ssh_host (only if mode: "remote") |
| Test credentials | config.yaml → credentials.[role] (email, password, phone, role) |
If reports section missing or mode is "local" → save to .tl/reports/ only. Always save locally.
1. Task Readiness
Read .tl/tasks/UC###/status.json and confirm:
phases.sync=done(BE and FE are synchronized)phases.stubs=done(no critical stubs remain)
If not met, report the current state and suggest /nacl-tl-sync UC### or /nacl-tl-stubs UC###.
2. Dev Servers Running
Verify both servers are accessible by navigating to them:
playwright_navigate -> frontend URL (e.g., http://localhost:5173)
playwright_navigate -> backend health (e.g., http://localhost:3000/api/health)
Read impl-brief.md and impl-brief-fe.md to determine actual ports.
HTTP-200 assertion: both playwright_navigate calls must return HTTP 200. If either server returns a non-200 status or is unreachable:
→ emit: QA HALTED — NO_INFRA (frontend unreachable) ← use exact label
→ halt with explicit status; do NOT exit silently
→ tell the user which URL failed and suggest starting the dev server
Do not proceed past this step unless both servers confirm HTTP 200.
3. Screenshots Directory
rm -rf .tl/qa-screenshots/UC###/
mkdir -p .tl/qa-screenshots/UC###/
What to Read
Files from .tl/tasks/UC###/:
| File | Purpose | Required |
|---|---|---|
acceptance.md | Primary checklist -- every criterion becomes a test | Yes |
task-be.md | API behavior, endpoints, validation rules | Yes |
task-fe.md | UI behavior, pages, forms, components | Yes |
api-contract.md | Request/response shapes, status codes | Yes |
impl-brief.md | Backend URLs, ports | Yes |
impl-brief-fe.md | Frontend routes, selectors | Yes |
result-be.md | What was implemented (backend) | If exists |
result-fe.md | What was implemented (frontend) | If exists |
QA Workflow
Step 0: Testable-Criteria Gate
Read acceptance.md. Count how many criteria have ui_testable == true (or equivalent — any criterion that can be verified through the browser).
IF count(ui_testable criteria) == 0:
→ emit: QA HALTED — UNVERIFIED (no testable criteria)
→ halt immediately; do NOT proceed to any Playwright calls
If at least one testable criterion exists, continue to the next step.
Step 0b: Find or Generate Scenario
Check for existing scenario:
IF .tl/scenarios/verify-UC###.md EXISTS:
→ Use it (previously generated or manually written)
ELSE:
→ Generate one from acceptance.md (see below)
Scenario generation (from acceptance criteria):
- Read
acceptance.md— extract all testable criteria - Read
task-fe.md— extract routes, components, user flows - Read
api-contract.md— extract endpoints for DB checkpoint verification - Generate
.tl/scenarios/verify-UC###.mdin this format:
# Verify: UC### — [Title]
## Metadata
- **Task**: UC###
- **Modules**: frontend, backend
- **Generated**: [date]
- **Source**: acceptance.md
## Prerequisites
- Dev servers running (frontend + backend)
- Test user credentials available (from `config.yaml → credentials.[role]`: email, password, phone)
## Test Data
[From acceptance.md or test fixtures if available]
## Scenario Blocks
### BLOCK 1: [Flow name]
| # | Action | Data | Expected result |
|---|--------|------|-----------------|
| 1 | Navigate to [route] | — | Page loaded, [element] visible |
| 2 | Fill [field] | [value] | Field accepts input |
| 3 | Click [button] | — | [Expected outcome] |
| 4 | Verify [result] | — | [Assertion] |
### BLOCK 2: [Error flow]
...
## DB Checkpoints (optional)
[SQL queries to verify data was saved correctly]
## Pass/Fail Criteria
All blocks PASS = test PASS. Any FAIL = test FAIL.
The scenario is saved for reuse in regression testing.
Step 1: Parse Acceptance Criteria
Read acceptance.md (and the scenario if generated) and map each criterion to a test. Classify each as UI-testable (test it) or N/A (cannot verify via UI -- mark with reason).
Requirements-coverage gate (traceability). Build the explicit matrix criterion → stage(s) → status for every criterion, not just the ones you happened to exercise. A criterion is only allowed to be N/A when it genuinely cannot be observed through the browser and it carries no provider/runtime dependency — never use N/A to drop a provider-dependent criterion (route those to LIVE_PROVIDER_SMOKE/PROD_GOLDEN_PATH). Any UI-testable criterion left unmapped (no stage exercises it) is not verified: it forces the aggregate to UNVERIFIED via the same weakest-stage floor as a NOT_RUN mandatory stage — a green run that silently skipped a required criterion must not read as VERIFIED. Record unmapped criteria alongside qa_not_run_mandatory_stages.
Step 2: Update Status
Set phases.qa to in_progress in status.json. Record qa_started timestamp.
Step 3: Execute Main Flow Scenarios
For each happy-path acceptance criterion:
a. Navigate to the target page
-> playwright_navigate(url)
-> playwright_screenshot(name: "step-NN-description")
-> stat .tl/qa-screenshots/UC###/step-NN-description.png
IF file absent or empty: mark step FAIL, append "(screenshot missing)" to step record
b. Perform user actions (use credentials from config.yaml → credentials.[role] for login/auth forms)
-> playwright_fill / playwright_select / playwright_click
-> playwright_screenshot(name: "step-NN-description")
-> stat .tl/qa-screenshots/UC###/step-NN-description.png
IF file absent or empty: mark step FAIL, append "(screenshot missing)" to step record
c. Verify the expected result
-> playwright_get_visible_text / playwright_get_visible_html / playwright_evaluate
-> playwright_screenshot(name: "step-NN-description")
-> stat .tl/qa-screenshots/UC###/step-NN-description.png
IF file absent or empty: mark step FAIL, append "(screenshot missing)" to step record
d. Record PASS or FAIL for this criterion
Example scenario for "User can create an order":
Step 01: Navigate to /orders/new
-> playwright_navigate(url: "http://localhost:5173/orders/new")
-> playwright_screenshot(name: "step-01-navigate-to-order-form")
-> playwright_get_visible_text() -- confirm page shows "Create Order"
Step 02: Select a client
-> playwright_click(selector: "[data-testid='client-select']")
-> playwright_click(selector: "[data-testid='client-option-1']")
-> playwright_screenshot(name: "step-02-select-client")
Step 03: Add a product item
-> playwright_click(selector: "[data-testid='add-item-btn']")
-> playwright_fill(selector: "input[name='quantity']", value: "2")
-> playwright_screenshot(name: "step-03-add-product-item")
Step 04: Submit the form
-> playwright_click(selector: "button[type='submit']")
-> playwright_screenshot(name: "step-04-submit-order")
-> playwright_get_visible_text() -- confirm "Order created" message
-> playwright_evaluate(script: "window.location.pathname") -- confirm redirect
Criterion: PASS (order created, confirmation shown, redirect happened)
Step 4: Execute Error/Validation Scenarios
Test alternative and error flows:
- Validation errors: Submit forms with empty required fields, invalid data
- Boundary values: Zero quantities, long strings, special characters
- Authorization: Access protected pages without authentication
- Not found: Navigate to non-existent resources
- Server errors: Trigger error states if possible through UI
Step 5: Generate Reports
5a: qa-report.md (always)
Create .tl/tasks/UC###/qa-report.md using nacl-tl-core/templates/qa-report-template.md. Include: frontmatter with verdict and counts, scenario description, every test step with action/expected/actual/status/screenshot, acceptance criteria table, bug descriptions (if any), verdict with conditions, recommendation.
5b: qa-report.html (always)
Generate an HTML report alongside the markdown report. Save to .tl/tasks/UC###/qa-report.html.
Structure:
<!DOCTYPE html>
<html>
<head>
<title>QA Report: UC### — [Title]</title>
<style>
/* Inline styles for standalone viewing (no external CSS) */
body { font-family: -apple-system, sans-serif; max-width: 900px; margin: 0 auto; padding: 20px; }
.pass { color: #22c55e; } .fail { color: #ef4444; }
.badge { padding: 4px 12px; border-radius: 4px; font-weight: bold; }
.badge-pass { background: #dcfce7; color: #166534; }
.badge-fail { background: #fef2f2; color: #991b1b; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #e5e7eb; padding: 8px; text-align: left; }
th { background: #f9fafb; }
img { max-width: 100%; border: 1px solid #e5e7eb; border-radius: 4px; margin: 8px 0; }
.screenshot-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
</style>
</head>
<body>
<h1>QA Report: UC### — [Title]</h1>
<p>Date: [date] | Duration: [time] | Verdict: <span class="badge badge-[pass/fail]">[PASS/FAIL]</span></p>
<h2>Summary</h2>
<table>
<tr><th>Total criteria</th><td>[N]</td></tr>
<tr><th>Tested</th><td>[N]</td></tr>
<tr><th>Passed</th><td class="pass">[N]</td></tr>
<tr><th>Failed</th><td class="fail">[N]</td></tr>
<tr><th>N/A</th><td>[N]</td></tr>
<tr><th>Bugs found</th><td>[N]</td></tr>
</table>
<h2>Test Steps</h2>
<table>
<tr><th>#</th><th>Action</th><th>Expected</th><th>Actual</th><th>Status</th></tr>
<!-- One row per step -->
</table>
<h2>Screenshots</h2>
<div class="screenshot-grid">
<!-- Include ALL .png files from the screenshots directory, sorted alphabetically.
Do NOT rely only on screenshots mentioned in the steps table.
Scan the directory: ls .tl/qa-screenshots/UC###/*.png | sort
For each file: <figure><img src="screenshots/{filename}"><figcaption>{filename}</figcaption></figure> -->
</div>
<h2>Bugs</h2>
<!-- Bug descriptions if any -->
<footer><p>Generated by /nacl-tl-qa | Claude Skills · {N} screenshots</p></footer>
</body>
</html>
Screenshots must cover ALL files from the directory — scan before generating the section:
ls .tl/qa-screenshots/UC###/*.png | sort
Use screenshots/{filename} as the relative path (screenshots will be copied to a screenshots/ subdirectory alongside the report).
5c: Save report to reports directory
Read config.yaml → reports. Resolution chain:
IF config.yaml → reports.mode == "remote" AND ssh_host is set:
→ Save locally AND publish via rsync
IF config.yaml → reports.mode == "local" OR reports section empty OR config.yaml missing:
→ Save locally only (DEFAULT)
Local save (always happens):
REPORT_DIR="$(config.reports.local_path || '.tl/reports')/qa-UC###-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$REPORT_DIR/screenshots"
cp .tl/qa-screenshots/UC###/*.png "$REPORT_DIR/screenshots/"
cp .tl/tasks/UC###/qa-report.html "$REPORT_DIR/"
The report uses screenshots/{filename} relative paths — these work correctly in $REPORT_DIR/ because screenshots are copied into $REPORT_DIR/screenshots/.
Tell the user:
Report saved: .tl/reports/qa-UC###-20260327-143200/qa-report.html
Open: open .tl/reports/qa-UC###-20260327-143200/qa-report.html
Remote publish (only if mode: "remote"):
rsync -avz "$REPORT_DIR/" \
"${config.reports.ssh_host}:${config.reports.remote_path}/$(basename $REPORT_DIR)/"
Report URL: https://${config.reports.domain}/$(basename $REPORT_DIR)/qa-report.html
Step 5d: Create bug tasks in YouGile (if configured)
If bugs were found AND YouGile is configured (config.yaml → yougile):
Threshold from config.yaml:
yougile:
auto_create_bugs:
critical: true # always (cannot be disabled)
major: true # default: create tasks
minor: false # default: skip (noise reduction)
If auto_create_bugs section is missing → use defaults above.
For each bug meeting the threshold:
- Create a task in the Reopened column:
create_task( title: "[BUG-NNN] UC###: short description", columnId: config.yougile.columns.reopened, description: "Severity: MAJOR\nFound by: /nacl-tl-qa UC###\n\nDescription: ...\nExpected: ...\nActual: ...\nScreenshot: step-NN.png", stickers: { task_type: "bug", module: detected_module, source: "agent" } ) - If parent UC task exists in YouGile → link as subtask:
add_subtask(parentTaskId: UC_task_id, childTaskId: bug_task_id) - Report to user: "Created N bug tasks in YouGile (Reopened column)"
If YouGile not configured → skip, bugs only in qa-report.
Step 6: Update Tracking
Every per-stage status is recorded in status.json under
phases.qa_stages, regardless of the aggregate:
"phases": {
"qa": "done | unverified | failed | halted",
"qa_stages": {
"component": "VERIFIED | PARTIALLY_VERIFIED | FAILED | BLOCKED | NOT_RUN | UNVERIFIED",
"local_runtime": "...",
"wire_contract": "...",
"provider_fixture": "...",
"live_provider_smoke": "...",
"prod_golden_path": "..."
},
"qa_aggregate_status": "VERIFIED | PARTIALLY_VERIFIED | UNVERIFIED | FAILED | BLOCKED"
}
If aggregate VERIFIED (QA COMPLETE): phases.qa = "done", record qa_completed, qa_verdict: "QA COMPLETE".
If aggregate PARTIALLY_VERIFIED or UNVERIFIED (QA APPLIED — UNVERIFIED): phases.qa = "unverified", record qa_completed, qa_verdict set to the headline, and (when applicable) qa_not_run_mandatory_stages array enumerating the mandatory stages with NOT_RUN status.
If aggregate FAILED (QA INCOMPLETE — REGRESSION): phases.qa = "failed", record qa_completed, qa_verdict: "QA INCOMPLETE — REGRESSION", qa_failures array.
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 27
- Forks
- 4
- Last commit
- Sep 2026
Advanced
- Item type
- skill
- Key
nacl-tl-qa- Source
- github.com/itsalt/nacl
Related picks
Skill · handsontable
The pick for End-to-end testingmstar-e2e
Skill · btspoony
The pick for End-to-end testingcompare-screenshots
Skill · dzhng
The pick for Screenshotsagent-first-screenshots
Skill · devin-axis
The pick for Screenshotsbrowser-use
Skill · browser-use
More in Web & browsingwebapp-testing
Skill · anthropics
More in Web & browsing