diff --git a/app/components/ConnectorModal.vue b/app/components/ConnectorModal.vue index 7807110c22..22add06365 100644 --- a/app/components/ConnectorModal.vue +++ b/app/components/ConnectorModal.vue @@ -125,21 +125,25 @@ watch(open, isOpen => { > $ {{ executeNpmxConnectorCommand }} - +
+ + + +

{{ $t('connector.modal.paste_token') }}

diff --git a/app/components/PackageManagerSelect.vue b/app/components/PackageManagerSelect.vue new file mode 100644 index 0000000000..8a9bc4df7f --- /dev/null +++ b/app/components/PackageManagerSelect.vue @@ -0,0 +1,192 @@ + + + + + diff --git a/app/components/PackageManagerTabs.vue b/app/components/PackageManagerTabs.vue deleted file mode 100644 index 57812bec0e..0000000000 --- a/app/components/PackageManagerTabs.vue +++ /dev/null @@ -1,97 +0,0 @@ - - - - - diff --git a/app/pages/[...package].vue b/app/pages/[...package].vue index 0be1584031..7c1d95f4cb 100644 --- a/app/pages/[...package].vue +++ b/app/pages/[...package].vue @@ -798,8 +798,8 @@ function handleClick(event: MouseEvent) {

{{ $t('package.run.title') }}

- - + +
- - + +
{ describe('DateTime', () => { @@ -1293,4 +1294,12 @@ describe('component accessibility audits', () => { expect(results.violations).toEqual([]) }) }) + + describe('PackageManagerSelect', () => { + it('should have no accessibility violations', async () => { + const component = await mountSuspended(PackageManagerSelect) + const results = await runAxe(component) + expect(results.violations).toEqual([]) + }) + }) }) diff --git a/tests/package-manager-select.spec.ts b/tests/package-manager-select.spec.ts new file mode 100644 index 0000000000..e26d61eb75 --- /dev/null +++ b/tests/package-manager-select.spec.ts @@ -0,0 +1,33 @@ +import { expect, test } from '@nuxt/test-utils/playwright' + +test.describe('Package Page', () => { + test('/vue → package manager select dropdown works', async ({ page, goto }) => { + await goto('/vue', { waitUntil: 'domcontentloaded' }) + + const packageManagerButton = page.locator('button[aria-haspopup="listbox"]').first() + await expect(packageManagerButton).toBeVisible() + + // Open dropdown + await packageManagerButton.click() + const packageManagerDropdown = page.locator('[role="listbox"]') + await expect(packageManagerDropdown).toBeVisible() + + // Arrow keys navigate the listbox + await packageManagerButton.press('ArrowDown') + const firstDescendant = await packageManagerDropdown.getAttribute('aria-activedescendant') + await packageManagerButton.press('ArrowDown') + const secondDescendant = await packageManagerDropdown.getAttribute('aria-activedescendant') + expect(secondDescendant).not.toBe(firstDescendant) + + // Escape closes dropdown and returns focus + await packageManagerButton.press('Escape') + await expect(packageManagerDropdown).not.toBeVisible() + await expect(packageManagerButton).toBeFocused() + + // Enter selects option and closes dropdown + await packageManagerButton.click() + await packageManagerButton.press('ArrowDown') + await packageManagerButton.press('Enter') + await expect(packageManagerDropdown).not.toBeVisible() + }) +}) diff --git a/tests/package-manager-tabs.spec.ts b/tests/package-manager-tabs.spec.ts deleted file mode 100644 index ab25880bc6..0000000000 --- a/tests/package-manager-tabs.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { expect, test } from '@nuxt/test-utils/playwright' - -test.describe('Package Page', () => { - test('/vue → package manager tabs use roving tabindex', async ({ page, goto }) => { - await goto('/vue', { waitUntil: 'domcontentloaded' }) - - const tablist = page.locator('[role="tablist"]').first() - await expect(tablist).toBeVisible() - - const tabs = tablist.locator('[role="tab"]') - const tabCount = await tabs.count() - expect(tabCount).toBeGreaterThan(1) - - const firstTab = tabs.first() - await firstTab.focus() - await expect(firstTab).toBeFocused() - - await page.keyboard.press('ArrowRight') - - const secondTab = tabs.nth(1) - await expect(secondTab).toBeFocused() - await expect(secondTab).toHaveAttribute('aria-selected', 'true') - await expect(secondTab).toHaveAttribute('tabindex', '0') - await expect(firstTab).toHaveAttribute('tabindex', '-1') - - const tabpanel = page.locator('[role="tabpanel"]').first() - const controls = await secondTab.getAttribute('aria-controls') - const panelId = await tabpanel.getAttribute('id') - expect(controls).toBe(panelId) - - const labelledBy = await tabpanel.getAttribute('aria-labelledby') - const tabId = await secondTab.getAttribute('id') - expect(labelledBy).toBe(tabId) - }) -})