Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 53 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: CI

on:
push:
branches:
- main
pull_request:

permissions:
contents: read

jobs:
test:
name: Test (PHP ${{ matrix.php }})
runs-on: ubuntu-latest

strategy:
# Run every PHP version even if one fails so we see the full matrix.
fail-fast: false
matrix:
# Floor is the lowest PHP still in security support (Requires PHP: 8.2);
# 8.5 is the current latest. Keep in sync with the plugin's Requires PHP.
php: ['8.2', '8.3', '8.4', '8.5']

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

# The regression harness needs WordPress core's HTML API sources.
# Pin to a specific tag for reproducible runs. Bump this DELIBERATELY
# (not via automation): 7.0.0 is the latest stable release as of 2026-06
# (latest 6.x is 6.9.4). A shallow checkout keeps the clone small.
- name: Checkout WordPress source
uses: actions/checkout@v4
with:
repository: WordPress/wordpress-develop
ref: '7.0.0'
path: wordpress-develop
fetch-depth: 1

- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none

- name: Install Composer dependencies
run: composer install --prefer-dist --no-progress

- name: Run tests (regression harness + phpcs)
env:
WP_CORE_DIR: ${{ github.workspace }}/wordpress-develop/src
run: composer test
13 changes: 13 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,18 @@
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"scripts": {
"test": [
"@test:harness",
"@test:phpcs"
],
"test:harness": "php tests/html-api-integration-regression.php",
"test:phpcs": "phpcs"
},
"scripts-descriptions": {
"test": "Run the HTML API regression harness and phpcs (requires WP_CORE_DIR for the harness).",
"test:harness": "Run the HTML API integration regression harness (requires WP_CORE_DIR).",
"test:phpcs": "Run phpcs against the plugin source using phpcs.xml."
}
}
71 changes: 51 additions & 20 deletions tests/html-api-integration-regression.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,30 +67,61 @@ function do_action( $hook_name, ...$args ) {
}

if ( ! class_exists( 'WP_HTML_Processor' ) ) {
require "{$include_dir}/class-wp-token-map.php";
$required_files = array(
"{$include_dir}/class-wp-token-map.php",
"{$include_dir}/html-api/class-wp-html-text-replacement.php",
"{$include_dir}/html-api/class-wp-html-span.php",
"{$include_dir}/html-api/class-wp-html-attribute-token.php",
"{$include_dir}/html-api/class-wp-html-doctype-info.php",
"{$include_dir}/html-api/class-wp-html-unsupported-exception.php",
"{$include_dir}/html-api/class-wp-html-decoder.php",
"{$include_dir}/html-api/class-wp-html-tag-processor.php",
"{$include_dir}/html-api/class-wp-html-token.php",
"{$include_dir}/html-api/class-wp-html-stack-event.php",
"{$include_dir}/html-api/class-wp-html-open-elements.php",
"{$include_dir}/html-api/class-wp-html-active-formatting-elements.php",
"{$include_dir}/html-api/class-wp-html-processor-state.php",
"{$include_dir}/html-api/class-wp-html-processor.php",
);

foreach (
array(
'class-wp-html-text-replacement.php',
'class-wp-html-span.php',
'class-wp-html-attribute-token.php',
'class-wp-html-doctype-info.php',
'class-wp-html-unsupported-exception.php',
'class-wp-html-decoder.php',
'class-wp-html-tag-processor.php',
'class-wp-html-token.php',
'class-wp-html-stack-event.php',
'class-wp-html-open-elements.php',
'class-wp-html-active-formatting-elements.php',
'class-wp-html-processor-state.php',
'class-wp-html-processor.php',
) as $file
) {
require "{$include_dir}/html-api/{$file}";
// Verify every dependency exists before requiring any of them so a moved or
// renamed file produces a clear message instead of a fatal mid-bootstrap.
$missing_files = array();
foreach ( $required_files as $file ) {
if ( ! file_exists( $file ) ) {
$missing_files[] = $file;
}
}

if ( $missing_files ) {
fwrite( STDERR, "Cannot bootstrap the HTML API from WP_CORE_DIR; the following required files are missing:\n" );
fwrite( STDERR, ' - ' . implode( "\n - ", $missing_files ) . "\n" );
fwrite( STDERR, "This WordPress version may be incompatible with the regression harness.\n" );
exit( 2 );
}

foreach ( $required_files as $file ) {
require $file;
}
}

require dirname( __DIR__ ) . '/html-api-debugger/html-api-integration.php';
// Bail clearly if the HTML API still is not available after bootstrap.
if ( ! class_exists( 'WP_HTML_Processor' ) ) {
fwrite( STDERR, "Bootstrap completed but WP_HTML_Processor is undefined; the HTML API may have changed in this WordPress version.\n" );
exit( 2 );
}

$integration_file = dirname( __DIR__ ) . '/html-api-debugger/html-api-integration.php';
if ( ! file_exists( $integration_file ) ) {
fwrite( STDERR, "Missing plugin integration file: {$integration_file}\n" );
exit( 2 );
}
require $integration_file;

if ( ! function_exists( 'HTML_API_Debugger\HTML_API_Integration\get_tree' ) ) {
fwrite( STDERR, "Plugin integration loaded but HTML_API_Debugger\\HTML_API_Integration\\get_tree() is undefined.\n" );
exit( 2 );
}

/**
* Convert a debugger tree into stable text lines.
Expand Down
Loading