> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wrixton.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Testing Across Both War.re Apps: Jest and Playwright

> Explore war.re testing: Jest component tests in subdomains/ryan/, Playwright e2e smoke tests in both apps, TypeScript checks, and linting.

The war.re project uses two distinct testing layers: Jest component tests that run in Node against a jsdom environment, and Playwright end-to-end tests that drive a real browser against the static production build. Type checking and linting round out the quality toolchain. Each tool has a specific scope — read on to understand where each layer lives and how to run it.

<Note>
  `main/` has no Jest unit tests — only the Playwright e2e suite applies there. All Jest tests live exclusively in `subdomains/ryan/`.
</Note>

## Unit Tests — Jest + React Testing Library

Jest and React Testing Library are set up in `subdomains/ryan/` to test individual React components in isolation. The suite covers the four components that contain meaningful rendering logic:

| Test file                 | Component under test | What it covers                                                                                                             |
| ------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `Activity.test.tsx`       | `Activity`           | Duration formatting (years/months/singular/plural), "Present" end date, heading and metadata rendering, date range display |
| `ActivityList.test.tsx`   | `ActivityList`       | List rendering with multiple items, empty-list behaviour                                                                   |
| `Experience.test.tsx`     | `Experience`         | Section heading rendering                                                                                                  |
| `ExperienceItem.test.tsx` | `ExperienceItem`     | Link rendering when a URL is provided, plain-text fallback without a URL                                                   |

### Running unit tests

Run the full Jest suite from inside `subdomains/ryan/`:

```bash theme={null}
cd subdomains/ryan

yarn test               # run all tests
yarn test:coverage      # run all tests and generate a coverage report
```

To run a single test file, pass its path directly to Jest via the `--testPathPattern` flag:

```bash theme={null}
cd subdomains/ryan
yarn test -- --testPathPattern=Activity.test.tsx
```

### Example: Activity duration tests

The `Activity` component contains the only real business logic in the codebase — a `formatDuration` function that is private to the module. The tests exercise it through the rendered `<h6>` duration badge:

```typescript theme={null}
it('renders years and months together', () => {
  render(<Activity name="Engineer" start="January 2020" end="March 2022" items={[]} />)
  expect(duration()).toBe('[2 Years 2 Months]')
})

it('measures the span up to the current date', () => {
  // beforeEach pins the clock to 2024-06-15 with jest.useFakeTimers()
  render(<Activity name="Engineer" start="March 2024" end="Present" items={[]} />)
  expect(duration()).toBe('[3 Months]')
})
```

## End-to-End Tests — Playwright

Both `main/` and `subdomains/ryan/` include a Playwright e2e suite. The tests open the app in a real browser and verify that key pages render correctly, external links are safe, metadata is present, and the visual appearance is stable across changes.

Playwright snapshots are stored at `e2e/__snapshots__/` inside each app directory. When you run `yarn e2e` for the first time, Playwright creates baseline screenshots; subsequent runs compare against those baselines.

### What the tests cover

**`main/` smoke tests** (`e2e/smoke.spec.ts`):

* The `/n` content route renders the homepage with correct headings and title
* Visual screenshot comparison of the full page (`content.png`)
* All external links carry `target="_blank"` and `rel="noopener"`
* Social icon images expose descriptive alt text
* Canonical URL and Open Graph metadata are correct
* The root `/` redirects to `/n` via meta-refresh
* Unknown routes return a 404 response

**`subdomains/ryan/` smoke tests** (`e2e/smoke.spec.ts`):

* The `/n` content route renders the resume with the correct title
* All four major resume sections are visible (Technical Experience, Relevant Work Experience, Related Activities, Education)
* Visual screenshot comparison of the full page (`content.png`)
* All external links carry `target="_blank"` and `rel="noopener"`
* Canonical URL and Open Graph metadata are correct
* The root `/` redirects to `/n` via meta-refresh
* Unknown routes return a 404 response

### Running e2e tests

<Tip>
  Run `yarn build` before `yarn e2e`. Playwright serves the static `out/` directory — if you skip the build step, the tests will fail because there is no output to serve.
</Tip>

<CodeGroup>
  ```bash main/ theme={null}
  cd main
  yarn build
  yarn e2e              # smoke tests
  yarn e2e:coverage     # smoke tests with V8 source-map coverage
  ```

  ```bash subdomains/ryan/ theme={null}
  cd subdomains/ryan
  yarn build
  yarn e2e              # smoke tests
  ```
</CodeGroup>

`yarn e2e:coverage` is only available in `main/`. It maps Playwright V8 coverage data back to TypeScript source files using `monocart-coverage-reports`.

### Updating snapshots

If you intentionally change the visual output of a page, update the Playwright baseline screenshots by running:

```bash theme={null}
yarn e2e -- --update-snapshots
```

## Type Checking

Both apps include a `typecheck` script that runs the TypeScript compiler in no-emit mode. A `pretypecheck` lifecycle hook automatically runs `next typegen` first to regenerate Next.js type definitions (such as route types) before the compiler sees your code:

```bash theme={null}
# Run from inside either app directory
yarn typecheck
```

The effective command sequence is:

```bash theme={null}
next typegen   # runs automatically via pretypecheck
tsc --noEmit   # runs as typecheck
```

TypeScript errors surface as non-zero exit codes, which makes `yarn typecheck` safe to use in CI.

## Linting

Both apps run ESLint with the `next/core-web-vitals` configuration, which enforces React, accessibility, and Next.js-specific rules:

```bash theme={null}
# Run from inside either app directory
yarn lint
```

To auto-fix lint issues where possible, you can pass the `--fix` flag directly:

```bash theme={null}
yarn lint -- --fix
```
