Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
11e758e
Fix typo in comment
sirreal Jan 20, 2026
84c65af
Do not trim leading text node whitespace
sirreal Jan 20, 2026
d483c8d
Update test without leading whitespace, use nowdoc
sirreal Jan 20, 2026
72e7c40
Add test for https://core.trac.wordpress.org/ticket/64531
sirreal Jan 20, 2026
9f672ba
Add whitespace inside block delimiters
sirreal Jan 20, 2026
19ed504
Merge branch 'trunk' into 64531/ensure-whitespace-check-assertEqualHTML
sirreal Jan 20, 2026
1e9b067
Correct whitespace in scripts HTML tests
sirreal Jan 20, 2026
76ec5b1
lint
sirreal Jan 20, 2026
79d0a66
Cleanup debug code
sirreal Jan 20, 2026
e90bfbf
Fix script modules tests
sirreal Jan 20, 2026
e205a2c
Remove redundant "snapshots" from assertEqualHTML test assertion mess…
sirreal Jan 20, 2026
2493b26
Fix archives tests
sirreal Jan 20, 2026
b2cca85
Use nowdoc without indentation for block_markup
sirreal Jan 20, 2026
1bfbe89
Remove redundant snapshot from assertion message
sirreal Jan 20, 2026
1580d3b
Fix simple test, remove extra whitespace
sirreal Jan 20, 2026
e44a2ad
Add nested blocks text nodes test
sirreal Jan 20, 2026
951307e
Fix whitespace in blocks tests
sirreal Jan 20, 2026
23e18f7
Debugging code with invis chars
sirreal Jan 20, 2026
d2a2977
Revert "Debugging code with invis chars"
sirreal Jan 20, 2026
29faaf5
remove block indentation
sirreal Jan 20, 2026
236267a
Fix block-template-utils HTML whitespace in tests
sirreal Jan 20, 2026
f670eb8
Improve comment language
sirreal Jan 21, 2026
6e9877b
Merge branch 'trunk' into 64531/ensure-whitespace-check-assertEqualHTML
sirreal Jan 21, 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
4 changes: 2 additions & 2 deletions tests/phpunit/includes/build-visual-html-tree.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ static function ( $a, $b ) {
case '#cdata-section':
case '#text':
$text_content = $processor->get_modifiable_text();
if ( '' === trim( $text_content, " \f\t\r\n" ) ) {
if ( '' === $text_content ) {
Copy link
Member Author

Choose a reason for hiding this comment

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

This was the main problem, it effectively eliminated whitespace text completely, and leading whitespace from existing text nodes.

Copy link
Member

Choose a reason for hiding this comment

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

Why was this added in the first place? The trim() here occurs after decoding, meaning that any raw markup would have already been processed and whitespace normalized.

Copy link
Member Author

Choose a reason for hiding this comment

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

It was introduced as part of block delimiters appearing in the HTML tree. That change is not open source, this was largely developed in another project before being proposed for Core.

break;
}
$was_text = true;
Expand Down Expand Up @@ -237,7 +237,7 @@ static function ( $a, $b ) {
++$indent_level;
}

// If they're no attributes, we're done here.
// When no attributes are present, there’s nothing left to do.
if ( empty( $block_attrs ) ) {
break;
}
Expand Down
28 changes: 12 additions & 16 deletions tests/phpunit/tests/block-template-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,9 @@ public function data_remove_theme_attribute_in_block_template_content() {
*/
public function test_block_template_add_skip_link_inserts_link_and_adds_main_id_when_missing() {
$template_html = '<div class="wp-site-blocks"><main>Content</main></div>';
$expected = '
<a class="skip-link screen-reader-text" id="wp-skip-link" href="#wp--skip-link--target">Skip to content</a>
<div class="wp-site-blocks"><main id="wp--skip-link--target">Content</main></div>
';
$expected =
'<a class="skip-link screen-reader-text" id="wp-skip-link" href="#wp--skip-link--target">Skip to content</a>' .
'<div class="wp-site-blocks"><main id="wp--skip-link--target">Content</main></div>';

$this->assertEqualHTML( $expected, _block_template_add_skip_link( $template_html ) );
}
Expand All @@ -323,10 +322,9 @@ public function test_block_template_add_skip_link_inserts_link_and_adds_main_id_
*/
public function test_block_template_add_skip_link_uses_existing_main_id() {
$template_html = '<div class="wp-site-blocks"><main id="custom-id">Content</main></div>';
$expected = '
<a class="skip-link screen-reader-text" id="wp-skip-link" href="#custom-id">Skip to content</a>
<div class="wp-site-blocks"><main id="custom-id">Content</main></div>
';
$expected =
'<a class="skip-link screen-reader-text" id="wp-skip-link" href="#custom-id">Skip to content</a>' .
'<div class="wp-site-blocks"><main id="custom-id">Content</main></div>';

$this->assertEqualHTML( $expected, _block_template_add_skip_link( $template_html ) );
}
Expand All @@ -340,10 +338,9 @@ public function test_block_template_add_skip_link_uses_existing_main_id() {
*/
public function test_block_template_add_skip_link_handles_boolean_main_id() {
$template_html = '<div class="wp-site-blocks"><main id>Content</main></div>';
$expected = '
<a class="skip-link screen-reader-text" id="wp-skip-link" href="#wp--skip-link--target">Skip to content</a>
<div class="wp-site-blocks"><main id="wp--skip-link--target">Content</main></div>
';
$expected =
'<a class="skip-link screen-reader-text" id="wp-skip-link" href="#wp--skip-link--target">Skip to content</a>' .
'<div class="wp-site-blocks"><main id="wp--skip-link--target">Content</main></div>';

$this->assertEqualHTML( $expected, _block_template_add_skip_link( $template_html ) );
}
Expand All @@ -357,10 +354,9 @@ public function test_block_template_add_skip_link_handles_boolean_main_id() {
*/
public function test_block_template_add_skip_link_preserves_whitespace_main_id() {
$template_html = '<div class="wp-site-blocks"><main id=" my-id ">Content</main></div>';
$expected = '
<a class="skip-link screen-reader-text" id="wp-skip-link" href="#%20my-id%20">Skip to content</a>
<div class="wp-site-blocks"><main id=" my-id ">Content</main></div>
';
$expected =
'<a class="skip-link screen-reader-text" id="wp-skip-link" href="#%20my-id%20">Skip to content</a>' .
'<div class="wp-site-blocks"><main id=" my-id ">Content</main></div>';

$this->assertEqualHTML( $expected, _block_template_add_skip_link( $template_html ) );
}
Expand Down
148 changes: 94 additions & 54 deletions tests/phpunit/tests/blocks/wpBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -368,32 +368,39 @@ public function test_render_applies_dynamic_render_block_filter() {
* @return array
*/
public function data_provider_test_render_enqueues_scripts_and_styles(): array {
$block_markup = '
<!-- wp:static -->
<div class="static">
<!-- wp:static-child -->
<div class="static-child">First child</div>
<!-- /wp:static-child -->
<!-- wp:dynamic /-->
<!-- wp:static-child -->
<div class="static-child">Last child</div>
<!-- /wp:static-child -->
</div>
<!-- /wp:static -->
';
$block_markup = <<<'HTML'
<!-- wp:static -->
<div class="static">
<!-- wp:static-child -->
<div class="static-child">First child</div>
<!-- /wp:static-child -->
<!-- wp:dynamic /-->
<!-- wp:static-child -->
<div class="static-child">Last child</div>
<!-- /wp:static-child -->
</div>
<!-- /wp:static -->
HTML;

// TODO: Add case where a dynamic block renders other blocks?
return array(
'all_printed' => array(
'set_up' => null,
'block_markup' => $block_markup,
'expected_rendered_block' => '
<div class="static">
<div class="static-child">First child</div>
<p class="dynamic">Hello World!</p>
<div class="static-child">Last child</div>
</div>
',
'expected_rendered_block' => <<<'HTML'

<div class="static">

Copy link
Member

Choose a reason for hiding this comment

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

I’m not sure how to think through this, and I think you are alluding to it in how we split blocks from the HTML, but is this right? It seems to be producing two newlines which I wouldn’t have expected.

Also, the test code itself performs an initial trim() on the supplied test data. Could that be making these more confusing than they need to be. That @todo looks like a good candidate for WP_Block_Processor::extract_full_block_and_advance()

// test_render_enqueues_scripts_and_styles:L670

// TODO: Why not use do_blocks() instead?
$parsed_blocks  = parse_blocks( trim( $block_markup ) );

Copy link
Member Author

Choose a reason for hiding this comment

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

I’m not sure how to think through this, and I think you are alluding to it in how we split blocks from the HTML, but is this right? It seems to be producing two newlines which I wouldn’t have expected.

The block markup is this (after removing leading whitespace in this PR):

<!-- wp:static -->
<div class="static">
<!-- wp:static-child -->
<div class="static-child">First child</div>
<!-- /wp:static-child -->
<!-- wp:dynamic /-->
<!-- wp:static-child -->
<div class="static-child">Last child</div>
<!-- /wp:static-child -->
</div>
<!-- /wp:static -->

Rendering removes the block delimiters (and replaces the registered dynamic block), but preserves everything else. The result is this:

<div class="static">

<div class="static-child">First child</div>

<p class="dynamic">Hello World!</p>

<div class="static-child">Last child</div>

</div>

Before removing the indentation, this is what caused the \n\t\n sequences (whitespace characters added for clarity):

<!-- wp:static -->␊
␉	<div class="static">␊
␉	<!-- wp:static-child -->␊
␉	<div class="static-child">First child</div>␊
␉	<!-- /wp:static-child -->␊
␉	<!-- wp:dynamic /-->␊
␉	<!-- wp:static-child -->␊
␉	<div class="static-child">Last child</div>␊
␉	<!-- /wp:static-child -->␊
␉	</div><!-- /wp:static -->

Becomes:

␊
␉	<div class="static">␊
␉	␊
␉	<div class="static-child">First child</div>␊
␉	␊
␉	<p class="dynamic">Hello World!</p>␊
␉	␊
␉	<div class="static-child">Last child</div>␊
␉	␊
␉	</div>

I've noticed here that the indentation was inconsistent, with the static block's contents being indented, but static-child block's content remains at the same indentation:

$block_markup = '
<!-- wp:static -->
<div class="static">
<!-- wp:static-child -->
<div class="static-child">First child</div>
<!-- /wp:static-child -->
<!-- wp:dynamic /-->
<!-- wp:static-child -->
<div class="static-child">Last child</div>
<!-- /wp:static-child -->
</div>
<!-- /wp:static -->
';

<div class="static-child">First child</div>

<p class="dynamic">Hello World!</p>

<div class="static-child">Last child</div>

</div>

HTML
,
'expected_styles' => array( 'static-view-style', 'static-child-view-style', 'dynamic-view-style' ),
'expected_scripts' => array( 'static-view-script', 'static-child-view-script', 'dynamic-view-script' ),
'expected_script_modules' => array( 'static-view-script-module', 'static-child-view-script-module', 'dynamic-view-script-module' ),
Expand All @@ -414,13 +421,20 @@ static function ( $content ) {
);
},
'block_markup' => $block_markup,
'expected_rendered_block' => '
<div class="static">
<div class="static-child">First child</div>
<p class="dynamic filtered">Hello World!</p>
<div class="static-child">Last child</div>
</div>
',
'expected_rendered_block' => <<<'HTML'

<div class="static">

<div class="static-child">First child</div>

<p class="dynamic filtered">Hello World!</p>

<div class="static-child">Last child</div>

</div>

HTML
,
'expected_styles' => array( 'static-view-style', 'dynamic-extra', 'static-child-view-style', 'dynamic-view-style' ),
'expected_scripts' => array( 'static-view-script', 'static-child-view-script', 'dynamic-view-script' ),
'expected_script_modules' => array( 'static-view-script-module', 'static-child-view-script-module', 'dynamic-view-script-module' ),
Expand All @@ -430,12 +444,20 @@ static function ( $content ) {
add_filter( 'render_block_core/dynamic', '__return_empty_string' );
},
'block_markup' => $block_markup,
'expected_rendered_block' => '
<div class="static">
<div class="static-child">First child</div>
<div class="static-child">Last child</div>
</div>
',
'expected_rendered_block' => <<<'HTML'

<div class="static">

<div class="static-child">First child</div>



<div class="static-child">Last child</div>

</div>

HTML
,
'expected_styles' => array( 'static-view-style', 'static-child-view-style' ),
'expected_scripts' => array( 'static-view-script', 'static-child-view-script' ),
'expected_script_modules' => array( 'static-view-script-module', 'static-child-view-script-module' ),
Expand All @@ -456,12 +478,20 @@ static function ( $enqueue, $block_name ) {
);
},
'block_markup' => $block_markup,
'expected_rendered_block' => '
<div class="static">
<div class="static-child">First child</div>
<div class="static-child">Last child</div>
</div>
',
'expected_rendered_block' => <<<'HTML'

<div class="static">

<div class="static-child">First child</div>



<div class="static-child">Last child</div>

</div>

HTML
,
'expected_styles' => array( 'static-view-style', 'static-child-view-style', 'dynamic-view-style' ),
'expected_scripts' => array( 'static-view-script', 'static-child-view-script', 'dynamic-view-script' ),
'expected_script_modules' => array( 'static-view-script-module', 'static-child-view-script-module', 'dynamic-view-script-module' ),
Expand All @@ -488,11 +518,16 @@ static function ( $content ) {
add_filter( 'render_block_core/static-child', '__return_empty_string' );
},
'block_markup' => $block_markup,
'expected_rendered_block' => '
<div class="static">
<p class="dynamic">Hello World!</p>
</div>
',
'expected_rendered_block' => <<<'HTML'

<div class="static">

<p class="dynamic">Hello World!</p>

</div>

HTML
,
'expected_styles' => array( 'static-view-style', 'dynamic-view-style' ),
'expected_scripts' => array( 'static-view-script', 'dynamic-view-script' ),
'expected_script_modules' => array( 'static-view-script-module', 'dynamic-view-script-module' ),
Expand All @@ -512,12 +547,18 @@ static function ( $content ) {
);
},
'block_markup' => $block_markup,
'expected_rendered_block' => '
<div class="static">
<div class="static-child">First child</div>
<p class="dynamic">Hello World!</p>
</div>
',
'expected_rendered_block' => <<<'HTML'

<div class="static">

<div class="static-child">First child</div>

<p class="dynamic">Hello World!</p>

</div>

HTML
,
'expected_styles' => array( 'static-view-style', 'static-child-view-style', 'dynamic-view-style' ),
'expected_scripts' => array( 'static-view-script', 'static-child-view-script', 'dynamic-view-script' ),
'expected_script_modules' => array( 'static-view-script-module', 'static-child-view-script-module', 'dynamic-view-script-module' ),
Expand Down Expand Up @@ -562,9 +603,8 @@ static function ( $content ) {
);
},
'block_markup' => '<!-- wp:static --><div class="static"></div><!-- /wp:static -->',
'expected_rendered_block' => '
<div class="static yes-admin-bar-script-enqueued yes-admin-bar-style-enqueued"></div>
',
'expected_rendered_block' =>
'<div class="static yes-admin-bar-script-enqueued yes-admin-bar-style-enqueued"></div>',
'expected_styles' => array( 'static-view-style', 'admin-bar' ),
'expected_scripts' => array( 'static-view-script', 'admin-bar' ),
'expected_script_modules' => array( 'static-view-script-module' ),
Expand Down Expand Up @@ -682,7 +722,7 @@ public function test_render_enqueues_scripts_and_styles( ?Closure $set_up, strin
$expected_rendered_block,
$rendered_block,
'<body>',
"Rendered block does not contain expected HTML:\n$rendered_block"
'Rendered block does not contain expected HTML.'
);
}

Expand Down
Loading
Loading