From bd81352ed5b1b5002b9cfdff6349cd69239daa39 Mon Sep 17 00:00:00 2001 From: nod_ Date: Fri, 3 May 2024 07:00:06 +0900 Subject: [PATCH] Issue #3432632 by simohell, smustgrave, kostyashupenko, andypost: Collapsed nav-tabs status not exposed to screen reader --- .../Tests/Claro/claroPrimaryTabsTest.js | 51 ++++++++++++++ .../TestSiteClaroInstallTestScript.php | 70 +++++++++++++++++++ core/themes/claro/js/nav-tabs.js | 3 + 3 files changed, 124 insertions(+) create mode 100644 core/tests/Drupal/Nightwatch/Tests/Claro/claroPrimaryTabsTest.js create mode 100644 core/tests/Drupal/TestSite/TestSiteClaroInstallTestScript.php diff --git a/core/tests/Drupal/Nightwatch/Tests/Claro/claroPrimaryTabsTest.js b/core/tests/Drupal/Nightwatch/Tests/Claro/claroPrimaryTabsTest.js new file mode 100644 index 00000000000..53e208c5091 --- /dev/null +++ b/core/tests/Drupal/Nightwatch/Tests/Claro/claroPrimaryTabsTest.js @@ -0,0 +1,51 @@ +// This test is a duplicate of oliveroPrimaryTabsTest.js tagged for claro +const primaryTabsWrapper = '[data-drupal-nav-tabs]'; +const activeTab = '.tabs__tab.is-active'; +const inactiveTab = '.tabs__tab:not(.is-active)'; +const mobileToggle = `${activeTab} .tabs__trigger`; + +module.exports = { + '@tags': ['core', 'claro'], + before(browser) { + browser + .drupalInstall({ + setupFile: + 'core/tests/Drupal/TestSite/TestSiteClaroInstallTestScript.php', + installProfile: 'minimal', + }) + .drupalCreateUser({ + name: 'user', + password: '123', + permissions: ['administer nodes'], + }) + .drupalLogin({ name: 'user', password: '123' }); + browser.setWindowSize(1600, 800); + }, + after(browser) { + browser.drupalUninstall(); + }, + 'Verify desktop primary tab display': (browser) => { + browser + .drupalRelativeURL('/node/1') + .waitForElementVisible(primaryTabsWrapper) + .assert.visible(activeTab) + .assert.visible(inactiveTab) + .assert.not.visible(mobileToggle); + }, + 'Verify mobile tab display and click functionality': (browser) => { + browser + .setWindowSize(699, 800) + .drupalRelativeURL('/node/1') + .waitForElementVisible(primaryTabsWrapper) + .assert.visible(activeTab) + .assert.not.visible(inactiveTab) + .assert.visible(mobileToggle) + .assert.attributeEquals(mobileToggle, 'aria-expanded', 'false') + .click(mobileToggle) + .waitForElementVisible(inactiveTab) + .assert.attributeEquals(mobileToggle, 'aria-expanded', 'true') + .click(mobileToggle) + .waitForElementNotVisible(inactiveTab) + .assert.attributeEquals(mobileToggle, 'aria-expanded', 'false'); + }, +}; diff --git a/core/tests/Drupal/TestSite/TestSiteClaroInstallTestScript.php b/core/tests/Drupal/TestSite/TestSiteClaroInstallTestScript.php new file mode 100644 index 00000000000..4ab1b31f096 --- /dev/null +++ b/core/tests/Drupal/TestSite/TestSiteClaroInstallTestScript.php @@ -0,0 +1,70 @@ +install(['olivero_test']); + + // Install Claro instead of Olivero and set it as the default theme. + $theme_installer = \Drupal::service('theme_installer'); + assert($theme_installer instanceof ThemeInstallerInterface); + $theme_installer->install(['claro'], TRUE); + $system_theme_config = \Drupal::configFactory()->getEditable('system.theme'); + $system_theme_config->set('default', 'claro')->save(); + + // Create an article that will have no comments + $article_no_comments = Node::create(['type' => 'article']); + $article_no_comments->set('title', 'Article without comments'); + // Enable comments + $article_no_comments->set('comment', 2); + $article_no_comments->save(); + + // Create an article that will have comments + $article_with_comments = Node::create(['type' => 'article']); + $article_with_comments->set('title', 'Article with comments'); + // Enable comments + $article_with_comments->set('comment', 2); + $article_with_comments->save(); + + $values = [ + // These values are for the entity that you're creating the comment for, not the comment itself. + 'entity_type' => 'node', + 'entity_id' => 2, + 'field_name' => 'comment', + 'uid' => 1, + // These values are for the comment itself. + 'comment_type' => 'comment', + 'subject' => 'A comment', + 'comment_body' => 'Body of comment', + // Whether the comment is 'approved' or not. + 'status' => 1, + ]; + // Create comment entities out of our field values + $comment1 = Comment::create($values); + $comment1->save(); + + $comment2 = Comment::create($values); + $comment2->save(); + } + +} diff --git a/core/themes/claro/js/nav-tabs.js b/core/themes/claro/js/nav-tabs.js index 023acfefe49..1d91dc054c8 100644 --- a/core/themes/claro/js/nav-tabs.js +++ b/core/themes/claro/js/nav-tabs.js @@ -13,6 +13,7 @@ const openMenu = () => { $target.toggleClass('is-open'); + $target.find('button').attr('aria-expanded', $target.hasClass('is-open')); }; const toggleOrder = (reset) => { @@ -54,9 +55,11 @@ // the width of the parent container. const isHorizontal = $tab.attr('data-width') <= $tab.outerWidth(); $tab.toggleClass('is-horizontal', isHorizontal); + $tab.find('button').attr('aria-expanded', null); toggleOrder(isHorizontal); } else { toggleOrder(false); + $tab.find('button').attr('aria-expanded', 'false'); } };