Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
43b7ef0
docs: comprehensive testing plan for FAIR plugin
chuckadams Jun 9, 2026
8859783
Phase 1: migrate test infrastructure to tests/unit/
chuckadams Jun 9, 2026
4a8d626
fix: lock composer deps to PHP 8.0 via platform config
chuckadams Jun 9, 2026
17fe617
Phase 2: add test fixtures and factories
chuckadams Jun 9, 2026
639c4a5
Phase 3: add DID pipeline pure function unit tests
chuckadams Jun 9, 2026
1001540
Phase 4: add DTO validation unit tests
chuckadams Jun 9, 2026
8d9fcc9
Phase 5: add transient/HTTP function unit tests
chuckadams Jun 9, 2026
853695c
Phase 6: add Updater unit tests
chuckadams Jun 9, 2026
5b5a994
Phase 7: add supplementary module unit tests
chuckadams Jun 9, 2026
bde2ae3
Add self-bootstrapping local test runner
chuckadams Jun 9, 2026
bad2f92
Phase 8: add integration test harness
chuckadams Jun 9, 2026
83ce76c
Phase 9: add package data and update transient integration tests
chuckadams Jun 9, 2026
325d923
Phase 6b: add updater edge case unit tests
chuckadams Jun 9, 2026
4e747d7
Phase 10: add HTTP test harness + tests
chuckadams Jun 9, 2026
3c57ec4
Phase 11: browser test harness + 15 accessibility-first Playwright tests
chuckadams Jun 9, 2026
81a52a6
Phase 12: CI workflow for integration + browser tests
chuckadams Jun 9, 2026
4f3e7d7
Phase 13: coverage baseline + Infection mutation testing
chuckadams Jun 9, 2026
6a0ec91
docs: consolidate totals table, move deferred items to Phase 14
chuckadams Jun 9, 2026
cacbe9e
feat: add Ed25519 key fixtures, signed hello-dolly.zip, plugin catalog
chuckadams Jun 9, 2026
c918d0a
feat: idempotent key generation, wired into test:setup
chuckadams Jun 9, 2026
c9c83a8
test: SignatureVerificationTest — 14 tests for Ed25519 signature pipe…
chuckadams Jun 9, 2026
9a5001e
chore: add test:integration, test:http, test:browser, test:e2e, test:…
chuckadams Jun 9, 2026
b6d87b1
fix: patch WP test library install.php to remove E_STRICT reference
chuckadams Jun 9, 2026
5997c4b
refactor: isolate infection mutation testing to tests/mutation/
chuckadams Jun 9, 2026
6c5a079
fix: validate_package_alias cache falsey-value collision
chuckadams Jun 9, 2026
0ed8f2b
refactor: flatten tests/sites/ephemeral/ → tests/sites/
chuckadams Jun 9, 2026
d5b0f82
feat: complete remaining active testing gaps
chuckadams Jun 10, 2026
e6674aa
docs: test quality audit — vacuous tests, antipatterns, security gaps
chuckadams Jun 10, 2026
252e546
fix: remove vacuous and redundant tests (audit items 1-6)
chuckadams Jun 10, 2026
e01fadf
feat: high-priority security and memoization tests (audit #7-10)
chuckadams Jun 10, 2026
17a95dc
docs: collapse resolved audit items into summaries
chuckadams Jun 10, 2026
cb4876f
docs: mark 3.4 replay attack as protocol concern, not testable
chuckadams Jun 10, 2026
c2eeb9e
fix: resolve audit items 2.3, 2.4, 3.2 (zero-refactoring batch)
chuckadams Jun 10, 2026
2b675f2
feat: three more zero-refactoring audit items (#15, #16, #17)
chuckadams Jun 10, 2026
a180991
refactor: move pipeline-mock success tests from unit to integration (…
chuckadams Jun 10, 2026
27ef1fb
feat: customize_theme_update_html unit tests (#18)
chuckadams Jun 10, 2026
8f09528
docs: finalize audit — all zero-refactoring items resolved
chuckadams Jun 10, 2026
1fbb9eb
Remove accidentally committed tests/browser/node_modules
chuckadams Jun 10, 2026
febfe93
Revert null-transient normalization, split multi-class test files
chuckadams Jun 10, 2026
5e43aab
Simplify pick_release: drop empty() guard, use reset() ?: null
chuckadams Jun 10, 2026
ba62145
Silence PHPCS: exclude tests/, bin/, and suppress PHP 8.5 deprecation…
chuckadams Jun 10, 2026
6febb1d
make integration-tests.yml workflow_dispatch only
chuckadams Jun 10, 2026
de3809d
Exclude ai/, .envrc, .pi/, tmp/, infection.json from release zips
chuckadams Jun 10, 2026
58e866d
Remove platform.php from composer.json; pin release workflow to PHP 8.0
chuckadams Jun 10, 2026
eea4203
Remove tracked Playwright auth state file from repo
chuckadams Jun 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .distignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ package-lock.json
.gitattributes
.distignore
.editorconfig
.envrc
.pi/
tmp/
ai/
infection.json
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ package-lock.json export-ignore
.gitattributes export-ignore
.distignore export-ignore
.editorconfig export-ignore
/ai export-ignore
.envrc export-ignore
.pi/ export-ignore
/tmp export-ignore
infection.json export-ignore
173 changes: 173 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
name: Integration & Browser Tests

on:
# push:
# branches: [main, development, 'release/*']
# pull_request:
# branches: [main, development]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true

permissions:
contents: read

jobs:
# ── Integration + HTTP tests (ephemeral Docker) ────────────────────
docker-tests:
name: Docker (${{ matrix.php }}, WP ${{ matrix.wp }})
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
php: ['8.0', '8.4']
wp: ['5.4', 'latest']

steps:
- uses: actions/checkout@v4

- name: Run integration + HTTP tests
timeout-minutes: 12
run: |
PHP_VERSION=${{ matrix.php }} \
WORDPRESS_VERSION=${{ matrix.wp }} \
bin/run-integration.sh

- name: Verify no leftover Docker containers
if: always()
run: |
LEFTOVERS=$(docker ps -q 2>/dev/null | wc -l)
if [ "$LEFTOVERS" -gt 0 ]; then
echo "WARNING: $LEFTOVERS leftover containers"
docker ps
docker rm -f $(docker ps -q)
fi

# ── Browser tests (Playwright, fast only) ──────────────────────────
browser-tests:
name: Browser (chromium, fast)
runs-on: ubuntu-latest
timeout-minutes: 15
# Only run on push to main/development/release, or on PRs labeled run-browser-tests.
if: |
github.event_name != 'pull_request' ||
contains(github.event.pull_request.labels.*.name, 'run-browser-tests')

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install Playwright
run: |
cd tests/browser
npm ci
npx playwright install chromium --with-deps

- name: Start Docker services
run: |
docker compose -f tests/sites/browser-test/docker-compose.yml up -d --wait

- name: Install WordPress and seed
run: |
docker compose -f tests/sites/browser-test/docker-compose.yml run --rm wp-cli \
wp core install \
--url=http://localhost:8899 \
--title="FAIR CI Test" \
--admin_user=admin \
--admin_password=password \
--admin_email=admin@ci.local

docker compose -f tests/sites/browser-test/docker-compose.yml run --rm wp-cli \
wp plugin activate fair-plugin

docker compose -f tests/sites/browser-test/docker-compose.yml run --rm wp-cli \
php /var/www/html/wp-content/plugins/fair-plugin/tests/sites/browser-test/seed.php

- name: Run browser tests
id: browser
run: |
cd tests/browser
npx playwright test --grep-invert @slow
env:
FAIR_TEST_BASE_URL: http://localhost:8899

- name: Upload test results on failure
if: failure() && steps.browser.outcome == 'failure'
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: tests/browser/test-results/
retention-days: 7

- name: Tear down Docker
if: always()
run: |
docker compose -f tests/sites/browser-test/docker-compose.yml down -v --remove-orphans

# ── All @slow browser tests on main/RC only ────────────────────────
browser-slow:
name: Browser (chromium, @slow)
runs-on: ubuntu-latest
timeout-minutes: 20
if: |
github.event_name == 'push' &&
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/'))

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install Playwright
run: |
cd tests/browser
npm ci
npx playwright install chromium --with-deps

- name: Start Docker services
run: |
docker compose -f tests/sites/browser-test/docker-compose.yml up -d --wait

- name: Install WordPress and seed
run: |
docker compose -f tests/sites/browser-test/docker-compose.yml run --rm wp-cli \
wp core install \
--url=http://localhost:8899 \
--title="FAIR CI Test" \
--admin_user=admin \
--admin_password=password \
--admin_email=admin@ci.local

docker compose -f tests/sites/browser-test/docker-compose.yml run --rm wp-cli \
wp plugin activate fair-plugin

docker compose -f tests/sites/browser-test/docker-compose.yml run --rm wp-cli \
php /var/www/html/wp-content/plugins/fair-plugin/tests/sites/browser-test/seed.php

- name: Run @slow browser tests
run: |
cd tests/browser
npx playwright test --grep @slow
env:
FAIR_TEST_BASE_URL: http://localhost:8899

- name: Upload test results on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report-slow
path: tests/browser/test-results/
retention-days: 7

- name: Tear down Docker
if: always()
run: |
docker compose -f tests/sites/browser-test/docker-compose.yml down -v --remove-orphans
54 changes: 54 additions & 0 deletions .github/workflows/phpunit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,57 @@ jobs:
run: |
echo "define('WP_TESTS_PHPUNIT_POLYFILLS_PATH', '$HOME/.composer/vendor/yoast/phpunit-polyfills');" >> ${{ runner.temp }}/wordpress-tests-lib/wp-tests-config.php
phpunit

# ── Coverage (single PHP version, push to main/release only) ─────
coverage:
name: Coverage (PHP 8.4, WP latest)
runs-on: ubuntu-latest
timeout-minutes: 15
if: |
github.event_name == 'push' &&
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/development' || startsWith(github.ref, 'refs/heads/release/'))

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup MySQL
uses: shogo82148/actions-setup-mysql@v1
with:
mysql-version: '8.0'
my-cnf: |
bind_address=127.0.0.1
default-authentication-plugin=mysql_native_password
root-password: root

- name: Set up PHP with XDebug
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
coverage: xdebug
extensions: mysql, mysqli
tools: composer
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Install Composer dependencies
run: composer update --optimize-autoloader --prefer-dist

- name: Install test suite
run: |
echo "TMPDIR=${{ runner.temp }}" >> $GITHUB_ENV
echo "WP_TESTS_DIR=${{ runner.temp }}/wordpress-tests-lib" >> $GITHUB_ENV
echo "WP_CORE_DIR=${{ runner.temp }}/wordpress" >> $GITHUB_ENV
TMPDIR=${{ runner.temp }} bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1 latest

- name: Run coverage
run: composer run coverage:full
env:
XDEBUG_MODE: coverage

- name: Upload coverage HTML
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: tests/unit/coverage/html/full/
retention-days: 30
6 changes: 4 additions & 2 deletions .github/workflows/releases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ jobs:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.0'
tools: composer

- name: Install Composer dependencies
run: composer install --no-dev --optimize-autoloader --no-interaction
run: |
composer config platform.php 8.0
composer update --no-dev --optimize-autoloader --no-interaction

- name: Get tag
id: tag
Expand Down
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,17 @@ wp-tests-config.php

# Track placeholders so that empty directories stay in the repo.
!.gitkeep

# Playwright browser test artifacts
.playwright-cli/
tests/browser/test-results/
tests/browser/.auth/
tests/browser/node_modules/

# Infection mutation test output
tests/unit/infection/
tests/mutation/vendor/
tests/mutation/composer.lock

# Test fixture generated artifacts (keys are reproducible via generate.php)
tests/fixtures/keys/ed25519-keypair.json
2 changes: 1 addition & 1 deletion .wp-env.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"phpVersion": "7.4",
"phpVersion": "8.0",
"plugins": [
"norcross/airplane-mode",
"johnbillion/query-monitor#3.18.0"
Expand Down
27 changes: 27 additions & 0 deletions ai/plans/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Testing Plan — FAIR Plugin

> **Status:** Design validated, pending implementation
> **Date:** 2026-06-09
> **Branch:** `development` (or dedicated feature branch)

## Overview

Four-layer test pyramid for the FAIR WordPress plugin. The DID-manager package pipeline (`inc/packages/`) is the top-priority functional area. Edge case coverage must be exhaustive; Infection mutation testing will be added in a follow-up pass.

| Layer | Directory | Docker? | Target URL |
|-------|-----------|---------|------------|
| Unit | `tests/unit/` | No | N/A |
| Integration | `tests/integration/` | Yes (ephemeral) | `tests/sites/ephemeral/<suite>/` |
| HTTP | `tests/http/` | Optional | Configurable (ephemeral or pet) |
| Browser | `tests/browser/` | Recommended | Configurable (ephemeral or pet) |

## Documents

- **[test-directory-layout.md](./test-directory-layout.md)** — File structure, bootstrap files, configs
- **[unit-tests.md](./unit-tests.md)** — Packages/DID pipeline strategy, factory/fixture design, module coverage matrix
- **[integration-tests.md](./integration-tests.md)** — Docker Compose harness, mock DID server, site lifecycle, seeding
- **[http-tests.md](./http-tests.md)** — HTTP-level tests against configurable base URL, group annotations
- **[browser-tests.md](./browser-tests.md)** — Playwright specs, auth bootstrap, UI coverage
- **[static-sites.md](./static-sites.md)** — Persistent pet instances for exotic configurations (Bedrock, custom dir layouts, etc.)
- **[ci-strategy.md](./ci-strategy.md)** — GitHub Actions workflow, matrix, group-gated gates
- **[implementation-order.md](./implementation-order.md)** — 13-phase execution plan with parallelization notes
Loading
Loading