Skip to content

Commit

Permalink
Fix/combo-box-value-changed (#583)
Browse files Browse the repository at this point in the history
* fix(combo-box): update state after interactions before firing value change event

* fix(combo-box): refactor dispatchCustomEvent as a util

* fix(combo-box): add new test cases for value update & free text mode

* fix(combo-box): fix JSDoc of test util openUpdated()

* fix(combo-box): organize test cases of combo-box value
  • Loading branch information
wattachai-lseg authored Feb 3, 2023
1 parent 436b15d commit bae20f0
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { fixture, expect, elementUpdated, keyboardEvent, nextFrame, isIE } from '@refinitiv-ui/test-helpers';
import { getData, openedUpdated, makeQueryRequest, onFocusEl } from './utils';
import { getData, openedUpdated, makeQueryRequest, onFocusEl, dispatchCustomEvent } from './utils';

import '@refinitiv-ui/elements/combo-box';
import '@refinitiv-ui/elemental-theme/light/ef-combo-box';
Expand All @@ -8,13 +8,6 @@ import '@refinitiv-ui/elemental-theme/light/ef-combo-box';
// set this flag to false to run all tests locally in IE
const skipCITest = isIE() && true;

const dispatchCustomEvent = async (el, eventName) => {
el.dispatchEvent(new CustomEvent(eventName, {
bubbles: true,
composed: true
}));
};

describe('combo-box/Interaction', () => {
describe('Can Open Popup By Different Means', () => {
it('Tapping on combo-box should open popup', async function () {
Expand Down
46 changes: 42 additions & 4 deletions packages/elements/src/combo-box/__test__/combo-box.value.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { fixture, expect, elementUpdated, nextFrame } from '@refinitiv-ui/test-helpers';
import { getData, openedUpdated, snapshotIgnore, makeQueryRequest } from './utils';
import { fixture, expect, elementUpdated, nextFrame, oneEvent } from '@refinitiv-ui/test-helpers';
import { getData, openedUpdated, snapshotIgnore, makeQueryRequest, dispatchCustomEvent } from './utils';

import '@refinitiv-ui/elements/combo-box';
import '@refinitiv-ui/elemental-theme/light/ef-combo-box';
Expand Down Expand Up @@ -59,7 +59,10 @@ describe('combo-box/Value', () => {
expect(el).shadowDom.to.equalSnapshot(snapshotIgnore);
});

it('Free text. Set any value via API', async () => {
});
describe('Free Text mode', () => {

it('Set any value via API', async () => {
const el = await fixture('<ef-combo-box free-text value="AF" opened lang="en"></ef-combo-box>');
el.data = getData();
await openedUpdated(el);
Expand All @@ -76,7 +79,42 @@ describe('combo-box/Value', () => {
expect(el.value).to.equal('Any', 'Value must be "Any" string');
});

it('Free text. Reset value via API', async () => {
it('Set any value via API then select value in the list', async () => {
// set value via attribute
const el = await fixture('<ef-combo-box free-text value="attribute" opened lang="en"></ef-combo-box>');
el.data = getData();
await openedUpdated(el);

let afItem = el.listEl.querySelectorAll('ef-list-item')[1]; // AF, Afghanistan
setTimeout(() => dispatchCustomEvent(afItem, 'tap'));

const attributeEvent = await oneEvent(el, 'value-changed');
expect(attributeEvent.detail.value).to.equal('AF', `value-changed event's value doesn't equal selected value`);

// set value via input element
await makeQueryRequest(el, 'A');

const axItem = el.listEl.querySelectorAll('ef-list-item')[2]; // AX, AAland Islands
setTimeout(() => dispatchCustomEvent(axItem, 'tap'));

const inputEvent = await oneEvent(el, 'value-changed');
expect(inputEvent.detail.value).to.equal('AX', `value-changed event's value doesn't equal selected value`);

// set value via property
// cleanup first
el.value = '';
await elementUpdated(el);

el.value = 'property';

const alItem = el.listEl.querySelectorAll('ef-list-item')[3]; // AL, Albania
setTimeout(() => dispatchCustomEvent(alItem, 'tap'));

const propertyEvent = await oneEvent(el, 'value-changed');
expect(propertyEvent.detail.value).to.equal('AL', `value-changed event's value doesn't equal selected value`);
});

it('Reset value via API', async () => {
const el = await fixture('<ef-combo-box free-text value="AF" opened lang="en"></ef-combo-box>');
el.data = getData();
await openedUpdated(el);
Expand Down
12 changes: 10 additions & 2 deletions packages/elements/src/combo-box/__test__/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ export const snapshotIgnore = {

/**
* Cross browser function to wait while select element becomes opened/closed and resized
* @async
* @param {Select} el Select
* @returns {void}
* @returns {Promise<void>} Empty promise
*/
export const openedUpdated = async (el) => {
await elementUpdated(el);
await nextFrame();
await nextFrame(); // IE11 needs a second iframe, otherwise resize observer is not run;
await nextFrame(); // IE11 needs another frame, otherwise resize observer is not run;
};

export const data = [{
Expand Down Expand Up @@ -55,3 +56,10 @@ export const makeQueryRequest = async (el, textInput) => {
await elementUpdated(el);
await aTimeout(100);
};

export const dispatchCustomEvent = (el, eventName) => {
el.dispatchEvent(new CustomEvent(eventName, {
bubbles: true,
composed: true
}));
};
2 changes: 1 addition & 1 deletion packages/elements/src/combo-box/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -968,8 +968,8 @@ export class ComboBox<T extends DataItem = ItemData> extends FormFieldElement {
*/
protected onListValueChanged (): void {
// cascade value changed event
this.notifyPropertyChange('value', this.value);
this.onListInteraction();
this.notifyPropertyChange('value', this.value);
}

/**
Expand Down

0 comments on commit bae20f0

Please sign in to comment.