Title: Anki Playwright Agents — LearnCoachAssist

Q: Playwright (Node): minimal setup?
A: npm i -D @playwright/test
npx playwright install
npx playwright test

Q: Where do Playwright tests live?
A: Common: ./tests or ./e2e (you choose). Configure testDir in playwright.config.ts so agents know where to add new tests.

Q: Key playwright.config.ts settings?
A: use.baseURL, webServer (start app), projects (chromium/firefox/webkit), retries/workers, reporter (html + junit), trace/video/screenshot policies.

Q: How do I auto-start my app for tests?
A: Use playwright.config.ts webServer: { command: "npm run dev", url: "http://127.0.0.1:3000", reuseExistingServer: !process.env.CI }.

Q: Run one test or one spec?
A: npx playwright test tests/foo.spec.ts
npx playwright test -g "test name"

Q: Fastest debugging loop?
A: PWDEBUG=1 npx playwright test -g "name" --headed
or npx playwright test --debug (inspector)

Q: Best selector strategy?
A: Prefer getByRole/getByLabel/getByPlaceholder for resilient tests. Add data-testid only when semantics are missing or ambiguous.

Q: When should I add data-testid?
A: When UI text is unstable (i18n), roles are missing, or multiple similar elements exist. Keep ids stable and semantic (e.g., save-button).

Q: Reuse login across tests?
A: Create storageState once (globalSetup) and set test.use({ storageState: "storageState.json" }) to avoid logging in every test.

Q: Make tests deterministic (data)?
A: Seed data via API/db fixtures, use unique test IDs per run, and clean up. Avoid depending on existing prod-like data.

Q: Avoid flaky waits?
A: Use Playwright auto-wait + expect(locator).toBeVisible/toHaveText/toHaveURL. Avoid page.waitForTimeout except as last resort.

Q: Visual regression assertion?
A: expect(page).toHaveScreenshot("home.png") or expect(locator).toHaveScreenshot("card.png")

Q: How do snapshot baselines update?
A: Run npx playwright test --update-snapshots (only when change is intended) and review diffs in PR.

Q: Mask dynamic areas in screenshots?
A: expect(page).toHaveScreenshot({ mask: [page.locator("[data-testid=clock]")] }) to ignore volatile regions.

Q: Compare data regressions?
A: Fetch JSON (page.request or API client) and expect(data).toMatchSnapshot() so diffs show exact field changes.

Q: Compare previous vs current UI?
A: Check out previous commit in a git worktree, run the same tests, and compare HTML reports and screenshot diffs between runs.

Q: Best artifacts to keep for comparisons?
A: HTML report, trace.zip, screenshots, and optionally videos. These let you diff behavior without rerunning locally.

Q: Design-change detection strategy?
A: Pick a small set of high-value pages/components, fix viewport/theme, disable animations, and snapshot them regularly.

Q: How to split smoke vs full suite?
A: Tag tests (e.g., @smoke, @critical) and run npx playwright test --grep @smoke in CI gates.

Q: CI essentials?
A: Install browsers (npx playwright install --with-deps), set CI=1, run npx playwright test, upload playwright-report/ and test-results/ artifacts.

Q: Parallel tests without chaos?
A: Isolate state per test (unique users/data), avoid shared mutable globals, and keep tests idempotent so workers can run safely.

Q: What should an AI agent do before writing a test?
A: Run existing suite, identify stable selectors, confirm the user flow steps, and agree on what must be asserted (URL, text, data).

Q: Prompt template for an agent to add a test?
A: "Add a Playwright test for [flow]. Use getByRole/Label first, add data-testid only if needed, assert key outcomes, keep it deterministic, and run it."

Q: Agent safety rule for snapshots?
A: Never update snapshots unless the user explicitly wants to accept visual changes; attach diff + reasoning when proposing updates.

Q: How to handle intentional UI changes?
A: Update assertions/testids first, then update screenshots with review. Record the reason (ticket/PR) so future diffs are explainable.

Q: Anki import: what file format does Anki accept?
A: Plain text (e.g., .txt/.tsv) with fields separated by comma/semicolon/tab/etc. Make sure it’s saved as UTF-8.

Q: Anki import: what does the first field control?
A: By default Anki uses the first field to detect duplicates; on import, duplicates can be updated/ignored/added depending on import settings.

Q: Anki import: what are file headers like #separator?
A: Anki 2.1.54+ supports top-of-file headers like #separator:Tab, #html:true, #deck:..., #notetype:..., #tags:..., #tags column:3 to preset import options.

Q: Anki import: how do I put tags in a column?
A: Add a tags column and include #tags column:3 (or whichever column). In each row, put tags separated by spaces.

Q: What is Playwright?
A: A browser automation framework (Chromium/Firefox/WebKit) with a built-in test runner (@playwright/test) for reliable end-to-end tests.

Q: Playwright “library” vs “@playwright/test”?
A: Use @playwright/test for the test runner, fixtures, expect API, reporting, retries, and parallelization; use playwright (library) for custom scripting without the runner.

Q: What’s a “project” in Playwright config?
A: A named browser/device configuration (e.g., chromium, firefox, webkit, mobile) that runs the same tests under different settings.

Q: How do I run only chromium tests?
A: npx playwright test --project=chromium

Q: How do I run tests in headed mode?
A: npx playwright test --headed

Q: How do I open the HTML report?
A: npx playwright show-report

Q: What is a Playwright trace?
A: A recorded timeline (screenshots, DOM snapshots, network, console, actions) you can inspect to debug failing/flaky tests.

Q: How do I enable traces on failures?
A: In playwright.config.ts: use: { trace: 'on-first-retry' } (or 'on' for always).

Q: How do I view a trace.zip?
A: npx playwright show-trace path/to/trace.zip

Q: How do I slow down actions for debugging?
A: Use PWDEBUG=1 (inspector) or launch with slowMo in custom scripts; in tests prefer --debug/PWDEBUG=1.

Q: What is Playwright “auto-wait”?
A: Playwright waits for elements to be actionable (attached/visible/stable/enabled) and for navigation where appropriate, reducing manual sleeps.

Q: When is page.waitForTimeout() acceptable?
A: Rarely: as a last resort for non-deterministic animations/3rd-party widgets. Prefer expect(...) and waiting on app state.

Q: What is a Locator?
A: A live selector handle that re-resolves automatically and supports auto-wait + strictness; prefer locators over element handles.

Q: Why prefer getByRole()?
A: It uses accessibility roles/names, making tests more resilient to DOM refactors and closer to user behavior.

Q: How do I target a button by accessible name?
A: page.getByRole('button', { name: 'Save' })

Q: How do I assert the URL?
A: await expect(page).toHaveURL(/\\/dashboard$/)

Q: How do I assert text inside an element?
A: await expect(page.getByTestId('toast')).toHaveText(/Saved/)

Q: What is “strict mode” for locators?
A: Most locator actions expect exactly one match; if multiple elements match, Playwright throws to prevent ambiguous tests.

Q: How do I disambiguate multiple matches?
A: Use better selectors (role/name), or refine with .filter({ hasText }), .nth(i), or scope with a parent locator.

Q: How do I group steps in the report?
A: await test.step('create customer', async () => { ... })

Q: How do I tag a test?
A: Add tags in the title like test('login @smoke', async ({ page }) => { ... }) and run with --grep @smoke.

Q: How do I skip or focus tests?
A: test.skip(...), test.describe.skip(...), test.only(...) (avoid committing .only).

Q: How do I share code between tests?
A: Create helper functions (e.g., in tests/helpers/), or Page Object Models for complex screens; keep them thin and assertion-focused.

Q: What is storageState?
A: A JSON file containing cookies/localStorage that can preload authenticated sessions without re-logging-in each test.

Q: How do I create a storageState file?
A: Run a one-time “login” test/script and call await context.storageState({ path: 'storageState.json' }).

Q: Where should storageState.json live?
A: Usually under the test project (e.g., e2e/.auth/storageState.json) and referenced in config; don’t commit real-user secrets.

Q: How do I do per-role logins (admin vs user)?
A: Create separate storage states (admin.json, user.json) and use test.use({ storageState: ... }) in different describe blocks/projects.

Q: How do I handle login forms in tests?
A: Navigate to /login, fill inputs with getByLabel/getByPlaceholder, click submit, then assert redirect + a visible logged-in UI element.

Q: What if my app uses SSO/2FA?
A: Prefer storageState created manually once, or authenticate via backend/API (test user) instead of automating brittle multi-factor UI flows.

Q: How do I start multiple servers for E2E?
A: Use playwright.config.ts webServer as an array: [{ command, url }, { command, url }], so Playwright waits for all before tests.

Q: What does reuseExistingServer do?
A: It avoids restarting your dev server locally if it’s already running; in CI you usually set reuseExistingServer:false.

Q: What is baseURL used for?
A: It lets you write page.goto('/login') instead of full URLs, and keeps tests portable between environments.

Q: How do I pass environment variables to tests?
A: Use process.env in playwright.config.ts and tests; set vars in shell or CI (e.g., BASE_URL, USERNAME, PASSWORD).

Q: Where do Playwright outputs go?
A: Default: playwright-report/ (HTML) and test-results/ (artifacts like traces/screenshots/videos).

Q: How do I record a video on failure?
A: In config: use: { video: 'retain-on-failure' } (or 'on' for always).

Q: How do I take screenshots on failure?
A: In config: use: { screenshot: 'only-on-failure' }

Q: How do I emulate a mobile device?
A: Use devices from playwright: import { devices } and set project.use = devices['iPhone 13'].

Q: How do I block external analytics calls?
A: Use page.route('**/google-analytics.com/**', route => route.abort()) to keep tests deterministic.

Q: How do I mock an API response?
A: page.route('**/api/reports', route => route.fulfill({ json: fakeData }))

Q: How do I seed data via HTTP in a test?
A: Use the built-in request fixture: const res = await request.post('/api/test/seed', { data: {...} });

Q: How do I verify a download occurred?
A: Use const download = await page.waitForEvent('download'); then download.path() or saveAs().

Q: How do I upload a file?
A: await page.setInputFiles('input[type=file]', 'path/to/file.pdf')

Q: How do I test in a clean DB state?
A: Create a test-only reset/seed endpoint or database script; run it in test.beforeEach/beforeAll for isolation.

Q: What’s a good “smoke test” set?
A: Login, navigate key pages, create/update a core entity, and verify a critical report/overview renders (fast, stable, minimal).

Q: How do I reduce flakiness from animations?
A: Disable animations via CSS injection (page.addStyleTag) or prefers-reduced-motion; avoid asserting pixel-perfect layout unless needed.

Q: How do I make selectors stable in Vue/Laravel apps?
A: Add semantic roles/labels where possible; add data-testid as a last resort on interactive elements and key containers.

Q: What port does portal-vue dev server use (per script)?
A: /start_dev_servers.sh starts portal-vue with yarn serve --port 3445.

Q: What port does portal-laravel dev server use (per script)?
A: /start_dev_servers.sh starts php artisan serve --port 7677.

Q: Where is AMS (Vue 3) Vite port configured?
A: In /root/myapp/admin/admin-2-vue/vite.config.ts under server.port.

Q: Where is Connect (Vue 3) Vite port configured?
A: In /root/myapp/portal/portal-2-vue/vite.config.ts under server.port.

Q: How do I choose baseURL for AMS tests?
A: Point baseURL at the UI you’re testing (e.g., admin-2-vue dev URL), and call API/seed endpoints separately if needed.

Q: How do I choose baseURL for Connect tests?
A: Point baseURL at portal-2-vue or portal-vue depending on which UI you are testing.

Q: How can one E2E suite cover both AMS and Connect?
A: Create separate Playwright projects (AMS, Connect) with different baseURL/webServer settings, and run all with one command.

Q: What’s the quickest way to generate a first draft test?
A: Use npx playwright codegen to record actions, then refactor into a stable @playwright/test spec with good locators/assertions.

Q: Why shouldn’t I keep raw codegen output?
A: It often uses brittle selectors and weak assertions; refactor to getByRole/testids and add meaningful expect() checks.

Q: How do I guide an AI agent to create Playwright tests I can run later?
A: Specify: repo path, testDir, baseURL(s), how to start servers, login method, required assertions, and “only write under e2e/”.

Q: Agent prompt: “add test and run it” template?
A: "In /root/myapp/[ams|connect]/..., add Playwright tests under e2e/. Start servers via config webServer. Implement login via storageState. Run npx playwright test and show failures."

Q: Agent prompt: “no risky changes” guardrail?
A: "Do not change app code or update snapshots unless I explicitly ask. Prefer stable locators. If blocked, propose minimal data-testid additions and wait for approval."

Q: How does Codex CLI help with Playwright?
A: It can generate/edit test files, run Playwright commands, parse failures, iterate on selectors/assertions, and leave runnable scripts/specs in the repo.

Q: How do I ask Codex CLI to keep changes confined?
A: Say “only write under ” and “don’t edit app code unless necessary”; also name exact file paths you want created/modified.

Q: How do I make an agent “run tests automatically”?
A: Ask it to: (1) add/modify tests, (2) run npx playwright test, (3) fix failures, (4) re-run until green, and (5) summarize what changed.

Q: What should an agent report after creating tests?
A: New files/paths, commands used, how to start servers, how login is handled (storageState path), and what the assertions verify.

Q: How do I install Playwright browsers + OS deps (Linux CI)?
A: npx playwright install --with-deps

Q: How do I install only Chromium?
A: npx playwright install chromium

Q: Where do Playwright browsers get installed?
A: Usually under a Playwright-managed cache; override with PLAYWRIGHT_BROWSERS_PATH=0 to install into node_modules/.cache.

Q: How do I verify Playwright is installed correctly?
A: npx playwright --version
npx playwright install --dry-run

Q: How do I run the Playwright test “UI mode”?
A: npx playwright test --ui

Q: How do I list all discovered tests without running them?
A: npx playwright test --list

Q: How do I stop after the first failure?
A: npx playwright test --max-failures=1

Q: How do I run with a single worker (no parallelism)?
A: npx playwright test --workers=1

Q: How do I retry failing tests from CLI?
A: npx playwright test --retries=2

Q: How do I set a global per-test timeout from CLI?
A: npx playwright test --timeout=60000

Q: How do I run only tests matching a tag?
A: npx playwright test --grep \"@smoke\"

Q: How do I exclude tests matching a tag?
A: npx playwright test --grep-invert \"@slow\"

Q: How do I run a shard of the suite in CI?
A: npx playwright test --shard=1/3 (and 2/3, 3/3)

Q: How do I fail CI if someone left test.only?
A: npx playwright test --forbid-only

Q: How do I run with a specific config file?
A: npx playwright test --config=playwright.config.ts

Q: How do I run and print verbose steps/actions?
A: Set DEBUG=pw:api (or PWDEBUG=1 for inspector).

Q: How do I record a quick script without the test runner?
A: npx playwright codegen http://localhost:8080

Q: How do I codegen against a mobile device profile?
A: npx playwright codegen --device \"iPhone 13\"

Q: How do I codegen while already logged in?
A: Use codegen with a persistent context (or load storage state) so it records post-login flows.

Q: What does testDir do in playwright.config.ts?
A: It tells Playwright where to look for spec files (e.g., e2e/ or tests/e2e/).

Q: What do testMatch/testIgnore control?
A: They include/exclude test file patterns (e.g., **/*.spec.ts) so only intended specs run.

Q: What’s baseURL used for in config?
A: It enables page.goto('/login') and makes tests portable across environments.

Q: What’s the difference between actionTimeout and navigationTimeout?
A: actionTimeout limits individual actions (click/fill); navigationTimeout limits navigations (goto/click causing nav).

Q: How do I change expect() timeout globally?
A: In config: expect: { timeout: 10000 }

Q: How do I force a consistent locale/timezone for stable tests?
A: In config use: { locale: 'de-DE', timezoneId: 'Europe/Berlin' }

Q: How do I emulate geolocation + permissions?
A: use: { geolocation: { latitude, longitude }, permissions: ['geolocation'] }

Q: How do I set extra HTTP headers for all requests?
A: use: { extraHTTPHeaders: { 'X-Test-Run': 'e2e' } }

Q: How do I ignore HTTPS errors in local dev?
A: use: { ignoreHTTPSErrors: true } (only for dev/testing).

Q: How do I set a consistent viewport?
A: use: { viewport: { width: 1280, height: 720 } }

Q: How do I run multiple browser “projects”?
A: Define projects: [{ name: 'chromium', use: { browserName: 'chromium' } }, ...]

Q: How do I give AMS and Connect different baseURLs?
A: Create projects like { name:'ams', use:{ baseURL:'http://127.0.0.1:3437' } } and { name:'connect', use:{ baseURL:'http://127.0.0.1:3445' } }.

Q: How do I start dev servers automatically for tests?
A: Use webServer in playwright.config.ts to run commands and wait for a URL to respond.

Q: How do I start multiple services (UI + API)?
A: Set webServer to an array: [{ command, url }, { command, url }].

Q: How do I pass env vars into webServer commands?
A: Use `command: 'BASE_URL=... npm run dev'` or set env in CI before running tests.

Q: How do I run a subset of projects?
A: npx playwright test --project=ams (or multiple --project flags).

Q: How do I disable video/trace locally for speed?
A: In config set use.video/use.trace to 'off' (or conditionally based on CI env).

Q: What is a Locator vs a CSS selector string?
A: A Locator is a smart handle with auto-wait and strictness; use locators to reduce flakiness.

Q: How do I select by test id?
A: page.getByTestId('save-button')

Q: How do I configure the test id attribute name?
A: In config: use: { testIdAttribute: 'data-testid' } (or your custom attribute).

Q: How do I select the first matching element?
A: Use locator.first() (but prefer a more specific selector when possible).

Q: How do I select the nth matching element?
A: Use locator.nth(0), locator.nth(1), ...

Q: How do I scope a selector to a section/card?
A: const card = page.getByTestId('report-card'); await card.getByRole('button', { name: 'Download' }).click();

Q: How do I select an element containing other elements?
A: Use locator.filter({ has: page.getByRole(...) }) to narrow by descendants.

Q: How do I select by partial text safely?
A: Prefer getByRole with name; if needed use getByText('Save', { exact: true/false }).

Q: How do I handle duplicated labels (same text twice)?
A: Scope to a container or use role+name+exact, then disambiguate with nth() as last resort.

Q: How do I select inside an iframe?
A: Use page.frameLocator('iframe[title=\"...\"]') and then getByRole/getByTestId on that frame locator.

Q: How do I wait for navigation after clicking?
A: Use await Promise.all([page.waitForURL('**/dashboard'), page.getByRole('button', { name: 'Login' }).click()])

Q: How do I wait for a specific network response?
A: const res = await page.waitForResponse(r => r.url().includes('/api/reports') && r.ok());

Q: How do I ensure an element is visible before clicking?
A: await expect(locator).toBeVisible(); await locator.click();

Q: How do I force a click when an overlay blocks it?
A: Try to fix the UI state; as last resort use locator.click({ force: true }) and document why.

Q: How do I hover to reveal a menu?
A: await page.getByRole('button', { name: 'More' }).hover();

Q: How do I fill a field reliably?
A: await page.getByLabel('Email').fill('user@example.com')

Q: How do I clear an input before typing?
A: await locator.fill(''); await locator.type('new value');

Q: How do I press Enter to submit?
A: await page.getByLabel('Password').press('Enter')

Q: How do I assert a page title?
A: await expect(page).toHaveTitle(/AMS/i)

Q: How do I assert an element count?
A: await expect(page.getByTestId('row')).toHaveCount(10)

Q: How do I assert an attribute?
A: await expect(locator).toHaveAttribute('aria-expanded', 'true')

Q: How do I assert an input value?
A: await expect(page.getByLabel('Search')).toHaveValue('foo')

Q: How do I assert a checkbox is checked?
A: await expect(page.getByRole('checkbox', { name: 'Active' })).toBeChecked()

Q: How do I assert a button is disabled/enabled?
A: await expect(page.getByRole('button', { name: 'Save' })).toBeDisabled()

Q: How do I do soft assertions (collect multiple failures)?
A: await expect.soft(locator).toHaveText('...')

Q: How do I poll until a condition becomes true?
A: await expect.poll(async () => await locator.textContent()).toContain('Ready')

Q: How do I assert a toast/snackbar appears?
A: await expect(page.getByRole('status')).toContainText(/saved/i)

Q: How do I assert the URL query params?
A: await expect(page).toHaveURL(/\\?page=2/)

Q: How do I assert a table row contains text?
A: const row = page.getByRole('row', { name: /Customer 123/ }); await expect(row).toBeVisible();

Q: How do I debug a failing test locally?
A: Run with `--headed --debug` (or `PWDEBUG=1`) and inspect locators/steps in the inspector.

Q: How do I capture screenshots on failure automatically?
A: In config: use: { screenshot: 'only-on-failure' }

Q: How do I keep videos only when a test fails?
A: In config: use: { video: 'retain-on-failure' }

Q: How do I run with traces always on (local)?
A: In config: use: { trace: 'on' }

Q: How do I attach extra debug info to the report?
A: Use testInfo.attach('name', { body: Buffer.from('...'), contentType: 'text/plain' }).

Q: How do I group tests by feature?
A: Use test.describe('Analytics', () => { ... }) and keep specs feature-scoped.

Q: How do I run setup steps before each test?
A: Use test.beforeEach(async ({ page }) => { ... })

Q: How do I run teardown after each test?
A: Use test.afterEach(async ({ page }) => { ... })

Q: How do I mark a test as slow?
A: test.slow(); or configure longer timeouts for a describe block.

Q: How do I skip a test in WebKit only?
A: test.skip(browserName === 'webkit', 'Not supported in WebKit');

Q: How do I temporarily mark a known bug as expected to fail?
A: test.fail(true, 'Known issue: ...');

Q: What is test.use() for?
A: It sets per-file/describe options like storageState, viewport, permissions, etc.

Q: How do I create reusable fixtures?
A: Use test.extend({ myFixture: async ({}, use) => { await use(value) } })

Q: What is the built-in request fixture?
A: It provides an APIRequestContext for HTTP calls (seed/reset/login) without using the UI.

Q: How do I seed data via request fixture?
A: await request.post('/api/test/seed', { data: { ... } }) (requires a test-only endpoint).

Q: How do I reset state once per file?
A: Use test.beforeAll/test.afterAll with careful isolation (avoid shared mutable state across workers).

Q: What’s the downside of beforeAll for UI state?
A: Shared state can make parallel runs flaky; prefer per-test isolation or API seeding.

Q: How do I add per-step reporting?
A: await test.step('create report', async () => { ... })

Q: What is testInfo useful for?
A: Access metadata like project name, retry count, outputDir, and attach artifacts.

Q: How do I take a manual screenshot into the report?
A: await page.screenshot({ path: testInfo.outputPath('debug.png') })

Q: How do I enforce consistent test data IDs?
A: Prefix with a run id (timestamp/UUID) and store it in testInfo or an env var.

Q: How do I avoid flaky “loading spinners”?
A: Wait for the spinner to disappear: await expect(page.getByTestId('spinner')).toBeHidden()

Q: How do I authenticate once and reuse it?
A: Create storageState.json in globalSetup and set test.use({ storageState }) for all tests.

Q: What should go into globalSetup for auth?
A: A scripted login that saves storageState; keep it fast and avoid UI details when possible.

Q: How do I login via API instead of UI?
A: Call a test login endpoint, set returned cookies/localStorage, then save storageState.

Q: How do I keep credentials out of the repo?
A: Read USERNAME/PASSWORD from env vars and avoid committing storageState created from real accounts.

Q: How do I create separate sessions for different roles?
A: Generate `storageState.admin.json` and `storageState.user.json`, then apply via test.use() per describe/project.

Q: How do I prevent auth state bleeding between tests?
A: Use separate browser contexts per test (default) and avoid reusing a context unless intentional.

Q: What’s a good post-login assertion?
A: Assert URL + a unique logged-in UI element (e.g., user menu visible) to avoid false positives.

Q: How do I handle “remember me” and cookies?
A: Prefer storageState; don’t depend on long-lived cookies that may expire unpredictably.

Q: How do I test logout?
A: Click logout and assert you’re redirected to /login and auth-only UI is gone.

Q: How do I deal with SSO redirect loops in tests?
A: Use storageState created manually once, or a test-only auth bypass in non-prod environments.

Q: How do I intercept and stub an API call?
A: page.route('**/api/**', route => route.fulfill({ status: 200, json: {...} }))

Q: How do I block third-party scripts to reduce flakiness?
A: page.route('**/*', route => route.request().url().includes('google') ? route.abort() : route.continue())

Q: How do I wait for a request to be sent?
A: await page.waitForRequest(r => r.url().includes('/api/login'))

Q: How do I assert an HTTP response body?
A: Use request fixture: const res = await request.get('/api/me'); expect(await res.json()).toMatchObject({...})

Q: How do I record a HAR file for debugging?
A: In context options: recordHar: { path: 'network.har' } (or use tracing/network logs).

Q: How do I replay network via HAR?
A: Use routeFromHAR to fulfill requests from a recorded HAR for deterministic tests.

Q: How do I wait for the app to become “idle”?
A: Prefer explicit signals (UI text, spinner hidden, or a specific API response), not generic “network idle”.

Q: How do I handle flaky “element detached” errors?
A: Use locators (not element handles), avoid storing DOM nodes, and re-locate before acting.

Q: How do I test file downloads?
A: const download = await page.waitForEvent('download'); await download.saveAs('tmp/file.csv');

Q: How do I assert a download filename?
A: await expect(download.suggestedFilename()).toMatch(/\\.csv$/)

Q: How do I upload a file in a form?
A: await page.setInputFiles('input[type=file]', 'fixtures/test.pdf')

Q: How do I handle a file chooser opened by a button?
A: const chooser = await page.waitForEvent('filechooser'); await chooser.setFiles('fixtures/a.png');

Q: How do I handle JavaScript confirm/alert dialogs?
A: page.once('dialog', d => d.accept()); then trigger the action.

Q: How do I test a popup/new tab flow?
A: const popup = await page.waitForEvent('popup'); then interact with popup.

Q: How do I handle multiple pages in one context?
A: Use context.waitForEvent('page') and keep references to each page object.

Q: How do I test copy-to-clipboard?
A: Grant permissions if needed and assert expected text via page.evaluate(() => navigator.clipboard.readText()).

Q: How do I grant permissions like clipboard/geolocation?
A: Set permissions in context/use config: permissions: ['clipboard-read', 'clipboard-write'].

Q: How do I emulate “prefers-reduced-motion”?
A: use: { reducedMotion: 'reduce' } to reduce animation flakiness.

Q: How do I disable animations via CSS?
A: await page.addStyleTag({ content: '*{transition:none!important;animation:none!important;}' })

Q: How do I test drag-and-drop?
A: Use locator.dragTo(targetLocator) (or dispatch drag events if the app requires it).

Q: How do I scroll an element into view?
A: await locator.scrollIntoViewIfNeeded();

Q: How do I work with virtualized lists?
A: Scroll until the row exists, then assert on visible items; avoid assuming all rows are in DOM.

Q: How do I set a consistent color scheme?
A: use: { colorScheme: 'light' } (or 'dark') to stabilize screenshots.

Q: How do I mask dynamic areas in screenshots?
A: expect(page).toHaveScreenshot({ mask: [page.getByTestId('clock')] })

Q: How do I avoid flaky visual diffs from fonts?
A: Use consistent browser/device/viewport and load fonts deterministically (or disable font-smoothing variations if needed).

Q: How do I create a minimal smoke suite?
A: Tag key tests with @smoke and run `--grep @smoke` as the fast gate.

Q: How do I run the full suite but keep it stable?
A: Isolate data per test, avoid shared accounts, and use retries + traces only as a safety net.

Q: How do I generate JUnit output for CI?
A: Set reporter to include junit in config (e.g., reporter: [['junit', { outputFile: 'results.xml' }]]).

Q: How do I keep HTML reports as artifacts?
A: Upload `playwright-report/` and `test-results/` from CI for debugging.

Q: How do I make CI runs deterministic?
A: Pin Playwright version, install browsers in CI, set fixed viewport/locale/timezone, and avoid external dependencies.

Q: How do I speed up CI?
A: Run fewer projects (chromium only), shard tests, and keep heavy flows behind tags (e.g., @slow).

Q: How do I debug CI-only failures?
A: Inspect trace.zip + screenshots from artifacts; reproduce locally with the same env vars and --workers=1.

Q: How do I run Playwright in Docker?
A: Use the official Playwright container image or install system deps via `npx playwright install --with-deps`.

Q: How do I make sure local servers are ready before tests?
A: Use webServer.url waiting (and consider a health endpoint) instead of sleep loops.

Q: What ports does the Connect dev script use?
A: portal-vue: 3445, portal-laravel: 7677 (per `start_dev_servers.sh`).

Q: Where do AMS/Connect Vue 3 ports come from?
A: Check `vite.config.ts` under `server.port` and/or the CLI `--port` used in scripts.

Q: What’s a common pitfall with running two Vite apps?
A: Both may default to the same port (e.g., 8080); run one with `npm run dev -- --port 3437` to avoid conflicts.

Q: How do I set Playwright baseURL when ports vary?
A: Pass BASE_URL via env and read it in config, so you can switch ports without editing tests.

Q: How do I test AMS + backend together?
A: Start `admin-laravel` (API) and `admin-2-vue` (UI), then set baseURL to the UI and seed/reset via API endpoints.

Q: How do I test Connect + backend together?
A: Start `portal-laravel` + the UI (`portal-2-vue` or `portal-vue`), then set baseURL to the chosen UI.

Q: Where should Playwright tests live for AMS/Connect?
A: Pick a dedicated folder like `/root/myapp/admin/e2e/` (or per-app `admin-2-vue/e2e/`) and document it in the config.

Q: How do I keep tests from depending on existing prod-like data?
A: Create test-only seed/reset tools (API endpoints or scripts) and use them from the request fixture.

Q: What’s a safe way to add selectors to the app?
A: Add stable `data-testid` on key controls/containers only, and keep it consistent across refactors.

Q: How do I tell an agent what “done” looks like for an E2E test?
A: Define the assertions: URL change, key text visible, API response OK, and a DB/data effect if applicable.

Q: How do I instruct an agent to avoid flaky selectors?
A: Require getByRole/getByLabel first; allow data-testid only if roles/labels are insufficient.

Q: How do I instruct an agent to create login reuse?
A: Ask for a globalSetup that writes `e2e/.auth/storageState.json` and to use it via test.use().

Q: How do I instruct an agent to avoid secrets?
A: Require placeholders for credentials and env-var injection (e.g., USERNAME/PASSWORD) with no hardcoded values.

Q: How do I instruct an agent to run tests and iterate?
A: “Create tests, run `npx playwright test`, fix failures, re-run until green, then summarize changes + commands.”

Q: How do I instruct an agent to keep changes scoped?
A: “Only write under `/e2e/` and do not modify app code unless I explicitly approve.”

Q: How do I instruct an agent to propose data-testid changes?
A: “List the minimum elements needing data-testid and why; wait for approval before editing app code.”

Q: How do I instruct an agent to handle visual snapshots safely?
A: “Do not run `--update-snapshots` unless I explicitly request it; include diffs + rationale.”

Q: How do I instruct an agent to add a smoke tag?
A: “Tag the test name with @smoke and ensure it runs with `--grep @smoke`.”

Q: How do I instruct an agent to add trace-on-failure?
A: “Set use.trace = 'on-first-retry' and include the trace location in the summary.”

Q: How do I instruct an agent to write maintainable helpers?
A: “Extract repeated flows into helpers (login, create entity) but keep assertions in the test.”

Q: How do I instruct an agent to minimize runtime?
A: “Prefer API seeding and storageState; avoid multi-minute UI setup in every test.”

Q: How does Codex CLI help when a test fails?
A: It can read the error, inspect selectors, adjust waits/assertions, and rerun until the test is stable.

Q: How do I give Codex CLI a reproducible test target?
A: Provide the exact start commands + baseURL + required env vars so it can run locally the same way every time.

Q: Anki import: how do I force Anki to treat content as HTML?
A: Add `#html:true` at the top; then `
` renders line breaks and `` works.

Q: Anki import: how do I keep one card per line?
A: Avoid newline characters inside fields; use `
` instead for multi-line Back content.

Q: Anki import: how do I avoid broken TSV parsing?
A: Do not include literal tab characters inside fields; keep exactly 2 tabs per card line.

Q: Anki import: how do I add global tags to every note?
A: Add `#tags:playwright codexcli e2e` header (space-separated tag list).

Q: Anki import: how do I change the deck target?
A: Set `#deck:YourDeck::Subdeck` in the file headers before importing.

Q: How do I set headless/headed behavior in config?
A: In playwright.config.ts set use: { headless: true/false }; override locally with `--headed` when you need to watch the run.

Q: What’s the difference between headless and headed?
A: Headless runs without a visible browser window; headed shows the browser UI for debugging.

Q: What does test.describe.configure({ mode: 'serial' }) do?
A: It forces tests in that describe block to run one-after-another (useful when they share state).

Q: How do I declare a describe block as parallel?
A: Use test.describe.parallel('feature', () => { ... }) to allow tests in that block to run concurrently.

Q: How do I pause a test mid-run?
A: Add `await page.pause()` and run with `--debug` so Playwright opens the inspector.

Q: How do I inspect selectors interactively?
A: Run `npx playwright test --debug` and use the inspector’s picker to find robust locators (role/label/testid).

Q: How do I print browser console logs in a test?
A: page.on('console', msg => console.log(msg.type(), msg.text()))

Q: How do I fail tests on uncaught page errors?
A: page.on('pageerror', err => { throw err }) (or record and assert after actions).

Q: How do I capture failed network requests?
A: page.on('requestfailed', req => console.log('FAILED', req.url(), req.failure()?.errorText))

Q: How do I disable service workers for stability?
A: In config: use: { serviceWorkers: 'block' }

Q: How do I set HTTP Basic Auth credentials?
A: In config: use: { httpCredentials: { username: process.env.BASIC_USER, password: process.env.BASIC_PASS } }

Q: How do I set a session cookie without UI login?
A: await context.addCookies([{ name: 'session', value: '...', domain: '127.0.0.1', path: '/' }]) then goto baseURL.

Q: How do I set localStorage before the app loads?
A: Use context.addInitScript(() => localStorage.setItem('key','value')) before page.goto().

Q: How do I freeze time in the browser for deterministic tests?
A: Use addInitScript to override Date/Intl (or a test-only “fixed clock” feature flag if the app supports it).

Q: How do I test a keyboard shortcut?
A: await page.keyboard.press('Control+K') (use 'Meta+K' on macOS if applicable).

Q: How do I set a checkbox reliably?
A: await page.getByRole('checkbox', { name: 'Active' }).setChecked(true)

Q: How do I select an option in a native
A: await page.getByLabel('Role').selectOption({ label: 'Admin' })

Q: How do I test a custom dropdown (not a
A: Click to open it, then choose an option by role (listbox/option) or by stable data-testid.

Q: How do I wait for DOMContentLoaded explicitly?
A: await page.waitForLoadState('domcontentloaded') (usually unnecessary—use expect() on UI instead).

Q: When is waitForLoadState('networkidle') useful?
A: Rarely; prefer explicit signals (spinner gone, API response) because “network idle” can be unstable with polling apps.

Q: How do I assert partial text (not exact)?
A: await expect(locator).toContainText(/Saved/)

Q: How do I assert an element has a CSS class?
A: await expect(locator).toHaveClass(/active/)

Q: How do I assert an element is focused?
A: await expect(page.getByLabel('Search')).toBeFocused()

Q: How do I run only one spec file?
A: npx playwright test e2e/auth.spec.ts

Q: How do I re-run only the last failed tests?
A: npx playwright test --last-failed

Q: How do I keep terminal output concise?
A: Use a simpler reporter like `--reporter=line` (or configure reporter in playwright.config.ts).

Q: How do I configure retries for a describe block?
A: Add `test.describe.configure({ retries: 2 })` inside the spec file.

Q: How do I increase timeout for one test?
A: Inside the test: `test.setTimeout(120000)`

Q: How do I set a longer timeout for a describe block?
A: Add `test.describe.configure({ timeout: 120000 })` for slower flows.

Q: How do I change where artifacts are written?
A: Set `outputDir` in playwright.config.ts (e.g., 'test-results').

Q: How do I attach JSON debug data to the report?
A: testInfo.attach('api-response.json', { body: Buffer.from(JSON.stringify(obj,null,2)), contentType: 'application/json' })

Q: How do I check basic navigation timing metrics?
A: Read `performance.getEntriesByType('navigation')` via page.evaluate and assert rough budgets if needed.

Q: How do I take an accessibility snapshot?
A: const tree = await page.accessibility.snapshot(); assert on roles/names to catch a11y regressions.

Q: How do I click an element that’s off-screen?
A: await locator.scrollIntoViewIfNeeded(); then click.

Q: AMS: how do I start the Laravel backend on a custom port?
A: cd /root/myapp/admin/admin-laravel && php artisan serve --port 8001

Q: AMS: how do I start the Vue 3 UI on a custom port?
A: cd /root/myapp/admin/admin-2-vue && npm run dev -- --port 3437

Q: Connect: how do I start the Vue 3 UI on a custom port?
A: cd /root/myapp/portal/portal-2-vue && npm run dev -- --port 3446

Q: Connect: how do I start the Laravel backend on a custom port?
A: cd /root/myapp/portal/portal-laravel && php artisan serve --port 7677