Skip to content

Commit a92aca9

Browse files
refactor(select): refactored open listbox into its own function
1 parent a6c9f57 commit a92aca9

File tree

3 files changed

+69
-96
lines changed

3 files changed

+69
-96
lines changed

apps/website/src/routes/docs/headless/select/select.driver.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Locator, Page } from '@playwright/test';
2-
1+
import { Locator, Page, expect } from '@playwright/test';
2+
import { type OpenKeys } from '@qwik-ui/headless';
33
export type DriverLocator = Locator | Page;
44

55
export function createTestDriver<T extends DriverLocator>(locator: T) {
@@ -23,6 +23,19 @@ export function createTestDriver<T extends DriverLocator>(locator: T) {
2323
return getTrigger().locator('[data-value]').textContent();
2424
};
2525

26+
const openListbox = async (key: OpenKeys | 'click') => {
27+
await getTrigger().focus();
28+
29+
if (key !== 'click') {
30+
await getTrigger().press(key);
31+
} else {
32+
await getTrigger().click();
33+
}
34+
35+
// should be open initially
36+
await expect(getListbox()).toBeVisible();
37+
};
38+
2639
return {
2740
...locator,
2841
locator,
@@ -31,5 +44,6 @@ export function createTestDriver<T extends DriverLocator>(locator: T) {
3144
getListbox,
3245
getOptions,
3346
getValue,
47+
openListbox,
3448
};
3549
}

apps/website/src/routes/docs/headless/select/select.spec.ts

Lines changed: 52 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ async function setup(page: Page, selector: string) {
55

66
const driver = createTestDriver(page.getByTestId(selector));
77

8-
const { getListbox, getTrigger, getOptions, getValue } = driver;
8+
const { getListbox, getTrigger, getOptions, getValue, openListbox } = driver;
99

1010
return {
1111
driver,
1212
getListbox,
1313
getTrigger,
1414
getOptions,
1515
getValue,
16+
openListbox,
1617
};
1718
}
1819

@@ -31,11 +32,9 @@ test.describe('Mouse Behavior', () => {
3132
test(`GIVEN a hero select with an open listbox
3233
WHEN the trigger is clicked
3334
THEN close the listbox AND aria-expanded should be false`, async ({ page }) => {
34-
const { getTrigger, getListbox } = await setup(page, 'select-hero-test');
35+
const { getTrigger, getListbox, openListbox } = await setup(page, 'select-hero-test');
3536

36-
await getTrigger().click();
37-
// should be open initially
38-
await expect(getListbox()).toBeVisible();
37+
await openListbox('click');
3938

4039
await getTrigger().click();
4140
await expect(getListbox()).toBeHidden();
@@ -45,11 +44,12 @@ test.describe('Mouse Behavior', () => {
4544
test(`GIVEN a hero select with an open listbox
4645
WHEN an option is clicked
4746
THEN close the listbox AND aria-expanded should be false`, async ({ page }) => {
48-
const { getTrigger, getListbox, getOptions } = await setup(page, 'select-hero-test');
47+
const { getTrigger, getListbox, getOptions, openListbox } = await setup(
48+
page,
49+
'select-hero-test',
50+
);
4951

50-
await getTrigger().click();
51-
// should be open initially
52-
await expect(getListbox()).toBeVisible();
52+
await openListbox('click');
5353

5454
const options = await getOptions();
5555
options[0].click();
@@ -61,11 +61,9 @@ test.describe('Mouse Behavior', () => {
6161
test(`GIVEN a hero select with an open listbox
6262
WHEN the 2nd option is clicked
6363
THEN the 2nd option should have aria-selected`, async ({ page }) => {
64-
const { getTrigger, getListbox, getOptions } = await setup(page, 'select-hero-test');
64+
const { getOptions, openListbox } = await setup(page, 'select-hero-test');
6565

66-
await getTrigger().click();
67-
// should be open initially
68-
await expect(getListbox()).toBeVisible();
66+
await openListbox('click');
6967

7068
const options = await getOptions();
7169
options[1].click();
@@ -76,14 +74,9 @@ test.describe('Mouse Behavior', () => {
7674
test(`GIVEN a hero select with an open listbox
7775
WHEN the 3rd option is clicked
7876
THEN the 3rd option should be the selected value`, async ({ page }) => {
79-
const { getTrigger, getListbox, getOptions, getValue } = await setup(
80-
page,
81-
'select-hero-test',
82-
);
77+
const { getOptions, getValue, openListbox } = await setup(page, 'select-hero-test');
8378

84-
await getTrigger().click();
85-
// should be open initially
86-
await expect(getListbox()).toBeVisible();
79+
await openListbox('click');
8780

8881
const options = await getOptions();
8982
await options[2].click();
@@ -110,11 +103,12 @@ test.describe('Keyboard Behavior', () => {
110103
test(`GIVEN a hero select with an open listbox
111104
WHEN focusing the trigger and hitting enter
112105
THEN close the listbox AND aria-expanded should be false`, async ({ page }) => {
113-
const { getTrigger, getListbox } = await setup(page, 'select-hero-test');
106+
const { getTrigger, getListbox, openListbox } = await setup(
107+
page,
108+
'select-hero-test',
109+
);
114110

115-
await getTrigger().click();
116-
// should be open initially
117-
await expect(getListbox()).toBeVisible();
111+
await openListbox('click');
118112

119113
await getTrigger().focus();
120114
await getTrigger().press('Enter');
@@ -137,12 +131,12 @@ test.describe('Keyboard Behavior', () => {
137131
test(`GIVEN a hero select with an open listbox
138132
WHEN pressing the space key
139133
THEN close listbox AND aria-expanded should be false`, async ({ page }) => {
140-
const { getTrigger, getListbox } = await setup(page, 'select-hero-test');
134+
const { getTrigger, getListbox, openListbox } = await setup(
135+
page,
136+
'select-hero-test',
137+
);
141138

142-
await getTrigger().focus();
143-
await getTrigger().press('Space');
144-
// should be open initially
145-
await expect(getListbox()).toBeVisible();
139+
await openListbox('Space');
146140

147141
await getTrigger().focus();
148142
await getTrigger().press('Space');
@@ -164,11 +158,12 @@ test.describe('Keyboard Behavior', () => {
164158
WHEN pressing the escape key
165159
THEN the listbox should close
166160
AND aria-expanded should be false`, async ({ page }) => {
167-
const { getTrigger, getListbox } = await setup(page, 'select-hero-test');
161+
const { getTrigger, getListbox, openListbox } = await setup(
162+
page,
163+
'select-hero-test',
164+
);
168165

169-
await getTrigger().click();
170-
// should be open initially
171-
await expect(getListbox()).toBeVisible();
166+
await openListbox('click');
172167

173168
await getTrigger().focus();
174169
await getTrigger().press('Escape');
@@ -249,14 +244,12 @@ test.describe('Keyboard Behavior', () => {
249244
test(`GIVEN an open hero select
250245
WHEN pressing the end key
251246
THEN the last option should have data-highlighted`, async ({ page }) => {
252-
const { getTrigger, getListbox, getOptions } = await setup(
247+
const { getTrigger, getOptions, openListbox } = await setup(
253248
page,
254249
'select-hero-test',
255250
);
256251

257-
await getTrigger().click();
258-
// should be open initially
259-
await expect(getListbox()).toBeVisible();
252+
await openListbox('click');
260253

261254
await getTrigger().focus();
262255
await getTrigger().press('End');
@@ -269,14 +262,12 @@ test.describe('Keyboard Behavior', () => {
269262
test(`GIVEN an open hero select
270263
WHEN pressing the home key after the end key
271264
THEN the first option should have data-highlighted`, async ({ page }) => {
272-
const { getTrigger, getListbox, getOptions } = await setup(
265+
const { getTrigger, getOptions, openListbox } = await setup(
273266
page,
274267
'select-hero-test',
275268
);
276269

277-
await getTrigger().click();
278-
// should be open initially
279-
await expect(getListbox()).toBeVisible();
270+
await openListbox('click');
280271

281272
// to last index
282273
await getTrigger().focus();
@@ -293,15 +284,12 @@ test.describe('Keyboard Behavior', () => {
293284
test(`GIVEN an open hero select
294285
WHEN the first option is highlighted and the down arrow key is pressed
295286
THEN the second option should have data-highlighted`, async ({ page }) => {
296-
const { getTrigger, getListbox, getOptions } = await setup(
287+
const { getTrigger, getOptions, openListbox } = await setup(
297288
page,
298289
'select-hero-test',
299290
);
300291

301-
await getTrigger().focus();
302-
await getTrigger().press('Enter');
303-
// should be open initially
304-
await expect(getListbox()).toBeVisible();
292+
await openListbox('Enter');
305293

306294
// first index highlighted
307295
const options = await getOptions();
@@ -315,15 +303,12 @@ test.describe('Keyboard Behavior', () => {
315303
test(`GIVEN an open hero select
316304
WHEN the third option is highlighted and the up arrow key is pressed
317305
THEN the second option should have data-highlighted`, async ({ page }) => {
318-
const { getTrigger, getListbox, getOptions } = await setup(
306+
const { getTrigger, getOptions, openListbox } = await setup(
319307
page,
320308
'select-hero-test',
321309
);
322310

323-
await getTrigger().focus();
324-
await getTrigger().press('Enter');
325-
// should be open initially
326-
await expect(getListbox()).toBeVisible();
311+
await openListbox('Enter');
327312

328313
const options = await getOptions();
329314
await expect(options[0]).toHaveAttribute('data-highlighted');
@@ -339,15 +324,12 @@ test.describe('Keyboard Behavior', () => {
339324
THEN the data-highlighted option should not change on re-open`, async ({
340325
page,
341326
}) => {
342-
const { getTrigger, getListbox, getOptions } = await setup(
327+
const { getTrigger, getListbox, getOptions, openListbox } = await setup(
343328
page,
344329
'select-hero-test',
345330
);
346331

347-
await getTrigger().focus();
348-
await getTrigger().press('Enter');
349-
// should be open initially
350-
await expect(getListbox()).toBeVisible();
332+
await openListbox('Enter');
351333

352334
// second option highlighted
353335
const options = await getOptions();
@@ -368,15 +350,12 @@ test.describe('Keyboard Behavior', () => {
368350
THEN the listbox should be closed and aria-expanded false`, async ({
369351
page,
370352
}) => {
371-
const { getTrigger, getListbox, getOptions } = await setup(
353+
const { getTrigger, getListbox, getOptions, openListbox } = await setup(
372354
page,
373355
'select-hero-test',
374356
);
375357

376-
await getTrigger().focus();
377-
await getTrigger().press('Enter');
378-
// should be open initially
379-
await expect(getListbox()).toBeVisible();
358+
await openListbox('Enter');
380359

381360
const options = await getOptions();
382361
await expect(options[0]).toHaveAttribute('data-highlighted');
@@ -390,15 +369,12 @@ test.describe('Keyboard Behavior', () => {
390369
AND the Enter key is pressed
391370
THEN option value should be the selected value
392371
AND should have an aria-selected of true`, async ({ page }) => {
393-
const { getTrigger, getListbox, getOptions, getValue } = await setup(
372+
const { getTrigger, getOptions, getValue, openListbox } = await setup(
394373
page,
395374
'select-hero-test',
396375
);
397376

398-
await getTrigger().focus();
399-
await getTrigger().press('Enter');
400-
// should be open initially
401-
await expect(getListbox()).toBeVisible();
377+
await openListbox('Enter');
402378

403379
const options = await getOptions();
404380
await expect(options[0]).toHaveAttribute('data-highlighted');
@@ -416,15 +392,12 @@ test.describe('Keyboard Behavior', () => {
416392
THEN the listbox should be closed and aria-expanded false`, async ({
417393
page,
418394
}) => {
419-
const { getTrigger, getListbox, getOptions } = await setup(
395+
const { getTrigger, getListbox, getOptions, openListbox } = await setup(
420396
page,
421397
'select-hero-test',
422398
);
423399

424-
await getTrigger().focus();
425-
await getTrigger().press('Space');
426-
// should be open initially
427-
await expect(getListbox()).toBeVisible();
400+
await openListbox('Space');
428401

429402
// second option highlighted
430403
const options = await getOptions();
@@ -440,15 +413,12 @@ test.describe('Disabled', () => {
440413
test(`GIVEN an open disabled select with the first option disabled
441414
WHEN clicking the disabled option
442415
It should have aria-disabled`, async ({ page }) => {
443-
const { getTrigger, getListbox, getOptions } = await setup(
416+
const { getTrigger, getOptions, openListbox } = await setup(
444417
page,
445418
'select-disabled-test',
446419
);
447420

448-
await getTrigger().focus();
449-
await getTrigger().press('Enter');
450-
// should be open initially
451-
await expect(getListbox()).toBeVisible();
421+
await openListbox('Enter');
452422

453423
await getTrigger().focus();
454424
await getTrigger().press('ArrowDown');
@@ -459,15 +429,12 @@ test.describe('Disabled', () => {
459429
test(`GIVEN an open disabled select with the first option disabled
460430
WHEN clicking the disabled option
461431
THEN the listbox should stay open`, async ({ page }) => {
462-
const { getTrigger, getListbox, getOptions } = await setup(
432+
const { getListbox, getOptions, openListbox } = await setup(
463433
page,
464434
'select-disabled-test',
465435
);
466436

467-
await getTrigger().focus();
468-
await getTrigger().press('Enter');
469-
// should be open initially
470-
await expect(getListbox()).toBeVisible();
437+
await openListbox('Enter');
471438

472439
const options = await getOptions();
473440
// eslint-disable-next-line playwright/no-force-option
@@ -478,31 +445,22 @@ test.describe('Disabled', () => {
478445
test(`GIVEN an open disabled select
479446
WHEN first option is disabled
480447
THEN the second option should have data-highlighted`, async ({ page }) => {
481-
const { getTrigger, getListbox, getOptions } = await setup(
482-
page,
483-
'select-disabled-test',
484-
);
448+
const { getOptions, openListbox } = await setup(page, 'select-disabled-test');
485449

486-
await getTrigger().focus();
487-
await getTrigger().press('ArrowDown');
488-
// should be open initially
489-
await expect(getListbox()).toBeVisible();
450+
await openListbox('ArrowDown');
490451
const options = await getOptions();
491452
await expect(options[1]).toHaveAttribute('data-highlighted');
492453
});
493454

494455
test(`GIVEN an open disabled select
495456
WHEN the last option is disabled and the end key is pressed
496457
THEN the second last index should have data-highlighted`, async ({ page }) => {
497-
const { getTrigger, getListbox, getOptions } = await setup(
458+
const { getTrigger, getOptions, openListbox } = await setup(
498459
page,
499460
'select-disabled-test',
500461
);
501462

502-
await getTrigger().focus();
503-
await getTrigger().press('ArrowDown');
504-
// should be open initially
505-
await expect(getListbox()).toBeVisible();
463+
await openListbox('ArrowDown');
506464
await getTrigger().press('End');
507465
const options = await getOptions();
508466
await expect(options[options.length - 2]).toHaveAttribute('data-highlighted');

packages/kit-headless/src/components/select/select-trigger.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export type OptionsType = {
66
element: HTMLLIElement;
77
isDisabled: boolean;
88
}[];
9+
export type OpenKeys = 'ArrowUp' | 'Enter' | 'Space' | 'ArrowDown';
910

1011
type SelectTriggerProps = PropsOf<'button'>;
1112
export type DisabledArr = Array<{ disabled: boolean }>;

0 commit comments

Comments
 (0)