diff --git a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php
index 22ace3890f..5720a96414 100644
--- a/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php
+++ b/tests/phpunit/tests/html-api/wpHtmlTagProcessor.php
@@ -460,6 +460,106 @@ class Tests_HtmlApi_WpHtmlTagProcessor extends WP_UnitTestCase {
 		);
 	}
 
+	/**
+	 * Ensures that an attribute added via set_attribute() is reported by
+	 * get_attribute_names_with_prefix() without first flushing the updates
+	 * through get_updated_html().
+	 *
+	 * @ticket 64567
+	 *
+	 * @covers WP_HTML_Tag_Processor::get_attribute_names_with_prefix
+	 */
+	public function test_get_attribute_names_with_prefix_reflects_set_attribute_without_flushing() {
+		$processor = new WP_HTML_Tag_Processor( '<div>Test</div>' );
+		$processor->next_tag();
+		$processor->set_attribute( 'id', 'test' );
+
+		$this->assertSame(
+			array( 'id' ),
+			$processor->get_attribute_names_with_prefix( '' ),
+			'Did not report an attribute enqueued via set_attribute() before the updates were flushed.'
+		);
+	}
+
+	/**
+	 * Ensures that an attribute removed via remove_attribute() is no longer
+	 * reported by get_attribute_names_with_prefix() without first flushing the
+	 * updates through get_updated_html().
+	 *
+	 * @ticket 64567
+	 *
+	 * @covers WP_HTML_Tag_Processor::get_attribute_names_with_prefix
+	 */
+	public function test_get_attribute_names_with_prefix_reflects_removed_attribute_without_flushing() {
+		$processor = new WP_HTML_Tag_Processor( '<div id="main" data-foo="bar">Test</div>' );
+		$processor->next_tag();
+		$processor->remove_attribute( 'data-foo' );
+
+		$this->assertSame(
+			array(),
+			$processor->get_attribute_names_with_prefix( 'data-' ),
+			'Reported an attribute that had been enqueued for removal before the updates were flushed.'
+		);
+		$this->assertSame(
+			array( 'id' ),
+			$processor->get_attribute_names_with_prefix( '' ),
+			'Did not reflect a removed attribute in the full attribute name list before flushing.'
+		);
+	}
+
+	/**
+	 * Ensures that a class enqueued via add_class() surfaces the `class`
+	 * attribute in get_attribute_names_with_prefix() without first flushing the
+	 * updates through get_updated_html().
+	 *
+	 * @ticket 64567
+	 *
+	 * @covers WP_HTML_Tag_Processor::get_attribute_names_with_prefix
+	 */
+	public function test_get_attribute_names_with_prefix_reflects_added_class_without_flushing() {
+		$processor = new WP_HTML_Tag_Processor( '<div>Test</div>' );
+		$processor->next_tag();
+		$processor->add_class( 'highlight' );
+
+		$this->assertSame(
+			array( 'class' ),
+			$processor->get_attribute_names_with_prefix( 'class' ),
+			'Did not report the class attribute enqueued via add_class() before the updates were flushed.'
+		);
+	}
+
+	/**
+	 * Ensures get_attribute_names_with_prefix() agrees with get_attribute()
+	 * after pending updates, returning each name once with no stale entries.
+	 *
+	 * @ticket 64567
+	 *
+	 * @covers WP_HTML_Tag_Processor::get_attribute_names_with_prefix
+	 */
+	public function test_get_attribute_names_with_prefix_agrees_with_get_attribute_after_updates() {
+		$processor = new WP_HTML_Tag_Processor( '<div data-keep="1" data-drop="2">Test</div>' );
+		$processor->next_tag();
+		$processor->set_attribute( 'data-keep', 'updated' );
+		$processor->set_attribute( 'data-add', 'new' );
+		$processor->remove_attribute( 'data-drop' );
+
+		$names = $processor->get_attribute_names_with_prefix( 'data-' );
+		sort( $names );
+
+		$this->assertSame(
+			array( 'data-add', 'data-keep' ),
+			$names,
+			'Enqueued additions, updates, and removals were not reflected accurately, or a name was duplicated.'
+		);
+
+		foreach ( $names as $name ) {
+			$this->assertNotNull(
+				$processor->get_attribute( $name ),
+				"get_attribute_names_with_prefix() reported \"{$name}\" but get_attribute() did not agree."
+			);
+		}
+	}
+
 	/**
 	 * @ticket 56299
 	 *
