mit einem Klick
test-frontend-e2e
// Generates Playwright E2E specs for PwnDoc. Tests run against the full stack (frontend + backend + MongoDB) with pre-authenticated browser sessions. Run with ./pwndoc-cli test --frontend-e2e.
// Generates Playwright E2E specs for PwnDoc. Tests run against the full stack (frontend + backend + MongoDB) with pre-authenticated browser sessions. Run with ./pwndoc-cli test --frontend-e2e.
Generates backend API integration tests for PwnDoc using Jest and supertest. Tests run against an ephemeral MongoDB instance via ./pwndoc-cli test --backend.
Generates frontend unit tests for PwnDoc using Vitest and Vue Test Utils. Handles services (axios mock), components (mount with Quasar), pages (full setup), and Pinia stores. Run with ./pwndoc-cli test --frontend-unit.
Test orchestrator for PwnDoc. Analyzes a feature or the full project to determine test gaps across backend (Jest), frontend unit (Vitest), and frontend E2E (Playwright), then delegates to /test-backend, /test-frontend-unit, and /test-frontend-e2e skills.
| name | test-frontend-e2e |
| description | Generates Playwright E2E specs for PwnDoc. Tests run against the full stack (frontend + backend + MongoDB) with pre-authenticated browser sessions. Run with ./pwndoc-cli test --frontend-e2e. |
| context | fork |
| agent | general-purpose |
| allowed-tools | ["Bash","Glob","Grep","Read","Write","Edit"] |
| argument-hint | [feature] e.g. audits, vulnerabilities, data-clients, settings |
You generate Playwright E2E tests for PwnDoc. Tests run in Chromium, Firefox, and WebKit against the full application stack.
$ARGUMENTS - The feature/flow to test (e.g., "audits", "vulnerabilities", "settings", "data-clients").
If $ARGUMENTS starts with --fix, the format is:
--fix {spec-file} "{failure summary}" [--no-run]
Example: --fix frontend/tests/e2e/vulnerabilities.spec.js "Timeout waiting for selector [data-testid='vuln-row']" --no-run
In fix mode:
frontend/tests/e2e/audits-list.spec.js--no-run is present, STOP — do not run tests. Otherwise proceed to Step 3 (Run and Fix)Before writing any tests, ALWAYS read:
frontend/src/pages/ related to the featurefrontend/tests/e2e/audits-list.spec.jsfrontend/tests/playwright.config.jsfrontend/tests/e2e/auth.setup.js and frontend/tests/e2e/init-user.setup.jsUnderstand the page's UI elements, forms, tables, and navigation before writing selectors.
Write the spec to frontend/tests/e2e/{feature}.spec.js.
Tests are pre-authenticated via setup projects. The Playwright config defines:
init-user project: registers the first admin userauth-{browser} projects: logs in and saves storageState.{browser}.json{browser} projects: run *.spec.js files with saved auth stateAll *.spec.js files run with authentication already handled. The test user is:
admin, Password: Admin123, Role: adminimport { test, expect } from './base.js';
Important: Always import from ./base.js, NOT from @playwright/test. The base fixture auto-saves browser storage state after each test, which is required because PwnDoc rotates refresh tokens on every use. Without this, subsequent tests load stale tokens and get redirected to /login.
See template-page-spec.md for the full test scaffold.
Follow this priority strictly. Use the first one that works — do NOT skip ahead to CSS selectors.
1. getByRole() — Always try first
page.getByRole('button', { name: 'Save' })
page.getByRole('textbox', { name: 'Title' })
page.getByRole('link', { name: 'Settings' })
page.getByRole('tab', { name: 'Languages' })
page.getByRole('row').filter({ hasText: 'row content' })
page.getByRole('cell', { name: 'value' })
page.getByRole('heading', { name: 'Audits' })
page.getByRole('dialog') // scope modals
page.getByRole('toolbar').getByRole('listitem') // scope toolbar
2. getByText() — Non-interactive elements
page.getByText('Vulnerability created successfully')
page.getByText(/already exists/i)
3. getByLabel() — Form controls with labels
page.getByLabel('Description')
page.getByLabel(/Name/)
4. getByPlaceholder() — Inputs with placeholder but no label
page.getByPlaceholder('Search...')
5. getByTestId() — When semantic locators don't work
page.getByTestId('delete-language-btn')
When you need getByTestId, add data-testid to the Vue source file yourself. This is preferred over CSS selectors.
6. CSS selectors — Absolute last resort
Only when the element is truly outside your control and none of the above work. NEVER use Quasar CSS class selectors (.q-dialog, .q-btn, .q-card, .q-table, .q-field, or any .q-* class). These are framework implementation details that break across versions.
// Scope to a dialog using role (NOT .q-dialog)
const dialog = page.getByRole('dialog');
await dialog.getByLabel('Title').fill('New Item');
await dialog.getByRole('button', { name: 'Create' }).click();
// Filter rows by text content
page.getByRole('row').filter({ hasText: 'Item Name' })
// First matching element
page.getByLabel(/Name/).first()
// Narrow with .and()
page.locator('input').and(page.getByLabel('Language'))
expect(...).toBeVisible() rather than explicit waits.await expect(page).toHaveURL('/expected-route')page.waitForResponse() — assert visual outcomes instead:
page.goto() or page.reload(): wait for a key UI element that only appears once data is fetched:
await page.goto(`/audits/${auditId}/general`);
await expect(page.getByLabel(/Name/).first()).not.toHaveValue('');
await page.keyboard.press('Control+s');
await expect(page.getByText('Audit updated successfully')).toBeVisible();
await expect(editor.locator('img')).toBeVisible({ timeout: 5000 });
| Route | Page | Description |
|---|---|---|
/audits | Audit List | Main dashboard |
/audits/{id} | Audit Edit | Multi-tab audit editor |
/vulnerabilities | Vulnerability List | Vulnerability database |
/data | Data Management | Overview page |
/data/custom | Custom Data | Languages, Audit Types, Vuln Types, Sections |
/data/clients | Clients | Client management |
/data/companies | Companies | Company management |
/data/templates | Templates | Report templates |
/data/collaborators | Collaborators | Collaborator management |
/data/spellcheck | Spellcheck | Spellcheck dictionary |
/data/languagetool-rules | LanguageTool Rules | Grammar rules |
/settings | Settings | Application settings, backups |
/profile | User Profile | Profile management |
If $ARGUMENTS contains --no-run, STOP HERE. Do not run tests — the calling orchestrator will handle test execution. Strip --no-run from arguments before processing the feature name in earlier steps.
Otherwise, run tests with:
./pwndoc-cli test --frontend-e2e
Do not combine E2E runs with --coverage; coverage mode only supports backend and frontend unit suites.
If tests fail, read the error output, fix the spec, and re-run. Iterate until all tests pass across all browsers.
See template-page-spec.md for a complete scaffold.