From 871344a2043c05ce51045ed85f0c0e5189e95769 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Wed, 9 Oct 2024 21:39:59 -0700 Subject: [PATCH] fix(notice): ensure closed notice does not affect layout (#10518) --- .../src/components/notice/notice.e2e.ts | 4 ++- .../src/components/notice/notice.scss | 2 ++ .../src/tests/commonTests/openClose.ts | 34 ++++++++++++++++--- .../src/tests/commonTests/themed.ts | 8 ++--- .../calcite-components/src/tests/utils.ts | 16 ++++++++- 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/packages/calcite-components/src/components/notice/notice.e2e.ts b/packages/calcite-components/src/components/notice/notice.e2e.ts index 5e63c1ef2e8..4965aafa08c 100644 --- a/packages/calcite-components/src/components/notice/notice.e2e.ts +++ b/packages/calcite-components/src/components/notice/notice.e2e.ts @@ -36,7 +36,9 @@ describe("calcite-notice", () => { }); describe("openClose", () => { - openClose("calcite-notice"); + openClose("calcite-notice", { + collapsedOnClose: "vertical", + }); }); describe("slots", () => { diff --git a/packages/calcite-components/src/components/notice/notice.scss b/packages/calcite-components/src/components/notice/notice.scss index 8d55050d3f5..6343992b784 100644 --- a/packages/calcite-components/src/components/notice/notice.scss +++ b/packages/calcite-components/src/components/notice/notice.scss @@ -78,6 +78,7 @@ flex w-full opacity-0; + overflow: hidden; max-block-size: 0; transition-property: opacity, max-block-size; transition-duration: var(--calcite-animation-timing); @@ -104,6 +105,7 @@ max-h-full items-center opacity-100; + overflow: visible; } @include slotted("title", "*", ".container") { diff --git a/packages/calcite-components/src/tests/commonTests/openClose.ts b/packages/calcite-components/src/tests/commonTests/openClose.ts index 566e7cfda23..edba09338c1 100644 --- a/packages/calcite-components/src/tests/commonTests/openClose.ts +++ b/packages/calcite-components/src/tests/commonTests/openClose.ts @@ -1,12 +1,19 @@ import { E2EPage } from "@stencil/core/testing"; import { toHaveNoViolations } from "jest-axe"; -import { GlobalTestProps, newProgrammaticE2EPage } from "../utils"; +import { GlobalTestProps, newProgrammaticE2EPage, toElementHandle } from "../utils"; import { getBeforeContent, getTagAndPage, noopBeforeContent } from "./utils"; import { ComponentTag, ComponentTestSetup, WithBeforeContent } from "./interfaces"; expect.extend(toHaveNoViolations); +type CollapseAxis = "horizontal" | "vertical"; + interface OpenCloseOptions { + /** + * When specified, testing will assert that the component is collapsed (does not affect layout) along the specified axis when closed. + */ + collapsedOnClose?: CollapseAxis; + /** * Toggle property to test. Currently, either "open" or "expanded". */ @@ -54,10 +61,11 @@ export function openClose(componentTestSetup: ComponentTestSetup, options?: Open await setUpEventListeners(tag, page); await testOpenCloseEvents({ - tag, - page, - openPropName: effectiveOptions.openPropName, animationsEnabled: !effectiveOptions.willUseFallback, + collapsedOnClose: effectiveOptions.collapsedOnClose, + openPropName: effectiveOptions.openPropName, + page, + tag, }); }); @@ -69,6 +77,7 @@ export function openClose(componentTestSetup: ComponentTestSetup, options?: Open await setUpEventListeners(tag, page); await testOpenCloseEvents({ animationsEnabled: false, + collapsedOnClose: effectiveOptions.collapsedOnClose, openPropName: effectiveOptions.openPropName, page, tag, @@ -149,6 +158,11 @@ interface TestOpenCloseEventsParams { */ startOpen?: boolean; + /** + * Whether the component should be collapsed (does not affect layout) along the specified axis when closed. + */ + collapsedOnClose?: CollapseAxis; + /** * Whether animations are enabled. */ @@ -159,6 +173,7 @@ async function testOpenCloseEvents({ animationsEnabled, openPropName, page, + collapsedOnClose, startOpen = false, tag, }: TestOpenCloseEventsParams): Promise { @@ -222,6 +237,17 @@ async function testOpenCloseEvents({ assertEventSequence([1, 1, 1, 1]); + if (collapsedOnClose !== undefined) { + const elementHandle = await toElementHandle(element); + const boundingBox = await elementHandle.boundingBox(); + const horizontalCollapse = collapsedOnClose === "horizontal"; + const dimension = horizontalCollapse ? "width" : "height"; + const scrollDimension = horizontalCollapse ? "scrollWidth" : "scrollHeight"; + + expect(boundingBox[dimension]).toBe(0); + expect(await elementHandle.evaluate((el, scrollDimension) => el[scrollDimension], scrollDimension)).toBe(0); + } + expect(await page.evaluate(() => (window as EventOrderWindow).events)).toEqual(eventSequence); const delayDeltaThreshold = 100; // smallest internal animation timing used diff --git a/packages/calcite-components/src/tests/commonTests/themed.ts b/packages/calcite-components/src/tests/commonTests/themed.ts index 5667ec25a84..d99ebcdbd9b 100644 --- a/packages/calcite-components/src/tests/commonTests/themed.ts +++ b/packages/calcite-components/src/tests/commonTests/themed.ts @@ -1,8 +1,8 @@ import { E2EElement, E2EPage } from "@stencil/core/testing"; import { toHaveNoViolations } from "jest-axe"; -import { ElementHandle } from "puppeteer"; import type { RequireExactlyOne } from "type-fest"; import { getTokenValue } from "../utils/cssTokenValues"; +import { toElementHandle } from "../utils"; import type { ComponentTestSetup } from "./interfaces"; import { getTagAndPage } from "./utils"; @@ -266,11 +266,9 @@ async function getComputedStylePropertyValue( property: string, pseudoElement?: string, ): Promise { - type E2EElementInternal = E2EElement & { - _elmHandle: ElementHandle; - }; + const elementHandle = await toElementHandle(element); - return await (element as E2EElementInternal)._elmHandle.evaluate( + return await elementHandle.evaluate( (el, targetProp, pseudoElement): string => window.getComputedStyle(el, pseudoElement).getPropertyValue(targetProp), property, pseudoElement, diff --git a/packages/calcite-components/src/tests/utils.ts b/packages/calcite-components/src/tests/utils.ts index e0de51cb882..c64fff61c50 100644 --- a/packages/calcite-components/src/tests/utils.ts +++ b/packages/calcite-components/src/tests/utils.ts @@ -1,5 +1,5 @@ import { E2EElement, E2EPage, newE2EPage } from "@stencil/core/testing"; -import { BoundingBox } from "puppeteer"; +import { BoundingBox, ElementHandle } from "puppeteer"; import type { JSX } from "../components"; import { ComponentTag } from "./commonTests/interfaces"; @@ -527,3 +527,17 @@ export async function assertCaretPosition({ ), ).toBeTruthy(); } + +/** + * This utils helps to get the element handle from an E2EElement. + * + * @param element - the E2E element + * @returns {Promise} - the element handle + */ +export async function toElementHandle(element: E2EElement): Promise { + type E2EElementInternal = E2EElement & { + _elmHandle: ElementHandle; + }; + + return (element as E2EElementInternal)._elmHandle; +}