Skip to content

Commit

Permalink
chore: add tests for native select
Browse files Browse the repository at this point in the history
  • Loading branch information
josemarluedke committed Feb 21, 2024
1 parent 081df54 commit 20f5870
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 3 deletions.
4 changes: 2 additions & 2 deletions packages/forms/src/components/native-select.gts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class NativeSelect extends Component<NativeSelectSignature> {
}}
{{on "change" this.handleOnChange}}
multiple={{this.isMultiple}}
data-test-id="select"
data-test-id="native-select"
class={{this.classNames}}
...attributes
>
Expand Down Expand Up @@ -194,7 +194,7 @@ class NativeSelectItem extends Component<SelectItemSignature> {
onRegister=this.onRegister
}}
data-selected="{{this.listItem.isSelected}}"
data-test-id="select-option"
data-test-id="option"
data-key={{this.key}}
selected={{this.listItem.isSelected}}
value={{this.key}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { registerCustomStyles } from '@frontile/theme';
import { tv } from 'tailwind-variants';

module(
'Integration | Component | Listbox | @frontile/buttons',
'Integration | Component | Listbox | @frontile/collections',
function (hooks) {
setupRenderingTest(hooks);

Expand Down
256 changes: 256 additions & 0 deletions test-app/tests/integration/components/forms/native-select-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { click, render, triggerEvent } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

function selectNativeOptionByKey(
selectSelector: string,
key: string
): Promise<void> {
return changeOption('selectNativeOptionByKey', selectSelector, key, false);
}

function toggleNativeOptionByKey(
selectSelector: string,
key: string
): Promise<void> {
return changeOption('toggleNativeOptionByKey', selectSelector, key, true);
}

function changeOption(
functionName: string,
selectSelector: string,
key: string,
toggle: boolean
): Promise<void> {
const select = document.querySelector(selectSelector);
if (!select) {
throw new Error(
`You called "${functionName}('${selectSelector}', '${key}')" but no select was found using selector "${selectSelector}"`
);
}
const option = select.querySelector(`[data-key="${key}"]`) as
| HTMLOptionElement
| undefined;
if (!option) {
throw new Error(
`You called "${functionName}('${selectSelector}', '${key}')" but no option with key "${key}" was found`
);
}
if (option.selected && toggle) {
option.selected = false;
} else {
option.selected = true;
}
return triggerEvent(select, 'change');
}

module(
'Integration | Component | NativeSelect | @frontile/forms',
function (hooks) {
setupRenderingTest(hooks);

const isSelected = (
assert: { ok: (val: boolean, mes: string) => void },
queryString: string
): void => {
const option = document.querySelector(queryString);
const isSelected = option && (option as HTMLOptionElement).selected;
assert.ok(!!isSelected, `Expected ${queryString} to be selected`);
};

const isNotSelected = (
assert: { ok: (val: boolean, mes: string) => void },
queryString: string
): void => {
const option = document.querySelector(queryString);
const isSelected = option && (option as HTMLOptionElement).selected;
assert.ok(!isSelected, `Expected ${queryString} to not be selected`);
};

test('it render static items', async function (assert) {
let selectedKeys: string[] = [];
this.set('onSelectionChange', function (keys: string[]) {
selectedKeys = keys;
});

assert.ok;

await render(
hbs`
<NativeSelect
@onSelectionChange={{this.onSelectionChange}}
@disabledKeys={{(array "item-3" "item-4")}}
@allowEmpty={{true}}
as |l|
>
<l.Item
@key="item-1"
>
Item 1
</l.Item>
<l.Item @key="item-2">Item 2</l.Item>
<l.Item @key="item-3">Item 3</l.Item>
<l.Item @key="item-4">Item 4</l.Item>
<l.Item @key="item-5">
Item 5
</l.Item>
</NativeSelect>`
);

assert.dom('[data-test-id="native-select"]').exists();
assert.dom('[data-key="item-1"]').exists();
assert.dom('[data-key="item-2"]').exists();
assert.dom('[data-key="item-3"]').exists();
assert.dom('[data-key="item-4"]').exists();
assert.dom('[data-key="item-5"]').exists();

assert.dom('[data-key="item-3"]').hasAttribute('disabled');
assert.dom('[data-key="item-4"]').hasAttribute('disabled');

assert.dom('[data-key="item-1"]').containsText('Item 1');
assert.dom('[data-key="item-2"]').containsText('Item 2');
assert.dom('[data-key="item-3"]').containsText('Item 3');
assert.dom('[data-key="item-4"]').containsText('Item 4');
assert.dom('[data-key="item-5"]').containsText('Item 5');

isNotSelected(assert, '[data-key="item-2"]');

await selectNativeOptionByKey('[data-test-id="native-select"]', 'item-2');

assert.deepEqual(selectedKeys, ['item-2']);
isSelected(assert, '[data-key="item-2"]');
});

test('it render dynamic items without yield of item selectionMode = single / multiple', async function (assert) {
this.set('selectionMode', 'single');
this.set('allowEmpty', false);
this.set('animals', ['cheetah', 'crocodile', 'elephant']);
let selectedKeys: string[] = [];

this.set('selectedKeys', []);
this.set('onSelectionChange', (keys: string[]) => {
this.set('selectedKeys', keys);
selectedKeys = keys;
});

await render(
hbs`
<NativeSelect
@allowEmpty={{this.allowEmpty}}
@selectionMode={{this.selectionMode}}
@items={{this.animals}}
@selectedKeys={{this.selectedKeys}}
@onSelectionChange={{this.onSelectionChange}}
/>`
);

assert.dom('[data-test-id="native-select"]').exists();

assert.dom('[data-key="cheetah"]').exists();
assert.dom('[data-key="crocodile"]').exists();
assert.dom('[data-key="elephant"]').exists();

// Selection Mode single
await selectNativeOptionByKey(
'[data-test-id="native-select"]',
'cheetah'
);

assert.equal(selectedKeys.length, 1);
assert.equal(selectedKeys[0], 'cheetah');

await selectNativeOptionByKey(
'[data-test-id="native-select"]',
'crocodile'
);
assert.equal(selectedKeys.length, 1);
assert.equal(selectedKeys[0], 'crocodile');

// Slect empty option when allowEmpty = true
this.set('allowEmpty', true);
await selectNativeOptionByKey('[data-test-id="native-select"]', '');
assert.equal(selectedKeys.length, 0);

// Selection Mode multiple
this.set('selectionMode', 'multiple');
this.set('selectedKeys', []);
selectedKeys = [];

await selectNativeOptionByKey(
'[data-test-id="native-select"]',
'elephant'
);

assert.equal(selectedKeys.length, 1);
assert.equal(selectedKeys[0], 'elephant');

await selectNativeOptionByKey(
'[data-test-id="native-select"]',
'crocodile'
);
assert.equal(selectedKeys.length, 2);

assert.ok(selectedKeys.includes('elephant'));
assert.ok(selectedKeys.includes('crocodile'));

await toggleNativeOptionByKey(
'[data-test-id="native-select"]',
'crocodile'
);

assert.equal(selectedKeys.length, 1);
assert.equal(selectedKeys[0], 'elephant');

await click('[data-key="elephant"]');
await toggleNativeOptionByKey(
'[data-test-id="native-select"]',
'elephant'
);

assert.equal(selectedKeys.length, 0);
});

test('it render dynamic items yielding of item', async function (assert) {
this.set('selectionMode', 'single');
this.set('allowEmpty', false);
this.set('animals', [
{ key: 'cheetah-key', value: 'cheetah-value' },
{ key: 'crocodile-key', value: 'crocodile-value' },
{ key: 'elephant-key', value: 'elephant-value' }
]);

this.set('selectedKeys', []);
this.set('onSelectionChange', (keys: string[]) => {
this.set('selectedKeys', keys);
});

await render(
hbs`
<NativeSelect
@allowEmpty={{this.allowEmpty}}
@selectionMode={{this.selectionMode}}
@items={{this.animals}}
@selectedKeys={{this.selectedKeys}}
@onSelectionChange={{this.onSelectionChange}}
>
<:item as |o|>
<o.Item @key={{o.item.key}}>
{{o.item.value}}
</o.Item>
</:item>
</NativeSelect>`
);

assert.dom('[data-test-id="native-select"]').exists();

assert.dom('[data-key="cheetah-key"]').exists();
assert.dom('[data-key="crocodile-key"]').exists();
assert.dom('[data-key="elephant-key"]').exists();

assert.dom('[data-key="cheetah-key"]').containsText('cheetah-value');
assert.dom('[data-key="crocodile-key"]').containsText('crocodile-value');
assert.dom('[data-key="elephant-key"]').containsText('elephant-value');
});
}
);

0 comments on commit 20f5870

Please sign in to comment.