innhold/tests/README.md

99 lines
3.4 KiB
Markdown
Raw Permalink Normal View History

# Test Suite
Browser tests using [Pest](https://pestphp.com/) + [pest-plugin-browser](https://github.com/pestphp/pest-plugin-browser) (Playwright/Chromium).
## Run tests
```bash
podman compose -f compose.test.yaml run --rm test
```
The `app` service (the site) starts automatically via `depends_on`. Tests run against `http://app.dns.podman` inside the Podman network.
## Structure
```
tests/
composer.json # pestphp/pest ^4, pestphp/pest-plugin-browser ^4
Pest.php # defines BASE_URL and CUSTOM_DIR constants; groups unit tests
Browser/ # browser tests (require running app + Playwright)
HomepageTest.php
NavigationTest.php
LanguageTest.php
PetitionTest.php
Screenshots/ # auto-saved on failure (gitignored)
Unit/ # unit tests (pure PHP, no browser needed)
PetitionFormTest.php
```
## Writing unit tests
Place tests in `tests/Unit/`. The constant `CUSTOM_DIR` points to `custom/` on the host.
Since `custom/` plugins are written as framework plugins (they call `Hooks::add()` and reference `Context`), stub those classes before requiring the file:
```php
<?php
class Context {}
class Hook { const TEMPLATE_VARS = 'template_vars'; }
class Hooks { public static function add(string $hook, callable $fn): void {} }
require_once CUSTOM_DIR . '/plugins/page/my-plugin.php';
it('does something', function () {
expect(myFunction('input'))->toBe('expected');
});
```
Only test functions from `custom/``app/` has its own test suite.
## Writing browser tests
All browser tests use `$this` for the Playwright page object via pest-plugin-browser.
```php
it('describes behavior', function () {
$this->visit(BASE_URL . '/path')
->assertSee('text') // visible text
->assertSourceHas('html snippet') // raw HTML/source
->assertPresent('css selector') // element exists in DOM
->click('css selector')
->press('input[type="submit"]') // click button/submit
->assertSee('expected result');
});
```
Place new test files in `tests/Browser/`. No registration needed — Pest autodiscovers `*Test.php` files.
**Reference:** [pestphp.com/docs/browser-testing](https://pestphp.com/docs/browser-testing) — full list of interactions (`type()`, `select()`, `check()`, `drag()`, …) and assertions (`assertUrlIs()`, `assertAttribute()`, `assertNoJavaScriptErrors()`, …).
## Infrastructure
- **Containerfile.test**: `php:8.4-cli-bookworm` + Node 22 + Composer + Playwright Chromium at `/opt/playwright`
- **compose.test.yaml**: `app` service = the site; `test` service = runner; mounts `./tests` as volume so edits apply without rebuild
- **Pest.php**: `BASE_URL` defaults to `http://app` if `APP_URL` not set
## Rebuild image
Only needed after changing `Containerfile.test` or `composer.json`:
```bash
podman compose -f compose.test.yaml build test
```
## Agent workflow
When modifying or adding code in `custom/` or `content/`:
1. Run the existing test suite first to establish a baseline.
2. Make your changes.
3. Run tests again. All previously passing tests must still pass.
4. If your change adds new behavior, add a test for it in `tests/Browser/`.
5. Do not mark work done until the test suite passes (excluding pre-existing known failures listed below).
Failed tests save screenshots to `tests/Browser/Screenshots/` — read them to diagnose rendering issues.
## Known failures
None.