Skip to main content

2 posts tagged with "migration"

View All Tags

Review: Adopting assertEqualHTML() in WordPress Tests (Migration Patterns)

· 3 min read
Victor Jimenez
Software Engineer & AI Agent Builder

The Hook WordPress 6.9 added assertEqualHTML(), which removes a lot of brittle test failures caused by formatting-only HTML differences.

Why I Built It In plugin and theme suites, many HTML tests still use strict string equality and fail on whitespace, indentation, or equivalent tag formatting instead of real behavior regressions.

The Solution Adopt assertEqualHTML() for semantic HTML equivalence checks, keep assertSame() where byte-for-byte output matters, and phase migration by risk and signal quality.

The Code No standalone project repo for this task. This is migration guidance for WordPress/PHPUnit test suites.

Recommendation

  • Adopt now if your suite has frequent brittle failures from HTML formatting differences.
  • Use it for rendered markup assertions where DOM meaning matters more than exact serialization.
  • Do not replace assertions that intentionally verify exact escaping, spacing, or deterministic serialization.

Concrete Migration Patterns

1) Direct string comparison to semantic HTML comparison

Before:

$this->assertSame(
'<p class="notice">Saved</p>',
$actual_html
);

After:

$this->assertEqualHTML(
'<p class="notice">Saved</p>',
$actual_html
);

2) Remove ad-hoc whitespace normalization

Before:

$normalize = static fn( $html ) => preg_replace( '/\s+/', ' ', trim( $html ) );
$this->assertSame( $normalize( $expected ), $normalize( $actual ) );

After:

$this->assertEqualHTML( $expected, $actual );

3) Output-buffer render tests

Before:

ob_start();
render_banner_block( array( 'message' => 'Hi' ) );
$actual = ob_get_clean();

$this->assertSame(
'<section class="banner"><p>Hi</p></section>',
$actual
);

After:

ob_start();
render_banner_block( array( 'message' => 'Hi' ) );
$actual = ob_get_clean();

$this->assertEqualHTML(
'<section class="banner"><p>Hi</p></section>',
$actual
);

4) Attribute/order formatting noise

Before:

$expected = '<a class="btn primary" href="/docs">Docs</a>';
$actual = '<a href="/docs" class="btn primary">Docs</a>';
$this->assertSame( $expected, $actual );

After:

$this->assertEqualHTML( $expected, $actual );

5) Version-safe bridge for mixed core baselines

If your suite runs against WordPress versions older than 6.9:

private function assertHtmlEquivalent( string $expected, string $actual ): void {
if ( method_exists( $this, 'assertEqualHTML' ) ) {
$this->assertEqualHTML( $expected, $actual );
return;
}

$this->assertSame( trim( $expected ), trim( $actual ) );
}

Rollout Guidance

  • Start with render-heavy tests (render_callback, shortcode output, template helpers).
  • Convert only tests currently compensating for formatting differences.
  • Keep assertSame() for escaping/security assertions and exact output contracts.
  • Add a short team note: "Use assertEqualHTML() for semantic markup checks."

What I Learned

  • assertEqualHTML() landed in WordPress core test tools in 6.9 and is intended to compare HTML equivalence, not raw string identity.
  • Most migration wins come from deleting custom normalization code and reducing flaky failures.
  • A two-lane assertion policy (assertEqualHTML() for semantics, assertSame() for exactness) keeps intent explicit and avoids over-migration.

References

Review: Iframed Editor Changes in WordPress 7.0 (Compatibility and Migration Impact)

· 2 min read
Victor Jimenez
Software Engineer & AI Agent Builder

The Hook WordPress 7.0 makes the iframed editor path the practical baseline, so plugins that still assume same-document admin DOM access are the first likely breakpoints.

Why I Built It Most upgrade checklists for WordPress 7.0 focus on features, but compatibility work is about execution context: iframe boundaries, asset loading, and editor-side JavaScript assumptions. I wanted a concise migration lens teams can apply before beta/final cutovers.

The Solution Treat iframe compatibility as a contract audit: verify how your code reaches the editor canvas, move to block-editor APIs where possible, and isolate admin styling/scripts so they do not assume shared DOM between parent admin and editor content frame.

The Code No separate repository for this one. This is a migration review based on WordPress core/editor roadmap and developer documentation.

What I Learned

  • WordPress started loading post editor content in an iframe by default in 6.3 when all registered blocks were API v3+ and no classic metaboxes existed; WordPress 7.0 raises the urgency for plugins still depending on legacy assumptions.
  • Code that queries editor-canvas DOM from the parent admin document is fragile; block editor data/store APIs are the safer migration target.
  • enqueue_block_assets is the right path for content styles/scripts that must run inside the editor canvas and on front end; editor shell assets should stay in enqueue_block_editor_assets.
  • The concrete pre-upgrade risk check: custom metabox usage, TinyMCE-era selectors, direct window/document editor probing, and CSS that depends on wp-admin wrapper ancestry.
  • The WordPress 7.0 release plan targets Beta 1 on March 17, 2026 and final on April 9, 2026, so compatibility testing should happen now, not after final release.

References