From 9b3ff16fb50e8a94f742421764d565d69fccb57d Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 18:29:20 +0100 Subject: [PATCH 01/12] Refactored codeception tests not to pass if under 95% code coverage. Added new badges for the plugin. Updated testsing docs. --- plugins/hwp-previews/README.md | 1 + plugins/hwp-previews/TESTING.md | 191 +++++++----------- plugins/hwp-previews/bin/run-codeception.sh | 98 ++++----- plugins/hwp-previews/codeception.dist.yml | 3 +- plugins/hwp-previews/composer.json | 3 +- .../bin/run-codeception.sh | 2 +- 6 files changed, 125 insertions(+), 173 deletions(-) diff --git a/plugins/hwp-previews/README.md b/plugins/hwp-previews/README.md index 8ccd559e..773e7e6a 100644 --- a/plugins/hwp-previews/README.md +++ b/plugins/hwp-previews/README.md @@ -13,6 +13,7 @@ ![GitHub forks](https://img.shields.io/github/forks/wpengine/hwptoolkit?style=social) ![GitHub stars](https://img.shields.io/github/stars/wpengine/hwptoolkit?style=social) [![Testing Integration](https://img.shields.io/github/check-runs/wpengine/hwptoolkit/main?checkName=hwp-previews%20codeception%20tests&label=Automated%20Tests)](https://github.com/wpengine/hwptoolkit/actions) +[![Code Coverage](https://img.shields.io/badge/coverage-%3E95%25-brightgreen?label=Code%20Coverage)](https://github.com/wpengine/hwptoolkit/actions) [![Code Quality](https://img.shields.io/github/check-runs/wpengine/hwptoolkit/main?checkName=hwp-previews%20php%20code%20quality%20checks&label=Code%20Quality%20Checks)](https://github.com/wpengine/hwptoolkit/actions) [![End-to-End Tests](https://github.com/wpengine/hwptoolkit/workflows/End-to-End%20Tests/badge.svg)](https://github.com/wpengine/hwptoolkit/actions?query=workflow%3A%22End-to-End+Tests%22) ----- diff --git a/plugins/hwp-previews/TESTING.md b/plugins/hwp-previews/TESTING.md index 5c8b9fe7..a368df04 100644 --- a/plugins/hwp-previews/TESTING.md +++ b/plugins/hwp-previews/TESTING.md @@ -1,155 +1,104 @@ # Testing HWP Previews -This plugin uses [Codeception](https://codeception.com/) with [WPBrowser](https://wpbrowser.wptestkit.dev/) for automated testing. -Tests are organized into suites for integration (wpunit), functional, and acceptance testing. +## Table of Contents ---- - -## Test Suites - -- **wpunit**: Unit/integration tests with WordPress loaded. -- **functional**: Simulates web requests, runs WordPress in a test environment. -- **acceptance**: Browser-based tests (WPBrowser/WPWebDriver). - -Configuration files for each suite are in the `tests/` directory (e.g., `wpunit.suite.dist.yml`). - ---- - -## Local Test Environment - -The plugin provides scripts to set up a local WordPress environment for testing, using Docker and environment variables defined in `.env.dist`. - -### Prerequisites - -- Docker (for local environment) -- Composer -- Node.js (for building assets, if needed) - ---- - -## Setup - -1. **Copy and configure environment variables:** - - ```bash - @TODO - cp .env.dist .env - # Edit .env as needed for your local setup - ``` - - -2. **Set up the test WordPress environment:** - - ```bash - bin/install-test-env.sh - ``` - - This script will: - - Create the test database (unless `SKIP_DB_CREATE=true`) - - Download and install WordPress in the directory specified by `WORDPRESS_ROOT_DIR` - - Symlink the plugin into the WordPress plugins directory - - Activate the plugin and set up test data +- [Overview](#overview) + - [Directory Structure](#directory-structure) + - [Technologies](#technologies) +- [Usage](#usage) + - [Running Tests](#running-tests) + - [GitHub Actions](#github-actions) +- [Setup Tests Locally](#setup-tests-locally) --- -## Running Tests - -Currently the plugin has the following suite of tests +## Overview -1. WP Unit Tests - (Unit and Integration Tests) -2. E2E Tests - Playright tests +HWP Previews comes with automated tests for unit, integration, and acceptance (E2E) scenarios. -### WPUnit (WordPress-aware Unit/Integration) Tests +## Directory Structure -You can also run WPUnit tests using Composer scripts: +A list of related files and directories for testing: -```bash -composer run test:unit -``` +```text +bin/ +├── install-test-env.sh # Set up test WP environment +├── run-codeception.sh # Run Codeception tests +├── run-e2e.sh # Run E2E (Playwright) tests +├── run-coverage.sh # Generate coverage reports +└── local/ + ├── run-unit-tests.sh # Run unit tests in Docker with Codeception + ├── run-e2e-tests.sh # Run e2e tests in Docker with Playwright + ├── run-qa.sh # Run php code quality checks with PHPStan, Psalm and PHPCS + ├── run-wpunit.sh # Run WPUnit tests in Docker + └── run-functional.sh # Run functional tests in Docker -To generate coverage reports: +tests/ +├── _data/ # Test data (e.g. DB dumps) +├── _envs/ # Environment configs +├── _output/ # Test output (logs, coverage) +├── _support/ # Helper classes, modules +├── wpunit/ # WPUnit (WordPress-aware unit/integration) test cases +├── wpunit.suite.dist.yml +└── wpunit/ + └── bootstrap.php # Bootstrap for WPUnit tests -```bash -composer run test:unit:coverage +.env.dist # Example environment variables for testing +codeception.dist.yml # Main Codeception config ``` +--- -To generate an HTML coverage report: +## Technologies -```bash -composer run test:unit:coverage-html -``` -> [!NOTE] -> HTML code coverage can be found here [tests/_output/coverage/index.html](tests/_output/coverage/index.html) +We use the following technologies to run our tests: +- [Codeception](https://codeception.com/) +- [WPBrowser](https://wpbrowser.wptestkit.dev/) +- [WPUnit](https://github.com/lipemat/wp-unit) +- [Docker](https://www.docker.com/) +- [Composer](https://getcomposer.org/) +- [Playwright](https://playwright.dev/) +- [npm](https://www.npmjs.com/) -### E2WTests +--- -Run browser-based acceptance tests: +## Usage -```bash -sh bin/local/run-e2e-tests.sh coverage -``` +Currently, the plugin has the following suite of tests: -### All Tests +1. **WP Unit Tests** – Unit and Integration Tests +2. **E2E Tests** – Acceptance tests -To run all suites: +### Running Tests -```bash -composer run test -# or -vendor/bin/codecept run -``` +| Command | Description | +|------------------------------------------|----------------------------------------------------------| +| `composer run test:unit:coverage` | Run WPUnit (unit/integration) tests with coverage report | +| `composer run test:unit:coverage-html` | Generate an HTML code coverage report | +| `composer run test:e2e` | Run end-to-end (E2E) acceptance tests | +| `composer run test` | Run all available test suites | --- -## Code Coverage - -To generate code coverage reports (requires Xdebug or PCOV): +## GitHub Actions -```bash -# Example for wpunit suite -SUITES=wpunit COVERAGE=1 bin/run-codeception.sh -``` +We have a few checks which run for a new PR being merged to main -Coverage output will be in `tests/_output/` or as specified by `COVERAGE_OUTPUT`. +| Workflow | Description | Link | +|-------------------------|---------------------------------------------|----------------------------------------------------------------------| +| Code Quality | Runs static analysis and linting checks | [View Workflow](../../actions/workflows/code-quality.yml) | +| E2E Tests | Runs Playwright end-to-end acceptance tests | [View Workflow](../../actions/workflows/e2e.yml) | +| Codeception (WPUnit) | Runs unit and integration tests | [View Workflow](../../actions/workflows/codeception.yml) | ---- -## Useful Scripts +> **INFO:** +> All tests are automatically run on every pull request via GitHub Actions. You can review test results and logs directly in the "Checks" tab of your PR on GitHub. -- `bin/install-test-env.sh` — Sets up the WordPress test environment. -- `bin/run-codeception.sh` — Runs Codeception tests inside the plugin directory. -- `bin/local/run-unit-tests.sh` — Runs unit tests in Docker. -- `bin/local/run-qa.sh` — Runs code quality checks (PHPStan, PHPCS, Psalm). +> **IMPORTANT:** +> Test coverage for WP Unit Tests is 95%. Any new code will require tests to be added in order to pass. --- -## Notes - -- The test database will be reset during setup. **Do not use a database with important data.** -- You can customize which suites to run by setting the `SUITES` environment variable. -- See `.env.dist` for all available environment variables and their descriptions. +## Setup Tests Locally ---- - -```text -tests/ -├── _data/ # Test data (e.g. DB dumps) -├── _envs/ # Environment configs -├── _output/ # Test output (logs, coverage) -├── _support/ # Helper classes, modules -├── wpunit/ # WPUnit (WordPress-aware unit/integration) test cases -├── wpunit.suite.dist.yml -└── wpunit/ - └── bootstrap.php # Bootstrap for WPUnit tests - -bin/ -├── install-test-env.sh # Script to set up test WP environment -├── run-codeception.sh # Script to run Codeception tests -└── local/ - ├── run-unit-tests.sh # Run unit tests in Docker - └── run-qa.sh # Run code quality checks - -.env.dist # Example environment variables for testing -codeception.dist.yml # Main Codeception config -``` +@TODO diff --git a/plugins/hwp-previews/bin/run-codeception.sh b/plugins/hwp-previews/bin/run-codeception.sh index b2838a3f..b28eb7fe 100755 --- a/plugins/hwp-previews/bin/run-codeception.sh +++ b/plugins/hwp-previews/bin/run-codeception.sh @@ -21,31 +21,6 @@ setup_before() { curl -L 'https://raw.github.com/Codeception/c3/2.0/c3.php' > "c3.php" fi - # Enable XDebug or PCOV for code coverage. - if [[ "$COVERAGE" == '1' ]]; then - if [[ "$USING_XDEBUG" == '1' ]]; then - echo "Enabling XDebug 3" - cp /usr/local/etc/php/conf.d/disabled/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/ - echo "xdebug.mode=coverage" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - else - echo "Using pcov/clobber for code coverage" - docker-php-ext-enable pcov - echo "pcov.enabled=1" >> /usr/local/etc/php/conf.d/docker-php-ext-pcov.ini - echo "pcov.directory=${PROJECT_DIR}" >> /usr/local/etc/php/conf.d/docker-php-ext-pcov.ini - COMPOSER_MEMORY_LIMIT=-1 composer require pcov/clobber --dev - vendor/bin/pcov clobber - fi - elif [[ -f /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini ]]; then - echo "Disabling XDebug" - rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - fi - - # Install the PHP dev-dependencies. - if [ ! -d "vendor" ]; then - echo "Running composer install" - COMPOSER_MEMORY_LIMIT=-1 composer install - fi - # Set output permission echo "Setting Codeception output directory permissions" chmod 777 -R tests/_output @@ -59,12 +34,6 @@ run_tests() { local debug="--debug" fi - local suites=$1 - if [[ -z "$SUITES" ]]; then - echo "No test suites specified. Must specify variable SUITES." - exit 1 - fi - if [[ -n "$COVERAGE" ]]; then if [[ -n "$COVERAGE_OUTPUT" ]]; then local coverage="--coverage --coverage-xml $COVERAGE_OUTPUT" @@ -79,25 +48,61 @@ run_tests() { wp maintenance-mode deactivate --allow-root fi - - # Suites is the comma separated list of suites/tests to run. - echo "Running Test Suite $suites" + echo "Running Unit and Integration tests" cd "$PROJECT_DIR" # IMPORTANT: Build Codeception classes before running tests - echo "Building Codeception test classes" - vendor/bin/codecept build -c codeception.dist.yml + echo "Building Codeception test classes" + vendor/bin/codecept build -c codeception.dist.yml - if [ $? -ne 0 ]; then - echo "Error: Codeception build failed" - exit 1 - fi + if [ $? -ne 0 ]; then + echo "Error: Codeception build failed" + exit 1 + fi - XDEBUG_MODE=coverage vendor/bin/codecept run -c codeception.dist.yml ${suites} ${coverage:-} ${debug:-} --no-exit + XDEBUG_MODE=coverage vendor/bin/codecept run -c codeception.dist.yml ${suites} ${coverage:-} ${debug:-} ${debug:-} if [ $? -ne 0 ]; then echo "Error: Codeception tests failed with exit code $?" exit 1 fi + + # Check code coverage if coverage was requested + if [[ -n "$COVERAGE" ]]; then + + if [[ -n "$COVERAGE_OUTPUT" ]]; then + coverage_percent=$(grep -oP '(\d+\.\d+)%' "tests/_output/coverage/index.html" | head -1 | tr -d '%') + else + coverage_percent=$(grep -oP 'line-rate="(\d+\.\d+)"' "tests/_output/coverage.xml" | head -1 | grep -oP '\d+\.\d+') + # Convert to percent + if [[ -n "$coverage_percent" ]]; then + coverage_percent=$(awk "BEGIN { printf \"%.2f\", $coverage_percent * 100 }") + fi + fi + if [[ -z "$coverage_percent" ]]; then + echo "Warning: Could not determine code coverage percentage." + exit 1 + fi + + echo "Code coverage percentage found: $coverage_percent" + + + required_coverage=$(grep 'min_coverage:' codeception.dist.yml | awk '{print $2}') + + if [[ -z "$required_coverage" ]]; then + echo "No min_coverage found in codeception.dist.yml. Defaulting to 80%" + required_coverage=80 + fi + + coverage_int=${coverage_percent%.*} + if (( coverage_int < required_coverage )); then + echo -e "\033[0;31mError: Code coverage is ${coverage_percent}%, which is below the required ${required_coverage}%.\033[0m" + exit 1 + else + echo -e "\033[0;32mCode coverage is ${coverage_percent}% (required: ${required_coverage}%)\033[0m" + fi + + fi + } ## @@ -117,12 +122,11 @@ cleanup_after() { if [[ "$USING_XDEBUG" == '1' ]]; then echo "Disabling XDebug 3" rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - else + else98 echo "Disabling pcov/clobber" docker-php-ext-disable pcov sed -i '/pcov.enabled=1/d' /usr/local/etc/php/conf.d/docker-php-ext-pcov.ini sed -i '/pcov.directory=${PROJECT_DIR}/d' /usr/local/etc/php/conf.d/docker-php-ext-pcov.ini - COMPOSER_MEMORY_LIMIT=-1 composer remove pcov/clobber --dev fi fi @@ -135,9 +139,7 @@ cleanup_after() { echo "Setting up for Codeception tests" setup_before - -# Run the tests -run_tests $SUITES +run_tests # Clean up after running tests. echo "Cleaning up after Codeception tests" @@ -145,8 +147,8 @@ cleanup_after # Check results and exit accordingly. if [ -f "tests/_output/failed" ]; then - echo "Uh oh, Codeception tests failed." + echo "Codeception tests failed." exit 1 else - echo "Woohoo! Codeception tests completed succesfully!" + echo "Codeception tests completed successfully!" fi diff --git a/plugins/hwp-previews/codeception.dist.yml b/plugins/hwp-previews/codeception.dist.yml index 002a5ff9..f2decb50 100644 --- a/plugins/hwp-previews/codeception.dist.yml +++ b/plugins/hwp-previews/codeception.dist.yml @@ -50,7 +50,8 @@ coverage: - /tests/* - /vendor/* - /src/Templates/* - show_only_summary: false + show_only_summary: true + min_coverage: 95 modules: config: REST: diff --git a/plugins/hwp-previews/composer.json b/plugins/hwp-previews/composer.json index efcb0de3..fd79adbb 100644 --- a/plugins/hwp-previews/composer.json +++ b/plugins/hwp-previews/composer.json @@ -143,10 +143,9 @@ "php:psalm:fix": "psalm --alter", "qa": "sh bin/local/run-qa.sh", "test": [ - "sh bin/local/run-unit-tests.sh", + "sh bin/local/run-unit-tests.sh coverage", "sh bin/local/run-e2e-tests.sh" ], - "test:unit": "sh bin/local/run-unit-tests.sh", "test:unit:coverage": "sh bin/local/run-unit-tests.sh coverage", "test:unit:coverage-html": "sh bin/local/run-unit-tests.sh coverage --coverage-html", "test:e2e": "sh bin/local/run-e2e-tests.sh" diff --git a/plugins/wp-graphql-headless-webhooks/bin/run-codeception.sh b/plugins/wp-graphql-headless-webhooks/bin/run-codeception.sh index f7d8f22b..47f6f55b 100644 --- a/plugins/wp-graphql-headless-webhooks/bin/run-codeception.sh +++ b/plugins/wp-graphql-headless-webhooks/bin/run-codeception.sh @@ -128,4 +128,4 @@ if [ -f "tests/_output/failed" ]; then exit 1 else echo "Woohoo! Codeception tests completed succesfully!" -fi \ No newline at end of file +fi From fc793d4ee1dbab92156682fb1852186e4ce5ebb6 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 18:42:12 +0100 Subject: [PATCH 02/12] Refactoring @josephfusco work for plugin slug into a re-usable bash script to help reduce duplicate code for the various workflows. --- .github/scripts/get-plugin-slug.sh | 43 ++++++++++++++++++++ .github/workflows/plugin-artifact-for-pr.yml | 14 +++---- 2 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 .github/scripts/get-plugin-slug.sh diff --git a/.github/scripts/get-plugin-slug.sh b/.github/scripts/get-plugin-slug.sh new file mode 100644 index 00000000..dd2c98ee --- /dev/null +++ b/.github/scripts/get-plugin-slug.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -e + +BASE_SHA="$1" +HEAD_SHA="$2" + +git fetch --prune --unshallow + +# Get changed files in plugins subdirectories +CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" | grep '^plugins/[^/]\+/' || true) + +if [ -z "$CHANGED_FILES" ]; then + echo "No plugin files changed" + exit 1 +fi + +# Extract plugin names from both old and new paths +PLUGINS=() +for file in $CHANGED_FILES; do + plugin=$(echo $file | cut -d/ -f2) + PLUGINS+=("$plugin") +done + +# Get unique plugin names +UNIQUE_PLUGINS=($(printf '%s\n' "${PLUGINS[@]}" | sort -u)) + +# Find the first plugin that actually exists +PLUGIN_SLUG="" +for plugin in "${UNIQUE_PLUGINS[@]}"; do + if [ -d "plugins/$plugin" ]; then + PLUGIN_SLUG="$plugin" + echo "Found existing plugin directory: $PLUGIN_SLUG" + break + fi +done + +if [ -z "$PLUGIN_SLUG" ]; then + echo "No valid plugin directory found" + exit 1 +fi + +echo "slug=$PLUGIN_SLUG" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/plugin-artifact-for-pr.yml b/.github/workflows/plugin-artifact-for-pr.yml index a9305b01..f22025bb 100644 --- a/.github/workflows/plugin-artifact-for-pr.yml +++ b/.github/workflows/plugin-artifact-for-pr.yml @@ -20,9 +20,7 @@ jobs: - name: Get changed plugin directory id: plugin run: | - git fetch --prune --unshallow - plugin=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep '^plugins/' | head -1 | cut -d/ -f2) - echo "slug=$plugin" >> $GITHUB_OUTPUT + bash .github/scripts/get-plugin-slug.sh ${{ github.event.pull_request.base.sha }} ${{ github.sha }} - name: Create plugin artifact uses: ./.github/actions/create-plugin-artifact @@ -44,20 +42,20 @@ jobs: const artifactUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}`; const slug = process.env.PLUGIN_SLUG; const body = `ℹ️ [Download the latest ${slug} plugin zip from this PR](${artifactUrl})\n(See the 'Artifacts' section at the bottom)`; - + // Find existing comment from this bot const comments = await github.rest.issues.listComments({ issue_number: pr.number, owner: context.repo.owner, repo: context.repo.repo }); - - const botComment = comments.data.find(comment => - comment.user.type === 'Bot' && + + const botComment = comments.data.find(comment => + comment.user.type === 'Bot' && comment.user.login === 'github-actions[bot]' && comment.body.includes(`ℹ️ [Download the latest ${slug} plugin zip from this PR]`) ); - + if (botComment) { // Update existing comment core.info(`Updating existing comment with ID: ${botComment.id}`); From 09b900ac401affdf554881eda2bc7c2380a74a3a Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 19:55:41 +0100 Subject: [PATCH 03/12] PHP Code quality refactor to use plugin slug script --- .github/workflows/code-quality.yml | 44 ++++++++--------------------- plugins/hwp-previews/src/Plugin.php | 2 -- 2 files changed, 12 insertions(+), 34 deletions(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 2e0f07bc..48e486cf 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -28,51 +28,31 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Get changed plugin directory + id: plugin + run: | + bash .github/scripts/get-plugin-slug.sh ${{ github.event.pull_request.base.sha }} ${{ github.sha }} + - name: Detect changed plugins with quality config id: detect run: | - git fetch --prune --unshallow - CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep '^plugins/' || true) - - if [ -z "$CHANGED_FILES" ]; then - echo "No plugin files changed" + if [ -z "${{ steps.plugin.outputs.slug }}" ]; then + echo "No plugin slug detected" echo "plugins=[]" >> $GITHUB_OUTPUT echo "has-plugins=false" >> $GITHUB_OUTPUT exit 0 fi - # Extract unique plugin names and check for phpcs.xml - PLUGINS_WITH_CONFIG=() - CHECKED_PLUGINS=() - - for file in $CHANGED_FILES; do - plugin=$(echo $file | cut -d/ -f2) - - # Skip if we already checked this plugin - if [[ " ${CHECKED_PLUGINS[@]} " =~ " $plugin " ]]; then - continue - fi - - CHECKED_PLUGINS+=("$plugin") - - if [ -f "plugins/$plugin/phpcs.xml" ]; then - PLUGINS_WITH_CONFIG+=("$plugin") - echo "✅ Found phpcs.xml for plugin: $plugin" - else - echo "ℹ️ No phpcs.xml found for plugin: $plugin, skipping quality checks" - fi - done + PLUGIN="${{ steps.plugin.outputs.slug }}" - # Convert to JSON array - if [ ${#PLUGINS_WITH_CONFIG[@]} -gt 0 ]; then - PLUGINS_JSON=$(printf '%s\n' "${PLUGINS_WITH_CONFIG[@]}" | jq -R -s -c 'split("\n")[:-1]') - echo "plugins=${PLUGINS_JSON}" >> $GITHUB_OUTPUT + if [ -f "plugins/$PLUGIN/phpcs.xml" ]; then + echo "plugins=[\"$PLUGIN\"]" >> $GITHUB_OUTPUT echo "has-plugins=true" >> $GITHUB_OUTPUT - echo "Found ${#PLUGINS_WITH_CONFIG[@]} plugin(s) with quality config: ${PLUGINS_WITH_CONFIG[*]}" + echo "✅ Found phpcs.xml for plugin: $PLUGIN" else echo "plugins=[]" >> $GITHUB_OUTPUT echo "has-plugins=false" >> $GITHUB_OUTPUT - echo "No plugins found with quality configuration" + echo "ℹ️ No phpcs.xml found for plugin: $PLUGIN, skipping quality checks" fi quality-checks: needs: detect-plugins diff --git a/plugins/hwp-previews/src/Plugin.php b/plugins/hwp-previews/src/Plugin.php index 7b25e59f..c760ce6f 100644 --- a/plugins/hwp-previews/src/Plugin.php +++ b/plugins/hwp-previews/src/Plugin.php @@ -13,8 +13,6 @@ * * This class serves as the main entry point for the plugin, handling initialization, action and filter hooks. * - * @link https://github.com/wpengine/hwptoolkit/tree/main/plugins/hwp-previews - * * @package HWP\Previews */ final class Plugin { From fb80bb6df87f6876edaf5e0b93864dbc3e44c6b0 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 19:59:54 +0100 Subject: [PATCH 04/12] Refacted testing workflow to use bash script too. --- .github/workflows/codeception.yml | 59 +++++++------------------------ 1 file changed, 13 insertions(+), 46 deletions(-) diff --git a/.github/workflows/codeception.yml b/.github/workflows/codeception.yml index dce9983f..c91c0a3f 100644 --- a/.github/workflows/codeception.yml +++ b/.github/workflows/codeception.yml @@ -35,64 +35,31 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Detect changed plugins with test config - id: detect + - name: Get changed plugin directory + id: plugin run: | - git fetch --prune --unshallow + bash .github/scripts/get-plugin-slug.sh ${{ github.event.pull_request.base.sha }} ${{ github.sha }} - # Get changed files based on event type - if [ "${{ github.event_name }}" = "pull_request" ]; then - CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep '^plugins/' || true) - else - CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD | grep '^plugins/' || true) - fi - - if [ -z "$CHANGED_FILES" ]; then - echo "No plugin files changed" + - name: Detect changed plugins with quality config + id: detect + run: | + if [ -z "${{ steps.plugin.outputs.slug }}" ]; then + echo "No plugin slug detected" echo "plugins=[]" >> $GITHUB_OUTPUT echo "has-plugins=false" >> $GITHUB_OUTPUT exit 0 fi - # Extract unique plugin names and check for test config - PLUGINS_WITH_CONFIG=() - CHECKED_PLUGINS=() - - for file in $CHANGED_FILES; do - plugin=$(echo $file | cut -d/ -f2) - - # Skip if we already checked this plugin - if [[ " ${CHECKED_PLUGINS[@]} " =~ " $plugin " ]]; then - continue - fi - - CHECKED_PLUGINS+=("$plugin") - - # Check for both codeception.dist.yml and composer.json - if [ -f "plugins/$plugin/codeception.dist.yml" ] && [ -f "plugins/$plugin/composer.json" ]; then - PLUGINS_WITH_CONFIG+=("$plugin") - echo "✅ Found test config for plugin: $plugin (codeception.dist.yml + composer.json)" - else - echo "ℹ️ Missing test config for plugin: $plugin, skipping tests" - if [ ! -f "plugins/$plugin/codeception.dist.yml" ]; then - echo " - Missing: codeception.dist.yml" - fi - if [ ! -f "plugins/$plugin/composer.json" ]; then - echo " - Missing: composer.json" - fi - fi - done + PLUGIN="${{ steps.plugin.outputs.slug }}" - # Convert to JSON array - if [ ${#PLUGINS_WITH_CONFIG[@]} -gt 0 ]; then - PLUGINS_JSON=$(printf '%s\n' "${PLUGINS_WITH_CONFIG[@]}" | jq -R -s -c 'split("\n")[:-1]') - echo "plugins=${PLUGINS_JSON}" >> $GITHUB_OUTPUT + if [ -f "plugins/$PLUGIN/codeception.dist.yml" ]; then + echo "plugins=[\"$PLUGIN\"]" >> $GITHUB_OUTPUT echo "has-plugins=true" >> $GITHUB_OUTPUT - echo "Found ${#PLUGINS_WITH_CONFIG[@]} plugin(s) with test config: ${PLUGINS_WITH_CONFIG[*]}" + echo "✅ Found codeception.dist.yml for plugin: $PLUGIN" else echo "plugins=[]" >> $GITHUB_OUTPUT echo "has-plugins=false" >> $GITHUB_OUTPUT - echo "No plugins found with test configuration" + echo "ℹ️ No codeception.dist.yml found for plugin: $PLUGIN, skipping automated tests" fi continuous_integration: From ed6ba4278c2ed724eaa820015fa79d1a2adc4d91 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 20:23:26 +0100 Subject: [PATCH 05/12] Refacted e2e tests to run if wp-env exists for tests. Re-used bash script to get plugin slug --- .github/workflows/e2e-test.yml | 71 +++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index adc21778..4131251a 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -5,21 +5,64 @@ on: branches: - main paths: - - 'plugins/hwp-previews/**.php' - - 'plugins/hwp-previews/**.js' - - 'plugins/hwp-previews/**.css' - - 'plugins/hwp-previews/**.json' - + - 'plugins/**.php' + - 'plugins/**.js' + - 'plugins/**.css' + - 'plugins/**.json' pull_request: branches: - main paths: - - "plugins/hwp-previews/**" + - "plugins/**" jobs: + detect-plugins: + runs-on: ubuntu-latest + name: Detect plugins with E2E tests + outputs: + plugins: ${{ steps.detect.outputs.plugins }} + has-plugins: ${{ steps.detect.outputs.has-plugins }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Get changed plugin directory + id: plugin + run: | + bash .github/scripts/get-plugin-slug.sh ${{ github.event.pull_request.base.sha }} ${{ github.sha }} + + - name: Detect changed plugins with E2E config + id: detect + run: | + if [ -z "${{ steps.plugin.outputs.slug }}" ]; then + echo "No plugin slug detected" + echo "plugins=[]" >> $GITHUB_OUTPUT + echo "has-plugins=false" >> $GITHUB_OUTPUT + exit 0 + fi + + PLUGIN="${{ steps.plugin.outputs.slug }}" + + # Check for .wp-env.json file in the plugin directory + if [ -f "plugins/$PLUGIN/.wp-env.json" ]; then + echo "plugins=[\"$PLUGIN\"]" >> $GITHUB_OUTPUT + echo "has-plugins=true" >> $GITHUB_OUTPUT + echo "✅ Found .wp-env.json for plugin: $PLUGIN" + else + echo "plugins=[]" >> $GITHUB_OUTPUT + echo "has-plugins=false" >> $GITHUB_OUTPUT + echo "ℹ️ No .wp-env.json found for plugin: $PLUGIN, skipping E2E tests" + fi + playwright-e2e-tests: + needs: detect-plugins + if: needs.detect-plugins.outputs.has-plugins == 'true' runs-on: ubuntu-24.04 - + strategy: + matrix: + plugin: ${{ fromJson(needs.detect-plugins.outputs.plugins) }} + fail-fast: false + name: ${{ matrix.plugin }} Playwright E2E Tests steps: - name: Checkout code uses: actions/checkout@v4 @@ -32,27 +75,27 @@ jobs: - name: Install dependencies run: npm ci + working-directory: plugins/${{ matrix.plugin }} - name: Setup PHP with Cached Composer uses: ./.github/actions/setup-php-composer with: php-version: 8.2 - working-directory: plugins/hwp-previews + working-directory: plugins/${{ matrix.plugin }} composer-options: '--no-progress --optimize-autoloader --no-dev' - name: Install playwright browsers run: npx playwright install --with-deps - working-directory: plugins/hwp-previews + working-directory: plugins/${{ matrix.plugin }} - name: Start wp-env - run: | - npm run wp-env start - working-directory: plugins/hwp-previews + run: npm run wp-env start + working-directory: plugins/${{ matrix.plugin }} - name: Run Playwright tests run: npm run test:e2e - working-directory: plugins/hwp-previews + working-directory: plugins/${{ matrix.plugin }} - name: Stop wp-env run: npm run wp-env stop - working-directory: plugins/hwp-previews + working-directory: plugins/${{ matrix.plugin }} From cb3ff8b82409f9f46e45208766099accb5462119 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 20:30:41 +0100 Subject: [PATCH 06/12] Fixed previews badge for e2e tests. --- .github/workflows/e2e-test.yml | 8 ++++++++ plugins/hwp-previews/README.md | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 4131251a..39efc220 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -1,3 +1,11 @@ +# This does the following: +# 1. Detects modified plugins that have .wp-env.json configuration +# 2. Runs Playwright E2E tests on those plugins using the custom action +# 3. Creates a matrix job for each plugin that has a quality configuration +# Bonus: This means you can have plugin specific badges e.g. +# [![E2E Tests](https://img.shields.io/github/check-runs/wpengine/hwptoolkit/main?checkName=hwp-previews%20Playwright%20E2E%20Tests&label=End-to-End%20Tests)](https://github.com/wpengine/hwptoolkit/actions) + + name: End-to-End Tests on: diff --git a/plugins/hwp-previews/README.md b/plugins/hwp-previews/README.md index 773e7e6a..d2820c6e 100644 --- a/plugins/hwp-previews/README.md +++ b/plugins/hwp-previews/README.md @@ -15,7 +15,8 @@ [![Testing Integration](https://img.shields.io/github/check-runs/wpengine/hwptoolkit/main?checkName=hwp-previews%20codeception%20tests&label=Automated%20Tests)](https://github.com/wpengine/hwptoolkit/actions) [![Code Coverage](https://img.shields.io/badge/coverage-%3E95%25-brightgreen?label=Code%20Coverage)](https://github.com/wpengine/hwptoolkit/actions) [![Code Quality](https://img.shields.io/github/check-runs/wpengine/hwptoolkit/main?checkName=hwp-previews%20php%20code%20quality%20checks&label=Code%20Quality%20Checks)](https://github.com/wpengine/hwptoolkit/actions) -[![End-to-End Tests](https://github.com/wpengine/hwptoolkit/workflows/End-to-End%20Tests/badge.svg)](https://github.com/wpengine/hwptoolkit/actions?query=workflow%3A%22End-to-End+Tests%22) +[![End-to-End Tests](https://img.shields.io/github/check-runs/wpengine/hwptoolkit/main?checkName=hwp-previews%20Playwright%20E2E%20Tests&label=End-to-End%20Tests)](https://github.com/wpengine/hwptoolkit/actions) + ----- From 43cfa174c28d2c4cccd26fb014f0ee7c8ce5fd55 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 20:39:23 +0100 Subject: [PATCH 07/12] Fixing syntax issues. --- .github/workflows/e2e-test.yml | 56 ++++++++++++++++------------------ 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 39efc220..cf790002 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -3,7 +3,7 @@ # 2. Runs Playwright E2E tests on those plugins using the custom action # 3. Creates a matrix job for each plugin that has a quality configuration # Bonus: This means you can have plugin specific badges e.g. -# [![E2E Tests](https://img.shields.io/github/check-runs/wpengine/hwptoolkit/main?checkName=hwp-previews%20Playwright%20E2E%20Tests&label=End-to-End%20Tests)](https://github.com/wpengine/hwptoolkit/actions) +# [![E2E Te](https://img.shields.io/github/check-runs/wpengine/hwptoolkit/main?checkName=hwp-previews%20Playwright%20E2E%20Tests&label=End-to-End%20Tests)](https://github.com/wpengine/hwptoolkit/actions) name: End-to-End Tests @@ -24,12 +24,12 @@ on: - "plugins/**" jobs: - detect-plugins: + detect-plugin: runs-on: ubuntu-latest - name: Detect plugins with E2E tests + name: Detect plugin with E2E tests outputs: - plugins: ${{ steps.detect.outputs.plugins }} - has-plugins: ${{ steps.detect.outputs.has-plugins }} + plugin: ${{ steps.detect.outputs.plugin }} + has-plugin: ${{ steps.detect.outputs.has-plugin }} steps: - name: Checkout uses: actions/checkout@v4 @@ -39,13 +39,13 @@ jobs: run: | bash .github/scripts/get-plugin-slug.sh ${{ github.event.pull_request.base.sha }} ${{ github.sha }} - - name: Detect changed plugins with E2E config + - name: Detect changed plugin with E2E config id: detect run: | if [ -z "${{ steps.plugin.outputs.slug }}" ]; then echo "No plugin slug detected" - echo "plugins=[]" >> $GITHUB_OUTPUT - echo "has-plugins=false" >> $GITHUB_OUTPUT + echo "plugin=" >> $GITHUB_OUTPUT + echo "has-plugin=false" >> $GITHUB_OUTPUT exit 0 fi @@ -53,24 +53,22 @@ jobs: # Check for .wp-env.json file in the plugin directory if [ -f "plugins/$PLUGIN/.wp-env.json" ]; then - echo "plugins=[\"$PLUGIN\"]" >> $GITHUB_OUTPUT - echo "has-plugins=true" >> $GITHUB_OUTPUT + echo "plugin=$PLUGIN" >> $GITHUB_OUTPUT + echo "has-plugin=true" >> $GITHUB_OUTPUT echo "✅ Found .wp-env.json for plugin: $PLUGIN" else - echo "plugins=[]" >> $GITHUB_OUTPUT - echo "has-plugins=false" >> $GITHUB_OUTPUT + echo "plugin=" >> $GITHUB_OUTPUT + echo "has-plugin=false" >> $GITHUB_OUTPUT echo "ℹ️ No .wp-env.json found for plugin: $PLUGIN, skipping E2E tests" fi playwright-e2e-tests: - needs: detect-plugins - if: needs.detect-plugins.outputs.has-plugins == 'true' + needs: detect-plugin + if: needs.detect-plugin.outputs.has-plugin == 'true' runs-on: ubuntu-24.04 - strategy: - matrix: - plugin: ${{ fromJson(needs.detect-plugins.outputs.plugins) }} - fail-fast: false - name: ${{ matrix.plugin }} Playwright E2E Tests + name: ${{ needs.detect-plugin.outputs.plugin }} Playwright E2E Tests + env: + PLUGIN: ${{ needs.detect-plugin.outputs.plugin }} steps: - name: Checkout code uses: actions/checkout@v4 @@ -83,27 +81,27 @@ jobs: - name: Install dependencies run: npm ci - working-directory: plugins/${{ matrix.plugin }} + working-directory: plugins/${{ env.PLUGIN }} - name: Setup PHP with Cached Composer uses: ./.github/actions/setup-php-composer with: php-version: 8.2 - working-directory: plugins/${{ matrix.plugin }} + working-directory: plugins/${{ env.PLUGIN }} composer-options: '--no-progress --optimize-autoloader --no-dev' - - name: Install playwright browsers + - name: Install playwright browsers (${{ env.PLUGIN }}) run: npx playwright install --with-deps - working-directory: plugins/${{ matrix.plugin }} + working-directory: plugins/${{ env.PLUGIN }} - - name: Start wp-env + - name: Start wp-env (${{ env.PLUGIN }}) run: npm run wp-env start - working-directory: plugins/${{ matrix.plugin }} + working-directory: plugins/${{ env.PLUGIN }} - - name: Run Playwright tests + - name: Run Playwright tests (${{ env.PLUGIN }}) run: npm run test:e2e - working-directory: plugins/${{ matrix.plugin }} + working-directory: plugins/${{ env.PLUGIN }} - - name: Stop wp-env + - name: Stop wp-env (${{ env.PLUGIN }}) run: npm run wp-env stop - working-directory: plugins/${{ matrix.plugin }} + working-directory: plugins/${{ env.PLUGIN }} From fd41d15ea5fa66929a6ca5396b9bad5dba1a9251 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 20:45:56 +0100 Subject: [PATCH 08/12] Fixes. --- .github/workflows/e2e-test.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index cf790002..ca038807 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -69,6 +69,7 @@ jobs: name: ${{ needs.detect-plugin.outputs.plugin }} Playwright E2E Tests env: PLUGIN: ${{ needs.detect-plugin.outputs.plugin }} + steps: - name: Checkout code uses: actions/checkout@v4 @@ -81,27 +82,27 @@ jobs: - name: Install dependencies run: npm ci - working-directory: plugins/${{ env.PLUGIN }} - name: Setup PHP with Cached Composer uses: ./.github/actions/setup-php-composer with: php-version: 8.2 - working-directory: plugins/${{ env.PLUGIN }} + working-directory: plugins/${{ env.PLUGIN }} composer-options: '--no-progress --optimize-autoloader --no-dev' - - name: Install playwright browsers (${{ env.PLUGIN }}) + - name: Install playwright browsers run: npx playwright install --with-deps working-directory: plugins/${{ env.PLUGIN }} - - name: Start wp-env (${{ env.PLUGIN }}) - run: npm run wp-env start + - name: Start wp-env + run: | + npm run wp-env start working-directory: plugins/${{ env.PLUGIN }} - - name: Run Playwright tests (${{ env.PLUGIN }}) + - name: Run Playwright tests run: npm run test:e2e working-directory: plugins/${{ env.PLUGIN }} - - name: Stop wp-env (${{ env.PLUGIN }}) + - name: Stop wp-env run: npm run wp-env stop working-directory: plugins/${{ env.PLUGIN }} From eab3d3e74f47bc50582b593d730a30e1fc27089a Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 21:29:01 +0100 Subject: [PATCH 09/12] Updated docs for actions and filters. --- plugins/hwp-previews/ACTIONS_AND_FILTERS.md | 118 +++++++++----------- plugins/hwp-previews/TESTING.md | 5 + 2 files changed, 60 insertions(+), 63 deletions(-) diff --git a/plugins/hwp-previews/ACTIONS_AND_FILTERS.md b/plugins/hwp-previews/ACTIONS_AND_FILTERS.md index 33642bcb..c7c5651f 100644 --- a/plugins/hwp-previews/ACTIONS_AND_FILTERS.md +++ b/plugins/hwp-previews/ACTIONS_AND_FILTERS.md @@ -1,43 +1,54 @@ # Actions & Filters -## PHP Actions +## Table of Contents -- `hwp_previews_activate` - Plugin activation hook -- `hwp_previews_deactivate` - Plugin deactivation hook -- `hwp_previews_init` - Plugin initialization hook +- [PHP Actions](#php-actions) +- [PHP Filters](#php-filters) +- [Examples](#examples) + - [Actions](#actions) + - [Filters](#filters) +- [Contributing](#contributing) -## PHP Filters +--- -## Admin +This document lists the available PHP actions and filters provided by the HWP Previews plugin, along with explanations and usage examples. These hooks allow you to customize plugin behavior, settings, and integration with other plugins or your theme. -- `hwp_previews_settings_init` - Allows a user to modify the `Settings` instance -- `hwp_previews_settings_form_manager_init` - Allows a user to modify the `Settings_Form_Manager` instance and update fields and post types -- `hwp_previews_settings_fields` - Allows a user to register, modify, or remove settings fields for the settings page -- `hwp_previews_settings_group_option_key` - Filter to modify the settings group option key. Default is HWP_PREVIEWS_SETTINGS_KEY -- `hwp_previews_settings_group_settings_group` - Filter to modify the settings group name. Default is HWP_PREVIEWS_SETTINGS_GROUP +--- +## PHP Actions +| Action Name | Description | +|-----------------------------------------------|-----------------------------------------------------------------------------------------------| +| `hwp_previews_init` | Fired after the plugin is initialized. | +| `hwp_previews_activate` | Fired on plugin activation. | +| `hwp_previews_deactivate` | Fired on plugin deactivation. | +| `hwp_previews_settings_init` | Fired after the settings page is initialized. | +| `hwp_previews_settings_form_manager_init` | Fired after the settings form manager is initialized. | -- `hwp_previews_register_parameters` - Allows modification of the URL parameters used for previews for the class `Preview_Parameter_Registry` -- `hwp_previews_template_path` - To use our own template for iframe previews -- `hwp_previews_core` - Register or unregister URL parameters, and adjust types/statuses -- `hwp_previews_filter_available_post_types` - Filter to modify the available post types for Previews. -- `hwp_previews_filter_available_post_statuses` - Filter for post statuses for previews for Previews -- `hwp_previews_filter_available_parent_post_statuses` - Filter for parent post statuses for Previews -- `hwp_previews_settings_group_settings_config` - Filter to modify the settings array. See `Settings_Group` -- `hwp_previews_settings_group_cache_groups` - Filter to modify cache groups for `Settings_Group` -- `hwp_previews_get_post_types_config` - Filter for generating the instance of `Post_Types_Config_Interface` -- `hwp_previews_hooks_post_status_config` - Filter for post status config service for the Hook class -- `hwp_previews_hooks_preview_link_service` - Filter for preview link service for the Hook class +--- -## Usage Examples +## PHP Filters -@TODO - Redo +| Filter Name | Description | +|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------| +| `hwp_previews_settings_fields` | Modify or add settings fields for the settings page. | +| `hwp_previews_settings_group_option_key` | Change the settings group option key (default: `HWP_PREVIEWS_SETTINGS_KEY`). | +| `hwp_previews_settings_group_settings_group` | Change the settings group name (default: `HWP_PREVIEWS_SETTINGS_GROUP`). | +| `hwp_previews_register_parameters` | Allows users to modify or register parameters. | +| `hwp_previews_template_path` | Change the template file path for iframe previews. | +| `hwp_previews_filter_available_post_types` | Filter the available post types for previews (affects settings UI and preview logic). | +| `hwp_previews_filter_available_post_statuses` | Filter the available post statuses for previews. | +--- + +## Examples + +Below is some examples of usage for these actions/filters. -### Filter: Post Types List -Modify which post types appear in the settings UI: +#### `hwp_previews_filter_available_post_types` +**Description:** +Filter the available post types for previews (affects settings UI and preview logic). ```php // Removes attachment post type from the settings page configuration. @@ -51,51 +62,32 @@ function hwp_previews_filter_post_type_setting_callback( $post_types ) { } ``` -### Action: Core Registry -Register or unregister URL parameters, and adjust types/statuses: +#### `hwp_previews_template_path` +**Description:** +Change the template file path for iframe previews. ```php -add_action( 'hwp_previews_core', 'modify_preview_url_parameters' ); -function modify_preview_url_parameters( - \HWP\Previews\Preview\Parameter\Preview_Parameter_Registry $registry -) { - // Remove default parameter - $registry->unregister( 'author_ID' ); - - // Add custom parameter - $registry->register( new \HWP\Previews\Preview\Parameter\Preview_Parameter( - 'current_time', - static fn( \WP_Post $post ) => (string) time(), - __( 'Current Unix timestamp', 'your-domain' ) - ) ); -} -``` - -Modify post types and statuses: - -```php -add_action( 'hwp_previews_core', 'modify_post_types_and_statuses_configs', 10, 3 ); -function modify_post_types_and_statuses_configs( - \HWP\Previews\Preview\Parameter\Preview_Parameter_Registry $registry, - \HWP\Previews\Post\Type\Post_Types_Config $types, - \HWP\Previews\Post\Status\Post_Statuses_Config $statuses -) { - // Limit to pages only - $types->set_post_types( [ 'page' ] ); - // Only include drafts - $statuses->set_post_statuses( [ 'draft' ] ); -} +add_filter( 'hwp_previews_template_path', function( $default_path ) { + return get_stylesheet_directory() . '/my-preview-template.php'; +}); ``` -### Filter: Iframe Template Path - -Use your own template for iframe previews: +#### `hwp_previews_settings_group_option_key` and `hwp_previews_settings_group_settings_group` +**Description:** +Change the settings group option key or group name. ```php -add_filter( 'hwp_previews_template_path', function( $default_path ) { - return get_stylesheet_directory() . '/my-preview-template.php'; +add_filter( 'hwp_previews_settings_group_option_key', function( $default_key ) { + return 'my_custom_option_key'; +}); +add_filter( 'hwp_previews_settings_group_settings_group', function( $default_group ) { + return 'my_custom_settings_group'; }); ``` --- + +## Contributing + +If you feel like something is missing or you want to add tests or testing documentation, we encourage you to contribute! Please check out our [Contributing Guide](https://github.com/wpengine/hwptoolkit/blob/main/CONTRIBUTING.md) for more details. diff --git a/plugins/hwp-previews/TESTING.md b/plugins/hwp-previews/TESTING.md index a368df04..9488c56e 100644 --- a/plugins/hwp-previews/TESTING.md +++ b/plugins/hwp-previews/TESTING.md @@ -102,3 +102,8 @@ We have a few checks which run for a new PR being merged to main ## Setup Tests Locally @TODO + + +## Contributing + +If you feel like something is missing or you want to add tests or testing documentation, we encourage you to contribute! Please check out our [Contributing Guide](https://github.com/wpengine/hwptoolkit/blob/main/CONTRIBUTING.md) for more details. From f324c528e032fdbf80719166d6bda3fb58ceafbe Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 27 Jun 2025 21:31:05 +0100 Subject: [PATCH 10/12] Removed change for webhooks. --- plugins/wp-graphql-headless-webhooks/bin/run-codeception.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/wp-graphql-headless-webhooks/bin/run-codeception.sh b/plugins/wp-graphql-headless-webhooks/bin/run-codeception.sh index 47f6f55b..f7d8f22b 100644 --- a/plugins/wp-graphql-headless-webhooks/bin/run-codeception.sh +++ b/plugins/wp-graphql-headless-webhooks/bin/run-codeception.sh @@ -128,4 +128,4 @@ if [ -f "tests/_output/failed" ]; then exit 1 else echo "Woohoo! Codeception tests completed succesfully!" -fi +fi \ No newline at end of file From 5762f6b24fc1fe628c347ecf09b925bdf0140641 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Mon, 30 Jun 2025 11:37:27 +0100 Subject: [PATCH 11/12] Updated testing docs. Added script to setup tests locally. --- plugins/hwp-previews/TESTING.md | 182 +++++++++++++++--- .../bin/local/setup-docker-env.sh | 161 ++++++++++++++++ 2 files changed, 315 insertions(+), 28 deletions(-) create mode 100644 plugins/hwp-previews/bin/local/setup-docker-env.sh diff --git a/plugins/hwp-previews/TESTING.md b/plugins/hwp-previews/TESTING.md index 9488c56e..d65b6006 100644 --- a/plugins/hwp-previews/TESTING.md +++ b/plugins/hwp-previews/TESTING.md @@ -3,20 +3,26 @@ ## Table of Contents - [Overview](#overview) - - [Directory Structure](#directory-structure) - - [Technologies](#technologies) + - [Directory Structure](#directory-structure) + - [Technologies](#technologies) - [Usage](#usage) - [Running Tests](#running-tests) - [GitHub Actions](#github-actions) - [Setup Tests Locally](#setup-tests-locally) + - [Prerequisites](#prerequisites) + - [Docker Setup](#docker-setup) + - [What the Setup Script Does](#what-the-setup-script-does) + - [Running Tests Locally](#running-tests-locally) +- [Troubleshooting](#troubleshooting) +- [Contributing](#contributing) --- ## Overview -HWP Previews comes with automated tests for unit, integration, and acceptance (E2E) scenarios. +HWP Previews comes with automated tests for unit, integration, and acceptance (E2E) scenarios to ensure code quality and functionality. -## Directory Structure +### Directory Structure A list of related files and directories for testing: @@ -27,6 +33,7 @@ bin/ ├── run-e2e.sh # Run E2E (Playwright) tests ├── run-coverage.sh # Generate coverage reports └── local/ + ├── setup-docker-env.sh # Setup Docker environment ├── run-unit-tests.sh # Run unit tests in Docker with Codeception ├── run-e2e-tests.sh # Run e2e tests in Docker with Playwright ├── run-qa.sh # Run php code quality checks with PHPStan, Psalm and PHPCS @@ -46,28 +53,27 @@ tests/ .env.dist # Example environment variables for testing codeception.dist.yml # Main Codeception config ``` ---- -## Technologies +### Technologies We use the following technologies to run our tests: -- [Codeception](https://codeception.com/) -- [WPBrowser](https://wpbrowser.wptestkit.dev/) -- [WPUnit](https://github.com/lipemat/wp-unit) -- [Docker](https://www.docker.com/) -- [Composer](https://getcomposer.org/) -- [Playwright](https://playwright.dev/) -- [npm](https://www.npmjs.com/) +- [Codeception](https://codeception.com/) - PHP testing framework +- [WPBrowser](https://wpbrowser.wptestkit.dev/) - WordPress-specific testing tools +- [WPUnit](https://github.com/lipemat/wp-unit) - WordPress unit testing +- [Docker](https://www.docker.com/) - Containerized testing environment +- [Composer](https://getcomposer.org/) - PHP dependency management +- [Playwright](https://playwright.dev/) - End-to-end testing framework +- [npm](https://www.npmjs.com/) - JavaScript package manager --- ## Usage -Currently, the plugin has the following suite of tests: +The plugin includes the following test suites: 1. **WP Unit Tests** – Unit and Integration Tests -2. **E2E Tests** – Acceptance tests +2. **E2E Tests** – Acceptance tests using Playwright ### Running Tests @@ -78,31 +84,151 @@ Currently, the plugin has the following suite of tests: | `composer run test:e2e` | Run end-to-end (E2E) acceptance tests | | `composer run test` | Run all available test suites | +### GitHub Actions + +Automated testing runs on every pull request via GitHub Actions for a modified plugin: + +| Workflow | Description | Status | +|-------------------------|---------------------------------------------|--------| +| **Code Quality** | Runs static analysis and linting checks | [View Workflow](../../actions/workflows/code-quality.yml) | +| **E2E Tests** | Runs Playwright end-to-end acceptance tests | [View Workflow](../../actions/workflows/e2e.yml) | +| **Codeception (WPUnit)** | Runs unit and integration tests | [View Workflow](../../actions/workflows/codeception.yml) | + + +>[!IMPORTANT] +> Test coverage for WP Unit Tests is **95%**. Any new code will require tests to be added in order to pass CI checks. This is set in [text](codeception.dist.yml) in the parameter `min_coverage`. + --- -## GitHub Actions +## Setup Tests Locally + +### Prerequisites + +- Docker and Docker Compose installed and running +- Composer installed +- Node.js and npm installed (for E2E tests) +- Terminal/command line access + +### Docker Setup + +>[!NOTE] +> You need Docker running locally before setting up tests. Alternatively, you can copy `.env.dist` to `.env` and update the database details to point to your local database. However, this will make database changes, so we recommend using the Docker setup instead. -We have a few checks which run for a new PR being merged to main +To set up your local Docker environment, run: -| Workflow | Description | Link | -|-------------------------|---------------------------------------------|----------------------------------------------------------------------| -| Code Quality | Runs static analysis and linting checks | [View Workflow](../../actions/workflows/code-quality.yml) | -| E2E Tests | Runs Playwright end-to-end acceptance tests | [View Workflow](../../actions/workflows/e2e.yml) | -| Codeception (WPUnit) | Runs unit and integration tests | [View Workflow](../../actions/workflows/codeception.yml) | +```shell +sh bin/local/setup-docker-env.sh +``` + +This script will automatically handle the complete Docker environment setup process. + +### What the Setup Script Does + +The setup script performs the following operations: + +#### 1. Environment Verification +- ✅ Checks that Docker is running +- ✅ Verifies required files exist + +#### 2. Configuration Setup +- 📁 Copies `bin/local/.env.local` to `.env` + - Uses local development configuration (different from `.env.dist`) + - Sets appropriate database credentials and WordPress settings +#### 3. Docker Container Management +- 🐳 Runs `composer run docker:build` + - Executes `sh bin/build-docker.sh` to create the Docker container + - Builds WordPress environment with PHP 8.2 +- 🚀 Runs `docker compose up -d` to start the container in detached mode + - Creates container named `hwp-previews-wordpress-1` + - Sets up WordPress with test database -> **INFO:** -> All tests are automatically run on every pull request via GitHub Actions. You can review test results and logs directly in the "Checks" tab of your PR on GitHub. +#### 4. Code Coverage Setup +- 🔧 Installs and configures PCOV extension (preferred for performance) +- 🔄 Falls back to XDebug if PCOV installation fails +- ⚙️ Configures coverage settings automatically +- 🔄 Restarts container to ensure extensions are loaded -> **IMPORTANT:** -> Test coverage for WP Unit Tests is 95%. Any new code will require tests to be added in order to pass. +#### 5. WordPress Installation +- 📝 Installs WordPress if not already present +- 🔌 Activates the plugin automatically +- ✅ Verifies the installation is working correctly + +### Running Tests Locally + +Once setup is complete, you can run tests using Composer: + +```shell +# Run unit tests with coverage +composer run test:unit:coverage + +# Run all tests +composer run test + +# Run E2E tests +composer run test:e2e +``` + +For a full list of available test commands, see the [Usage](#usage) section above. --- -## Setup Tests Locally +## Troubleshooting + +### Container Issues + +```shell +# Check container status +docker ps | grep hwp-previews + +# Restart containers if needed +docker compose restart + +# View container logs +docker compose logs hwp-previews-wordpress-1 +``` + +### Permission Issues + +```shell +# Fix test output permissions +docker exec hwp-previews-wordpress-1 chmod 777 -R tests/_output +``` -@TODO +### Coverage Driver Issues +```shell +# Check which coverage driver is available +docker exec hwp-previews-wordpress-1 php -m | grep -E "(pcov|xdebug)" + +# Re-run setup if coverage isn't working +sh bin/local/setup-docker-env.sh +``` + +### WordPress Database Issues + +```shell +# Reinstall WordPress +docker exec hwp-previews-wordpress-1 wp core install \ + --url=http://localhost \ + --title="Test Site" \ + --admin_user=admin \ + --admin_password=admin \ + --admin_email=admin@example.com \ + --allow-root +``` + +### Clean Up Environment + +```shell +# Stop containers +docker compose down + +# Remove containers and volumes (complete cleanup) +docker compose down -v +``` + +--- ## Contributing diff --git a/plugins/hwp-previews/bin/local/setup-docker-env.sh b/plugins/hwp-previews/bin/local/setup-docker-env.sh new file mode 100644 index 00000000..9e6bb32a --- /dev/null +++ b/plugins/hwp-previews/bin/local/setup-docker-env.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +set -e # Exit on any error + +echo "Setting up Docker environment..." + +# Copy environment file +if [ -f "bin/local/.env.local" ]; then + cp bin/local/.env.local .env + echo "✓ Environment file copied" +else + echo "❌ Error: bin/local/.env.local not found" + exit 1 +fi + +# Build and start containers +echo "Building and starting Docker containers..." +composer run docker:build +docker compose up -d + +# Wait for containers to be ready +echo "Waiting for containers to be ready..." +sleep 10 + +# Check if container is running +if ! docker ps | grep -q hwp-previews-wordpress-1; then + echo "❌ Error: Container hwp-previews-wordpress-1 is not running" + exit 1 +fi + +# Function to check if PHP extension is installed +check_extension() { + local extension=$1 + docker exec hwp-previews-wordpress-1 php -m | grep -q "$extension" +} + +# Install coverage driver (prefer PCOV over XDebug for performance) +echo "Setting up code coverage driver..." + +if check_extension "pcov"; then + echo "✓ PCOV already installed and loaded" +elif check_extension "xdebug"; then + echo "✓ XDebug already installed and loaded" +else + echo "Checking if PCOV is installed but not enabled..." + + # Check if PCOV is installed via PECL but not enabled + if docker exec hwp-previews-wordpress-1 pecl list | grep -q "pcov"; then + echo "PCOV is installed via PECL but not enabled. Enabling..." + docker exec hwp-previews-wordpress-1 bash -c " + docker-php-ext-enable pcov && + echo 'pcov.enabled=1' >> /usr/local/etc/php/conf.d/docker-php-ext-pcov.ini + " + + # Restart container to load the extension + echo "Restarting container to load PCOV..." + docker compose restart + sleep 10 + + if check_extension "pcov"; then + echo "✓ PCOV enabled successfully" + else + echo "❌ Failed to enable PCOV" + fi + else + echo "Installing PCOV for code coverage..." + docker exec hwp-previews-wordpress-1 bash -c " + pecl install --force pcov 2>/dev/null || true && + docker-php-ext-enable pcov && + echo 'pcov.enabled=1' >> /usr/local/etc/php/conf.d/docker-php-ext-pcov.ini + " + + # Restart container to load the extension + echo "Restarting container to load PCOV..." + docker compose restart + sleep 10 + + if check_extension "pcov"; then + echo "✓ PCOV installed and enabled successfully" + else + echo "⚠️ PCOV setup failed, trying XDebug..." + docker exec hwp-previews-wordpress-1 bash -c " + pecl install --force xdebug 2>/dev/null || true && + docker-php-ext-enable xdebug && + echo 'xdebug.mode=coverage' >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini + " + + # Restart container to load the extension + echo "Restarting container to load XDebug..." + docker compose restart + sleep 10 + + if check_extension "xdebug"; then + echo "✓ XDebug installed and enabled successfully" + else + echo "❌ Failed to install both PCOV and XDebug" + exit 1 + fi + fi + fi +fi + +# Verify WordPress installation +echo "Checking WordPress installation..." +if docker exec hwp-previews-wordpress-1 wp core is-installed --allow-root 2>/dev/null; then + echo "✓ WordPress is installed" +else + echo "Installing WordPress..." + docker exec hwp-previews-wordpress-1 wp core install \ + --url=http://localhost \ + --title="Test Site" \ + --admin_user=admin \ + --admin_password=admin \ + --admin_email=admin@example.com \ + --allow-root + + if [ $? -eq 0 ]; then + echo "✓ WordPress installed successfully" + else + echo "❌ WordPress installation failed" + exit 1 + fi +fi + +# Install and activate the plugin if needed +echo "Checking plugin activation..." +if docker exec hwp-previews-wordpress-1 wp plugin is-active hwp-previews --allow-root 2>/dev/null; then + echo "✓ Plugin is active" +else + echo "Activating plugin..." + docker exec hwp-previews-wordpress-1 wp plugin activate hwp-previews --allow-root +fi + +# Verify coverage driver is working +echo "Verifying code coverage setup..." +if docker exec hwp-previews-wordpress-1 php -r " + if (extension_loaded('pcov')) { + echo 'PCOV is available'; + exit(0); + } elseif (extension_loaded('xdebug')) { + echo 'XDebug is available'; + exit(0); + } else { + echo 'No coverage driver available'; + exit(1); + } +"; then + echo "✓ Code coverage driver is ready" +else + echo "❌ No code coverage driver available" + exit 1 +fi + +echo "" +echo "🎉 Docker environment setup complete!" +echo "" +echo "You can now run tests with:" +echo " docker exec -e COVERAGE=1 -e SUITES=wpunit -w /var/www/html/wp-content/plugins/hwp-previews hwp-previews-wordpress-1 bin/run-codeception.sh" +echo "" +echo "Or without coverage:" +echo " docker exec -e SUITES=wpunit -w /var/www/html/wp-content/plugins/hwp-previews hwp-previews-wordpress-1 bin/run-codeception.sh" From 8ab4aa54c9595320e63315aae78dd899f54e81f3 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Mon, 30 Jun 2025 11:41:05 +0100 Subject: [PATCH 12/12] Added Changeset --- .changeset/loud-baboons-bake.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/loud-baboons-bake.md diff --git a/.changeset/loud-baboons-bake.md b/.changeset/loud-baboons-bake.md new file mode 100644 index 00000000..25b65f56 --- /dev/null +++ b/.changeset/loud-baboons-bake.md @@ -0,0 +1,5 @@ +--- +"@wpengine/hwp-previews-wordpress-plugin": patch +--- + +chore: Updated action and filter docs.