From 6d6ac97b3ae91606121a4426e257e5e7f80322f3 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Wed, 11 Dec 2024 16:19:37 -0800 Subject: [PATCH 1/4] prevent event bubbling when the enter key is hit to select a menu item in the action menu --- app/ui/lib/ActionMenu.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/ui/lib/ActionMenu.tsx b/app/ui/lib/ActionMenu.tsx index b1aef8600e..aee7a8b1d4 100644 --- a/app/ui/lib/ActionMenu.tsx +++ b/app/ui/lib/ActionMenu.tsx @@ -99,6 +99,7 @@ export function ActionMenu(props: ActionMenuProps) { if (e.key === KEYS.enter) { if (selectedItem) { selectedItem.onSelect() + e.preventDefault() onDismiss() } } else if (e.key === KEYS.down) { From bf781c5a2a6403c566f332917b602282f8f90605 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Wed, 11 Dec 2024 16:51:21 -0800 Subject: [PATCH 2/4] Add test --- test/e2e/silos.e2e.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/e2e/silos.e2e.ts b/test/e2e/silos.e2e.ts index 87a33a84da..762c8fac61 100644 --- a/test/e2e/silos.e2e.ts +++ b/test/e2e/silos.e2e.ts @@ -164,6 +164,19 @@ test('Create silo', async ({ page }) => { await expect(otherSiloCell).toBeHidden() }) +test('Open create silo modal from ActionMenu', async ({ page }) => { + await page.goto('/system/silos') + // open the action menu + await page.getByRole('button', { name: 'JUMP TO' }).click() + // make sure the action menu modal is visible + await expect(page.getByRole('heading', { name: 'Actions' })).toBeVisible() + // New silo is the first item in the list, so we can just hit enter to open the modal + await page.keyboard.press('Enter') + await expect(page.getByRole('dialog', { name: 'Create silo' })).toBeVisible() + // make sure error text is not visible + await expectNotVisible(page, [page.getByText('Name is required')]) +}) + test('Default silo', async ({ page }) => { await page.goto('/system/silos') await page.getByRole('link', { name: 'myriad' }).click() From 924a3e15eb05a7b08d2033bae72a5daef43813cd Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Wed, 11 Dec 2024 17:57:34 -0800 Subject: [PATCH 3/4] Move ActionMenu tests to dedicated file --- test/e2e/action-menu.e2e.ts | 29 +++++++++++++++++++++++++++++ test/e2e/silos.e2e.ts | 13 ------------- 2 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 test/e2e/action-menu.e2e.ts diff --git a/test/e2e/action-menu.e2e.ts b/test/e2e/action-menu.e2e.ts new file mode 100644 index 0000000000..7d788dc096 --- /dev/null +++ b/test/e2e/action-menu.e2e.ts @@ -0,0 +1,29 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright Oxide Computer Company + */ +import { expect, test, type Page } from '@playwright/test' + +import { expectNotVisible } from './utils' + +const openActionMenu = async (page: Page) => { + // open the action menu (use the sidenav button, as keyboard events aren't reliable in Playwright) + await page.getByRole('button', { name: 'JUMP TO' }).click() + // make sure the action menu modal is visible + await expect(page.getByRole('heading', { name: 'Actions' })).toBeVisible() +} + +test('Ensure that the Enter key in the ActionMenu doesn’t prematurely submit a linked form', async ({ + page, +}) => { + await page.goto('/system/silos') + await openActionMenu(page) + // "New silo" is the first item in the list, so we can just hit enter to open the modal + await page.keyboard.press('Enter') + await expect(page.getByRole('dialog', { name: 'Create silo' })).toBeVisible() + // make sure error text is not visible + await expectNotVisible(page, [page.getByText('Name is required')]) +}) diff --git a/test/e2e/silos.e2e.ts b/test/e2e/silos.e2e.ts index 762c8fac61..87a33a84da 100644 --- a/test/e2e/silos.e2e.ts +++ b/test/e2e/silos.e2e.ts @@ -164,19 +164,6 @@ test('Create silo', async ({ page }) => { await expect(otherSiloCell).toBeHidden() }) -test('Open create silo modal from ActionMenu', async ({ page }) => { - await page.goto('/system/silos') - // open the action menu - await page.getByRole('button', { name: 'JUMP TO' }).click() - // make sure the action menu modal is visible - await expect(page.getByRole('heading', { name: 'Actions' })).toBeVisible() - // New silo is the first item in the list, so we can just hit enter to open the modal - await page.keyboard.press('Enter') - await expect(page.getByRole('dialog', { name: 'Create silo' })).toBeVisible() - // make sure error text is not visible - await expectNotVisible(page, [page.getByText('Name is required')]) -}) - test('Default silo', async ({ page }) => { await page.goto('/system/silos') await page.getByRole('link', { name: 'myriad' }).click() From 2537ad8907808fc84cde7e368cb86b0e71e299d7 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Wed, 11 Dec 2024 17:59:50 -0800 Subject: [PATCH 4/4] Use a more universal check for the openActionMenu helper --- test/e2e/action-menu.e2e.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/action-menu.e2e.ts b/test/e2e/action-menu.e2e.ts index 7d788dc096..6aadc1760d 100644 --- a/test/e2e/action-menu.e2e.ts +++ b/test/e2e/action-menu.e2e.ts @@ -13,7 +13,7 @@ const openActionMenu = async (page: Page) => { // open the action menu (use the sidenav button, as keyboard events aren't reliable in Playwright) await page.getByRole('button', { name: 'JUMP TO' }).click() // make sure the action menu modal is visible - await expect(page.getByRole('heading', { name: 'Actions' })).toBeVisible() + await expect(page.getByText('Enterto submit')).toBeVisible() } test('Ensure that the Enter key in the ActionMenu doesn’t prematurely submit a linked form', async ({