170 lines
7.2 KiB
JavaScript
170 lines
7.2 KiB
JavaScript
/* eslint-disable lit-a11y/no-autofocus */
|
|
import { expect, fixture as _fixture, html, waitUntil } from '@open-wc/testing';
|
|
import { sendKeys } from '@web/test-runner-commands';
|
|
|
|
import '@lion/ui/define/lion-button.js';
|
|
import '@lion/ui/define/lion-combobox.js';
|
|
import '@lion/ui/define/lion-select-rich.js';
|
|
import '@lion/ui/define/lion-option.js';
|
|
import '@lion/ui/define/lion-dialog.js';
|
|
import '@lion/ui/define/lion-tooltip.js';
|
|
|
|
import { mimicUserTyping } from '@lion/ui/combobox-test-helpers.js';
|
|
import sinon from 'sinon';
|
|
|
|
/**
|
|
* @typedef {import('../src/LionDialog.js').LionDialog} LionDialog
|
|
* @typedef {import('lit').TemplateResult} TemplateResult
|
|
*/
|
|
const fixture = /** @type {(arg: TemplateResult) => Promise<LionDialog>} */ (_fixture);
|
|
|
|
const dropDownEntries = ['Apple', 'Banana'];
|
|
|
|
describe('lion-dialog', () => {
|
|
describe('lion-combobox integration', () => {
|
|
it('should close lion-combobox dropdown on Escape and should not close the parent lion-dialog', async () => {
|
|
const el = await fixture(html`
|
|
<lion-dialog has-close-button>
|
|
<lion-button slot="invoker">Open Dialog</lion-button>
|
|
<div slot="header">Combobox example</div>
|
|
<div slot="content">
|
|
<lion-combobox name="combo" label="Select a fruit">
|
|
${dropDownEntries.map(
|
|
(/** @type { string } */ entry) =>
|
|
html` <lion-option .choiceValue="${entry}">${entry}</lion-option>`,
|
|
)}
|
|
</lion-combobox>
|
|
</div>
|
|
</lion-dialog>
|
|
`);
|
|
const dialogInvoker = /** @type {HTMLElement} */ (el.querySelector('[slot="invoker"]'));
|
|
dialogInvoker.click();
|
|
const combobox = /** @type {HTMLElement} */ el.querySelector('lion-combobox');
|
|
const isComboboxRendered = () => !!combobox?.shadowRoot?.childNodes.length;
|
|
await waitUntil(isComboboxRendered);
|
|
// @ts-ignore
|
|
await mimicUserTyping(combobox, 'a');
|
|
const firstOption = /** @type { HTMLElement | undefined } */ (
|
|
el.querySelectorAll('lion-option')?.[0]
|
|
);
|
|
// @ts-ignore
|
|
const isComboboxFirstOptionInDropdownVisible = () => firstOption?.checkVisibility();
|
|
await waitUntil(isComboboxFirstOptionInDropdownVisible);
|
|
const comboboxDialog = combobox?.shadowRoot?.querySelector('dialog');
|
|
// Note, do not remove `console.log` down below. There is a bug in test engine.
|
|
// Referring dialog.close from the test environement fixes the bug
|
|
console.log(sinon.spy(comboboxDialog?.close));
|
|
const comboboxInput = combobox?.querySelector('input');
|
|
comboboxInput?.focus();
|
|
const dropdownDialog = combobox?.shadowRoot?.querySelector('dialog');
|
|
// @ts-ignore
|
|
const dropdownDialogCloseSpy = sinon.spy(dropdownDialog, 'close');
|
|
await sendKeys({
|
|
press: 'Escape',
|
|
});
|
|
// @ts-ignore
|
|
const isDialogVisible = () => el?.shadowRoot?.querySelector('dialog')?.checkVisibility();
|
|
await waitUntil(() => dropdownDialogCloseSpy.called);
|
|
expect(isDialogVisible()).to.equal(true);
|
|
});
|
|
});
|
|
|
|
describe('lion-select-rich integration', () => {
|
|
it('should close lion-select-rich dropdown on Escape and should not close the parent lion-dialog', async () => {
|
|
const el = await fixture(html`
|
|
<lion-dialog has-close-button>
|
|
<lion-button slot="invoker">Open Dialog</lion-button>
|
|
<div slot="header">Select rich example</div>
|
|
<div slot="content">
|
|
<lion-select-rich label="Select a fruit">
|
|
${dropDownEntries.map(
|
|
(/** @type { string } */ entry) =>
|
|
html` <lion-option .choiceValue="${entry}">${entry}</lion-option>`,
|
|
)}
|
|
</lion-select-rich>
|
|
</div>
|
|
</lion-dialog>
|
|
`);
|
|
const dialogInvoker = /** @type {HTMLElement} */ (el.querySelector('[slot="invoker"]'));
|
|
dialogInvoker.click();
|
|
const selectRichInvoker = /** @type {HTMLElement} */ (
|
|
el.querySelector('lion-select-invoker')
|
|
);
|
|
const isSelectRichInvokerRendered = () => !!selectRichInvoker?.shadowRoot?.childNodes.length;
|
|
await waitUntil(isSelectRichInvokerRendered);
|
|
const selectRich = el?.querySelector('lion-select-rich');
|
|
const selectRichDialog = selectRich?.shadowRoot?.querySelector('dialog');
|
|
// Note, do not remove `console.log` down below. There is a bug in test engine.
|
|
// Referring dialog.close from the test environement fixes the bug
|
|
console.log(selectRichDialog?.close);
|
|
|
|
selectRichInvoker?.click();
|
|
const dropdownDialog = el
|
|
?.querySelector('lion-select-rich')
|
|
?.shadowRoot?.querySelector('dialog');
|
|
// @ts-ignore
|
|
const dropdownDialogCloseSpy = sinon.spy(dropdownDialog, 'close');
|
|
const isDropdownVisible = () =>
|
|
el
|
|
?.querySelector('lion-select-rich')
|
|
?.shadowRoot?.querySelector('dialog')
|
|
// @ts-ignore
|
|
?.checkVisibility();
|
|
await waitUntil(isDropdownVisible);
|
|
const lionOptions = /** @type {HTMLElement} */ (el.querySelector('lion-options'));
|
|
lionOptions?.focus();
|
|
await sendKeys({
|
|
press: 'Escape',
|
|
});
|
|
// @ts-ignore
|
|
const isDialogVisible = () => el?.shadowRoot?.querySelector('dialog')?.checkVisibility();
|
|
await waitUntil(() => dropdownDialogCloseSpy.called);
|
|
expect(isDialogVisible()).to.equal(true);
|
|
});
|
|
});
|
|
|
|
describe('lion-tooltip integration', () => {
|
|
it('should close lion-tooltip on first Escape and should close the parent lion-dialog on the second Escape', async () => {
|
|
const el = await fixture(html`
|
|
<lion-dialog has-close-button>
|
|
<lion-button slot="invoker" class="dialog-invoker">Open Dialog</lion-button>
|
|
<div slot="header">Tooltip example</div>
|
|
<div slot="content">
|
|
<lion-tooltip has-arrow>
|
|
<button slot="invoker" class="demo-tooltip-invoker">Focus on me</button>
|
|
<div slot="content">This is a tooltip</div>
|
|
</lion-tooltip>
|
|
</div>
|
|
</lion-dialog>
|
|
`);
|
|
|
|
await el.updateComplete;
|
|
const dialogInvoker = /** @type {HTMLElement} */ (el.querySelector('.dialog-invoker'));
|
|
dialogInvoker.click();
|
|
const tooltip = /** @type {HTMLElement} */ el.querySelector('lion-tooltip');
|
|
const isTooltipRendered = () => !!tooltip?.shadowRoot?.childNodes.length;
|
|
await waitUntil(isTooltipRendered);
|
|
const tooltipButton = /** @type {HTMLElement} */ (el.querySelector('.demo-tooltip-invoker'));
|
|
tooltipButton?.focus();
|
|
const getTooltipContent = () =>
|
|
el
|
|
.querySelector('lion-tooltip')
|
|
?.shadowRoot?.querySelector('#overlay-content-node-wrapper');
|
|
// @ts-ignore
|
|
const isTooltipContentVisible = () => getTooltipContent()?.checkVisibility();
|
|
await waitUntil(isTooltipContentVisible);
|
|
await sendKeys({
|
|
press: 'Escape',
|
|
});
|
|
// @ts-ignore
|
|
const isDialogVisible = () => el?.shadowRoot?.querySelector('dialog')?.checkVisibility();
|
|
expect(isTooltipContentVisible()).to.equal(false);
|
|
expect(isDialogVisible()).to.equal(true);
|
|
await sendKeys({
|
|
press: 'Escape',
|
|
});
|
|
expect(isTooltipContentVisible()).to.equal(false);
|
|
expect(isDialogVisible()).to.equal(false);
|
|
});
|
|
});
|
|
});
|