|
1 | 1 | import { expect, test } from '../../test/playwright/index.js'; |
| 2 | +import type { Dropdown } from './dropdown.js'; |
2 | 3 |
|
3 | 4 | test.describe('Dropdown', () => { |
4 | 5 | test.use({ |
5 | 6 | tagName: 'fluent-dropdown', |
6 | 7 | innerHTML: /* html */ ` |
7 | 8 | <fluent-listbox> |
8 | | - <fluent-option value="apple">Apple</fluent-option> |
9 | | - <fluent-option value="banana">Banana</fluent-option> |
10 | | - <fluent-option value="orange">Orange</fluent-option> |
11 | | - <fluent-option value="mango">Mango</fluent-option> |
12 | | - <fluent-option value="kiwi">Kiwi</fluent-option> |
13 | | - <fluent-option value="cherry">Cherry</fluent-option> |
14 | | - <fluent-option value="grapefruit">Grapefruit</fluent-option> |
15 | | - <fluent-option value="papaya">Papaya</fluent-option> |
16 | | - </fluent-listbox> |
| 9 | + <fluent-option value="apple">Apple</fluent-option> |
| 10 | + <fluent-option value="banana">Banana</fluent-option> |
| 11 | + <fluent-option value="orange">Orange</fluent-option> |
| 12 | + <fluent-option value="mango">Mango</fluent-option> |
| 13 | + <fluent-option value="kiwi">Kiwi</fluent-option> |
| 14 | + <fluent-option value="cherry">Cherry</fluent-option> |
| 15 | + <fluent-option value="grapefruit">Grapefruit</fluent-option> |
| 16 | + <fluent-option value="papaya">Papaya</fluent-option> |
| 17 | + </fluent-listbox> |
17 | 18 | `, |
18 | 19 | waitFor: ['fluent-listbox', 'fluent-option'], |
19 | 20 | }); |
@@ -345,5 +346,113 @@ test.describe('Dropdown', () => { |
345 | 346 |
|
346 | 347 | await expect(input).toHaveValue('Kiwi'); |
347 | 348 | }); |
| 349 | + |
| 350 | + test('should emit a `change` event when the value changes and the control loses focus via blur', async ({ |
| 351 | + fastPage, |
| 352 | + page, |
| 353 | + }) => { |
| 354 | + const { element } = fastPage; |
| 355 | + const input = element.locator('input'); |
| 356 | + const listbox = element.locator('fluent-listbox'); |
| 357 | + |
| 358 | + await fastPage.setTemplate({ attributes: { type: 'combobox' } }); |
| 359 | + |
| 360 | + await input.fill('kiwi'); |
| 361 | + |
| 362 | + await expect(listbox).toBeVisible(); |
| 363 | + |
| 364 | + await expect(input).toHaveValue('kiwi'); |
| 365 | + |
| 366 | + await expect(input).toBeFocused(); |
| 367 | + |
| 368 | + await element.evaluate((el: Dropdown) => { |
| 369 | + el.addEventListener('change', () => el.insertAdjacentText('afterend', 'changed'), { once: true }); |
| 370 | + }); |
| 371 | + |
| 372 | + await input.blur(); |
| 373 | + |
| 374 | + await expect(page.locator('text=changed')).toBeVisible(); |
| 375 | + }); |
| 376 | + }); |
| 377 | + |
| 378 | + test('should emit a `change` event when value changes and the control loses focus via click', async ({ |
| 379 | + fastPage, |
| 380 | + page, |
| 381 | + }) => { |
| 382 | + const { element } = fastPage; |
| 383 | + const listbox = element.locator('fluent-listbox'); |
| 384 | + |
| 385 | + await element.click(); |
| 386 | + |
| 387 | + await expect(listbox).toBeVisible(); |
| 388 | + |
| 389 | + await expect(page.locator('text=changed')).toHaveCount(0); |
| 390 | + |
| 391 | + await element.evaluate((el: Dropdown) => { |
| 392 | + el.addEventListener('change', () => el.insertAdjacentText('afterend', 'changed'), { once: true }); |
| 393 | + }); |
| 394 | + |
| 395 | + await expect(page.locator('text=changed')).toHaveCount(0); |
| 396 | + |
| 397 | + await element.locator('[value=kiwi]').click(); |
| 398 | + |
| 399 | + await expect(page.locator('text=changed')).toHaveCount(1); |
| 400 | + |
| 401 | + await expect(page.locator('text=changed')).toBeVisible(); |
| 402 | + }); |
| 403 | + |
| 404 | + test('should emit a `change` event when the value is confirmed by pressing Enter', async ({ fastPage }) => { |
| 405 | + const { element } = fastPage; |
| 406 | + const listbox = element.locator('fluent-listbox'); |
| 407 | + |
| 408 | + await element.click(); |
| 409 | + |
| 410 | + await expect(listbox).toBeVisible(); |
| 411 | + |
| 412 | + await element.press('ArrowDown'); |
| 413 | + await element.press('ArrowDown'); |
| 414 | + await element.press('ArrowDown'); |
| 415 | + await element.press('ArrowDown'); |
| 416 | + await element.press('ArrowDown'); |
| 417 | + |
| 418 | + await expect(element).toHaveJSProperty('activeIndex', 4); |
| 419 | + |
| 420 | + const [wasChanged] = await Promise.all([ |
| 421 | + element.evaluate( |
| 422 | + el => |
| 423 | + new Promise((resolve, reject) => { |
| 424 | + const timeout = setTimeout(() => reject('change event was not emitted'), 1000); |
| 425 | + el.addEventListener( |
| 426 | + 'change', |
| 427 | + () => { |
| 428 | + clearTimeout(timeout); |
| 429 | + resolve('changed'); |
| 430 | + }, |
| 431 | + { once: true }, |
| 432 | + ); |
| 433 | + }), |
| 434 | + ), |
| 435 | + element.evaluate(el => el.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }))), |
| 436 | + ]); |
| 437 | + |
| 438 | + expect(wasChanged).toBe('changed'); |
| 439 | + }); |
| 440 | + |
| 441 | + test('should NOT emit a `change` event when the value is changed programmatically', async ({ fastPage, page }) => { |
| 442 | + const { element } = fastPage; |
| 443 | + |
| 444 | + await element.evaluate((el: Dropdown) => { |
| 445 | + el.addEventListener('change', () => el.insertAdjacentText('afterend', 'changed'), { once: true }); |
| 446 | + }); |
| 447 | + |
| 448 | + await element.evaluate((el: Dropdown) => { |
| 449 | + el.value = 'kiwi'; |
| 450 | + }); |
| 451 | + |
| 452 | + await expect(page.locator('text=changed')).toHaveCount(0); |
| 453 | + |
| 454 | + await expect(element).toHaveJSProperty('value', 'kiwi'); |
| 455 | + |
| 456 | + await expect(element.locator('fluent-option[value=kiwi]')).toHaveJSProperty('selected', true); |
348 | 457 | }); |
349 | 458 | }); |
0 commit comments