|
1 | 1 | /* eslint-disable lit-a11y/no-autofocus */ |
2 | | -import { expect, fixture as _fixture, html, unsafeStatic, aTimeout } from '@open-wc/testing'; |
| 2 | +import { |
| 3 | + expect, |
| 4 | + fixture as _fixture, |
| 5 | + html, |
| 6 | + unsafeStatic, |
| 7 | + aTimeout, |
| 8 | + defineCE, |
| 9 | + waitUntil, |
| 10 | +} from '@open-wc/testing'; |
| 11 | +import { cache } from 'lit/directives/cache.js'; |
| 12 | +import { LitElement, nothing } from 'lit'; |
3 | 13 | import { runOverlayMixinSuite } from '../../overlays/test-suites/OverlayMixin.suite.js'; |
4 | 14 | import { isActiveElement } from '../../core/test-helpers/isActiveElement.js'; |
5 | 15 | import '../test-helpers/test-router.js'; |
6 | 16 | import '@lion/ui/define/lion-dialog.js'; |
| 17 | +import '@lion/ui/define/lion-tabs.js'; |
7 | 18 |
|
8 | 19 | /** |
9 | 20 | * @typedef {import('../src/LionDialog.js').LionDialog} LionDialog |
@@ -296,5 +307,107 @@ describe('lion-dialog', () => { |
296 | 307 | await dialogAfterRouteChange._overlayCtrl._showComplete; |
297 | 308 | expect(dialogAfterRouteChange.opened).to.be.true; |
298 | 309 | }); |
| 310 | + |
| 311 | + it('should close the popup dialog after rendered from cache', async () => { |
| 312 | + /** |
| 313 | + * |
| 314 | + * @param {Event} e |
| 315 | + * @returns |
| 316 | + */ |
| 317 | + const closeButtonHandler = e => |
| 318 | + e.target?.dispatchEvent(new Event('close-overlay', { bubbles: true })); |
| 319 | + const dialog = html` <lion-dialog> |
| 320 | + <button slot="invoker" class="invoker-button">Click me to open dialog</button> |
| 321 | + <div slot="content" class="demo-dialog-content"> |
| 322 | + Hello! You can close this dialog here: |
| 323 | + <button class="close-button" @click="${closeButtonHandler}">⨯</button> |
| 324 | + </div> |
| 325 | + </lion-dialog>`; |
| 326 | + |
| 327 | + /** |
| 328 | + * Note, inactive tab content is **destroyed** on every tab switch. |
| 329 | + */ |
| 330 | + class Wrapper extends LitElement { |
| 331 | + static properties = { |
| 332 | + ...super.properties, |
| 333 | + activeTabIndex: { type: Number }, |
| 334 | + }; |
| 335 | + |
| 336 | + constructor() { |
| 337 | + super(); |
| 338 | + this.activeTabIndex = 0; |
| 339 | + } |
| 340 | + |
| 341 | + /** |
| 342 | + * @param {number} index |
| 343 | + */ |
| 344 | + changeActiveTabIndex(index) { |
| 345 | + this.activeTabIndex = index; |
| 346 | + } |
| 347 | + |
| 348 | + render() { |
| 349 | + const changeActiveTabIndexRef = this.changeActiveTabIndex.bind(this); |
| 350 | + return html` |
| 351 | + <lion-tabs> |
| 352 | + <button slot="tab" class="first-button" @click=${() => changeActiveTabIndexRef(0)}> |
| 353 | + First |
| 354 | + </button> |
| 355 | + <p slot="panel">${cache(this.activeTabIndex === 0 ? dialog : nothing)}</p> |
| 356 | + <button slot="tab" class="second-button" @click=${() => changeActiveTabIndexRef(1)}> |
| 357 | + Second |
| 358 | + </button> |
| 359 | + <p slot="panel">Info page with lots of information about us.</p> |
| 360 | + </lion-tabs> |
| 361 | + `; |
| 362 | + } |
| 363 | + } |
| 364 | + |
| 365 | + const wrapperFixture = /** @type {(arg: TemplateResult) => Promise<Wrapper>} */ (_fixture); |
| 366 | + const tagString = defineCE(Wrapper); |
| 367 | + const wrapperTag = unsafeStatic(tagString); |
| 368 | + const wrapperElement = /** @type {Wrapper} */ ( |
| 369 | + await wrapperFixture(html`<${wrapperTag}></${wrapperTag}>`) |
| 370 | + ); |
| 371 | + await wrapperElement.updateComplete; |
| 372 | + const wrapperElementShadowRoot = wrapperElement.shadowRoot; |
| 373 | + /** |
| 374 | + * @returns { HTMLElement | null | undefined } |
| 375 | + */ |
| 376 | + const getFirstButton = () => wrapperElementShadowRoot?.querySelector('.first-button'); |
| 377 | + /** |
| 378 | + * @returns { HTMLElement | null | undefined } |
| 379 | + */ |
| 380 | + const getSecondButton = () => wrapperElementShadowRoot?.querySelector('.second-button'); |
| 381 | + /** |
| 382 | + * @returns { HTMLElement | null | undefined } |
| 383 | + */ |
| 384 | + const getInvokerButton = () => wrapperElementShadowRoot?.querySelector('.invoker-button'); |
| 385 | + /** |
| 386 | + * @returns { HTMLElement | null | undefined } |
| 387 | + */ |
| 388 | + const getCloseButton = () => wrapperElementShadowRoot?.querySelector('.close-button'); |
| 389 | + /** |
| 390 | + * @returns { Element | null | undefined } |
| 391 | + */ |
| 392 | + const getDialog = () => |
| 393 | + wrapperElementShadowRoot?.querySelector('lion-dialog')?.shadowRoot?.querySelector('dialog'); |
| 394 | + // @ts-ignore |
| 395 | + const isDialogVisible = () => getDialog()?.checkVisibility() === true; |
| 396 | + const isDialogRendered = () => |
| 397 | + !!wrapperElement.shadowRoot?.querySelector('lion-dialog')?.shadowRoot?.childNodes.length; |
| 398 | + getInvokerButton()?.click(); |
| 399 | + await waitUntil(isDialogVisible); |
| 400 | + getCloseButton()?.click(); |
| 401 | + await waitUntil(() => !isDialogVisible()); |
| 402 | + getSecondButton()?.click(); |
| 403 | + await waitUntil(() => !isDialogRendered()); |
| 404 | + getFirstButton()?.click(); |
| 405 | + await waitUntil(isDialogRendered); |
| 406 | + getInvokerButton()?.click(); |
| 407 | + await waitUntil(isDialogVisible); |
| 408 | + getCloseButton()?.click(); |
| 409 | + await waitUntil(() => !isDialogVisible()); |
| 410 | + expect(isDialogVisible()).to.equal(false); |
| 411 | + }); |
299 | 412 | }); |
300 | 413 | }); |
0 commit comments