# Visual Verification Testing Skill (International Press Zone)

## Purpose

This skill defines a Playwright-based verification workflow for the `international-press-zone` plugin.
It exists to prevent regressions when changing:

- Admin SPA layout/styling (webpack-built CSS + JS)
- REST API contracts used by the admin
- Frontend language switcher markup/behavior
- Language routing and URL generation

The goal is simple: no "looks fine" guesses. Prove behavior and visuals in a real browser.

## When To Use This Skill

### Required Usage (MANDATORY)

- Before committing changes that touch `admin/src/styles/**` or `assets/css/**`
- Before committing changes that affect admin rendering/routing (admin SPA pages/components)
- Before committing changes to language switching/routing (`includes/Frontend/**`, `includes/Core/LanguageManager.php`, `includes/Frontend/URLManager.php`)
- Before releases or tag builds as final QA

### Recommended Usage

- After refactors that change DOM structure/classes in admin pages
- After modifying REST responses consumed by admin UI
- When fixing any "invisible/blank page" issue in wp-admin
- After changes that affect responsiveness (sidebar, tables, modals)

## Testing Philosophy

### Zero-Tolerance For Regressions

- No guessing: validate computed styles and real DOM output
- No blind commits: verify BEFORE and AFTER the fix
- No false positives: check browser-rendered values (computed styles, element visibility)
- Prefer stable selectors: page root IDs and plugin-specific classnames

### Test-Driven Workflow

1. Create/extend a Playwright spec that reproduces the issue.
2. Run it BEFORE the fix (expect FAIL).
3. Apply the fix.
4. Build admin assets if needed.
5. Run the spec AGAIN (expect PASS).
6. Only commit when all relevant specs pass.

## Local Environment Assumptions

- WordPress base URL: `http://localhost:8080`
- Admin credentials: `admin` / `admin123`
- Admin SPA entry: `/wp-admin/admin.php?page=international-press-zone`

## Build Step (Admin Assets)

If you changed admin JS/SCSS:

```bash
cd admin
npm run build
```

Do not use inline CSS as a "quick fix". All styles live in SCSS/CSS files.

## How To Run Verification

Playwright E2E tests live in `tests/e2e/`.

```bash
cd tests/e2e
npx playwright test --project=chromium
```

Targeted runs are strongly preferred during iteration:

```bash
cd tests/e2e
npx playwright test routing.spec.js languages-rest-api.spec.js --project=chromium
```

## Coverage Requirements

### Admin SPA Page Coverage

At minimum, verify these routes render and the expected page root is visible:

- Dashboard: `/wp-admin/admin.php?page=international-press-zone` (root: `#ipz-dashboard-root`)
- Languages: `/wp-admin/admin.php?page=international-press-zone#/languages` (root: `#ipz-languages-root`)
- Translations: `/wp-admin/admin.php?page=international-press-zone#/translations` (root: `#ipz-translations-root`)
- Analytics: `/wp-admin/admin.php?page=international-press-zone#/analytics` (root: `#ipz-analytics-root`)
- Settings: `/wp-admin/admin.php?page=international-press-zone#/settings` (root: `#ipz-settings-root`)
- Licensing: `/wp-admin/admin.php?page=international-press-zone#/licensing` (root: `#ipz-licensing-root`)
- Migration: `/wp-admin/admin.php?page=international-press-zone#/migration` (root: `#ipz-migration-root`)

Additionally, always verify:

- `#ipz-admin-root` is present (SPA shell)
- No console errors and no blank screens
- Sidebar navigation links are visible and lead to the correct route

### Admin Component Coverage

Verify key interactive components using real interactions:

- Tables (Languages list): header styles, cell alignment, empty/loading states
- Modals (Add/Edit Language): open/close, required fields, validation errors visible
- Tabs (Settings): correct panel switches; no hidden panels overlapping
- Forms (Settings): toggles/selects/input focus-visible state remains visible
- Buttons: primary/secondary/destructive variants and disabled states

### Frontend Coverage (Language Switching)

The plugin provides a Language Switcher widget with 3 modes. Verify the rendered markup and basic behavior on the frontend:

- Dropdown mode: `select.ipz-language-select` exists and contains active languages
- Flags mode: `a.ipz-flag-link img.ipz-flag` renders for languages with flags
- List mode: `ul.ipz-language-list a.ipz-language-link` renders and highlights current language

Behavior checks to verify:

- Switching language preserves query parameters for dropdown mode (hidden inputs)
- Switcher does not render broken UI when languages are missing/inactive
- URLs generated by the switcher are valid and navigable

Note: because the switcher is a widget, tests should not assume it appears on the homepage unless the test setup adds it to a sidebar.

## Implementation Pattern (Playwright)

Use the existing `@playwright/test` harness.

```js
const { test, expect } = require('@playwright/test');

async function login(page) {
  await page.goto('/wp-login.php');
  await page.fill('#user_login', 'admin');
  await page.fill('#user_pass', 'admin123');
  await page.click('#wp-submit');
  await page.waitForSelector('#wpadminbar');
}

test('Languages page renders and table headers are consistent', async ({ page }) => {
  const consoleErrors = [];
  page.on('console', (msg) => {
    if (msg.type() === 'error') consoleErrors.push(msg.text());
  });

  await login(page);
  await page.goto('/wp-admin/admin.php?page=international-press-zone#/languages', { waitUntil: 'domcontentloaded' });
  await page.waitForSelector('#ipz-admin-root');
  await expect(page.locator('#ipz-languages-root')).toBeVisible();

  // Example computed-style check
  const flagHeaderSize = await page.locator('th.ipz-col-flag').evaluate((el) => getComputedStyle(el).fontSize);
  const nameHeaderSize = await page.locator('th.ipz-col-name').evaluate((el) => getComputedStyle(el).fontSize);
  expect(flagHeaderSize).toBe(nameHeaderSize);

  expect(consoleErrors).toHaveLength(0);
});
```

## Screenshot Strategy

Use screenshots for evidence when:

- Fixing a visual bug (before/after)
- Debugging flaky selector issues
- Capturing responsive layouts

Keep screenshots in Playwright-managed artifacts (test-results) rather than committing ad-hoc images.

## Responsive Testing

Minimum viewports to verify for admin layout changes:

- Mobile-ish: 375x667 (sidebar behavior, tables)
- Tablet: 768x1024
- Desktop: 1280x720

## Existing Relevant Specs

Use these first before writing new ones:

- `tests/e2e/routing.spec.js` (SPA roots per route)
- `tests/e2e/installation.spec.js` (plugin activation, admin assets)
- `tests/e2e/language-management.spec.js` (Languages UI flows)
- `tests/e2e/languages-rest-api.spec.js` (Languages REST contract)
- `tests/e2e/rest-api.spec.js` (basic REST coverage)
- `tests/e2e/settings-visual.spec.js` (Settings UI checks)

## Common Failure Debugging

### Blank Admin Page

- Confirm `#ipz-admin-root` exists
- Capture console errors and `pageerror`
- Verify admin build ran (`cd admin && npm run build`) if you changed SPA assets

### "401/403" REST Failures

- Confirm nonce source: `window.internationalPressZone.nonce`
- Confirm requests send `X-WP-Nonce`
- Ensure the test logs in before calling API

### Flaky Login / wp-admin Bar Not Appearing

- Re-login only if login form exists
- Wait for `#wpadminbar` and avoid `networkidle` for wp-admin pages

## Summary

This skill ensures we can confidently change the International Press Zone plugin by verifying:

- Admin SPA routes render and key UI remains consistent
- REST endpoints match what the admin UI and tests expect
- Frontend language switching outputs valid markup and navigable URLs

Use Playwright as the proof mechanism, not as a checkbox.
