From 033c5e3d0fdd5a334c7c113310ca466b8a494d40 Mon Sep 17 00:00:00 2001 From: Maggie Date: Thu, 13 Jul 2023 16:23:06 +0200 Subject: [PATCH] Nav block: link text color inheritance fixes and tests (#51710) * tests and fix for link color inheritance * test agains emptytheme too, refactor setup, added better comments * change setup for tests * removed inherit color for the moment on the block * finished the first test with all cases * finished second test * finished third test * started the last test * spacing on comments * removed unnecessary actions from before/after testing functions * insert specific id of nav directly to speed up things * finish checking colors in the editor on desktop * test the overlay and reset settings * use variables for colors, cover rest of the cases to test * introduced a third link to cover non submenu links * undo unwanted change * finish the overlay background tests and fix issues with inheritance * turn colors into variables for readibility * fix wrong color syntax * Create test page before creating navigation menu * Add test coverage for selecting group text color that should be inherited by all links This test is currently failing. TDD. * Fix incorrect selector structure. The &:where(.wp-block-navigation-item a) rule would never apply, as .wp-block-navigation__responsive-container would never also have a .wp-block-navigation-item class on it. Adding the space allows it to apply the inherit rule to the a tag. * Update tests to check for black text defaults on navigation links * Big refactor of navigation color tests * Changed link names from non-descriptive firstLink, secondLink, and thirdLink to clearer names: customLink, submenuLink, and pageLink. * Combined some repeated operations such as openEditorOverlay, openFrontendOverlay, and resetGlobalStyles * Added ColorControl for keeping track of all the link selectors * Revert link color settings changing the navigation link colors The trunk behavior is to have text color global styles change the navigation color styles, while the global link color styles do not change the navigation colors. Also updated the tests to not have any of those color changes impact the submenus. * Large refactor of navigation color tests It was getting difficult to work within several very long tests with a lot of shared code, so I refactored into shared pieces that would make writing the tests easier while keeping debugging easy as well. Also, one large change was to remove the reliance on global styles since resetting the global styles after a failed test was proving very difficult, and we don't need to use global styles since we can rely on creating a group instead. By wrapping a group on the navigation block we can test the same thing while not needing to deal with global styles. * Add test for navigation background colors Also added closing the sidebar in the tests so we don't accidentally grab the links from the sidebar when the navigation block has the sidebar menu open with the same link text. * Add test to ensure navigation text does not inherit link color from the theme/group * Only set default navigation submenu and overlay text colors if no navigation text color is selected * Have li navigation items inherit background color so it can be inherited by the submenu background * Change how to test editor mobile overlay colors The tests were a little flaky when tryingn to click the button to open the mobile view since the animation from desktop to mobile in the editor took some time, and the test was trying to click the open menu button before it was able to be clicked. This updates the test to use the navigation settings itself, which doesn't have an animation, so it should be more reliable. * Move navigation color tests to own file * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js * update comments * Update test/e2e/specs/editor/blocks/navigation-colors.spec.js --------- Co-authored-by: Jerry Jones Co-authored-by: Ben Dwyer --- .../block-library/src/navigation/block.json | 9 - .../block-library/src/navigation/style.scss | 35 +- .../editor/blocks/navigation-colors.spec.js | 542 ++++++++++++++++++ 3 files changed, 569 insertions(+), 17 deletions(-) create mode 100644 test/e2e/specs/editor/blocks/navigation-colors.spec.js diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json index 0fbb2f5ed2b919..2e116821ba9962 100644 --- a/packages/block-library/src/navigation/block.json +++ b/packages/block-library/src/navigation/block.json @@ -123,15 +123,6 @@ "type": "flex" } }, - "__experimentalStyle": { - "elements": { - "link": { - "color": { - "text": "inherit" - } - } - } - }, "interactivity": true }, "viewScript": [ "file:./view.min.js", "file:./view-modal.min.js" ], diff --git a/packages/block-library/src/navigation/style.scss b/packages/block-library/src/navigation/style.scss index b0c8748075bdd7..180b40b43daca1 100644 --- a/packages/block-library/src/navigation/style.scss +++ b/packages/block-library/src/navigation/style.scss @@ -31,6 +31,7 @@ $navigation-icon-size: 24px; // Menu item container. .wp-block-navigation-item { + background-color: inherit; display: flex; align-items: center; position: relative; @@ -398,15 +399,26 @@ button.wp-block-navigation-item__content { } // Default background and font color. -.wp-block-navigation:not(.has-background) { +.wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container { + // Set a background color for submenus so that they're not transparent. + // NOTE TO DEVS - if refactoring this code, please double-check that + // submenus have a default background color, this feature has regressed + // several times, so care needs to be taken. + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.15); +} + +// If we do have a background color selected, inherit it from the navigation block +.wp-block-navigation.has-background { .wp-block-navigation__submenu-container { - // Set a background color for submenus so that they're not transparent. - // NOTE TO DEVS - if refactoring this code, please double-check that - // submenus have a default background color, this feature has regressed - // several times, so care needs to be taken. - background-color: #fff; + background-color: inherit; + } +} + +.wp-block-navigation:not(.has-text-color) { + .wp-block-navigation__submenu-container { + // Set a default color for submenu text if none is selected color: #000; - border: 1px solid rgba(0, 0, 0, 0.15); } } @@ -458,7 +470,8 @@ button.wp-block-navigation-item__content { right: 0; bottom: 0; - .wp-block-navigation-link a { + // Low specificity so that themes can override. + & :where(.wp-block-navigation-item a) { color: inherit; } @@ -579,6 +592,7 @@ button.wp-block-navigation-item__content { // Remove background colors for items inside the overlay menu. // Has to be !important to override global styles. .wp-block-navigation-item .wp-block-navigation__submenu-container, + .wp-block-navigation__container, .wp-block-navigation-item, .wp-block-page-list { color: inherit !important; @@ -620,9 +634,14 @@ button.wp-block-navigation-item__content { .wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open { background-color: #fff; +} + +.wp-block-navigation:not(.has-text-color) +.wp-block-navigation__responsive-container.is-menu-open { color: #000; } + // Overlay menu toggle button label .wp-block-navigation__toggle_button_label { font-size: 1rem; diff --git a/test/e2e/specs/editor/blocks/navigation-colors.spec.js b/test/e2e/specs/editor/blocks/navigation-colors.spec.js new file mode 100644 index 00000000000000..dd74b3194a16a4 --- /dev/null +++ b/test/e2e/specs/editor/blocks/navigation-colors.spec.js @@ -0,0 +1,542 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'Navigation colors', () => { + test.beforeAll( async ( { requestUtils } ) => { + // We want emptytheme because it doesn't have any styles. + await requestUtils.activateTheme( 'emptytheme' ); + await requestUtils.deleteAllTemplates( 'wp_template_part' ); + await requestUtils.deleteAllMenus(); + await requestUtils.deleteAllPages(); + } ); + + test.beforeEach( async ( { admin, editor, requestUtils } ) => { + await admin.visitSiteEditor( { + postId: 'emptytheme//header', + postType: 'wp_template_part', + } ); + await editor.canvas.click( 'body' ); + const { id: pageId } = await requestUtils.createPage( { + title: 'Test Page', + status: 'publish', + } ); + const { id: menuId } = await requestUtils.createNavigationMenu( { + title: 'Colored menu', + content: ``, + attributes: { openSubmenusOnClick: true }, + } ); + await editor.insertBlock( { + name: 'core/navigation', + attributes: { + ref: menuId, + }, + } ); + + await editor.saveSiteEditorEntities(); + await admin.visitSiteEditor(); + await editor.canvas.click( 'body' ); + // Focus the navigation block inside the header template part. + await editor.canvas + .getByRole( 'document', { name: 'Block: header' } ) + .focus(); + await editor.canvas + .getByRole( 'document', { name: 'Block: Navigation' } ) + .click(); + } ); + + test.afterEach( async ( { requestUtils } ) => { + await requestUtils.deleteAllTemplates( 'wp_template_part' ); + await requestUtils.deleteAllMenus(); + await requestUtils.deleteAllPages(); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await Promise.all( [ + requestUtils.deleteAllTemplates( 'wp_template_part' ), + requestUtils.deleteAllMenus(), + requestUtils.deleteAllPages(), + requestUtils.activateTheme( 'twentytwentyone' ), + ] ); + } ); + + test.use( { + colorControl: async ( { admin, editor, page, pageUtils }, use ) => { + await use( new ColorControl( { admin, editor, page, pageUtils } ) ); + }, + } ); + + test( 'All navigation links should default to the body color and submenus and mobile overlay should default to a white background with black text', async ( { + page, + colorControl, + } ) => { + const expectedNavigationColors = { + textColor: colorControl.black, + backgroundColor: colorControl.transparent, // There should be no background color set even though the body background is black. + submenuTextColor: colorControl.black, + submenuBackgroundColor: colorControl.white, + }; + + await colorControl.testEditorColors( expectedNavigationColors ); + + // And finally we check the colors of the links on the frontend. + await page.goto( '/' ); + + await colorControl.testFrontendColors( expectedNavigationColors ); + } ); + + test( 'Top level navigation links inherit the text color from the theme/group but do not apply to the submenu or overlay text', async ( { + page, + editor, + colorControl, + } ) => { + // Set the text and background styles for the group. The text color should apply to the top level links but not the submenu or overlay. + // We wrap the nav block inside a group block. + await page + .getByRole( 'toolbar', { name: 'Block tools' } ) + .getByRole( 'button', { name: 'Options' } ) + .click(); + await page.getByRole( 'menuitem', { name: 'Group' } ).click(); + + // In the sidebar inspector we add a link color and link hover color to the group block. + await editor.openDocumentSettingsSidebar(); + await page.getByRole( 'tab', { name: 'Styles' } ).click(); + await page.getByRole( 'button', { name: 'Color Text styles' } ).click(); + await page + .getByRole( 'button', { name: 'Color: White' } ) + .click( { force: true } ); + + await page + .getByRole( 'button', { name: 'Color Background styles' } ) + .click(); + await page + .getByRole( 'button', { name: 'Color: Black' } ) + .click( { force: true } ); + + // Save them so we can check on the frontend later too. + await editor.saveSiteEditorEntities(); + // Close the sidebar so our selectors don't accidentally select the sidebar links instead of the editor canvas. + await page + .getByRole( 'button', { name: 'Close Settings' } ) + .click( { force: true } ); + + await editor.canvas.click( 'body' ); + + // Focus the navigation block inside the header template part. + await editor.canvas + .getByRole( 'document', { name: 'Block: header' } ) + .focus(); + await editor.canvas + .getByRole( 'document', { name: 'Block: Navigation' } ) + .click(); + + const expectedNavigationColors = { + textColor: colorControl.white, + backgroundColor: colorControl.transparent, // There should be no background color set even though the body background is black. + submenuTextColor: colorControl.black, + submenuBackgroundColor: colorControl.white, + }; + + await colorControl.testEditorColors( expectedNavigationColors ); + + // And finally we check the colors of the links on the frontend. + await page.goto( '/' ); + + await colorControl.testFrontendColors( expectedNavigationColors ); + } ); + + test( 'Navigation text does not inherit the link color from the theme/group', async ( { + page, + editor, + colorControl, + } ) => { + // Wrap the nav block inside a group block. + await page + .getByRole( 'toolbar', { name: 'Block tools' } ) + .getByRole( 'button', { name: 'Options' } ) + .click(); + await page.getByRole( 'menuitem', { name: 'Group' } ).click(); + + // In the sidebar inspector we add a link color and link hover color to the group block. + await editor.openDocumentSettingsSidebar(); + await page.getByRole( 'tab', { name: 'Styles' } ).click(); + await page.getByRole( 'button', { name: 'Color options' } ).click(); + await page + .getByRole( 'menuitemcheckbox', { name: 'Show Link' } ) + .click(); + await page.getByRole( 'tab', { name: 'Styles' } ).click(); + await page.getByRole( 'button', { name: 'Color Link styles' } ).click(); + // rga(207, 46 ,46) is the color of the "vivid red" color preset. + await page + .getByRole( 'button', { name: 'Color: Vivid red' } ) + .click( { force: true } ); + await page.getByRole( 'tab', { name: 'Hover' } ).click(); + // rgb(155, 81, 224) is the color of the "vivid purple" color preset. + await page + .getByRole( 'button', { name: 'Color: Vivid purple' } ) + .click( { force: true } ); + + // Save them so we can check on the frontend later too. + await editor.saveSiteEditorEntities(); + // Close the sidebar so our selectors don't accidentally select the sidebar links instead of the editor canvas. + await page + .getByRole( 'button', { name: 'Close Settings' } ) + .click( { force: true } ); + + await editor.canvas.click( 'body' ); + + // Focus the navigation block inside the header template part. + await editor.canvas + .getByRole( 'document', { name: 'Block: header' } ) + .focus(); + await editor.canvas + .getByRole( 'document', { name: 'Block: Navigation' } ) + .click(); + + const expectedNavigationColors = { + textColor: colorControl.black, + backgroundColor: colorControl.transparent, + submenuTextColor: colorControl.black, + submenuBackgroundColor: colorControl.white, + }; + + await colorControl.testEditorColors( expectedNavigationColors ); + + // And finally we check the colors of the links on the frontend. + await page.goto( '/' ); + + await colorControl.testFrontendColors( expectedNavigationColors ); + } ); + + test( 'The navigation text color should apply to all navigation links including submenu and overlay text', async ( { + page, + editor, + colorControl, + } ) => { + await editor.openDocumentSettingsSidebar(); + + // In the inspector sidebar, we change the nav block colors. + await page.getByRole( 'tab', { name: 'Styles' } ).click(); + // Pale pink for the text color. + await page.getByRole( 'button', { name: 'Text', exact: true } ).click(); + // 247, 141, 167 is the color of the "Pale pink" color preset. + const palePink = 'rgb(247, 141, 167)'; + await page + .getByRole( 'button', { name: 'Color: Pale pink' } ) + .click( { force: true } ); + + await editor.saveSiteEditorEntities(); + // Close the sidebar so our selectors don't accidentally select the sidebar links instead of the editor canvas. + await page + .getByRole( 'button', { name: 'Close Settings' } ) + .click( { force: true } ); + + await editor.canvas.click( 'body' ); + + // Focus the navigation block inside the header template part. + await editor.canvas + .getByRole( 'document', { name: 'Block: header' } ) + .focus(); + await editor.canvas + .getByRole( 'document', { name: 'Block: Navigation' } ) + .click(); + + const expectedNavigationColors = { + textColor: palePink, + backgroundColor: colorControl.transparent, // There should be no background color set. + submenuTextColor: palePink, + submenuBackgroundColor: colorControl.white, + }; + + await colorControl.testEditorColors( expectedNavigationColors ); + + // And finally we check the colors of the links on the frontend. + await page.goto( '/' ); + + await colorControl.testFrontendColors( expectedNavigationColors ); + } ); + + test( 'The navigation background color should apply to all navigation links including submenu and overlay backgrounds', async ( { + page, + editor, + colorControl, + } ) => { + await editor.openDocumentSettingsSidebar(); + + // In the inspector sidebar, we change the nav block colors. + await page.getByRole( 'tab', { name: 'Styles' } ).click(); + // Pale pink for the text color. + await page + .getByRole( 'button', { name: 'Background', exact: true } ) + .click(); + // 142, 209, 252 is the color of the "Pale cyan blue" color preset. + const paleCyan = 'rgb(142, 209, 252)'; + await page + .getByRole( 'button', { name: 'Color: Pale cyan blue' } ) + .click( { force: true } ); + + await editor.saveSiteEditorEntities(); + // Close the sidebar so our selectors don't accidentally select the sidebar links instead of the editor canvas. + await page + .getByRole( 'button', { name: 'Close Settings' } ) + .click( { force: true } ); + await editor.canvas.click( 'body' ); + + // Focus the navigation block inside the header template part. + await editor.canvas + .getByRole( 'document', { name: 'Block: header' } ) + .focus(); + await editor.canvas + .getByRole( 'document', { name: 'Block: Navigation' } ) + .click(); + + // The navigation background, submenu background and overlay background should all be paleCyan. + const expectedNavigationColors = { + textColor: colorControl.black, + backgroundColor: paleCyan, + submenuTextColor: colorControl.black, + submenuBackgroundColor: paleCyan, + }; + + await colorControl.testEditorColors( expectedNavigationColors ); + + // And finally we check the colors of the links on the frontend. + await page.goto( '/' ); + + await colorControl.testFrontendColors( expectedNavigationColors ); + } ); + + test( 'As a user I expect my navigation to use the colors I selected for it', async ( { + editor, + page, + colorControl, + } ) => { + await editor.openDocumentSettingsSidebar(); + + // In the inspector sidebar, we change the nav block colors. + await page.getByRole( 'tab', { name: 'Styles' } ).click(); + // Pale pink for the text color. + await page.getByRole( 'button', { name: 'Text', exact: true } ).click(); + // 247, 141, 167 is the color of the "Pale pink" color preset. + const palePink = 'rgb(247, 141, 167)'; + await page + .getByRole( 'button', { name: 'Color: Pale pink' } ) + .click( { force: true } ); + // Pale cyan blue for the background color. + await page + .getByRole( 'button', { name: 'Background', exact: true } ) + .click(); + // 142, 209, 252 is the color of the "Pale cyan blue" color preset. + const paleCyan = 'rgb(142, 209, 252)'; + await page + .getByRole( 'button', { name: 'Color: Pale cyan blue' } ) + .click( { force: true } ); + // Cyan bluish gray for the submenu and overlay text color. + await page + .getByRole( 'button', { name: 'Submenu & overlay text' } ) + .click(); + // 171, 184, 195 is the color of the "Cyan bluish gray" color preset. + const cyanBluishGray = 'rgb(171, 184, 195)'; + await page + .getByRole( 'button', { name: 'Color: Cyan bluish gray' } ) + .click( { force: true } ); + // Luminous vivid amber for the submenu and overlay background color. + await page + .getByRole( 'button', { name: 'Submenu & overlay background' } ) + .click(); + // 252, 185, 0 is the color of the "Luminous vivid amber" color preset. + const vividAmber = 'rgb(252, 185, 0)'; + await page + .getByRole( 'button', { name: 'Color: Luminous vivid amber' } ) + .click( { force: true } ); + + await editor.saveSiteEditorEntities(); + // Close the sidebar so our selectors don't accidentally select the sidebar links instead of the editor canvas. + await page + .getByRole( 'button', { name: 'Close Settings' } ) + .click( { force: true } ); + + await editor.canvas.click( 'body' ); + + // Focus the navigation block inside the header template part. + await editor.canvas + .getByRole( 'document', { name: 'Block: header' } ) + .focus(); + await editor.canvas + .getByRole( 'document', { name: 'Block: Navigation' } ) + .click(); + + const expectedNavigationColors = { + textColor: palePink, + backgroundColor: paleCyan, // There should be no background color set. + submenuTextColor: cyanBluishGray, + submenuBackgroundColor: vividAmber, + }; + + await colorControl.testEditorColors( expectedNavigationColors ); + + // And finally we check the colors of the links on the frontend. + await page.goto( '/' ); + + await colorControl.testFrontendColors( expectedNavigationColors ); + } ); +} ); + +class ColorControl { + constructor( { admin, editor, page, pageUtils } ) { + this.admin = admin; + this.editor = editor; + this.page = page; + this.pageUtils = pageUtils; + + // Colors for readability. + this.black = 'rgb(0, 0, 0)'; + this.white = 'rgb(255, 255, 255)'; + // If there is no background color set, it will not have any background, which computes to 'rgab(0, 0, 0, 0)'. + this.transparent = 'rgba(0, 0, 0, 0)'; + } + + async testEditorColors( { + textColor, + backgroundColor, + submenuTextColor, + submenuBackgroundColor, + } ) { + // Editor elements. + const customLink = this.editor.canvas + .locator( 'a' ) + .filter( { hasText: 'Custom Link' } ); + const pageLink = this.editor.canvas + .locator( 'a' ) + .filter( { hasText: 'Page Link' } ); + + await expect( customLink ).toHaveCSS( 'color', textColor ); + await expect( pageLink ).toHaveCSS( 'color', textColor ); + // Navigation background. + const navigationWrapper = this.editor.canvas.getByRole( 'document', { + name: 'Block: Navigation', + } ); + await expect( navigationWrapper ).toHaveCSS( + 'background-color', + backgroundColor + ); + + await customLink.click(); + + // Submenu elements. + const submenuLink = this.editor.canvas + .locator( 'a' ) + .filter( { hasText: 'Submenu Link' } ); + const submenuWrapper = this.editor.canvas + .getByRole( 'document', { name: 'Block: Custom Link' } ) + .filter( { has: submenuLink } ); + + // Submenu link color. + await expect( submenuLink ).toHaveCSS( 'color', submenuTextColor ); + + // Submenu background color. + await expect( submenuWrapper ).toHaveCSS( + 'background-color', + submenuBackgroundColor + ); + + // Switch to mobile view for the rest of the editor color tests. + // Focus the navigation block. + await this.editor.canvas + .getByRole( 'document', { name: 'Block: Navigation' } ) + .click(); + await this.editor.openDocumentSettingsSidebar(); + // Switch to settings tab. + await this.page.getByRole( 'tab', { name: 'Settings' } ).click(); + // Set it to always be the mobile view, but don't save this setting so we can still check all the frontend colors. + await this.page.getByRole( 'radio', { name: 'Always' } ).click(); + await this.editor.canvas + .getByRole( 'button', { name: 'Open menu' } ) + .click(); + + const overlay = this.editor.canvas + .locator( '.wp-block-navigation__responsive-container' ) + .filter( { hasText: 'Submenu Link' } ); + + // All of the mobile menu navigation links should be the same color as the submenuTextColor. + await expect( customLink ).toHaveCSS( 'color', submenuTextColor ); + await expect( submenuLink ).toHaveCSS( 'color', submenuTextColor ); + await expect( pageLink ).toHaveCSS( 'color', submenuTextColor ); + + // The mobile menu background should be the same color as the submenu background. + await expect( overlay ).toHaveCSS( + 'background-color', + submenuBackgroundColor + ); + } + + async testFrontendColors( { + textColor, + backgroundColor, + submenuTextColor, + submenuBackgroundColor, + } ) { + // Top level link elements. + const customLink = this.page + .locator( 'a' ) + .filter( { hasText: 'Custom Link' } ); + const pageLink = this.page + .locator( 'a' ) + .filter( { hasText: 'Page Link' } ); + + // Top level link colors. + await expect( customLink ).toHaveCSS( 'color', textColor ); + await expect( pageLink ).toHaveCSS( 'color', textColor ); + + // Navigation background. + const menuWrapperFront = this.page + .getByRole( 'navigation', { name: 'Colored menu' } ) + .getByRole( 'list' ); + await expect( menuWrapperFront ).toHaveCSS( + 'background-color', + backgroundColor + ); + + await customLink.hover(); + + // Submenu elements. + const submenuLink = this.page + .locator( 'a' ) + .filter( { hasText: 'Submenu Link' } ); + const submenuWrapper = this.page + .locator( '.wp-block-navigation__submenu-container' ) + .filter( { has: submenuLink } ); + + // Submenu link color. + await expect( submenuLink ).toHaveCSS( 'color', submenuTextColor ); + + // Submenu background color. + await expect( submenuWrapper ).toHaveCSS( + 'background-color', + submenuBackgroundColor + ); + + // Open the frontend overlay so we can test the colors. + await this.pageUtils.setBrowserViewport( { width: 599, height: 700 } ); + await this.page.getByRole( 'button', { name: 'Open menu' } ).click(); + + // All of the mobile menu navigation links should be the same color as the submenuTextColor. + await expect( customLink ).toHaveCSS( 'color', submenuTextColor ); + await expect( submenuLink ).toHaveCSS( 'color', submenuTextColor ); + await expect( pageLink ).toHaveCSS( 'color', submenuTextColor ); + + const overlayFront = this.page + .locator( '.wp-block-navigation__responsive-container' ) + .filter( { hasText: 'Submenu Link' } ); + + // The mobile menu background should be the same color as the submenu background. + await expect( overlayFront ).toHaveCSS( + 'background-color', + submenuBackgroundColor + ); + + // We need to reset the overlay to the default viewport if something runs after these tests. + await this.pageUtils.setBrowserViewport( 'large' ); + } +}