Skip to content

Conversation

@ockham
Copy link
Contributor

@ockham ockham commented Jun 2, 2025

Proposed changes

Add assertEqualHTML method to WP_UnitTestClass for tests comparing HTML (potentially including block markup).

Comparing HTML markup can be error prone and fragile. Typically we're interested in semantically equivalent HTML, which is what this assertion allows for; i.e. it has built-in tolerance for different attribute and class name order.

Internally, it builds a deterministic tree string representation of the HTML (using the HTML API) and compares the results.

The format of the tree is inspired by the HTML5lib-tests tree format.. It is extended with a special representation of block delimiters and their attributes.

This format also makes it easier to visually spot the differences between the two strings of HTML markup, as reported by the assertion. Quoting the inline documentation (PHPDoc) that's part of this PR:

For example, consider the following block markup:

    <!-- wp:separator {"className":"is-style-default has-custom-classname","style":{"spacing":{"margin":{"top":"50px","bottom":"50px"}}},"backgroundColor":"accent-1"} -->
        <hr class="wp-block-separator is-style-default has-custom-classname" style="margin-top: 50px; margin-bottom: 50px" />
    <!-- /wp:separator -->

This will be represented as:

    BLOCK["core/separator"]
      {
        "backgroundColor": "accent-1",
        "className": "has-custom-classname is-style-default",
        "style": {
          "spacing": {
            "margin": {
              "top": "50px",
              "bottom": "50px"
            }
          }
        }
      }
      <hr>
        class="has-custom-classname is-style-default wp-block-separator"
        style="margin-top:50px;margin-bottom:50px;"

Note

Edit: Fixed by @sirreal, see #8882 (comment).

This PR adds the new assertEqualBlockMarkup method to the WP_UnitTestCase class. Note that class Tests_Dependencies_Scripts, which is a subclass of WP_UnitTestCase, already contains a protected method named assertEqualMarkup. The latter is exclusively used for dependencies/scripts tests. The new assertEqualBlockMarkup cannot be used as a drop-in replacement, due to some differences in what it considers semantically equivalent HTML.

The existence of that protected assertEqualMarkup method was a consideration in naming the new method assertEqualBlockMarkup, so that it wouldn't collide. It seems like a reasonable choice, given that assertEqualBlockMarkup is indeed capable not only of parsing HTML, but also block markup.

In a future iteration, we might choose to retire the existing assertEqualMarkup method (and use assertEqualBlockMarkup for dependencies/scripts tests). This would then also pave the way for a general-purpose assertEqualMarkup method (which is able to parse HTML but agnostic of block markup), should the need arise.

Props @sirreal @dmsnell
Trac ticket: https://core.trac.wordpress.org/ticket/63527


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@ockham ockham self-assigned this Jun 2, 2025
@ockham ockham changed the title Add/assert equal markup Tests: Add new assertEqualMarkup assertion Jun 2, 2025
@github-actions
Copy link

github-actions bot commented Jun 2, 2025

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • The Plugin and Theme Directories cannot be accessed within Playground.
  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@sirreal
Copy link
Member

sirreal commented Jun 5, 2025

I've pushed some changes to completely remove the previous assertEqualMarkup with this implementation.

The work discovered at least one bug in the tests where the previous implementation "normalized" the output and forced the markup to appear equivalent when, in face, it was not. In this case, it purported to test html5 script behavior, but did not set html5 theme support.

public function test_wp_enqueue_script_with_html5_support_does_not_contain_type_attribute() {
global $wp_version;
$this->add_html5_script_theme_support();

There are a number of changes where /* <![CDATA[ */ /* ]]> */ wrappers are introduced around script tag contents or attributes were produced like defer="defer" instead of booleans.

It's clear that this implementation of assertEqualMarkup provides a much more accurate representation of the markup.


There's a conversation to be had around HTML5 support and whether the non HTML5 behaviors even make sense today, but that's beyond the scope of this PR.

Comment on lines +2144 to +2145
$expected .= "<script type=\"text/javascript\" src=\"http://example.com\" id=\"test-example-js\"></script>\n";
$expected .= "<script type=\"text/javascript\" id=\"test-example-js-after\">\n/* <![CDATA[ */\nconsole.log(\"after\");\n/* ]]> */\n</script>\n";
Copy link
Member

@sirreal sirreal Jun 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few cases like this where the contents of an (IE conditional) HTML comment were changed.

These script tags, on their own, would be recognized as equivalent with double " or single ' quotes. But they're not script tags, they are the text contents of an HTML comment where ' is not the same as ".

@sirreal
Copy link
Member

sirreal commented Jun 5, 2025

All of the tests here for IE conditional comments also seem quite out of place in today's internet.

Copy link
Member

@sirreal sirreal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left some feedback but I think this is great and ready to go for the most part. It becomes much easier and less error prone to compare HTML.

It's worth mentioning that the tree builder functionality is largely duplicated from existing html5lib tests used for the HTML API. It's already seen significant usage, although the block parsing is new.

private static function build_tree_representation( ?string $fragment_context, string $html ) {

ockham and others added 3 commits June 10, 2025 10:26
Co-authored-by: Jon Surrell <sirreal@users.noreply.github.com>
Co-authored-by: Jon Surrell <sirreal@users.noreply.github.com>
@ockham
Copy link
Contributor Author

ockham commented Jun 10, 2025

It's worth mentioning that the tree builder functionality is largely duplicated from existing html5lib tests used for the HTML API. It's already seen significant usage, although the block parsing is new.

@sirreal Think it's worth doing a follow-up to share code between the two?

@ockham ockham changed the title Tests: Add new assertEqualBlockMarkup assertion Tests: Add new assertEqualHTML assertion Jun 10, 2025
@sirreal
Copy link
Member

sirreal commented Jun 10, 2025

I only mentioned it because it seemed relevant for other reviewers. We could try out the sharing but I don't think it's necessary.

@github-actions
Copy link

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 60295
GitHub commit: fe6c27b

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions bot closed this Jun 10, 2025
@ockham ockham deleted the add/assert-equal-markup branch June 10, 2025 10:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants