diff --git a/classes/views/styles/_form-title.php b/classes/views/styles/_form-title.php index 3a322f1453..be28362bdc 100644 --- a/classes/views/styles/_form-title.php +++ b/classes/views/styles/_form-title.php @@ -4,8 +4,8 @@ } ?>
-
@@ -14,7 +14,7 @@ class="frm-style-item-heading">get_field_name( 'title_color' ), $style->post_content['title_color'], array( - 'id' => 'frm_fieldset_color', + 'id' => 'frm_title_color', 'action_slug' => 'title_color', ) ); diff --git a/classes/views/styles/_quick-settings.php b/classes/views/styles/_quick-settings.php index 82b4716d1c..af08997ba6 100644 --- a/classes/views/styles/_quick-settings.php +++ b/classes/views/styles/_quick-settings.php @@ -118,8 +118,8 @@ class="frm-style-item-heading">
-
@@ -128,7 +128,7 @@ class="frm-style-item-heading">post_content['field_margin'], array( - 'id' => 'frm_field_margin', + 'id' => 'frm_style_qsettings_field_margin', 'max_value' => 100, 'will_change' => array( $frm_style->get_field_name( 'field_margin' ), @@ -139,8 +139,8 @@ class="frm-style-item-heading">
-
@@ -149,7 +149,7 @@ class="frm-style-item-heading">post_content['field_pad'], array( - 'id' => 'frm_field_pad', + 'id' => 'frm_style_qsettings_field_pad', 'max_value' => 100, 'will_change' => array( $frm_style->get_field_name( 'field_pad' ), @@ -206,8 +206,8 @@ class="frm-style-item-heading">
-
@@ -216,7 +216,7 @@ class="frm-style-item-heading">post_content['border_radius'], array( - 'id' => 'frm_border_radius', + 'id' => 'frm_style_qsettings_border_radius', 'max_value' => 50, 'will_change' => array( $frm_style->get_field_name( 'border_radius' ), diff --git a/tests/phpunit/base/FrmUnitTest.php b/tests/phpunit/base/FrmUnitTest.php index 1dad220136..4cf62b0cab 100644 --- a/tests/phpunit/base/FrmUnitTest.php +++ b/tests/phpunit/base/FrmUnitTest.php @@ -843,4 +843,23 @@ protected function use_frm_role( $role ) { break; } } + + /** + * Assert that none of the given HTML element ids appears more than once in some + * rendered HTML (aria_id_unique — a duplicate id breaks any ARIA property that + * references it, since the reference can no longer resolve to a single element). + * + * @since x.x + * + * @param string $html + * @param array $ids + * + * @return void + */ + protected function assert_no_duplicate_element_ids( $html, $ids ) { + foreach ( $ids as $id ) { + $count = preg_match_all( '/\bid=["\']' . preg_quote( $id, '/' ) . '["\']/', $html ); + $this->assertSame( 1, $count, 'Expected exactly one element with id "' . $id . '"' ); + } + } } diff --git a/tests/phpunit/styles/test_FrmStylesController.php b/tests/phpunit/styles/test_FrmStylesController.php index d4061d4bdb..0224aee62b 100644 --- a/tests/phpunit/styles/test_FrmStylesController.php +++ b/tests/phpunit/styles/test_FrmStylesController.php @@ -48,6 +48,52 @@ private function get_custom_stylesheet() { return $stylesheet_urls; } + /** + * The styler edit page's "Quick Settings" panel and its "Advanced Settings" + * accordion sections both render into the DOM unconditionally (only one is + * shown at a time via CSS), so an id reused between a quick-settings control + * and its advanced-settings equivalent collides and breaks any ARIA property + * that references it (aria_id_unique). + * + * @covers FrmStylesController::render_style_page + */ + public function test_render_style_page_has_no_duplicate_ids() { + $this->set_current_user_to_1(); + + // render_style_page() reads $_GET to decide the view ('edit' vs 'list'); a leftover + // 'form'/'style_id' from another test would silently switch this to the list view. + $_GET = array(); + + $form_id = $this->factory->form->create(); + $form = FrmForm::getOne( $form_id ); + $frm_style = new FrmStyle( 'default' ); + $active_style = $frm_style->get_one(); + + ob_start(); + $this->run_private_method( + array( 'FrmStylesController', 'render_style_page' ), + array( $active_style, $form, $active_style ) + ); + $html = ob_get_clean(); + + $this->assert_no_duplicate_element_ids( + $html, + array( + 'frm_field_pad', + 'frm_field_margin', + 'frm_border_radius', + 'frm_fieldset_color', + // The renamed quick-settings/form-title ids themselves, so a future edit that + // deletes one of these elements (instead of just re-duplicating its id) still + // fails loudly here. + 'frm_style_qsettings_field_pad', + 'frm_style_qsettings_field_margin', + 'frm_style_qsettings_border_radius', + 'frm_title_color', + ) + ); + } + /** * @covers FrmStylesController::save_style * @covers FrmStyle::update