From 5ca244665f0248e4552119fe1a232be4a3d959cd Mon Sep 17 00:00:00 2001 From: Lukas Maurer Date: Mon, 2 Dec 2024 13:13:45 +0100 Subject: [PATCH] test(core/select): make tests less flaky (#1580) --- .../dropdown-item/dropdown-item.scss | 4 - .../src/components/select/test/select.ct.ts | 172 +++++++----------- 2 files changed, 63 insertions(+), 113 deletions(-) diff --git a/packages/core/src/components/dropdown-item/dropdown-item.scss b/packages/core/src/components/dropdown-item/dropdown-item.scss index 7be0a801c38..6211dee767a 100644 --- a/packages/core/src/components/dropdown-item/dropdown-item.scss +++ b/packages/core/src/components/dropdown-item/dropdown-item.scss @@ -79,10 +79,6 @@ $focusBorder: 0.0625rem; white-space: nowrap; } - .dropdown-item:focus-visible { - outline: 1px solid yellow; - } - .submenu-icon { margin-left: auto; } diff --git a/packages/core/src/components/select/test/select.ct.ts b/packages/core/src/components/select/test/select.ct.ts index 05db3bb7564..ad5390490d7 100644 --- a/packages/core/src/components/select/test/select.ct.ts +++ b/packages/core/src/components/select/test/select.ct.ts @@ -6,7 +6,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -import { expect } from '@playwright/test'; +import { expect, Page } from '@playwright/test'; import { getFormValue, preventFormSubmission, test } from '@utils/test'; test('renders', async ({ mount, page }) => { @@ -354,6 +354,17 @@ test('pass object as value and check if it is selectable', async ({ }); test.describe('arrow key navigation', () => { + const expectFocusMoved = async ( + direction: 'ArrowDown' | 'ArrowUp', + pattern: string, + page: Page + ) => { + const selector = `.dropdown-item:nth-of-type(${pattern}):focus-visible`; + await page.keyboard.press(direction); + await page.locator(selector); + await expect(page.locator(selector)).toBeFocused(); + }; + test.describe('ArrowDown', () => { test('input -> slotted item', async ({ mount, page }) => { await mount(` @@ -364,9 +375,7 @@ test.describe('arrow key navigation', () => { `); await page.locator('ix-select input').click(); - await page.keyboard.down('ArrowDown'); - const itemOne = await page.locator('ix-select-item').first(); - await expect(itemOne).toBeFocused(); + await expectFocusMoved('ArrowDown', '1', page); }); test('input -> dynamic item', async ({ mount, page }) => { @@ -374,14 +383,12 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('I'); await page.waitForSelector('.add-item'); - await page.keyboard.down('ArrowDown'); - const itemOne = await page.locator('.add-item'); - await expect(itemOne).toBeFocused(); + await expectFocusMoved('ArrowDown', '1', page); }); test('input -> add item', async ({ mount, page }) => { @@ -389,16 +396,15 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + await page.waitForSelector('ix-select'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('I'); await page.keyboard.down('Enter'); await page.locator('ix-icon-button').click(); await page.waitForSelector('.checkmark'); - await page.keyboard.down('ArrowDown'); - const addItem = page.locator('ix-dropdown-item'); - await expect(addItem).toBeFocused(); + await expectFocusMoved('ArrowDown', '1', page); }); test('slot -> dynamic item', async ({ mount, page }) => { @@ -409,19 +415,17 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + await page.waitForSelector('ix-select'); + const input = page.locator('ix-select input'); await input.focus(); - await input.fill('I'); + await page.keyboard.down('I'); await page.keyboard.down('Enter'); await page.locator('ix-icon-button').click(); - await page.waitForSelector('.checkmark'); + await page.waitForSelector('ix-dropdown'); + await expectFocusMoved('ArrowDown', '1', page); + await expectFocusMoved('ArrowDown', 'odd', page); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); const itemThree = page.locator('ix-select-item').last(); await expect(itemThree).toBeFocused(); @@ -435,17 +439,15 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + await page.waitForSelector('ix-select'); + const input = page.locator('ix-select input'); await input.focus(); - await input.fill('I'); - await page.waitForSelector('.add-item'); + await page.keyboard.down('I'); + await page.waitForSelector('.dropdown-item-icon'); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); + await expectFocusMoved('ArrowDown', '1', page); + await expectFocusMoved('ArrowDown', 'odd', page); + await page.keyboard.press('ArrowDown'); const addItem = page.locator('.add-item'); await expect(addItem).toBeFocused(); @@ -458,7 +460,7 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('Item 2'); await page.keyboard.down('Enter'); @@ -469,12 +471,9 @@ test.describe('arrow key navigation', () => { await input.fill('I'); await page.waitForSelector('.add-item'); + await expectFocusMoved('ArrowDown', '1', page); + await expectFocusMoved('ArrowDown', 'odd', page); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); const addItem = page.locator('.add-item'); await expect(addItem).toBeFocused(); @@ -487,25 +486,20 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('Item 2'); await page.keyboard.press('Enter'); await input.clear(); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); + await page.waitForSelector('ix-dropdown'); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); const itemTwo = page.locator('ix-select-item').nth(1); await expect(itemTwo).toBeFocused(); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - - const itemOne = page.locator('ix-select-item').first(); - await expect(itemOne).toBeFocused(); + await expectFocusMoved('ArrowDown', '1', page); }); test('wrap - add item -> slot', async ({ mount, page }) => { @@ -515,24 +509,18 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('I'); await page.waitForSelector('.add-item'); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); const addItem = page.locator('.add-item'); await expect(addItem).toBeFocused(); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - - const itemOne = page.locator('ix-select-item').first(); - await expect(itemOne).toBeFocused(); + await expectFocusMoved('ArrowDown', '1', page); }); test('wrap - add item -> dynamic item', async ({ mount, page }) => { @@ -540,7 +528,7 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('Item 1'); await page.keyboard.press('Enter'); @@ -552,18 +540,12 @@ test.describe('arrow key navigation', () => { await page.waitForSelector('.add-item'); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); const addItem = page.locator('.add-item'); await expect(addItem).toBeFocused(); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - - const itemOne = page.locator('ix-select-item'); - await expect(itemOne).toBeFocused(); + await expectFocusMoved('ArrowDown', '1', page); }); }); @@ -575,26 +557,16 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('I'); await page.keyboard.down('Enter'); await page.locator('ix-icon-button').click(); await page.waitForSelector('.checkmark'); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - - const itemTwo = page.locator('ix-select-item').last(); - await expect(itemTwo).toBeFocused(); - - await page.keyboard.down('ArrowUp'); - await page.waitForTimeout(100); - - const itemOne = page.locator('ix-select-item').first(); - await expect(itemOne).toBeFocused(); + await expectFocusMoved('ArrowDown', '1', page); + await expectFocusMoved('ArrowDown', 'odd', page); + await expectFocusMoved('ArrowUp', '1', page); }); test('add item -> slot', async ({ mount, page }) => { @@ -604,24 +576,18 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('I'); await page.waitForSelector('.add-item'); + await expectFocusMoved('ArrowDown', '1', page); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); const addItem = page.locator('.add-item'); await expect(addItem).toBeFocused(); - await page.keyboard.down('ArrowUp'); - await page.waitForTimeout(100); - - const itemOne = page.locator('ix-select-item'); - await expect(itemOne).toBeFocused(); + await expectFocusMoved('ArrowUp', '1', page); }); test('add item -> dynamic item', async ({ mount, page }) => { @@ -629,7 +595,7 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('Item 1'); await page.keyboard.press('Enter'); @@ -640,19 +606,13 @@ test.describe('arrow key navigation', () => { await input.fill('I'); await page.waitForSelector('.add-item'); + await expectFocusMoved('ArrowDown', '1', page); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); const addItem = page.locator('.add-item'); await expect(addItem).toBeFocused(); - await page.keyboard.down('ArrowUp'); - await page.waitForTimeout(100); - - const itemOne = page.locator('ix-select-item'); - await expect(itemOne).toBeFocused(); + await expectFocusMoved('ArrowUp', '1', page); }); test('wrap - slot -> dynamic item', async ({ mount, page }) => { @@ -662,7 +622,7 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('input'); + const input = page.locator('input'); await input.focus(); await input.fill('Item 2'); await page.keyboard.press('Enter'); @@ -670,9 +630,7 @@ test.describe('arrow key navigation', () => { await page.locator('input').clear(); await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); await page.keyboard.down('ArrowUp'); - await page.waitForTimeout(100); const itemTwo = page.locator('ix-select-item').last(); await expect(itemTwo).toBeFocused(); @@ -685,15 +643,13 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('I'); await page.waitForSelector('.add-item'); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); + await expectFocusMoved('ArrowDown', '1', page); await page.keyboard.down('ArrowUp'); - await page.waitForTimeout(100); const addItem = page.locator('.add-item'); await expect(addItem).toBeFocused(); @@ -704,7 +660,7 @@ test.describe('arrow key navigation', () => { `); - const input = await page.locator('ix-select input'); + const input = page.locator('ix-select input'); await input.focus(); await input.fill('Item 1'); await page.keyboard.press('Enter'); @@ -715,10 +671,8 @@ test.describe('arrow key navigation', () => { await input.fill('I'); await page.waitForSelector('.add-item'); - await page.keyboard.down('ArrowDown'); - await page.waitForTimeout(100); + await expectFocusMoved('ArrowDown', '1', page); await page.keyboard.down('ArrowUp'); - await page.waitForTimeout(100); const addItem = page.locator('.add-item'); await expect(addItem).toBeFocused(); @@ -772,7 +726,7 @@ test.describe('Events', () => { `); - const select = await page.locator('ix-select'); + const select = page.locator('ix-select'); const valueChanged = select.evaluate((elm) => { return new Promise((resolve) => { elm.addEventListener('valueChange', (e: Event) => @@ -791,7 +745,7 @@ test.describe('Events', () => { test('add item', async ({ mount, page }) => { const itemText = 'test'; await mount(``); - const select = await page.locator('ix-select'); + const select = page.locator('ix-select'); const itemAdded = select.evaluate((elm) => { return new Promise((resolve) => { elm.addEventListener('addItem', (e: Event) => @@ -799,7 +753,7 @@ test.describe('Events', () => { ); }); }); - const input = await page.locator('input'); + const input = page.locator('input'); await input.focus(); await input.fill(itemText); await page.keyboard.press('Enter'); @@ -813,23 +767,23 @@ test.describe('Events', () => { await mount(` `); - const select = await page.locator('ix-select'); + const select = page.locator('ix-select'); await select.evaluate((i) => i.addEventListener('vauleChange', (e) => e.preventDefault()) ); await page.locator('ix-icon-button').click(); - const item = await page.locator('ix-select-item'); + const item = page.locator('ix-select-item'); await item.click(); await expect(item).not.toHaveClass('selected'); }); test('add item', async ({ mount, page }) => { await mount(``); - const select = await page.locator('ix-select'); + const select = page.locator('ix-select'); await select.evaluate((i) => i.addEventListener('addItem', (e) => e.preventDefault()) ); - const input = await page.locator('input'); + const input = page.locator('input'); await input.focus(); await input.fill('test'); await page.keyboard.press('Enter');