diff --git a/src/wp-admin/includes/class-wp-application-passwords-list-table.php b/src/wp-admin/includes/class-wp-application-passwords-list-table.php
index 9a60853016fc5..b3dccaf478a83 100644
--- a/src/wp-admin/includes/class-wp-application-passwords-list-table.php
+++ b/src/wp-admin/includes/class-wp-application-passwords-list-table.php
@@ -214,7 +214,12 @@ public function print_js_template_row() {
$classes .= ' hidden';
}
- printf( '
', esc_attr( $classes ), esc_attr( wp_strip_all_tags( $display_name ) ) );
+ // The primary column is a ` | ` row header, matching the
+ // server-rendered markup in WP_List_Table::single_row_columns().
+ $tag = $is_primary ? 'th' : 'td';
+ $scope = $is_primary ? ' scope="row"' : '';
+
+ printf( '<%1$s class="%2$s" data-colname="%3$s"%4$s>', $tag, esc_attr( $classes ), esc_attr( wp_strip_all_tags( $display_name ) ), $scope );
switch ( $column_name ) {
case 'name':
@@ -259,7 +264,7 @@ public function print_js_template_row() {
'';
}
- echo '';
+ echo "{$tag}>";
}
echo '';
diff --git a/tests/phpunit/tests/admin/wpApplicationPasswordsListTable.php b/tests/phpunit/tests/admin/wpApplicationPasswordsListTable.php
new file mode 100644
index 0000000000000..2c6eda10b050d
--- /dev/null
+++ b/tests/phpunit/tests/admin/wpApplicationPasswordsListTable.php
@@ -0,0 +1,59 @@
+table = _get_list_table(
+ 'WP_Application_Passwords_List_Table',
+ array( 'screen' => 'application-passwords-user' )
+ );
+ }
+
+ /**
+ * Ensures the JavaScript row template used for a password created via AJAX
+ * renders the primary column as a ` | ` row header, matching
+ * the server-rendered markup from WP_List_Table::single_row_columns().
+ *
+ * @ticket 65707
+ *
+ * @covers WP_Application_Passwords_List_Table::print_js_template_row
+ */
+ public function test_print_js_template_row_uses_th_row_header_for_primary_column() {
+ ob_start();
+ $this->table->print_js_template_row();
+ $html = ob_get_clean();
+
+ // Assert on the tag structure and `scope="row"` rather than the localized
+ // column label, so the test does not depend on the current locale or on
+ // filters that adjust the column headers.
+ $this->assertMatchesRegularExpression(
+ '/ | /',
+ $html,
+ 'The primary column should be rendered as a | row header.'
+ );
+
+ $this->assertStringNotContainsString(
+ ' | cells.'
+ );
+ }
+}
|