From c67df8c630b988a722e36ecb8dd6884823c8f9a1 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Thu, 15 May 2025 14:37:42 -0700 Subject: [PATCH 01/49] chore: drop waitForChanges delay --- packages/calcite-components/vite.config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/calcite-components/vite.config.ts b/packages/calcite-components/vite.config.ts index 43d09ef7300..1c707cb73e6 100644 --- a/packages/calcite-components/vite.config.ts +++ b/packages/calcite-components/vite.config.ts @@ -54,7 +54,6 @@ export default defineConfig({ }, puppeteerTesting: { enabled: !runBrowserTests, - waitForChangesDelay: 100, launchOptions: { devtools: process.env.DEVTOOLS === "true", headless: process.env.HEADLESS === "false" ? false : undefined, From 299b34587766d20498af43d1f7af10ce6777c58a Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 16 May 2025 13:39:23 -0700 Subject: [PATCH 02/49] fix: ensure transition-duration is used in Tailwind utils --- .../accordion-item/accordion-item.scss | 4 +-- .../src/components/action/action.scss | 2 -- .../src/components/block/block.scss | 2 -- .../src/components/chip/chip.scss | 2 +- .../color-picker-swatch.scss | 2 +- .../combobox-item/combobox-item.scss | 1 - .../date-picker-month-header.scss | 6 ++--- .../dropdown-item/dropdown-item.scss | 3 +-- .../src/components/meter/meter.scss | 2 +- .../components/stepper-item/stepper-item.scss | 4 +-- .../src/components/switch/switch.scss | 1 - .../components/tile-select/tile-select.scss | 3 --- .../calcite-components/tailwind.config.ts | 8 +++++- packages/calcite-tailwind-preset/src/index.ts | 26 +++++++++++-------- 14 files changed, 32 insertions(+), 34 deletions(-) diff --git a/packages/calcite-components/src/components/accordion-item/accordion-item.scss b/packages/calcite-components/src/components/accordion-item/accordion-item.scss index e5628836702..7dc65ba574f 100644 --- a/packages/calcite-components/src/components/accordion-item/accordion-item.scss +++ b/packages/calcite-components/src/components/accordion-item/accordion-item.scss @@ -137,7 +137,6 @@ .actions-end { @apply flex items-center - duration-150 ease-in-out; @include word-break(); } @@ -192,8 +191,7 @@ } .icon { - @apply duration-150 - ease-in-out + @apply ease-in-out flex items-center; margin-inline-end: var(--calcite-internal-accordion-item-icon-spacing-start); diff --git a/packages/calcite-components/src/components/action/action.scss b/packages/calcite-components/src/components/action/action.scss index 6930832d09d..a6fd65a46df 100755 --- a/packages/calcite-components/src/components/action/action.scss +++ b/packages/calcite-components/src/components/action/action.scss @@ -116,7 +116,6 @@ leading-6 opacity-0 transition-opacity - duration-150 ease-in-out; transition-property: margin; @@ -173,7 +172,6 @@ .button { @apply bg-transparent transition-shadow - duration-150 ease-in-out; &:hover { diff --git a/packages/calcite-components/src/components/block/block.scss b/packages/calcite-components/src/components/block/block.scss index 534c7a0cf0a..d209fa013e0 100644 --- a/packages/calcite-components/src/components/block/block.scss +++ b/packages/calcite-components/src/components/block/block.scss @@ -121,7 +121,6 @@ calcite-handle { transition-color font-medium leading-tight - duration-150 ease-in-out p-0; @@ -171,7 +170,6 @@ calcite-handle { @apply transition-color self-center justify-self-end - duration-150 ease-in-out; margin-inline-end: var(--calcite-spacing-md); diff --git a/packages/calcite-components/src/components/chip/chip.scss b/packages/calcite-components/src/components/chip/chip.scss index f56e1df6993..60ce9b617b0 100644 --- a/packages/calcite-components/src/components/chip/chip.scss +++ b/packages/calcite-components/src/components/chip/chip.scss @@ -415,7 +415,7 @@ } .chip-icon { - @apply relative my-0 inline-flex duration-150 ease-in-out; + @apply relative my-0 inline-flex ease-in-out; color: var(--calcite-chip-icon-color, var(--calcite-chip-text-color, var(--calcite-icon-color, currentColor))); padding-inline: var(--calcite-internal-chip-icon-space, var(--calcite-spacing-xs, 0.375rem) /* 6px */); } diff --git a/packages/calcite-components/src/components/color-picker-swatch/color-picker-swatch.scss b/packages/calcite-components/src/components/color-picker-swatch/color-picker-swatch.scss index 531bcc3d898..ca54899fe1d 100644 --- a/packages/calcite-components/src/components/color-picker-swatch/color-picker-swatch.scss +++ b/packages/calcite-components/src/components/color-picker-swatch/color-picker-swatch.scss @@ -24,7 +24,7 @@ $size-l: 28px; inline-size: inherit; rect { - @apply transition-all duration-150 ease-in-out; + @apply transition-all ease-in-out; } } diff --git a/packages/calcite-components/src/components/combobox-item/combobox-item.scss b/packages/calcite-components/src/components/combobox-item/combobox-item.scss index 51d68826869..80eea4cbf10 100644 --- a/packages/calcite-components/src/components/combobox-item/combobox-item.scss +++ b/packages/calcite-components/src/components/combobox-item/combobox-item.scss @@ -115,7 +115,6 @@ ul:focus { .icon { @apply inline-flex - duration-150 ease-in-out; color: var(--calcite-color-border-input); diff --git a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss index d912aec38a5..286b3c856d6 100644 --- a/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss +++ b/packages/calcite-components/src/components/date-picker-month-header/date-picker-month-header.scss @@ -57,8 +57,8 @@ items-center justify-center border-none - transition-default - w-full + transition-default + w-full h-full; --calcite-internal-action-padding-block: 0; --calcite-action-background-color: var(--calcite-date-picker-header-action-background-color); @@ -117,7 +117,7 @@ text-center; inline-size: #{$calcite-size-44}; &:hover { - @apply duration-100 ease-in-out; + @apply ease-in-out; transition-property: outline-color; outline: 2px solid var(--calcite-color-border-2); outline-offset: -2px; diff --git a/packages/calcite-components/src/components/dropdown-item/dropdown-item.scss b/packages/calcite-components/src/components/dropdown-item/dropdown-item.scss index 00a69227776..e85c35dc706 100644 --- a/packages/calcite-components/src/components/dropdown-item/dropdown-item.scss +++ b/packages/calcite-components/src/components/dropdown-item/dropdown-item.scss @@ -5,7 +5,7 @@ * * @prop --calcite-dropdown-item-background-color-hover: Specifies the item's background color when hovered. * @prop --calcite-dropdown-item-background-color-press: Specifies the item's background color when selected or active. - * @prop --calcite-dropdown-item-icon-color-hover: [Deprecated] Specifies the item's icon selection color when hovered. + * @prop --calcite-dropdown-item-icon-color-hover: [Deprecated] Specifies the item's icon selection color when hovered. * @prop --calcite-dropdown-item-icon-color-press: Specifies the item's icon selection color when selected or active. * @prop --calcite-dropdown-item-text-color-press: Specifies the item's text when selected or active. * @prop --calcite-dropdown-item-text-color: Specifies the item's text color. @@ -48,7 +48,6 @@ .dropdown-item-icon { @apply relative opacity-0 - duration-150 ease-in-out; transform: scale(0.9); } diff --git a/packages/calcite-components/src/components/meter/meter.scss b/packages/calcite-components/src/components/meter/meter.scss index 6e223ac5974..84278b8508c 100644 --- a/packages/calcite-components/src/components/meter/meter.scss +++ b/packages/calcite-components/src/components/meter/meter.scss @@ -132,7 +132,7 @@ } .fill { - @apply block absolute duration-150 ease-in-out z-default; + @apply block absolute ease-in-out z-default; inset-inline-start: var(--calcite-internal-meter-space); inset-block: var(--calcite-internal-meter-space); border-radius: var(--calcite-internal-meter-corner-radius); diff --git a/packages/calcite-components/src/components/stepper-item/stepper-item.scss b/packages/calcite-components/src/components/stepper-item/stepper-item.scss index cf1e9806e3c..db5ffcc98a3 100644 --- a/packages/calcite-components/src/components/stepper-item/stepper-item.scss +++ b/packages/calcite-components/src/components/stepper-item/stepper-item.scss @@ -294,12 +294,12 @@ border-color: var(--calcite-stepper-bar-fill-color, var(--calcite-color-border-3)); &:focus { - @apply focus-outset duration-0; + @apply focus-outset; } } .stepper-item-content { - @apply cursor-auto duration-150 ease-in-out; + @apply cursor-auto ease-in-out; padding-block: 0; padding-inline-end: var(--calcite-internal-stepper-item-spacing-unit-m); text-align: start; diff --git a/packages/calcite-components/src/components/switch/switch.scss b/packages/calcite-components/src/components/switch/switch.scss index bf1fcb1ed24..bd80c3c03c1 100644 --- a/packages/calcite-components/src/components/switch/switch.scss +++ b/packages/calcite-components/src/components/switch/switch.scss @@ -91,7 +91,6 @@ absolute block transition-all - duration-150 ease-in-out; inset-block-start: var(--calcite-spacing-base); inset-inline: var(--calcite-spacing-base) auto; diff --git a/packages/calcite-components/src/components/tile-select/tile-select.scss b/packages/calcite-components/src/components/tile-select/tile-select.scss index 02c7d1482c0..061ba5b18cb 100644 --- a/packages/calcite-components/src/components/tile-select/tile-select.scss +++ b/packages/calcite-components/src/components/tile-select/tile-select.scss @@ -125,7 +125,6 @@ $spacing: $baseline * 0.5; .tile { @apply bg-foreground-1 box-border - duration-150 ease-in-out flex flex-col @@ -155,7 +154,6 @@ $spacing: $baseline * 0.5; .tile-heading { @apply break-words - duration-150 ease-in-out font-medium pointer-events-none @@ -165,7 +163,6 @@ $spacing: $baseline * 0.5; .tile-description { @apply break-words - duration-150 ease-in-out pointer-events-none text-color-3 diff --git a/packages/calcite-components/tailwind.config.ts b/packages/calcite-components/tailwind.config.ts index 717ac85af5f..07bf7afde80 100644 --- a/packages/calcite-components/tailwind.config.ts +++ b/packages/calcite-components/tailwind.config.ts @@ -1,6 +1,7 @@ +import type { Config } from "tailwindcss"; import calcitePreset from "@esri/calcite-tailwind-preset"; -export default { +const config: Config = { presets: [calcitePreset], content: ["./src/components/**/*.scss"], theme: { @@ -11,6 +12,11 @@ export default { "in-up": "in-up var(--calcite-internal-animation-timing-slow) ease-in-out", "in-scale": "in-scale var(--calcite-internal-animation-timing-slow) linear", }, + transitionDuration: { + DEFAULT: "var(--calcite-animation-timing)", + }, }, }, }; + +export default config; diff --git a/packages/calcite-tailwind-preset/src/index.ts b/packages/calcite-tailwind-preset/src/index.ts index ff24f9a0fd7..67b5d9021a5 100644 --- a/packages/calcite-tailwind-preset/src/index.ts +++ b/packages/calcite-tailwind-preset/src/index.ts @@ -1,3 +1,4 @@ +import type { Config } from "tailwindcss"; import flattenColorPalette from "tailwindcss/lib/util/flattenColorPalette"; import plugin from "tailwindcss/plugin"; @@ -23,9 +24,10 @@ function invert(value: string, flagPropName: string): string { )`; } -export default { +// we omit content to work around https://github.com/tailwindlabs/tailwindcss/issues/11725 (fixed in v4, but not v3) +const config: Omit = { theme: { - borderColor: ({ theme }): object => ({ + borderColor: ({ theme }) => ({ color: { 1: "var(--calcite-color-border-1)", 2: "var(--calcite-color-border-2)", @@ -133,7 +135,7 @@ export default { l: "1024px", xl: "1440px", }, - backgroundColor: ({ theme }): object => ({ + backgroundColor: ({ theme }) => ({ ...theme("colors.background"), transparent: theme("colors.transparent"), brand: theme("colors.brand"), @@ -168,39 +170,39 @@ export default { keyframes: { in: { "0%": { - opacity: 0, + opacity: "0", }, "100%": { - opacity: 1, + opacity: "1", }, }, "in-down": { "0%": { - opacity: 0, + opacity: "0", transform: "translate3D(0, -5px, 0)", }, "100%": { - opacity: 1, + opacity: "1", transform: "translate3D(0, 0, 0)", }, }, "in-up": { "0%": { - opacity: 0, + opacity: "0", transform: "translate3D(0, 5px, 0)", }, "100%": { - opacity: 1, + opacity: "1", transform: "translate3D(0, 0, 0)", }, }, "in-scale": { "0%": { - opacity: 0, + opacity: "0", transform: "scale3D(0.95, 0.95, 1)", }, "100%": { - opacity: 1, + opacity: "1", transform: "scale3D(1, 1, 1)", }, }, @@ -296,3 +298,5 @@ export default { }), ], }; + +export default config; From 00744e2f85890b23f0d11d618ef251eaa8759ce3 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 16 May 2025 16:45:39 -0700 Subject: [PATCH 03/49] remove redundant style --- packages/calcite-components/src/components/block/block.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/calcite-components/src/components/block/block.scss b/packages/calcite-components/src/components/block/block.scss index d209fa013e0..43fea417d4e 100644 --- a/packages/calcite-components/src/components/block/block.scss +++ b/packages/calcite-components/src/components/block/block.scss @@ -22,7 +22,6 @@ @apply transition-margin ease-cubic flex flex-shrink-0 flex-grow-0 flex-col border-0 border-b border-solid p-0; flex-basis: auto; - transition-duration: var(--calcite-animation-timing); border-color: var(--calcite-block-border-color, var(--calcite-color-border-3)); } From 5c11e13abc0ef024839d00f61e2457140dfb707b Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 16 May 2025 16:46:15 -0700 Subject: [PATCH 04/49] remove unnecessary delay that might trigger JSHandle disposed error --- packages/calcite-components/src/tests/commonTests/themed.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/calcite-components/src/tests/commonTests/themed.ts b/packages/calcite-components/src/tests/commonTests/themed.ts index 4939092e388..dd9e35a1057 100644 --- a/packages/calcite-components/src/tests/commonTests/themed.ts +++ b/packages/calcite-components/src/tests/commonTests/themed.ts @@ -330,8 +330,6 @@ async function assertThemedProps(page: E2EPage, options: TestTarget): Promise Date: Fri, 16 May 2025 16:46:47 -0700 Subject: [PATCH 05/49] minor util doc update --- packages/calcite-components/src/tests/commonTests/themed.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/calcite-components/src/tests/commonTests/themed.ts b/packages/calcite-components/src/tests/commonTests/themed.ts index dd9e35a1057..d90fc01d94c 100644 --- a/packages/calcite-components/src/tests/commonTests/themed.ts +++ b/packages/calcite-components/src/tests/commonTests/themed.ts @@ -181,7 +181,7 @@ type State = "press" | "hover" | "focus"; /** Describes a test target for themed components. */ type TestTarget = { - /** An object with target element and selector info. */ + /** An object with the target element and selector info. */ target: TargetInfo; /** The selector for the interaction's target element. */ From b0369c06271d3abeec1843a1c50a51f90e2f2689 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 16 May 2025 21:24:46 -0700 Subject: [PATCH 06/49] fix global styles test --- .../src/tests/globalStyles.e2e.ts | 65 +++++++++---------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/packages/calcite-components/src/tests/globalStyles.e2e.ts b/packages/calcite-components/src/tests/globalStyles.e2e.ts index 975274347d8..fb47543e102 100644 --- a/packages/calcite-components/src/tests/globalStyles.e2e.ts +++ b/packages/calcite-components/src/tests/globalStyles.e2e.ts @@ -1,15 +1,17 @@ import { newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; import { describe, expect, it } from "vitest"; import { html } from "../../support/formatting"; + describe("global styles", () => { describe("animation", () => { - const snippet = ` + const snippet = html`
Hello world
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna. -

+        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
+        magna.
       
`; + const globalClasses = [ "calcite-animate__in", "calcite-animate__in-down", @@ -17,30 +19,30 @@ describe("global styles", () => { "calcite-animate__in-left", "calcite-animate__in-right", "calcite-animate__in-scale", - ]; + ] as const; globalClasses.forEach((className) => { it(`should support rendering component with ${className} animation`, async () => { - const page = await newE2EPage({ html: snippet }); + const page = await newE2EPage(); + await page.setContent(snippet); const element = await page.find("calcite-notice"); - await element.setProperty("active", true); - await element.classList.add(className); + element.classList.add(className); await page.waitForChanges(); - const noticeAnimation = await page.evaluate(() => { - const noticeEl = document.querySelector("calcite-notice"); - if (!noticeEl) { - return null; - } - const { animationName, animationDuration, opacity } = window.getComputedStyle(noticeEl); + element.setProperty("active", true); + await page.waitForChanges(); + + const noticeAnimation = await page.$eval("calcite-notice", (noticeEl) => { + const { animationName: name, animationDuration: duration, opacity } = window.getComputedStyle(noticeEl); return { - name: animationName, - duration: animationDuration, - opacity: opacity, + name, + duration, + opacity, }; }); - expect(noticeAnimation?.duration).toEqual("0.15s"); - expect(noticeAnimation?.name).toEqual(className.slice(className.indexOf("_") + 2)); - expect(noticeAnimation?.opacity).not.toBe("0"); + + expect(noticeAnimation.duration).toEqual("0.15s"); + expect(noticeAnimation.name).toEqual(className.slice(className.indexOf("_") + 2)); + expect(noticeAnimation.opacity).not.toBe("0"); }); }); @@ -60,11 +62,8 @@ describe("global styles", () => { `, }); await page.waitForChanges(); - const eleTransitionDuration = await page.evaluate(() => { - const ele = document.querySelector("div"); - return ele ? window.getComputedStyle(ele).transitionDuration : null; - }); - expect(eleTransitionDuration).toEqual("0s"); + const elTransitionDuration = await page.$eval("div", (el) => window.getComputedStyle(el).transitionDuration); + expect(elTransitionDuration).toEqual("0s"); }); }); @@ -73,24 +72,18 @@ describe("global styles", () => { html: html`
`, }); await page.waitForChanges(); - await page.$eval("div", (element: any) => { - element.style.setProperty("--calcite-duration-factor", 0); + await page.$eval("div", (element) => { + element.style.setProperty("--calcite-duration-factor", "0"); }); - const eleTransitionDuration = await page.evaluate(() => { - const ele = document.querySelector("div"); - return ele ? window.getComputedStyle(ele).transitionDuration : null; - }); - expect(eleTransitionDuration).toEqual("0.15s"); + const elTransitionDuration = await page.$eval("div", (el) => window.getComputedStyle(el).transitionDuration); + expect(elTransitionDuration).toEqual("0.15s"); }); it("should set animation duration to default value 150ms", async () => { const page = await newE2EPage({ html: html`
`, }); - const eleTransitionDuration = await page.evaluate(() => { - const ele = document.querySelector("div"); - return ele ? window.getComputedStyle(ele).transitionDuration : null; - }); - expect(eleTransitionDuration).toEqual("0.15s"); + const elTransitionDuration = await page.$eval("div", (el) => window.getComputedStyle(el).transitionDuration); + expect(elTransitionDuration).toEqual("0.15s"); }); }); From ad71e26bcf6772557ce98e010e4d7a0dc703717b Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 16 May 2025 22:43:22 -0700 Subject: [PATCH 07/49] drop redundant button tests --- .../src/components/button/button.e2e.ts | 71 ------------------- 1 file changed, 71 deletions(-) diff --git a/packages/calcite-components/src/components/button/button.e2e.ts b/packages/calcite-components/src/components/button/button.e2e.ts index 925732807f3..7281b9b90f4 100644 --- a/packages/calcite-components/src/components/button/button.e2e.ts +++ b/packages/calcite-components/src/components/button/button.e2e.ts @@ -497,77 +497,6 @@ describe("calcite-button", () => { expect(elementAsButton).not.toHaveClass(CSS.contentSlotted); }); - describe("CSS properties for light/dark mode", () => { - const buttonSnippet = ` - - Layers - - `; - - it("should have defined CSS custom properties", async () => { - const page = await newE2EPage({ html: buttonSnippet }); - const buttonStyles = await page.evaluate(() => { - const buttonEl = document.querySelector("calcite-button"); - buttonEl.style.setProperty("--calcite-color-transparent-hover", "rgba(34, 23, 200, 0.4)"); - buttonEl.style.setProperty("--calcite-color-transparent-press", "rgba(1, 20, 44, 0.1"); - return { - hoverFocus: window.getComputedStyle(buttonEl).getPropertyValue("--calcite-color-transparent-hover"), - active: window.getComputedStyle(buttonEl).getPropertyValue("--calcite-color-transparent-press"), - }; - }); - expect(buttonStyles.hoverFocus).toEqual("rgba(34, 23, 200, 0.4)"); - expect(buttonStyles.active).toEqual("rgba(1, 20, 44, 0.1"); - }); - - describe("when mode attribute is not provided", () => { - it("should render button pseudo classes with default values tied to light mode", async () => { - const page = await newE2EPage({ html: buttonSnippet }); - const buttonEl = await page.find("calcite-button >>> button"); - await buttonEl.hover(); - await page.waitForChanges(); - const buttonHoverStyle = await buttonEl.getComputedStyle(); - expect(buttonHoverStyle.getPropertyValue("background-color")).toEqual("rgba(0, 0, 0, 0.04)"); - }); - }); - - describe("when mode attribute is dark", () => { - it("should render button pseudo classes with value tied to dark mode", async () => { - const page = await newE2EPage({ - html: `
${buttonSnippet}
`, - }); - const buttonEl = await page.find("calcite-button >>> button"); - await buttonEl.hover(); - await page.waitForChanges(); - const buttonHoverStyle = await buttonEl.getComputedStyle(); - expect(buttonHoverStyle.getPropertyValue("background-color")).toEqual("rgba(255, 255, 255, 0.12)"); - }); - }); - - it("should allow the CSS custom property to be overridden", async () => { - const overrideStyle = "rgba(255, 255, 0, 0.9)"; - const page = await newE2EPage({ - html: ` - -
${buttonSnippet}
`, - }); - const buttonEl = await page.find("calcite-button >>> button"); - await buttonEl.hover(); - await page.waitForChanges(); - const buttonHoverStyle = await buttonEl.getComputedStyle(); - expect(buttonHoverStyle.getPropertyValue("background-color")).toEqual(overrideStyle); - }); - }); - it("should remove calcite-loader from dom when `loading` is false", async () => { const page = await newE2EPage(); await page.setContent(``); From e487cc371bda17fd2c113b77d4e97640e382aba0 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 16 May 2025 23:41:14 -0700 Subject: [PATCH 08/49] chore: add test tooling to await for animation frames within E2E page context --- .../src/tests/commonTests/disabled.ts | 6 +++++- .../src/tests/utils/puppeteer.ts | 14 +++++++++++++- .../calcite-components/src/tests/utils/timing.ts | 5 +++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/calcite-components/src/tests/commonTests/disabled.ts b/packages/calcite-components/src/tests/commonTests/disabled.ts index 019769b9496..74920db4ead 100644 --- a/packages/calcite-components/src/tests/commonTests/disabled.ts +++ b/packages/calcite-components/src/tests/commonTests/disabled.ts @@ -2,7 +2,7 @@ import { SetFieldType } from "type-fest"; import { E2EPage, E2EElement, EventSpy } from "@arcgis/lumina-compiler/puppeteerTesting"; import { expect, it } from "vitest"; -import { IntrinsicElementsWithProp, skipAnimations } from "../utils/puppeteer"; +import { IntrinsicElementsWithProp, skipAnimations, waitForAnimationFrame } from "../utils/puppeteer"; import { getTagAndPage } from "./utils"; import { ComponentTestSetup, DisabledOptions, FocusTarget, TabAndClickFocusTargets } from "./interfaces"; @@ -185,6 +185,10 @@ export function disabled(componentTestSetup: ComponentTestSetup, options?: Disab await page.mouse.click(shadowFocusableCenterX, shadowFocusableCenterY); await page.waitForChanges(); + // wait 2 frames to ensure focus has been applied and browser has flushed layout + await waitForAnimationFrame(page); + await waitForAnimationFrame(page); + await expectToBeFocused(page, effectiveFocusTarget.click.pointer, "click"); await resetFocusOrder(); diff --git a/packages/calcite-components/src/tests/utils/puppeteer.ts b/packages/calcite-components/src/tests/utils/puppeteer.ts index 87e50a0baed..91a28f9cb8c 100644 --- a/packages/calcite-components/src/tests/utils/puppeteer.ts +++ b/packages/calcite-components/src/tests/utils/puppeteer.ts @@ -4,6 +4,7 @@ import { LitElement, LuminaJsx, ToElement } from "@arcgis/lumina"; import { E2EElement, E2EPage, newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; import { expect } from "vitest"; import { ComponentTag } from "../commonTests/interfaces"; +import { waitForAnimationFrame as waitForRaf } from "./timing"; /** Util to help type global props for testing. */ export type GlobalTestProps = T & Window & typeof globalThis; @@ -281,7 +282,16 @@ export async function visualizeMouseCursor(page: E2EPage): Promise { }); } -export { waitForAnimationFrame } from "./timing"; +/** + * Helper function to wait for the next animation frame within the Puppeteer browser context. + * + * If you need to run this without Puppeteer dependencies, you can use the `waitForAnimationFrame` function from the `timing` module. + * + * @param page + */ +export async function waitForAnimationFrame(page: E2EPage): Promise { + await page.evaluate(waitForRaf); +} /** * Creates an E2E page for tests that need to create and set up elements programmatically. @@ -336,6 +346,8 @@ export async function isElementFocused( (selector: string, shadowed: boolean): boolean => { const targetDoc = shadowed ? document.activeElement?.shadowRoot : document; + console.log(targetDoc?.activeElement?.tagName); + return !!targetDoc?.activeElement?.matches(selector); }, selector, diff --git a/packages/calcite-components/src/tests/utils/timing.ts b/packages/calcite-components/src/tests/utils/timing.ts index dbb26c79048..8b7cd66bce3 100644 --- a/packages/calcite-components/src/tests/utils/timing.ts +++ b/packages/calcite-components/src/tests/utils/timing.ts @@ -1,6 +1,7 @@ /** - * Tells the browser that you wish to perform an animation. - * https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame + * Helper function to wait for the next animation frame. + * + * If you need to run this within a Puppeteer browser context, please see the `waitForAnimationFrame` function in the `puppeteer` module. * * @returns {Promise} */ From 286d6b6cac8127dc6d760c4c4a5c0f75aa2fef44 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 16 May 2025 23:42:58 -0700 Subject: [PATCH 09/49] feat(dropdown): focus items sooner on open --- .../calcite-components/src/components/dropdown/dropdown.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/calcite-components/src/components/dropdown/dropdown.tsx b/packages/calcite-components/src/components/dropdown/dropdown.tsx index 1fa72c01f47..496824dbec7 100644 --- a/packages/calcite-components/src/components/dropdown/dropdown.tsx +++ b/packages/calcite-components/src/components/dropdown/dropdown.tsx @@ -495,11 +495,11 @@ export class Dropdown } onBeforeOpen(): void { + this.focusOnFirstActiveOrDefaultItem(); this.calciteDropdownBeforeOpen.emit(); } - async onOpen(): Promise { - this.focusOnFirstActiveOrDefaultItem(); + onOpen(): void { this.calciteDropdownOpen.emit(); } From 35992d7ad4d412d61ec82149472090ab19fa7dee Mon Sep 17 00:00:00 2001 From: JC Franco Date: Sun, 18 May 2025 14:15:08 -0700 Subject: [PATCH 10/49] fix tests --- .../src/components/modal/modal.e2e.ts | 18 +++++++++++++++--- .../src/tests/utils/puppeteer.ts | 2 -- .../calcite-components/src/utils/dom.spec.ts | 2 +- .../src/utils/floating-ui.spec.ts | 2 +- .../src/utils/openCloseComponent.spec.ts | 2 +- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/calcite-components/src/components/modal/modal.e2e.ts b/packages/calcite-components/src/components/modal/modal.e2e.ts index 40f840935e3..76f3ef01b82 100644 --- a/packages/calcite-components/src/components/modal/modal.e2e.ts +++ b/packages/calcite-components/src/components/modal/modal.e2e.ts @@ -179,6 +179,7 @@ describe("calcite-modal", () => { `); const modal = await page.find("calcite-modal"); + const openEvent = page.waitForEvent("calciteModalOpen"); await page.$eval( "calcite-modal", (el: Modal["el"]) => @@ -189,6 +190,7 @@ describe("calcite-modal", () => { modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await modal.getProperty("opened")).toBe(true); await page.keyboard.press("Escape"); @@ -329,9 +331,11 @@ describe("calcite-modal", () => { ); await skipAnimations(page); const modal = await page.find("calcite-modal"); + const openEvent = page.waitForEvent("calciteModalOpen"); await modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await isElementFocused(page, `#${button1Id}`)).toBe(true); await page.keyboard.press("Tab"); @@ -429,20 +433,24 @@ describe("calcite-modal", () => { await page.setContent(``); await skipAnimations(page); const modal = await page.find("calcite-modal"); - const openedEvent = page.waitForEvent("calciteModalOpen"); + let openEvent = page.waitForEvent("calciteModalOpen"); modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await modal.isVisible()).toBe(true); + const closeEvent = page.waitForEvent("calciteModalClose"); await page.keyboard.press("Escape"); await page.waitForChanges(); + await closeEvent; expect(await modal.isVisible()).toBe(false); expect(await modal.getProperty("open")).toBe(false); + openEvent = page.waitForEvent("calciteModalOpen"); modal.setProperty("open", true); await page.waitForChanges(); - await openedEvent; + await openEvent; expect(await modal.isVisible()).toBe(true); }); @@ -451,13 +459,17 @@ describe("calcite-modal", () => { await page.setContent(``); await skipAnimations(page); const modal = await page.find("calcite-modal"); + const openEvent = page.waitForEvent("calciteModalOpen"); modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await modal.isVisible()).toBe(true); + const closeEvent = page.waitForEvent("calciteModalClose"); await page.keyboard.press("Escape"); await page.waitForChanges(); + await closeEvent; expect(await modal.isVisible()).toBe(false); expect(await modal.getProperty("open")).toBe(false); }); @@ -475,7 +487,7 @@ describe("calcite-modal", () => { await page.keyboard.press("Escape"); await page.waitForChanges(); - await waitForAnimationFrame(); + await waitForAnimationFrame(page); expect(modal).not.toHaveAttribute("open"); await modal.setProperty("open", true); diff --git a/packages/calcite-components/src/tests/utils/puppeteer.ts b/packages/calcite-components/src/tests/utils/puppeteer.ts index 91a28f9cb8c..f418be8e9c2 100644 --- a/packages/calcite-components/src/tests/utils/puppeteer.ts +++ b/packages/calcite-components/src/tests/utils/puppeteer.ts @@ -346,8 +346,6 @@ export async function isElementFocused( (selector: string, shadowed: boolean): boolean => { const targetDoc = shadowed ? document.activeElement?.shadowRoot : document; - console.log(targetDoc?.activeElement?.tagName); - return !!targetDoc?.activeElement?.matches(selector); }, selector, diff --git a/packages/calcite-components/src/utils/dom.spec.ts b/packages/calcite-components/src/utils/dom.spec.ts index 89f403c0edf..df52dbc6e46 100644 --- a/packages/calcite-components/src/utils/dom.spec.ts +++ b/packages/calcite-components/src/utils/dom.spec.ts @@ -2,7 +2,7 @@ import { beforeAll, beforeEach, describe, expect, it, Mock, vi } from "vitest"; import { ModeName } from "../components/interfaces"; import { html } from "../../support/formatting"; -import { waitForAnimationFrame } from "../tests/utils/puppeteer"; +import { waitForAnimationFrame } from "../tests/utils/timing"; import { createControlledPromise } from "../tests/utils/promises"; import { guidPattern } from "./guid.spec"; import { diff --git a/packages/calcite-components/src/utils/floating-ui.spec.ts b/packages/calcite-components/src/utils/floating-ui.spec.ts index ef33d2326fa..5b3b4a468f2 100644 --- a/packages/calcite-components/src/utils/floating-ui.spec.ts +++ b/packages/calcite-components/src/utils/floating-ui.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, beforeEach, vi } from "vitest"; -import { waitForAnimationFrame } from "../tests/utils/puppeteer"; +import { waitForAnimationFrame } from "../tests/utils/timing"; import { DEBOUNCE } from "./resources"; import * as floatingUI from "./floating-ui"; import type { positionFloatingUI } from "./floating-ui"; diff --git a/packages/calcite-components/src/utils/openCloseComponent.spec.ts b/packages/calcite-components/src/utils/openCloseComponent.spec.ts index 3cc2bef031f..29b8286d537 100644 --- a/packages/calcite-components/src/utils/openCloseComponent.spec.ts +++ b/packages/calcite-components/src/utils/openCloseComponent.spec.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { waitForAnimationFrame } from "../tests/utils/puppeteer"; +import { waitForAnimationFrame } from "../tests/utils/timing"; import { createControlledPromise } from "../tests/utils/promises"; import * as openCloseComponent from "./openCloseComponent"; From 0ef4e483d23190ff01d4182d43081ce5556c2f7b Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 20 May 2025 14:57:17 -0700 Subject: [PATCH 11/49] fix tests --- .../components/action-menu/action-menu.e2e.ts | 17 ++++++++--------- .../src/components/block/block.e2e.ts | 10 ++++++++++ .../src/tests/commonTests/accessible.ts | 3 ++- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts index 69143a0bc91..7d1d97630e6 100755 --- a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts +++ b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts @@ -142,6 +142,11 @@ describe("calcite-action-menu", () => { ); }); + async function waitForActionMenuClose(page: E2EPage): Promise { + // replace with close event handling once https://github.com/Esri/calcite-design-system/issues/4544 lands + await page.waitForFunction(() => document.querySelector("calcite-action-menu").open === false); + } + it("should close menu if clicked outside", async () => { const page = await newE2EPage({ html: ` @@ -154,26 +159,19 @@ describe("calcite-action-menu", () => { `, }); - await page.waitForChanges(); - const actionMenu = await page.find("calcite-action-menu"); - const popover = await page.find("calcite-action-menu >>> calcite-popover"); + const outside = await page.find("#outside"); expect(await popover.getProperty("autoClose")).toBe(true); - expect(await popover.getProperty("open")).toBe(true); - expect(await actionMenu.getProperty("open")).toBe(true); - const outside = await page.find("#outside"); - await outside.click(); - await page.waitForChanges(); + await waitForActionMenuClose(page); expect(await actionMenu.getProperty("open")).toBe(false); - expect(await popover.getProperty("open")).toBe(false); }); @@ -314,6 +312,7 @@ describe("calcite-action-menu", () => { await outside.click(); await page.waitForChanges(); + await waitForActionMenuClose(page); expect(await actionMenu.getProperty("open")).toBe(false); diff --git a/packages/calcite-components/src/components/block/block.e2e.ts b/packages/calcite-components/src/components/block/block.e2e.ts index e87346b75f7..7a11a939b6d 100644 --- a/packages/calcite-components/src/components/block/block.e2e.ts +++ b/packages/calcite-components/src/components/block/block.e2e.ts @@ -250,7 +250,9 @@ describe("calcite-block", () => { expect(toggle.getAttribute("aria-expanded")).toBe("false"); expect(toggle.getAttribute("title")).toBe(messages.expand); + const openEvent = element.waitForEvent("calciteBlockOpen"); await toggle.click(); + await openEvent; expect(toggleSpy).toHaveReceivedEventTimes(1); expect(openSpy).toHaveReceivedEventTimes(1); @@ -258,7 +260,9 @@ describe("calcite-block", () => { expect(toggle.getAttribute("aria-expanded")).toBe("true"); expect(toggle.getAttribute("title")).toBe(messages.collapse); + const closeEvent = element.waitForEvent("calciteBlockClose"); await toggle.click(); + await closeEvent; expect(toggleSpy).toHaveReceivedEventTimes(2); expect(closeSpy).toHaveReceivedEventTimes(1); @@ -333,12 +337,18 @@ describe("calcite-block", () => { await control.press("Space"); await control.press("Enter"); await control.click(); + expect(blockOpenSpy).toHaveReceivedEventTimes(0); expect(blockToggleSpy).toHaveReceivedEventTimes(0); expect(blockCloseSpy).toHaveReceivedEventTimes(0); + const openEvent = page.waitForEvent("calciteBlockOpen"); + const closeEvent = page.waitForEvent("calciteBlockClose"); await block.click(); + await openEvent; await block.click(); + await closeEvent; + expect(blockToggleSpy).toHaveReceivedEventTimes(2); expect(blockOpenSpy).toHaveReceivedEventTimes(1); expect(blockCloseSpy).toHaveReceivedEventTimes(1); diff --git a/packages/calcite-components/src/tests/commonTests/accessible.ts b/packages/calcite-components/src/tests/commonTests/accessible.ts index 47a16ddaa28..421c709786c 100644 --- a/packages/calcite-components/src/tests/commonTests/accessible.ts +++ b/packages/calcite-components/src/tests/commonTests/accessible.ts @@ -1,7 +1,7 @@ import axe from "axe-core"; import { toHaveNoViolations } from "jest-axe"; import { expect, it } from "vitest"; -import { GlobalTestProps } from "../utils/puppeteer"; +import { GlobalTestProps, skipAnimations } from "../utils/puppeteer"; import { getTagAndPage } from "./utils"; import { ComponentTestSetup, ComponentTag } from "./interfaces"; @@ -24,6 +24,7 @@ export function accessible(componentTestSetup: ComponentTestSetup): void { it("is accessible", async () => { const { page, tag } = await getTagAndPage(componentTestSetup); + await skipAnimations(page); await page.addScriptTag({ path: require.resolve("axe-core") }); await page.waitForFunction(() => (window as AxeOwningWindow).axe); From eca300c5b39aff525d3d6bd5e63f8fdbecea5256 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 20 May 2025 15:37:55 -0700 Subject: [PATCH 12/49] fix tests --- .../components/card-group/card-group.e2e.ts | 36 +++++++++++++++++++ .../src/components/combobox/combobox.e2e.ts | 2 ++ .../src/components/dialog/dialog.e2e.ts | 8 +++++ .../input-time-picker.e2e.ts | 8 +++++ 4 files changed, 54 insertions(+) diff --git a/packages/calcite-components/src/components/card-group/card-group.e2e.ts b/packages/calcite-components/src/components/card-group/card-group.e2e.ts index e858554b136..3748a1a5b17 100644 --- a/packages/calcite-components/src/components/card-group/card-group.e2e.ts +++ b/packages/calcite-components/src/components/card-group/card-group.e2e.ts @@ -90,8 +90,11 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card2.id]); + let selectEvent = page.waitForEvent("calciteCardSelect"); card1CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(await cardGroupSelectSpy).toHaveReceivedEventTimes(1); expect(await cardSelectSpy1).toHaveReceivedEventTimes(1); expect(await cardSelectSpy2).toHaveReceivedEventTimes(0); @@ -100,8 +103,11 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card1.id]); + selectEvent = page.waitForEvent("calciteCardSelect"); card2CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(2); expect(cardSelectSpy1).toHaveReceivedEventTimes(1); expect(cardSelectSpy2).toHaveReceivedEventTimes(1); @@ -110,8 +116,11 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card2.id]); + selectEvent = page.waitForEvent("calciteCardSelect"); card2CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(3); expect(cardSelectSpy1).toHaveReceivedEventTimes(1); expect(cardSelectSpy2).toHaveReceivedEventTimes(2); @@ -148,24 +157,33 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card1.id]); + let selectEvent = page.waitForEvent("calciteCardSelect"); card1CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(1); expect(await card1.getProperty("selected")).toBe(true); expect(await card2.getProperty("selected")).toBe(false); expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card1.id]); + selectEvent = page.waitForEvent("calciteCardSelect"); card2CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(2); expect(await card1.getProperty("selected")).toBe(false); expect(await card2.getProperty("selected")).toBe(true); expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card2.id]); + selectEvent = page.waitForEvent("calciteCardSelect"); card2CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(3); expect(await card1.getProperty("selected")).toBe(false); expect(await card2.getProperty("selected")).toBe(true); @@ -203,8 +221,11 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toEqual([]); await selectedItemAsserter([]); + let selectEvent = page.waitForEvent("calciteCardSelect"); card1CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(1); expect(await card1.getProperty("selected")).toBe(true); expect(await card2.getProperty("selected")).toBe(false); @@ -212,8 +233,11 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card1.id]); + selectEvent = page.waitForEvent("calciteCardSelect"); card2CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(2); expect(await card1.getProperty("selected")).toBe(true); expect(await card2.getProperty("selected")).toBe(true); @@ -221,8 +245,11 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(2); await selectedItemAsserter([card1.id, card2.id]); + selectEvent = page.waitForEvent("calciteCardSelect"); card3CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(3); expect(await card1.getProperty("selected")).toBe(true); expect(await card2.getProperty("selected")).toBe(true); @@ -230,8 +257,11 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(3); await selectedItemAsserter([card1.id, card2.id, card3.id]); + selectEvent = page.waitForEvent("calciteCardSelect"); card1CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(4); expect(await card1.getProperty("selected")).toBe(false); expect(await card2.getProperty("selected")).toBe(true); @@ -239,8 +269,11 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(2); await selectedItemAsserter([card2.id, card3.id]); + selectEvent = page.waitForEvent("calciteCardSelect"); card2CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(5); expect(await card1.getProperty("selected")).toBe(false); expect(await card2.getProperty("selected")).toBe(false); @@ -248,8 +281,11 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card3.id]); + selectEvent = page.waitForEvent("calciteCardSelect"); card3CheckAction.click(); await page.waitForChanges(); + await selectEvent; + expect(cardGroupSelectSpy).toHaveReceivedEventTimes(6); expect(await card1.getProperty("selected")).toBe(false); expect(await card2.getProperty("selected")).toBe(false); diff --git a/packages/calcite-components/src/components/combobox/combobox.e2e.ts b/packages/calcite-components/src/components/combobox/combobox.e2e.ts index b5bbd9f5660..7ef74193542 100644 --- a/packages/calcite-components/src/components/combobox/combobox.e2e.ts +++ b/packages/calcite-components/src/components/combobox/combobox.e2e.ts @@ -1577,8 +1577,10 @@ describe("calcite-combobox", () => { expect(await getDataTestId()).toBe(inputId); await assertCaretPosition({ page, componentTag, position: 0 }); + const filterChangeEvent = page.waitForEvent("calciteComboboxFilterChange"); await page.keyboard.type("zz"); await page.waitForChanges(); + await filterChangeEvent; await page.keyboard.press("ArrowRight"); await page.waitForChanges(); diff --git a/packages/calcite-components/src/components/dialog/dialog.e2e.ts b/packages/calcite-components/src/components/dialog/dialog.e2e.ts index 1f1d5858a7d..8b6688388ed 100644 --- a/packages/calcite-components/src/components/dialog/dialog.e2e.ts +++ b/packages/calcite-components/src/components/dialog/dialog.e2e.ts @@ -464,12 +464,17 @@ describe("calcite-dialog", () => { await page.$eval("calcite-dialog", (el: Dialog["el"]) => (el.beforeClose = (window as TestWindow).beforeClose)); await page.waitForChanges(); + const openEvent = page.waitForEvent("calciteDialogOpen"); dialog.setProperty("open", true); await page.waitForChanges(); + await openEvent; + expect(await page.find(`calcite-dialog >>> .${CSS.containerOpen}`)).toBeDefined(); + const closeEvent = page.waitForEvent("calciteDialogClose"); await page.keyboard.press("Escape"); await page.waitForChanges(); + await closeEvent; expect(mockCallBack).toHaveBeenCalledTimes(2); expect(await page.find(`calcite-dialog >>> .${CSS.containerOpen}`)).toBeNull(); @@ -621,8 +626,11 @@ describe("calcite-dialog", () => { await skipAnimations(page); const dialog = await page.find("calcite-dialog"); + const openEvent = page.waitForEvent("calciteDialogOpen"); dialog.setProperty("open", true); await page.waitForChanges(); + await openEvent; + expect(await isElementFocused(page, `#${button1Id}`)).toBe(true); await page.keyboard.press("Tab"); diff --git a/packages/calcite-components/src/components/input-time-picker/input-time-picker.e2e.ts b/packages/calcite-components/src/components/input-time-picker/input-time-picker.e2e.ts index 5aece073c74..bb5208a024b 100644 --- a/packages/calcite-components/src/components/input-time-picker/input-time-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-time-picker/input-time-picker.e2e.ts @@ -1513,8 +1513,10 @@ describe("calcite-input-time-picker", () => { expect(await isElementFocused(page, "calcite-input-time-picker")).toBe(true); + const openEvent = page.waitForEvent("calciteInputTimePickerOpen"); await toggleButton.click(); await page.waitForChanges(); + await openEvent; expect(await popoverPositionContainer.isVisible()).toBe(true); @@ -1536,8 +1538,10 @@ describe("calcite-input-time-picker", () => { expect(await isElementFocused(page, "calcite-time-picker", { shadowed: true })).toBe(true); + const closeEvent = page.waitForEvent("calciteInputTimePickerClose"); await page.keyboard.press("Escape"); await page.waitForChanges(); + await closeEvent; expect(await popoverPositionContainer.isVisible()).toBe(false); expect(await isElementFocused(page, "calcite-input-time-picker")).toBe(true); @@ -1577,13 +1581,17 @@ describe("calcite-input-time-picker", () => { expect(await popoverPositionContainer.isVisible()).toBe(false); + const openEvent = page.waitForEvent("calciteInputTimePickerOpen"); await toggleButton.click(); await page.waitForChanges(); + await openEvent; expect(await popoverPositionContainer.isVisible()).toBe(true); + const closeEvent = page.waitForEvent("calciteInputTimePickerClose"); await toggleButton.click(); await page.waitForChanges(); + await closeEvent; expect(await popoverPositionContainer.isVisible()).toBe(false); }); From ac1a34e474bf0ab6561ee3b7168c34ceab3435c8 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 20 May 2025 15:53:24 -0700 Subject: [PATCH 13/49] drop redundant chip tests --- .../src/components/chip/chip.e2e.ts | 91 ++----------------- 1 file changed, 9 insertions(+), 82 deletions(-) diff --git a/packages/calcite-components/src/components/chip/chip.e2e.ts b/packages/calcite-components/src/components/chip/chip.e2e.ts index 53f5ea89630..a9be591a83d 100644 --- a/packages/calcite-components/src/components/chip/chip.e2e.ts +++ b/packages/calcite-components/src/components/chip/chip.e2e.ts @@ -163,90 +163,17 @@ describe("calcite-chip", () => { }); }); - describe("CSS properties for light/dark mode", () => { - const chipSnippet = ` - - Layers - - `; - let page; - let chipCloseButton; - let chipCloseButtonFocusStyle; - let chipCloseButtonHoverStyle; - - describe("when mode attribute is not provided", () => { - it("should render chip pseudo classes with default values tied to mode", async () => { - page = await newE2EPage({ html: chipSnippet }); - chipCloseButton = await page.find("calcite-chip >>> button"); - await chipCloseButton.focus(); - await page.waitForChanges(); - chipCloseButtonFocusStyle = await chipCloseButton.getComputedStyle(); - expect(chipCloseButtonFocusStyle.getPropertyValue("background-color")).toEqual("rgba(0, 0, 0, 0.04)"); - - await chipCloseButton.hover(); - await page.waitForChanges(); - chipCloseButtonHoverStyle = await chipCloseButton.getComputedStyle(); - expect(chipCloseButtonHoverStyle.getPropertyValue("background-color")).toEqual("rgba(0, 0, 0, 0.04)"); - }); - }); - - describe("when mode attribute is dark", () => { - it("should render button pseudo classes with value tied to dark mode", async () => { - page = await newE2EPage({ - html: `
${chipSnippet}
`, - }); - chipCloseButton = await page.find("calcite-chip >>> button"); - await chipCloseButton.focus(); - await page.waitForChanges(); - chipCloseButtonFocusStyle = await chipCloseButton.getComputedStyle(); - expect(chipCloseButtonFocusStyle.getPropertyValue("background-color")).toEqual("rgba(255, 255, 255, 0.12)"); - - await chipCloseButton.hover(); - await page.waitForChanges(); - chipCloseButtonHoverStyle = await chipCloseButton.getComputedStyle(); - expect(chipCloseButtonHoverStyle.getPropertyValue("background-color")).toEqual("rgba(255, 255, 255, 0.12)"); - }); - }); - - it("should allow the CSS custom property to be overridden", async () => { - const overrideStyle = "rgba(55, 5, 10, 0.19)"; - page = await newE2EPage({ - html: ` - -
${chipSnippet}
`, - }); - chipCloseButton = await page.find("calcite-chip >>> button"); - await chipCloseButton.focus(); - await page.waitForChanges(); - chipCloseButtonFocusStyle = await chipCloseButton.getComputedStyle(); - expect(chipCloseButtonFocusStyle.getPropertyValue("background-color")).toEqual(overrideStyle); - - await chipCloseButton.hover(); - await page.waitForChanges(); - chipCloseButtonHoverStyle = await chipCloseButton.getComputedStyle(); - expect(chipCloseButtonHoverStyle.getPropertyValue("background-color")).toEqual(overrideStyle); - }); - - it("should not render chip when closed set to true", async () => { - const page = await newE2EPage(); - await page.setContent(`
${chipSnippet}
`); + it("should not render chip when closed set to true", async () => { + const page = await newE2EPage(); + await page.setContent(html` + Layers + `); - const chipEl = await page.find(`calcite-chip`); - chipEl.toggleAttribute("closed", true); - await page.waitForChanges(); + const chipEl = await page.find(`calcite-chip`); + chipEl.toggleAttribute("closed", true); + await page.waitForChanges(); - expect(await chipEl.isVisible()).toBe(false); - }); + expect(await chipEl.isVisible()).toBe(false); }); describe("translation support", () => { From c986475a81cd1246f4c4e96c777ebde2856748a2 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Thu, 22 May 2025 15:57:04 -0700 Subject: [PATCH 14/49] fix tests --- .../src/components/combobox/combobox.e2e.ts | 4 ++++ .../inline-editable/inline-editable.e2e.ts | 12 +++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/calcite-components/src/components/combobox/combobox.e2e.ts b/packages/calcite-components/src/components/combobox/combobox.e2e.ts index 7ef74193542..6bf54a82002 100644 --- a/packages/calcite-components/src/components/combobox/combobox.e2e.ts +++ b/packages/calcite-components/src/components/combobox/combobox.e2e.ts @@ -1701,13 +1701,17 @@ describe("calcite-combobox", () => { await page.waitForChanges(); expect(await page.evaluate(() => document.activeElement.id)).toBe("myCombobox"); + const openEvent = page.waitForEvent("calciteComboboxOpen"); await page.keyboard.press("Space"); await page.waitForChanges(); + await openEvent; const floatingUI = await page.find(`#myCombobox >>> .${CSS.floatingUIContainer}`); expect(await floatingUI.isVisible()).toBe(true); + const closeEvent = page.waitForEvent("calciteComboboxClose"); await page.keyboard.press("Tab"); await page.waitForChanges(); + await closeEvent; expect(await floatingUI.isVisible()).toBe(false); }); diff --git a/packages/calcite-components/src/components/inline-editable/inline-editable.e2e.ts b/packages/calcite-components/src/components/inline-editable/inline-editable.e2e.ts index 895613bc512..4abf7fbd06f 100644 --- a/packages/calcite-components/src/components/inline-editable/inline-editable.e2e.ts +++ b/packages/calcite-components/src/components/inline-editable/inline-editable.e2e.ts @@ -5,6 +5,7 @@ import { accessible, disabled, hidden, labelable, renders, t9n, themed } from ". import { html } from "../../../support/formatting"; import type { Input } from "../input/input"; import { findAll } from "../../tests/utils/puppeteer"; +import { createControlledPromise } from "../../tests/utils/promises"; import { CSS } from "./resources"; import type { InlineEditable } from "./inline-editable"; @@ -304,7 +305,8 @@ describe("calcite-inline-editable", () => { it("disables editing when afterConfirm resolves successfully", async () => { const element = await page.find("calcite-inline-editable"); - const afterConfirm: () => Promise = () => new Promise((resolve) => global.setTimeout(resolve, 100)); + const { promise, resolve } = createControlledPromise(); + const afterConfirm = () => promise; // https://github.com/ionic-team/stencil/issues/1174 await page.exposeFunction("afterConfirm", afterConfirm); await page.$eval("calcite-inline-editable", (el: InlineEditable["el"]) => { @@ -314,15 +316,19 @@ describe("calcite-inline-editable", () => { const input = await page.find("calcite-input"); const enableEditingButton = await page.find(`calcite-inline-editable >>> .${CSS.enableEditingButton}`); await enableEditingButton.click(); - const confirmChangesButton = await page.find("calcite-inline-editable >>> .confirm-changes-button"); + const confirmChangesButton = await page.find(`calcite-inline-editable >>> .${CSS.confirmChangesButton}`); await page.$eval("calcite-input", (element: Input["el"]): void => { const input = element.shadowRoot.querySelector("input"); input.setSelectionRange(input.value.length, input.value.length); }); await input.type("Moe"); + const confirmEvent = page.waitForEvent("calciteInlineEditableEditConfirm"); await confirmChangesButton.click(); - expect(calciteInlineEditableEditConfirm).toHaveReceivedEventTimes(1); + resolve(); await page.waitForChanges(); + await confirmEvent; + await afterConfirm; + expect(calciteInlineEditableEditConfirm).toHaveReceivedEventTimes(1); expect(await input.getProperty("value")).toBe("John DoeMoe"); expect(element).not.toHaveAttribute("editing-enabled"); }); From f08ffa2446a27ff8de398b6188b0a936b233b806 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Thu, 22 May 2025 16:06:45 -0700 Subject: [PATCH 15/49] chore(sheet): drop redundant openClose tests --- .../src/components/sheet/sheet.e2e.ts | 204 +----------------- 1 file changed, 1 insertion(+), 203 deletions(-) diff --git a/packages/calcite-components/src/components/sheet/sheet.e2e.ts b/packages/calcite-components/src/components/sheet/sheet.e2e.ts index b74a4fe2510..859655a6fe5 100644 --- a/packages/calcite-components/src/components/sheet/sheet.e2e.ts +++ b/packages/calcite-components/src/components/sheet/sheet.e2e.ts @@ -3,7 +3,7 @@ import { newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; import { describe, expect, it, vi } from "vitest"; import { html } from "../../../support/formatting"; import { accessible, defaults, focusable, hidden, openClose, reflects, renders, themed } from "../../tests/commonTests"; -import { GlobalTestProps, newProgrammaticE2EPage, skipAnimations } from "../../tests/utils/puppeteer"; +import { GlobalTestProps, skipAnimations } from "../../tests/utils/puppeteer"; import { resizeStep, resizeShiftStep } from "../../utils/resources"; import { focusTrap } from "../../tests/commonTests/focusTrap"; import { CSS } from "./resources"; @@ -430,208 +430,6 @@ describe("calcite-sheet properties", () => { expect(documentClass).toEqual(false); }); - describe("opening and closing behavior", () => { - it("opens and closes", async () => { - const page = await newE2EPage(); - await page.setContent(html``); - const sheet = await page.find("calcite-sheet"); - - type SheetEventOrderWindow = GlobalTestProps<{ events: string[] }>; - - await page.$eval("calcite-sheet", (sheet: Sheet["el"]) => { - const receivedEvents: string[] = []; - (window as SheetEventOrderWindow).events = receivedEvents; - - ["calciteSheetBeforeOpen", "calciteSheetOpen", "calciteSheetBeforeClose", "calciteSheetClose"].forEach( - (eventType) => { - sheet.addEventListener(eventType, (event) => receivedEvents.push(event.type)); - }, - ); - }); - - const beforeOpenSpy = await sheet.spyOnEvent("calciteSheetBeforeOpen"); - const openSpy = await sheet.spyOnEvent("calciteSheetOpen"); - const beforeCloseSpy = await sheet.spyOnEvent("calciteSheetBeforeClose"); - const closeSpy = await sheet.spyOnEvent("calciteSheetClose"); - - expect(beforeOpenSpy).toHaveReceivedEventTimes(0); - expect(openSpy).toHaveReceivedEventTimes(0); - expect(beforeCloseSpy).toHaveReceivedEventTimes(0); - expect(closeSpy).toHaveReceivedEventTimes(0); - - expect(await sheet.isVisible()).toBe(false); - - const sheetBeforeOpen = page.waitForEvent("calciteSheetBeforeOpen"); - const sheetOpen = page.waitForEvent("calciteSheetOpen"); - sheet.setProperty("open", true); - await page.waitForChanges(); - - await sheetBeforeOpen; - await sheetOpen; - - expect(beforeOpenSpy).toHaveReceivedEventTimes(1); - expect(openSpy).toHaveReceivedEventTimes(1); - expect(beforeCloseSpy).toHaveReceivedEventTimes(0); - expect(closeSpy).toHaveReceivedEventTimes(0); - - expect(await sheet.isVisible()).toBe(true); - - const sheetBeforeClose = page.waitForEvent("calciteSheetBeforeClose"); - const sheetClose = page.waitForEvent("calciteSheetClose"); - sheet.setProperty("open", false); - await page.waitForChanges(); - - await sheetBeforeClose; - await sheetClose; - - expect(beforeOpenSpy).toHaveReceivedEventTimes(1); - expect(openSpy).toHaveReceivedEventTimes(1); - expect(beforeCloseSpy).toHaveReceivedEventTimes(1); - expect(closeSpy).toHaveReceivedEventTimes(1); - - expect(await sheet.isVisible()).toBe(false); - - expect(await page.evaluate(() => (window as SheetEventOrderWindow).events)).toEqual([ - "calciteSheetBeforeOpen", - "calciteSheetOpen", - "calciteSheetBeforeClose", - "calciteSheetClose", - ]); - }); - - it("emits when closing on click", async () => { - const page = await newE2EPage(); - await page.setContent(html``); - const sheet = await page.find("calcite-sheet"); - - const beforeOpenSpy = await sheet.spyOnEvent("calciteSheetBeforeOpen"); - const openSpy = await sheet.spyOnEvent("calciteSheetOpen"); - const beforeCloseSpy = await sheet.spyOnEvent("calciteSheetBeforeClose"); - const closeSpy = await sheet.spyOnEvent("calciteSheetClose"); - - expect(beforeOpenSpy).toHaveReceivedEventTimes(0); - expect(openSpy).toHaveReceivedEventTimes(0); - expect(beforeCloseSpy).toHaveReceivedEventTimes(0); - expect(closeSpy).toHaveReceivedEventTimes(0); - - expect(await sheet.isVisible()).toBe(false); - - const sheetBeforeOpen = page.waitForEvent("calciteSheetBeforeOpen"); - const sheetOpen = page.waitForEvent("calciteSheetOpen"); - sheet.setProperty("open", true); - await page.waitForChanges(); - - await sheetBeforeOpen; - await sheetOpen; - - expect(beforeOpenSpy).toHaveReceivedEventTimes(1); - expect(openSpy).toHaveReceivedEventTimes(1); - expect(beforeCloseSpy).toHaveReceivedEventTimes(0); - expect(closeSpy).toHaveReceivedEventTimes(0); - - expect(await sheet.isVisible()).toBe(true); - - const sheetBeforeClose = page.waitForEvent("calciteSheetBeforeClose"); - const sheetClose = page.waitForEvent("calciteSheetClose"); - const scrim = await page.find(`calcite-sheet >>> .${CSS.scrim}`); - await scrim.click(); - await page.waitForChanges(); - - await sheetBeforeClose; - await sheetClose; - - expect(beforeOpenSpy).toHaveReceivedEventTimes(1); - expect(openSpy).toHaveReceivedEventTimes(1); - expect(beforeCloseSpy).toHaveReceivedEventTimes(1); - expect(closeSpy).toHaveReceivedEventTimes(1); - - expect(await sheet.isVisible()).toBe(false); - }); - - it("emits when set to open on initial render", async () => { - const page = await newProgrammaticE2EPage(); - - const beforeOpenSpy = await page.spyOnEvent("calciteSheetBeforeOpen"); - const openSpy = await page.spyOnEvent("calciteSheetOpen"); - - const waitForBeforeOpenEvent = page.waitForEvent("calciteSheetBeforeOpen"); - const waitForOpenEvent = page.waitForEvent("calciteSheetOpen"); - - await page.evaluate((): void => { - const sheet = document.createElement("calcite-sheet"); - sheet.open = true; - document.body.append(sheet); - }); - - await page.waitForChanges(); - await waitForBeforeOpenEvent; - await waitForOpenEvent; - - expect(beforeOpenSpy).toHaveReceivedEventTimes(1); - expect(openSpy).toHaveReceivedEventTimes(1); - }); - - it("emits when set to open on initial render and duration is 0", async () => { - const page = await newProgrammaticE2EPage(); - await skipAnimations(page); - - const beforeOpenSpy = await page.spyOnEvent("calciteSheetBeforeOpen"); - const openSpy = await page.spyOnEvent("calciteSheetOpen"); - - const waitForOpenEvent = page.waitForEvent("calciteSheetOpen"); - const waitForBeforeOpenEvent = page.waitForEvent("calciteSheetBeforeOpen"); - - await page.evaluate((): void => { - const sheet = document.createElement("calcite-sheet"); - sheet.open = true; - document.body.append(sheet); - }); - - await page.waitForChanges(); - await waitForBeforeOpenEvent; - await waitForOpenEvent; - - expect(beforeOpenSpy).toHaveReceivedEventTimes(1); - expect(openSpy).toHaveReceivedEventTimes(1); - }); - - it("emits when duration is set to 0", async () => { - const page = await newProgrammaticE2EPage(); - await skipAnimations(page); - - const beforeOpenSpy = await page.spyOnEvent("calciteSheetBeforeOpen"); - const openSpy = await page.spyOnEvent("calciteSheetOpen"); - - const beforeCloseSpy = await page.spyOnEvent("calciteSheetBeforeClose"); - const closeSpy = await page.spyOnEvent("calciteSheetClose"); - - await page.evaluate((): void => { - const sheet = document.createElement("calcite-sheet"); - sheet.open = true; - document.body.append(sheet); - }); - - await page.waitForChanges(); - await beforeOpenSpy; - await openSpy; - - expect(beforeOpenSpy).toHaveReceivedEventTimes(1); - expect(openSpy).toHaveReceivedEventTimes(1); - - await page.evaluate(() => { - const sheet = document.querySelector("calcite-sheet"); - sheet.open = false; - }); - - await page.waitForChanges(); - await beforeCloseSpy; - await closeSpy; - - expect(beforeCloseSpy).toHaveReceivedEventTimes(1); - expect(closeSpy).toHaveReceivedEventTimes(1); - }); - }); - describe("keyboard resize", () => { it("should resize properly via arrow keys", async () => { const maxSize = 600; From f1d0e134ce6922a00228ee52f7f697577ad389d8 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Thu, 22 May 2025 16:15:44 -0700 Subject: [PATCH 16/49] fix tests --- .../src/components/popover/popover.e2e.ts | 23 +++---- .../src/components/sheet/sheet.e2e.ts | 60 +++++++++++++++---- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/packages/calcite-components/src/components/popover/popover.e2e.ts b/packages/calcite-components/src/components/popover/popover.e2e.ts index e8554251e70..b42261183a0 100644 --- a/packages/calcite-components/src/components/popover/popover.e2e.ts +++ b/packages/calcite-components/src/components/popover/popover.e2e.ts @@ -264,60 +264,60 @@ describe("calcite-popover", () => { it("should honor Enter key interaction", async () => { const page = await newE2EPage(); - await page.setContent( html`content
referenceElement
`, ); - await skipAnimations(page); - await page.waitForChanges(); - const positionContainer = await page.find(`calcite-popover >>> .${CSS.positionContainer}`); const ref = await page.find("#ref"); expect(await positionContainer.isVisible()).toBe(false); + let openEvent = page.waitForEvent("calcitePopoverOpen"); await ref.focus(); await page.keyboard.press("Enter"); await page.waitForChanges(); + await openEvent; expect(await positionContainer.isVisible()).toBe(true); + openEvent = page.waitForEvent("calcitePopoverClose"); await ref.focus(); await page.keyboard.press("Enter"); await page.waitForChanges(); + await openEvent; expect(await positionContainer.isVisible()).toBe(false); }); it("should honor Space key interaction", async () => { const page = await newE2EPage(); - await page.setContent( html`content
referenceElement
`, ); - await skipAnimations(page); - await page.waitForChanges(); - const positionContainer = await page.find(`calcite-popover >>> .${CSS.positionContainer}`); const ref = await page.find("#ref"); expect(await positionContainer.isVisible()).toBe(false); + const openEvent = page.waitForEvent("calcitePopoverOpen"); await ref.focus(); await page.keyboard.press(" "); await page.waitForChanges(); + await openEvent; expect(await positionContainer.isVisible()).toBe(true); + const closeEvent = page.waitForEvent("calcitePopoverClose"); await ref.focus(); await page.keyboard.press(" "); await page.waitForChanges(); + await closeEvent; expect(await positionContainer.isVisible()).toBe(false); }); @@ -657,7 +657,6 @@ describe("calcite-popover", () => { it("should still function when disconnected and reconnected", async () => { const page = await newE2EPage(); - await page.setContent( `content
@@ -669,17 +668,21 @@ describe("calcite-popover", () => { const ref = await page.find("#ref"); expect(await positionContainer.isVisible()).toBe(true); + const closeEvent = page.waitForEvent("calcitePopoverClose"); await ref.click(); await page.waitForChanges(); + await closeEvent; + expect(await positionContainer.isVisible()).toBe(false); await page.$eval("calcite-popover", (popoverEl: Popover["el"]) => { const transferEl = document.getElementById("transfer"); transferEl.appendChild(popoverEl); }); - await page.waitForChanges(); + const openEvent = page.waitForEvent("calcitePopoverOpen"); await ref.click(); + await openEvent; expect(await positionContainer.isVisible()).toBe(true); }); diff --git a/packages/calcite-components/src/components/sheet/sheet.e2e.ts b/packages/calcite-components/src/components/sheet/sheet.e2e.ts index 859655a6fe5..5a34a0c2698 100644 --- a/packages/calcite-components/src/components/sheet/sheet.e2e.ts +++ b/packages/calcite-components/src/components/sheet/sheet.e2e.ts @@ -98,17 +98,41 @@ describe("calcite-sheet properties", () => { }); describe("accessible", () => { - accessible(`Hello everyone!`); - accessible(`

- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. - Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -

- tincidunt lobortis - amet porttitor -
`); + accessible(async () => { + const page = await newE2EPage(); + await page.setContent(html`Hello everyone!`); + const openEvent = page.waitForEvent("calciteSheetOpen"); + const sheet = await page.find("calcite-sheet"); + sheet.setProperty("open", true); + await page.waitForChanges(); + await openEvent; + return { page, tag: "calcite-sheet" }; + }); + + accessible(async () => { + const page = await newE2EPage(); + await page.setContent(html` + +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et + dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex + ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu + fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt + mollit anim id est laborum. +

+ tincidunt lobortis + amet porttitor +
+
+ `); + const openEvent = page.waitForEvent("calciteSheetOpen"); + const sheet = await page.find("calcite-sheet"); + sheet.setProperty("open", true); + await page.waitForChanges(); + await openEvent; + return { page, tag: "calcite-sheet" }; + }); }); describe("setFocus", () => { @@ -326,18 +350,30 @@ describe("calcite-sheet properties", () => { it("closes and allows re-opening when Escape key is pressed", async () => { const page = await newE2EPage(); - await page.setContent(``); + await page.setContent(``); await skipAnimations(page); const sheet = await page.find("calcite-sheet"); + + let openEvent = page.waitForEvent("calciteSheetOpen"); sheet.setProperty("open", true); await page.waitForChanges(); + await openEvent; + expect(await sheet.isVisible()).toBe(true); + + const closeEvent = page.waitForEvent("calciteSheetClose"); await page.keyboard.press("Escape"); await page.waitForChanges(); + await closeEvent; + expect(await sheet.isVisible()).toBe(false); expect(await sheet.getProperty("open")).toBe(false); + + openEvent = page.waitForEvent("calciteSheetOpen"); sheet.setProperty("open", true); await page.waitForChanges(); + await openEvent; + expect(await sheet.isVisible()).toBe(true); }); From 79e5db190c756e36b0887e2ae5e9a0718693aad2 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Thu, 22 May 2025 19:42:23 -0700 Subject: [PATCH 17/49] fix tests --- .../components/sort-handle/sort-handle.e2e.ts | 4 ++ .../src/components/tooltip/tooltip.e2e.ts | 60 +++++++++---------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/packages/calcite-components/src/components/sort-handle/sort-handle.e2e.ts b/packages/calcite-components/src/components/sort-handle/sort-handle.e2e.ts index 99334d1187c..22a9ef7953a 100644 --- a/packages/calcite-components/src/components/sort-handle/sort-handle.e2e.ts +++ b/packages/calcite-components/src/components/sort-handle/sort-handle.e2e.ts @@ -69,8 +69,10 @@ describe("calcite-sort-handle", () => { const action = await page.find(`calcite-sort-handle >>> .${CSS.handle}`); await action.callMethod("setFocus"); + const openEvent = page.waitForEvent("calciteSortHandleOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); + await openEvent; expect(await sortHandle.getProperty("open")).toBe(true); await page.keyboard.press("Enter"); @@ -99,8 +101,10 @@ describe("calcite-sort-handle", () => { const action = await page.find(`calcite-sort-handle >>> .${CSS.handle}`); await action.callMethod("setFocus"); + const openEvent = page.waitForEvent("calciteSortHandleOpen"); await page.keyboard.press("ArrowUp"); await page.waitForChanges(); + await openEvent; expect(await sortHandle.getProperty("open")).toBe(true); await page.keyboard.press(" "); diff --git a/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts b/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts index 764b43e7a8b..a96d93863c9 100644 --- a/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts +++ b/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts @@ -322,27 +322,22 @@ describe("calcite-tooltip", () => { it("should not open when hover event is prevented", async () => { const page = await newE2EPage(); - await page.setContent( `content
referenceElement
`, ); - - await page.waitForChanges(); - + await skipAnimations(page); const positionContainer = await page.find(`calcite-tooltip >>> .${CSS.positionContainer}`); - - expect(await positionContainer.isVisible()).toBe(false); - + const ref = await page.find("#ref"); await page.$eval("#ref", (ref) => { ref.addEventListener("pointermove", (event) => { event.preventDefault(); }); }); - const ref = await page.find("#ref"); + expect(await positionContainer.isVisible()).toBe(false); await ref.hover(); - + await page.waitForChanges(); await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); expect(await positionContainer.isVisible()).toBe(false); @@ -357,13 +352,13 @@ describe("calcite-tooltip", () => { `); await skipAnimations(page); - await page.waitForChanges(); - const positionContainer = await page.find(`calcite-tooltip >>> .${CSS.positionContainer}`); - const ref = await page.find("#ref"); + await ref.hover(); + await page.waitForChanges(); await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); + expect(await positionContainer.isVisible()).toBe(true); await page.$eval("#button-container", (buttonContainer) => { @@ -373,6 +368,7 @@ describe("calcite-tooltip", () => { }); await ref.hover(); + await page.waitForChanges(); await page.waitForTimeout(TOOLTIP_CLOSE_DELAY_MS); expect(await positionContainer.isVisible()).toBe(false); }); @@ -905,7 +901,6 @@ describe("calcite-tooltip", () => { await page.mouse.move(refElementX, refElementY, moveOptions); await page.mouse.move(refElementX + xMoveOffset, refElementY, moveOptions); await page.waitForChanges(); - await page.waitForTimeout(totalDelayFromMoveSteps); }, closeTooltip: async (page: E2EPage) => { @@ -915,7 +910,6 @@ describe("calcite-tooltip", () => { await page.mouse.move(refElementX, refElementY, moveOptions); await page.mouse.move(0, 0, moveOptions); await page.waitForChanges(); - await page.waitForTimeout(totalDelayFromMoveSteps); }, }); @@ -942,33 +936,38 @@ describe("calcite-tooltip", () => { await page.setContent( `content`, ); + await skipAnimations(page); const tooltip = await page.find("calcite-tooltip"); - const beforeOpenEvent = await tooltip.spyOnEvent("calciteTooltipBeforeOpen"); - const openEvent = await tooltip.spyOnEvent("calciteTooltipOpen"); - const beforeCloseEvent = await tooltip.spyOnEvent("calciteTooltipBeforeClose"); - const closeEvent = await tooltip.spyOnEvent("calciteTooltipClose"); + const beforeOpenEventSpy = await tooltip.spyOnEvent("calciteTooltipBeforeOpen"); + const openEventSpy = await tooltip.spyOnEvent("calciteTooltipOpen"); + const beforeCloseEventSpy = await tooltip.spyOnEvent("calciteTooltipBeforeClose"); + const closeEventSpy = await tooltip.spyOnEvent("calciteTooltipClose"); - expect(beforeOpenEvent).toHaveReceivedEventTimes(0); - expect(openEvent).toHaveReceivedEventTimes(0); - expect(beforeCloseEvent).toHaveReceivedEventTimes(0); - expect(closeEvent).toHaveReceivedEventTimes(0); + expect(beforeOpenEventSpy).toHaveReceivedEventTimes(0); + expect(openEventSpy).toHaveReceivedEventTimes(0); + expect(beforeCloseEventSpy).toHaveReceivedEventTimes(0); + expect(closeEventSpy).toHaveReceivedEventTimes(0); + const openEvent = page.waitForEvent("calciteTooltipOpen"); await params.openTooltip(page); await page.waitForChanges(); + await openEvent; - expect(beforeOpenEvent).toHaveReceivedEventTimes(1); - expect(openEvent).toHaveReceivedEventTimes(1); - expect(beforeCloseEvent).toHaveReceivedEventTimes(0); - expect(closeEvent).toHaveReceivedEventTimes(0); + expect(beforeOpenEventSpy).toHaveReceivedEventTimes(1); + expect(openEventSpy).toHaveReceivedEventTimes(1); + expect(beforeCloseEventSpy).toHaveReceivedEventTimes(0); + expect(closeEventSpy).toHaveReceivedEventTimes(0); + const closeEvent = page.waitForEvent("calciteTooltipClose"); await params.closeTooltip(page); await page.waitForChanges(); + await closeEvent; - expect(beforeOpenEvent).toHaveReceivedEventTimes(1); - expect(openEvent).toHaveReceivedEventTimes(1); - expect(beforeCloseEvent).toHaveReceivedEventTimes(1); - expect(closeEvent).toHaveReceivedEventTimes(1); + expect(beforeOpenEventSpy).toHaveReceivedEventTimes(1); + expect(openEventSpy).toHaveReceivedEventTimes(1); + expect(beforeCloseEventSpy).toHaveReceivedEventTimes(1); + expect(closeEventSpy).toHaveReceivedEventTimes(1); } it("when open, it emits close events if no longer rendered", async () => { @@ -997,6 +996,7 @@ describe("calcite-tooltip", () => { `); + await skipAnimations(page); const beforeCloseEvent = await page.spyOnEvent("calciteTooltipBeforeClose"); const closeEvent = await page.spyOnEvent("calciteTooltipClose"); From d51bb8f39ac9d70d88de8147d3fbfbcb41dbcf87 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Thu, 22 May 2025 19:42:23 -0700 Subject: [PATCH 18/49] fix tests --- .../src/components/carousel/carousel.e2e.ts | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/calcite-components/src/components/carousel/carousel.e2e.ts b/packages/calcite-components/src/components/carousel/carousel.e2e.ts index ec5102628c2..ad87cd0efd6 100644 --- a/packages/calcite-components/src/components/carousel/carousel.e2e.ts +++ b/packages/calcite-components/src/components/carousel/carousel.e2e.ts @@ -1037,11 +1037,17 @@ describe("calcite-carousel", () => { it("item slide animation finishes between paging/selection", async () => { const page = await newE2EPage(); await page.setContent( - html` -

first

-

second

-

third

-
`, + html` + +

first

+

second

+

third

+
`, ); const container = await page.find(`calcite-carousel >>> .${CSS.container}`); @@ -1049,10 +1055,15 @@ describe("calcite-carousel", () => { const animationEndSpy = await container.spyOnEvent("animationend"); const nextButton = await page.find(`calcite-carousel >>> .${CSS.pageNext}`); + let changeEvent = page.waitForEvent("calciteCarouselChange"); await nextButton.click(); await page.waitForChanges(); + await changeEvent; + + changeEvent = page.waitForEvent("calciteCarouselChange"); await nextButton.click(); await page.waitForChanges(); + await changeEvent; expect(animationStartSpy).toHaveReceivedEventTimes(2); expect(animationEndSpy).toHaveReceivedEventTimes(2); From f173ee62150bc3ede4e5643343447d13d981b501 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 23 May 2025 08:41:01 -0700 Subject: [PATCH 19/49] fix tests --- .../src/components/dropdown/dropdown.e2e.ts | 69 ++++++++++++++----- .../src/components/shell/shell.e2e.ts | 22 ++++-- 2 files changed, 68 insertions(+), 23 deletions(-) diff --git a/packages/calcite-components/src/components/dropdown/dropdown.e2e.ts b/packages/calcite-components/src/components/dropdown/dropdown.e2e.ts index 8ea1d2c0b87..e104bc72d31 100644 --- a/packages/calcite-components/src/components/dropdown/dropdown.e2e.ts +++ b/packages/calcite-components/src/components/dropdown/dropdown.e2e.ts @@ -782,32 +782,35 @@ describe("calcite-dropdown", () => { const dropdownWrapper = await page.find(`calcite-dropdown >>> .calcite-dropdown-wrapper`); const calciteDropdownOpen = await element.spyOnEvent("calciteDropdownOpen"); const calciteDropdownClose = await element.spyOnEvent("calciteDropdownClose"); - let waitForCalciteDropdownOpen = page.waitForEvent("calciteDropdownOpen"); - const waitForCalciteDropdownClose = page.waitForEvent("calciteDropdownClose"); expect(await dropdownWrapper.isVisible()).toBe(false); + + let openEvent = page.waitForEvent("calciteDropdownOpen"); await trigger.click(); await page.waitForChanges(); + await openEvent; + expect(await dropdownWrapper.isVisible()).toBe(true); - await waitForCalciteDropdownOpen; expect(calciteDropdownOpen).toHaveReceivedEventTimes(1); expect(calciteDropdownClose).toHaveReceivedEventTimes(0); await element.callMethod("setFocus"); await page.waitForChanges(); + const closeEvent = page.waitForEvent("calciteDropdownClose"); await page.keyboard.press("Space"); await page.waitForChanges(); + await closeEvent; + expect(await dropdownWrapper.isVisible()).toBe(false); - await waitForCalciteDropdownClose; expect(calciteDropdownOpen).toHaveReceivedEventTimes(1); expect(calciteDropdownClose).toHaveReceivedEventTimes(1); - waitForCalciteDropdownOpen = page.waitForEvent("calciteDropdownOpen"); - + openEvent = page.waitForEvent("calciteDropdownOpen"); await page.keyboard.press("Enter"); await page.waitForChanges(); + await openEvent; + expect(await dropdownWrapper.isVisible()).toBe(true); - await waitForCalciteDropdownOpen; expect(calciteDropdownOpen).toHaveReceivedEventTimes(2); expect(calciteDropdownClose).toHaveReceivedEventTimes(1); }); @@ -829,32 +832,35 @@ describe("calcite-dropdown", () => { const dropdownWrapper = await page.find(`calcite-dropdown >>> .calcite-dropdown-wrapper`); const calciteDropdownOpen = await element.spyOnEvent("calciteDropdownOpen"); const calciteDropdownClose = await element.spyOnEvent("calciteDropdownClose"); - let waitForCalciteDropdownOpen = page.waitForEvent("calciteDropdownOpen"); - const waitForCalciteDropdownClose = page.waitForEvent("calciteDropdownClose"); expect(await dropdownWrapper.isVisible()).toBe(false); + + let openEvent = page.waitForEvent("calciteDropdownOpen"); await trigger.click(); await page.waitForChanges(); + await openEvent; + expect(await dropdownWrapper.isVisible()).toBe(true); - await waitForCalciteDropdownOpen; expect(calciteDropdownOpen).toHaveReceivedEventTimes(1); expect(calciteDropdownClose).toHaveReceivedEventTimes(0); await element.callMethod("setFocus"); await page.waitForChanges(); + const closeEvent = page.waitForEvent("calciteDropdownClose"); await page.keyboard.press("Space"); await page.waitForChanges(); + await closeEvent; + expect(await dropdownWrapper.isVisible()).toBe(false); - await waitForCalciteDropdownClose; expect(calciteDropdownOpen).toHaveReceivedEventTimes(1); expect(calciteDropdownClose).toHaveReceivedEventTimes(1); - waitForCalciteDropdownOpen = page.waitForEvent("calciteDropdownOpen"); - + openEvent = page.waitForEvent("calciteDropdownOpen"); await page.keyboard.press("Enter"); await page.waitForChanges(); + await openEvent; + expect(await dropdownWrapper.isVisible()).toBe(true); - await waitForCalciteDropdownOpen; expect(calciteDropdownOpen).toHaveReceivedEventTimes(2); expect(calciteDropdownClose).toHaveReceivedEventTimes(1); }); @@ -875,7 +881,7 @@ describe("calcite-dropdown", () => { const dropdownWrapper = await page.find(`calcite-dropdown >>> .calcite-dropdown-wrapper`); const calciteDropdownOpen = await element.spyOnEvent("calciteDropdownOpen"); const calciteDropdownClose = await element.spyOnEvent("calciteDropdownClose"); - const waitForCalciteDropdownOpen = page.waitForEvent("calciteDropdownOpen"); + const openEvent = page.waitForEvent("calciteDropdownOpen"); expect(await dropdownWrapper.isVisible()).toBe(false); @@ -885,8 +891,9 @@ describe("calcite-dropdown", () => { }); await page.waitForChanges(); + await openEvent; + expect(await dropdownWrapper.isVisible()).toBe(true); - await waitForCalciteDropdownOpen; expect(calciteDropdownOpen).toHaveReceivedEventTimes(1); expect(calciteDropdownClose).toHaveReceivedEventTimes(0); }); @@ -912,15 +919,22 @@ describe("calcite-dropdown", () => { const calciteDropdownOpen = await element.spyOnEvent("calciteDropdownOpen"); expect(await dropdownWrapper.isVisible()).toBe(false); + + const openEvent = page.waitForEvent("calciteDropdownOpen"); await trigger.click(); await page.waitForChanges(); + await openEvent; + expect(await dropdownWrapper.isVisible()).toBe(true); expect(calciteDropdownOpen).toHaveReceivedEventTimes(1); expect(calciteDropdownClose).toHaveReceivedEventTimes(0); expect(await getFocusedElementProp(page, "id")).toBe("item-2"); + const closeEvent = page.waitForEvent("calciteDropdownClose"); await element.press("Tab"); await page.waitForChanges(); + await closeEvent; + expect(await getFocusedElementProp(page, "id")).toBe("button-1"); expect(calciteDropdownClose).toHaveReceivedEventTimes(1); expect(await dropdownWrapper.isVisible()).toBe(false); @@ -945,17 +959,24 @@ describe("calcite-dropdown", () => { const calciteDropdownOpen = await element.spyOnEvent("calciteDropdownOpen"); expect(await dropdownWrapper.isVisible()).toBe(false); + + const openEvent = page.waitForEvent("calciteDropdownOpen"); await trigger.click(); await page.waitForChanges(); + await openEvent; + expect(await dropdownWrapper.isVisible()).toBe(true); expect(calciteDropdownOpen).toHaveReceivedEventTimes(1); expect(calciteDropdownClose).toHaveReceivedEventTimes(0); expect(await getFocusedElementProp(page, "id")).toBe("item-2"); + const closeEvent = page.waitForEvent("calciteDropdownClose"); await page.keyboard.down("Shift"); await element.press("Tab"); await page.keyboard.up("Shift"); await page.waitForChanges(); + await closeEvent; + expect(await getFocusedElementProp(page, "id")).toBe("trigger"); expect(calciteDropdownClose).toHaveReceivedEventTimes(1); expect(await dropdownWrapper.isVisible()).toBe(false); @@ -1263,8 +1284,10 @@ describe("calcite-dropdown", () => { await dropdown.callMethod("setFocus"); await page.waitForChanges(); + const openEvent = page.waitForEvent("calciteDropdownOpen"); await page.keyboard.press("Enter"); await page.waitForChanges(); + await openEvent; expect(await isElementFocused(page, "#item-1")).toBe(true); @@ -1325,8 +1348,10 @@ describe("calcite-dropdown", () => { await dropdown.callMethod("setFocus"); await page.waitForChanges(); + const openEvent = page.waitForEvent("calciteDropdownOpen"); await page.keyboard.press("Enter"); await page.waitForChanges(); + await openEvent; expect(await isElementFocused(page, "#item-2")).toBe(true); @@ -1374,8 +1399,11 @@ describe("calcite-dropdown", () => { await dropdown.callMethod("setFocus"); await page.waitForChanges(); + const openEvent = page.waitForEvent("calciteDropdownOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); + await openEvent; + expect(await dropdown.getProperty("open")).toBe(true); expect(await isElementFocused(page, "#item-1")).toBe(true); @@ -1406,8 +1434,11 @@ describe("calcite-dropdown", () => { await dropdown.callMethod("setFocus"); await page.waitForChanges(); + const openEvent = page.waitForEvent("calciteDropdownOpen"); await page.keyboard.press("ArrowUp"); await page.waitForChanges(); + await openEvent; + expect(await dropdown.getProperty("open")).toBe(true); expect(await isElementFocused(page, "#item-3")).toBe(true); @@ -1438,8 +1469,11 @@ describe("calcite-dropdown", () => { await dropdown.callMethod("setFocus"); await page.waitForChanges(); + const openEvent = page.waitForEvent("calciteDropdownOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); + await openEvent; + expect(await dropdown.getProperty("open")).toBe(true); expect(await isElementFocused(page, "#item-2")).toBe(true); @@ -1470,8 +1504,11 @@ describe("calcite-dropdown", () => { await dropdown.callMethod("setFocus"); await page.waitForChanges(); + const openEvent = page.waitForEvent("calciteDropdownOpen"); await page.keyboard.press("ArrowUp"); await page.waitForChanges(); + await openEvent; + expect(await dropdown.getProperty("open")).toBe(true); expect(await isElementFocused(page, "#item-2")).toBe(true); diff --git a/packages/calcite-components/src/components/shell/shell.e2e.ts b/packages/calcite-components/src/components/shell/shell.e2e.ts index bb35cbe5120..4751b4cdd11 100644 --- a/packages/calcite-components/src/components/shell/shell.e2e.ts +++ b/packages/calcite-components/src/components/shell/shell.e2e.ts @@ -2,6 +2,7 @@ import { newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; import { describe, expect, it } from "vitest"; import { accessible, hidden, renders, slots, themed } from "../../tests/commonTests"; import { html } from "../../../support/formatting"; +import { getFocusedElementProp } from "../../tests/utils/puppeteer"; import { CSS, SLOTS } from "./resources"; describe("calcite-shell", () => { @@ -143,7 +144,6 @@ describe("calcite-shell", () => { it("sheet embedded in shell slot does not prevent interaction with page content outside slot", async () => { const page = await newE2EPage(); - await page.setContent( html` @@ -161,10 +161,13 @@ describe("calcite-shell", () => { `, ); const block = await page.find("calcite-block"); + + const openEvent = block.waitForEvent("calciteBlockOpen"); block.click(); - await page.waitForChanges(); + await openEvent; + expect(await block.getProperty("expanded")).toBe(true); - expect(await page.evaluate(() => document.activeElement.id)).toEqual(block.id); + expect(await getFocusedElementProp(page, "id")).toEqual(block.id); }); it("modal dialog embedded in shell slot does not prevent interaction with page content outside slot", async () => { @@ -185,10 +188,12 @@ describe("calcite-shell", () => { ); const block = await page.find("calcite-block"); + const openEvent = block.waitForEvent("calciteBlockOpen"); block.click(); - await page.waitForChanges(); + await openEvent; + expect(await block.getProperty("expanded")).toBe(true); - expect(await page.evaluate(() => document.activeElement.id)).toEqual(block.id); + expect(await getFocusedElementProp(page, "id")).toEqual(block.id); }); it("deprecated modal embedded in shell slot does not prevent interaction with page content outside slot", async () => { @@ -210,10 +215,13 @@ describe("calcite-shell", () => { `, ); const block = await page.find("calcite-block"); + + const openEvent = block.waitForEvent("calciteBlockOpen"); block.click(); - await page.waitForChanges(); + await openEvent; + expect(await block.getProperty("expanded")).toBe(true); - expect(await page.evaluate(() => document.activeElement.id)).toEqual(block.id); + expect(await getFocusedElementProp(page, "id")).toEqual(block.id); }); describe("theme", () => { From 9571c517bfd535cc461ce0ceb98ed79ce5b1a85f Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 23 May 2025 08:49:29 -0700 Subject: [PATCH 20/49] add missing awaits --- .../calcite-components/src/components/shell/shell.e2e.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/calcite-components/src/components/shell/shell.e2e.ts b/packages/calcite-components/src/components/shell/shell.e2e.ts index 4751b4cdd11..37740187cab 100644 --- a/packages/calcite-components/src/components/shell/shell.e2e.ts +++ b/packages/calcite-components/src/components/shell/shell.e2e.ts @@ -163,7 +163,7 @@ describe("calcite-shell", () => { const block = await page.find("calcite-block"); const openEvent = block.waitForEvent("calciteBlockOpen"); - block.click(); + await block.click(); await openEvent; expect(await block.getProperty("expanded")).toBe(true); @@ -189,7 +189,7 @@ describe("calcite-shell", () => { const block = await page.find("calcite-block"); const openEvent = block.waitForEvent("calciteBlockOpen"); - block.click(); + await block.click(); await openEvent; expect(await block.getProperty("expanded")).toBe(true); @@ -217,7 +217,7 @@ describe("calcite-shell", () => { const block = await page.find("calcite-block"); const openEvent = block.waitForEvent("calciteBlockOpen"); - block.click(); + await block.click(); await openEvent; expect(await block.getProperty("expanded")).toBe(true); From 8fc2f70334dcb98f5eb3b28f91a641f3243c715b Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 23 May 2025 11:37:11 -0700 Subject: [PATCH 21/49] fix tests --- .../src/components/combobox/combobox.e2e.ts | 22 ++++++++++++++----- .../src/components/modal/modal.e2e.ts | 3 +++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/packages/calcite-components/src/components/combobox/combobox.e2e.ts b/packages/calcite-components/src/components/combobox/combobox.e2e.ts index 6bf54a82002..ad52930bb8e 100644 --- a/packages/calcite-components/src/components/combobox/combobox.e2e.ts +++ b/packages/calcite-components/src/components/combobox/combobox.e2e.ts @@ -1673,6 +1673,7 @@ describe("calcite-combobox", () => { `); + await skipAnimations(page); }); it("should not show the listbox when it receives focus", async () => { @@ -1695,7 +1696,6 @@ describe("calcite-combobox", () => { }); it("tab will close the item group if it’s open", async () => { - await skipAnimations(page); const inputEl = await page.find(`#myCombobox >>> input`); await inputEl.focus(); await page.waitForChanges(); @@ -1737,30 +1737,39 @@ describe("calcite-combobox", () => { const inputEl = await page.find(`#myCombobox >>> input`); await inputEl.focus(); await page.waitForChanges(); + expect(await page.evaluate(() => document.activeElement.id)).toBe("myCombobox"); + const openEvent = page.waitForEvent("calciteComboboxOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); + await openEvent; const firstFocusedGroupItem = await page.find(`#one >>> .${ComboboxItemCSS.active}`); + expect(firstFocusedGroupItem).toBeTruthy(); }); it(`Escape closes the dropdown, but remains focused`, async () => { - await skipAnimations(page); const inputEl = await page.find(`#myCombobox >>> input`); await inputEl.focus(); await page.waitForChanges(); + expect(await page.evaluate(() => document.activeElement.id)).toBe("myCombobox"); + const openEvent = page.waitForEvent("calciteComboboxOpen"); await page.keyboard.press("Space"); await page.waitForChanges(); + await openEvent; const floatingUI = await page.find(`#myCombobox >>> .${CSS.floatingUIContainer}`); + expect(await floatingUI.isVisible()).toBe(true); + const closeEvent = page.waitForEvent("calciteComboboxClose"); await page.keyboard.press("Escape"); await page.waitForChanges(); - expect(await floatingUI.isVisible()).toBe(false); + await closeEvent; + expect(await floatingUI.isVisible()).toBe(false); expect(await page.evaluate(() => document.activeElement.id)).toBe("myCombobox"); }); @@ -1768,15 +1777,18 @@ describe("calcite-combobox", () => { const inputEl = await page.find(`#myCombobox >>> input`); await inputEl.focus(); await page.waitForChanges(); + expect(await page.evaluate(() => document.activeElement.id)).toBe("myCombobox"); + const openEvent = page.waitForEvent("calciteComboboxOpen"); await page.keyboard.press("Space"); await page.waitForChanges(); + await openEvent; const firstFocusedGroupItem = await page.find(`#one >>> .${ComboboxItemCSS.active}`); + expect(firstFocusedGroupItem).toBeTruthy(); - const visible = await firstFocusedGroupItem.isVisible(); - expect(visible).toBe(true); + expect(await firstFocusedGroupItem.isVisible()).toBe(true); await page.keyboard.press("Space"); await page.waitForChanges(); diff --git a/packages/calcite-components/src/components/modal/modal.e2e.ts b/packages/calcite-components/src/components/modal/modal.e2e.ts index 76f3ef01b82..384fe3c6b9d 100644 --- a/packages/calcite-components/src/components/modal/modal.e2e.ts +++ b/packages/calcite-components/src/components/modal/modal.e2e.ts @@ -201,6 +201,7 @@ describe("calcite-modal", () => { it("calls the beforeClose method prior to closing via attribute", async () => { const page = await newE2EPage(); + await skipAnimations(page); const mockCallBack = vi.fn(); await page.exposeFunction("beforeClose", mockCallBack); await page.setContent(` @@ -224,6 +225,7 @@ describe("calcite-modal", () => { it("should handle rejected 'beforeClose' promise'", async () => { const page = await newE2EPage(); + await skipAnimations(page); const mockCallBack = vi.fn().mockReturnValue(() => Promise.reject()); await page.exposeFunction("beforeClose", mockCallBack); @@ -244,6 +246,7 @@ describe("calcite-modal", () => { it("should remain open with rejected 'beforeClose' promise'", async () => { const page = await newE2EPage(); + await skipAnimations(page); await page.exposeFunction("beforeClose", () => Promise.reject()); await page.setContent(``); From 4588599955f722d53a098934baee0b47b12a7db0 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 23 May 2025 14:11:23 -0700 Subject: [PATCH 22/49] fix tests --- packages/calcite-components/src/components/icon/icon.e2e.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/calcite-components/src/components/icon/icon.e2e.ts b/packages/calcite-components/src/components/icon/icon.e2e.ts index b9aaf413068..aa11d7e6895 100644 --- a/packages/calcite-components/src/components/icon/icon.e2e.ts +++ b/packages/calcite-components/src/components/icon/icon.e2e.ts @@ -84,6 +84,9 @@ describe("calcite-icon", () => { expect(path.getAttribute("d")).toBeFalsy(); icon.setProperty("style", null); + + // intentional double waitForChanges to ensure the icon is loaded (sequenced prop updates) + await page.waitForChanges(); await page.waitForChanges(); expect(path.getAttribute("d")).toBeTruthy(); From 6d55f756bc05ed7bab90008a10571e181a66d174 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 23 May 2025 15:09:01 -0700 Subject: [PATCH 23/49] fix tests --- .../src/components/handle/handle.e2e.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/calcite-components/src/components/handle/handle.e2e.ts b/packages/calcite-components/src/components/handle/handle.e2e.ts index dc671ff64c7..6abfec9917d 100644 --- a/packages/calcite-components/src/components/handle/handle.e2e.ts +++ b/packages/calcite-components/src/components/handle/handle.e2e.ts @@ -109,18 +109,21 @@ describe("calcite-handle", () => { it("fires calciteHandleNudge event when focused and up or down key is pressed", async () => { const page = await newE2EPage(); await page.setContent(""); - const calciteHandleNudgeSpy = await page.spyOnEvent("calciteHandleNudge"); - const button = await page.find(`calcite-handle >>> .${CSS.handle}`); + let nudgeEvent = page.waitForEvent("calciteHandleNudge"); await button.focus(); - await page.keyboard.press(" "); await page.keyboard.press("ArrowUp"); + await nudgeEvent; + expect(await calciteHandleNudgeSpy.lastEvent.detail.direction).toBe("up"); + nudgeEvent = page.waitForEvent("calciteHandleNudge"); await page.keyboard.press("ArrowDown"); + await nudgeEvent; + expect(await calciteHandleNudgeSpy.lastEvent.detail.direction).toBe("down"); expect(calciteHandleNudgeSpy).toHaveReceivedEventTimes(2); }); From 14c9b44b9d699465d2a26afc5505c7ae42acd5ea Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 23 May 2025 16:29:01 -0700 Subject: [PATCH 24/49] fix tests --- .../src/components/handle/handle.e2e.ts | 16 ++++++++++------ .../src/tests/stackedFocusTrap.e2e.ts | 17 ++++++++++++----- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/packages/calcite-components/src/components/handle/handle.e2e.ts b/packages/calcite-components/src/components/handle/handle.e2e.ts index 6abfec9917d..4d1eddd681f 100644 --- a/packages/calcite-components/src/components/handle/handle.e2e.ts +++ b/packages/calcite-components/src/components/handle/handle.e2e.ts @@ -109,22 +109,26 @@ describe("calcite-handle", () => { it("fires calciteHandleNudge event when focused and up or down key is pressed", async () => { const page = await newE2EPage(); await page.setContent(""); + await skipAnimations(page); + const handle = await page.find(`calcite-handle`); + let nudgeEvent = handle.waitForEvent("calciteHandleNudge"); const calciteHandleNudgeSpy = await page.spyOnEvent("calciteHandleNudge"); - const button = await page.find(`calcite-handle >>> .${CSS.handle}`); - let nudgeEvent = page.waitForEvent("calciteHandleNudge"); - await button.focus(); + await handle.callMethod("setFocus"); await page.keyboard.press(" "); + await page.waitForChanges(); await page.keyboard.press("ArrowUp"); + await page.waitForChanges(); await nudgeEvent; - expect(await calciteHandleNudgeSpy.lastEvent.detail.direction).toBe("up"); + expect(calciteHandleNudgeSpy.lastEvent.detail.direction).toBe("up"); - nudgeEvent = page.waitForEvent("calciteHandleNudge"); + nudgeEvent = handle.waitForEvent("calciteHandleNudge"); await page.keyboard.press("ArrowDown"); + await page.waitForChanges(); await nudgeEvent; - expect(await calciteHandleNudgeSpy.lastEvent.detail.direction).toBe("down"); + expect(calciteHandleNudgeSpy.lastEvent.detail.direction).toBe("down"); expect(calciteHandleNudgeSpy).toHaveReceivedEventTimes(2); }); diff --git a/packages/calcite-components/src/tests/stackedFocusTrap.e2e.ts b/packages/calcite-components/src/tests/stackedFocusTrap.e2e.ts index 61067430655..32423335757 100644 --- a/packages/calcite-components/src/tests/stackedFocusTrap.e2e.ts +++ b/packages/calcite-components/src/tests/stackedFocusTrap.e2e.ts @@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest"; import { html } from "../../support/formatting"; import { IDS } from "../components/panel/resources"; import { CSS } from "../components/input-time-picker/resources"; -import { skipAnimations } from "./utils/puppeteer"; +import { skipAnimations, waitForAnimationFrame } from "./utils/puppeteer"; describe("stacked focus-trap components", () => { const componentStack = html` @@ -60,7 +60,10 @@ describe("stacked focus-trap components", () => { await page.setContent(componentStack); await skipAnimations(page); - async function testStackEscapeSequence(page: E2EPage, pickerType: string): Promise { + async function testStackEscapeSequence( + page: E2EPage, + pickerType: "calcite-input-date-picker" | "calcite-input-time-picker", + ): Promise { async function openAndCheckVisibility(element: E2EElement): Promise { const elTagNameCamelCased = camelCase(element.tagName); const openEvent = page.waitForEvent(`${elTagNameCamelCased}Open`); @@ -117,7 +120,7 @@ describe("stacked focus-trap components", () => { const firstModal = await page.find("#example-modal"); const secondModal = await page.find("#another-modal"); const popover = await page.find("#popover"); - const inputPicker = await page.find(pickerType); + const inputTimeOrDatePicker = await page.find(pickerType); await openAndCheckVisibility(sheet); await openAndCheckVisibility(dialog); @@ -128,10 +131,14 @@ describe("stacked focus-trap components", () => { const clickTarget = pickerType === "calcite-input-time-picker" ? await page.find(`calcite-input-time-picker >>> .${CSS.toggleIcon}`) - : inputPicker; + : inputTimeOrDatePicker; await clickTarget.click(); + await page.waitForChanges(); + // intentional double wait waitForAnimationFrame to ensure focus shift + await waitForAnimationFrame(page); + await waitForAnimationFrame(page); - await testEscapeAndAssertOpenState([inputPicker, popover, secondModal, firstModal, dialog, sheet]); + await testEscapeAndAssertOpenState([inputTimeOrDatePicker, popover, secondModal, firstModal, dialog, sheet]); } await testStackEscapeSequence(page, "calcite-input-time-picker"); From 3a830a6f11d04b72acf89d82fccb9ace60622813 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 23 May 2025 17:39:47 -0700 Subject: [PATCH 25/49] remove unnecessary skipAnimations --- packages/calcite-components/src/components/handle/handle.e2e.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/calcite-components/src/components/handle/handle.e2e.ts b/packages/calcite-components/src/components/handle/handle.e2e.ts index 4d1eddd681f..47df4536f03 100644 --- a/packages/calcite-components/src/components/handle/handle.e2e.ts +++ b/packages/calcite-components/src/components/handle/handle.e2e.ts @@ -109,7 +109,6 @@ describe("calcite-handle", () => { it("fires calciteHandleNudge event when focused and up or down key is pressed", async () => { const page = await newE2EPage(); await page.setContent(""); - await skipAnimations(page); const handle = await page.find(`calcite-handle`); let nudgeEvent = handle.waitForEvent("calciteHandleNudge"); const calciteHandleNudgeSpy = await page.spyOnEvent("calciteHandleNudge"); From 7b211b47ad549bb6d765f1ac860eec7ca8b012df Mon Sep 17 00:00:00 2001 From: JC Franco Date: Sat, 24 May 2025 00:03:34 -0700 Subject: [PATCH 26/49] drop redundant style tests --- .../src/components/modal/modal.e2e.ts | 43 ------------------- 1 file changed, 43 deletions(-) diff --git a/packages/calcite-components/src/components/modal/modal.e2e.ts b/packages/calcite-components/src/components/modal/modal.e2e.ts index 384fe3c6b9d..d61043ec6b2 100644 --- a/packages/calcite-components/src/components/modal/modal.e2e.ts +++ b/packages/calcite-components/src/components/modal/modal.e2e.ts @@ -664,49 +664,6 @@ describe("calcite-modal", () => { expect(await footer.isVisible()).toBe(false); }); - it("should render calcite-scrim with default background color", async () => { - const page = await newE2EPage({ - html: ` - - -
The actual content of the modal
- - Back - - Cancel - Save -
- `, - }); - const scrimStyles = await page.evaluate(() => { - const scrim = document.querySelector("calcite-modal").shadowRoot.querySelector(".scrim"); - return window.getComputedStyle(scrim).getPropertyValue("--calcite-scrim-background"); - }); - expect(scrimStyles.trim()).toEqual("rgba(0, 0, 0, 0.85)"); - }); - - it("when modal css override set, scrim should adhere to requested color", async () => { - const overrideStyle = "rgba(160, 20, 10, 0.5)"; - const page = await newE2EPage({ - html: ` - - -
The actual content of the modal
- - Back - - Cancel - Save -
- `, - }); - const scrimStyles = await page.evaluate(() => { - const scrim = document.querySelector("calcite-modal").shadowRoot.querySelector(".scrim"); - return window.getComputedStyle(scrim).getPropertyValue("--calcite-scrim-background"); - }); - expect(scrimStyles).toEqual(overrideStyle); - }); - it("correctly reflects the scale of the modal on the close button icon", async () => { const page = await newE2EPage(); await page.setContent(html` `); From de23b416ac9c9c03815319a855e2f3c2658c916b Mon Sep 17 00:00:00 2001 From: JC Franco Date: Sat, 24 May 2025 00:03:50 -0700 Subject: [PATCH 27/49] fix tests --- .../src/components/modal/modal.e2e.ts | 60 ++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/packages/calcite-components/src/components/modal/modal.e2e.ts b/packages/calcite-components/src/components/modal/modal.e2e.ts index d61043ec6b2..ac5667582ee 100644 --- a/packages/calcite-components/src/components/modal/modal.e2e.ts +++ b/packages/calcite-components/src/components/modal/modal.e2e.ts @@ -246,10 +246,9 @@ describe("calcite-modal", () => { it("should remain open with rejected 'beforeClose' promise'", async () => { const page = await newE2EPage(); + await page.setContent(``); await skipAnimations(page); - await page.exposeFunction("beforeClose", () => Promise.reject()); - await page.setContent(``); await page.$eval( "calcite-modal", @@ -278,6 +277,7 @@ describe("calcite-modal", () => { `, ); + await skipAnimations(page); const modal = await page.find("calcite-modal"); const opened = page.waitForEvent("calciteModalOpen"); modal.setProperty("open", true); @@ -519,36 +519,59 @@ describe("calcite-modal", () => { it("should close when the scrim is clicked", async () => { const page = await newE2EPage(); await page.setContent(``); + await skipAnimations(page); const modal = await page.find("calcite-modal"); + + const openEvent = page.waitForEvent("calciteModalOpen"); modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; + expect(modal).toHaveAttribute("open"); + + const closeEvent = page.waitForEvent("calciteModalClose"); await page.$eval("calcite-modal", (el) => el.shadowRoot.querySelector("calcite-scrim").click()); await page.waitForChanges(); + await closeEvent; + expect(await modal.getProperty("open")).toBe(false); }); it("should not close when the scrim is clicked", async () => { const page = await newE2EPage(); await page.setContent(``); + await skipAnimations(page); const modal = await page.find("calcite-modal"); + + const openEvent = page.waitForEvent("calciteModalOpen"); modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; + expect(modal).toHaveAttribute("open"); + await page.$eval("calcite-modal", (el) => el.shadowRoot.querySelector("calcite-scrim").click()); await page.waitForChanges(); + expect(await modal.getProperty("open")).toBe(true); }); it("does not close when Escape is pressed and escape-disabled is set", async () => { const page = await newE2EPage(); await page.setContent(``); + await skipAnimations(page); const modal = await page.find("calcite-modal"); + + const openEvent = page.waitForEvent("calciteModalOpen"); await modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; + expect(modal).toHaveAttribute("open"); + await page.keyboard.press("Escape"); await page.waitForChanges(); + expect(modal).toHaveAttribute("open"); }); @@ -560,15 +583,20 @@ describe("calcite-modal", () => { it("correctly sets overflow style on document when opened/closed", async () => { const page = await newE2EPage(); await page.setContent(``); + await skipAnimations(page); const modal = await page.find("calcite-modal"); + const openEvent = page.waitForEvent("calciteModalOpen"); await modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await hasOverflowStyle(page)).toEqual(true); + const closeEvent = page.waitForEvent("calciteModalClose"); await modal.setProperty("open", false); await page.waitForChanges(); + await closeEvent; expect(await hasOverflowStyle(page)).toEqual(false); }); @@ -576,16 +604,21 @@ describe("calcite-modal", () => { it("preserves existing overflow style when modal is opened/closed", async () => { const page = await newE2EPage(); await page.setContent(``); + await skipAnimations(page); await page.evaluate(() => (document.documentElement.style.overflow = "scroll")); const modal = await page.find("calcite-modal"); + const openEvent = page.waitForEvent("calciteModalOpen"); await modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await hasOverflowStyle(page)).toEqual(true); + const closeEvent = page.waitForEvent("calciteModalClose"); await modal.setProperty("open", false); await page.waitForChanges(); + await closeEvent; expect(await page.evaluate(() => document.documentElement.style.overflow)).toEqual("scroll"); }); @@ -593,10 +626,13 @@ describe("calcite-modal", () => { it("correctly does not add overflow style on document when open and slotted in shell modals slot", async () => { const page = await newE2EPage(); await page.setContent(``); + await skipAnimations(page); const modal = await page.find("calcite-modal"); + const openEvent = page.waitForEvent("calciteModalOpen"); await modal.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await hasOverflowStyle(page)).toEqual(false); }); @@ -607,20 +643,29 @@ describe("calcite-modal", () => { `); + await skipAnimations(page); const modal1 = await page.find("#modal-1"); const modal2 = await page.find("#modal-2"); + let openEvent = page.waitForEvent("calciteModalOpen"); await modal1.setProperty("open", true); await page.waitForChanges(); + await openEvent; + openEvent = page.waitForEvent("calciteModalOpen"); await modal2.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await hasOverflowStyle(page)).toEqual(true); + let closeEvent = page.waitForEvent("calciteModalClose"); await modal2.setProperty("open", false); await page.waitForChanges(); + await closeEvent; + closeEvent = page.waitForEvent("calciteModalClose"); await modal1.setProperty("open", false); await page.waitForChanges(); + await closeEvent; expect(await hasOverflowStyle(page)).toEqual(false); }); @@ -631,20 +676,29 @@ describe("calcite-modal", () => { `); + await skipAnimations(page); const modal1 = await page.find("#modal-1"); const modal2 = await page.find("#modal-2"); + let openEvent = page.waitForEvent("calciteModalOpen"); await modal1.setProperty("open", true); await page.waitForChanges(); + await openEvent; + openEvent = page.waitForEvent("calciteModalOpen"); await modal2.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await hasOverflowStyle(page)).toEqual(true); + let closeEvent = page.waitForEvent("calciteModalClose"); await modal1.setProperty("open", false); await page.waitForChanges(); + await closeEvent; + closeEvent = page.waitForEvent("calciteModalClose"); await modal2.setProperty("open", false); await page.waitForChanges(); + await closeEvent; expect(await hasOverflowStyle(page)).toEqual(false); }); @@ -657,6 +711,7 @@ describe("calcite-modal", () => { TEST `); + await skipAnimations(page); const footer = await page.find("calcite-modal >>> .footer"); expect(await footer.isVisible()).toBe(true); await page.$eval("calcite-button", (el) => el.parentElement.removeChild(el)); @@ -667,6 +722,7 @@ describe("calcite-modal", () => { it("correctly reflects the scale of the modal on the close button icon", async () => { const page = await newE2EPage(); await page.setContent(html` `); + await skipAnimations(page); const modal = await page.find("calcite-modal"); modal.setProperty("scale", "s"); await page.waitForChanges(); From e596f11b70827901835754798d90ce3d2f21d262 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 27 May 2025 09:06:11 -0700 Subject: [PATCH 28/49] move fn expose after page setup --- packages/calcite-components/src/components/modal/modal.e2e.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/calcite-components/src/components/modal/modal.e2e.ts b/packages/calcite-components/src/components/modal/modal.e2e.ts index ac5667582ee..403448bbf90 100644 --- a/packages/calcite-components/src/components/modal/modal.e2e.ts +++ b/packages/calcite-components/src/components/modal/modal.e2e.ts @@ -150,10 +150,10 @@ describe("calcite-modal", () => { it("calls the beforeClose method prior to closing via click", async () => { const page = await newE2EPage(); const mockCallBack = vi.fn(); - await page.exposeFunction("beforeClose", mockCallBack); await page.setContent(` `); + await page.exposeFunction("beforeClose", mockCallBack); const modal = await page.find("calcite-modal"); await page.$eval( "calcite-modal", From 498ef7ae80c051ea728ab0a3ebff99f2897d1495 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 27 May 2025 09:13:39 -0700 Subject: [PATCH 29/49] move fn expose after page setup --- .../calcite-components/src/components/sheet/sheet.e2e.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/calcite-components/src/components/sheet/sheet.e2e.ts b/packages/calcite-components/src/components/sheet/sheet.e2e.ts index 5a34a0c2698..28fae103f32 100644 --- a/packages/calcite-components/src/components/sheet/sheet.e2e.ts +++ b/packages/calcite-components/src/components/sheet/sheet.e2e.ts @@ -322,16 +322,15 @@ describe("calcite-sheet properties", () => { it("should remain open with rejected 'beforeClose' promise'", async () => { const page = await newE2EPage(); - - await page.exposeFunction("beforeClose", () => Promise.reject()); await page.setContent(``); + await page.exposeFunction("beforeClose", () => Promise.reject()); + const sheet = await page.find("calcite-sheet"); await page.$eval( "calcite-sheet", (elm: Sheet["el"]) => (elm.beforeClose = (window as typeof window & Pick).beforeClose), ); - const sheet = await page.find("calcite-sheet"); sheet.setProperty("open", false); await page.waitForChanges(); From 93a371ce07a5938fd21058974acf3b16f61b1626 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 27 May 2025 14:22:45 -0700 Subject: [PATCH 30/49] fix imports --- packages/calcite-components/src/components/shell/shell.e2e.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/calcite-components/src/components/shell/shell.e2e.ts b/packages/calcite-components/src/components/shell/shell.e2e.ts index e36284b7728..11c11daa328 100644 --- a/packages/calcite-components/src/components/shell/shell.e2e.ts +++ b/packages/calcite-components/src/components/shell/shell.e2e.ts @@ -3,8 +3,8 @@ import { describe, expect, it } from "vitest"; import { accessible, hidden, renders, slots, themed } from "../../tests/commonTests"; import { html } from "../../../support/formatting"; import { getFocusedElementProp } from "../../tests/utils/puppeteer"; -import { CSS, SLOTS } from "./resources"; import { mockConsole } from "../../tests/utils/logging"; +import { CSS, SLOTS } from "./resources"; describe("calcite-shell", () => { describe("renders", () => { From 84074d072583c31e01bfd6b0a8c50e10e6b64125 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 27 May 2025 14:47:02 -0700 Subject: [PATCH 31/49] restore unintentional mockConsole removal --- packages/calcite-components/src/components/shell/shell.e2e.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/calcite-components/src/components/shell/shell.e2e.ts b/packages/calcite-components/src/components/shell/shell.e2e.ts index 11c11daa328..65482b76684 100644 --- a/packages/calcite-components/src/components/shell/shell.e2e.ts +++ b/packages/calcite-components/src/components/shell/shell.e2e.ts @@ -231,6 +231,8 @@ describe("calcite-shell", () => { describe("theme", () => { describe("default", () => { + mockConsole(); + themed( html` Hello world From 0ebde94dde885f01fe06daf32e750a7bcbc63808 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 27 May 2025 16:38:33 -0700 Subject: [PATCH 32/49] group beforeClose tests --- .../src/components/modal/modal.e2e.ts | 194 ++++++++---------- 1 file changed, 91 insertions(+), 103 deletions(-) diff --git a/packages/calcite-components/src/components/modal/modal.e2e.ts b/packages/calcite-components/src/components/modal/modal.e2e.ts index 403448bbf90..f11edba1923 100644 --- a/packages/calcite-components/src/components/modal/modal.e2e.ts +++ b/packages/calcite-components/src/components/modal/modal.e2e.ts @@ -1,6 +1,6 @@ // @ts-strict-ignore -import { E2EPage, newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; -import { describe, expect, it, vi } from "vitest"; +import { E2EElement, E2EPage, newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { defaults, focusable, hidden, openClose, renders, slots, t9n } from "../../tests/commonTests"; import { html } from "../../../support/formatting"; import { @@ -147,121 +147,109 @@ describe("calcite-modal", () => { expect(styleH).toEqual("800px"); }); - it("calls the beforeClose method prior to closing via click", async () => { - const page = await newE2EPage(); - const mockCallBack = vi.fn(); - await page.setContent(` - - `); - await page.exposeFunction("beforeClose", mockCallBack); - const modal = await page.find("calcite-modal"); - await page.$eval( - "calcite-modal", - (el: Modal["el"]) => - (el.beforeClose = (window as GlobalTestProps<{ beforeClose: Modal["el"]["beforeClose"] }>).beforeClose), - ); - await page.waitForChanges(); - modal.setProperty("open", true); - await page.waitForChanges(); - expect(await modal.getProperty("opened")).toBe(true); - const closeButton = await page.find(`calcite-modal >>> .${CSS.close}`); - await closeButton.click(); - await page.waitForChanges(); - expect(mockCallBack).toHaveBeenCalledTimes(1); - expect(await modal.getProperty("opened")).toBe(false); - }); + describe("beforeClose", () => { + let page: E2EPage; + let modal: E2EElement; - it("calls the beforeClose method prior to closing via ESC key", async () => { - const page = await newE2EPage(); - const mockCallBack = vi.fn(); - await page.exposeFunction("beforeClose", mockCallBack); - await page.setContent(` - - `); - const modal = await page.find("calcite-modal"); - const openEvent = page.waitForEvent("calciteModalOpen"); - await page.$eval( - "calcite-modal", - (el: Modal["el"]) => - (el.beforeClose = (window as GlobalTestProps<{ beforeClose: Modal["el"]["beforeClose"] }>).beforeClose), - ); - await skipAnimations(page); - await page.waitForChanges(); + beforeEach(async () => { + page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + modal = await page.find("calcite-modal"); + const openEvent = page.waitForEvent("calciteModalOpen"); + modal.setProperty("open", true); + await page.waitForChanges(); + await openEvent; + }); - modal.setProperty("open", true); - await page.waitForChanges(); - await openEvent; - expect(await modal.getProperty("opened")).toBe(true); + it("calls the beforeClose method prior to closing via click", async () => { + const mockCallBack = vi.fn(); + await page.exposeFunction("beforeClose", mockCallBack); + await page.$eval( + "calcite-modal", + (el: Modal["el"]) => + (el.beforeClose = (window as GlobalTestProps<{ beforeClose: Modal["el"]["beforeClose"] }>).beforeClose), + ); + await page.waitForChanges(); - await page.keyboard.press("Escape"); - await page.waitForChanges(); - expect(mockCallBack).toHaveBeenCalledTimes(1); - expect(await modal.getProperty("opened")).toBe(false); - }); + expect(await modal.getProperty("opened")).toBe(true); - it("calls the beforeClose method prior to closing via attribute", async () => { - const page = await newE2EPage(); - await skipAnimations(page); - const mockCallBack = vi.fn(); - await page.exposeFunction("beforeClose", mockCallBack); - await page.setContent(` - - `); - const modal = await page.find("calcite-modal"); - await page.$eval( - "calcite-modal", - (el: Modal["el"]) => - (el.beforeClose = (window as GlobalTestProps<{ beforeClose: Modal["el"]["beforeClose"] }>).beforeClose), - ); - await page.waitForChanges(); - modal.setProperty("open", true); - await page.waitForChanges(); - expect(await modal.getProperty("opened")).toBe(true); - modal.removeAttribute("open"); - await page.waitForChanges(); - expect(mockCallBack).toHaveBeenCalledTimes(1); - expect(await modal.getProperty("opened")).toBe(false); - }); + const closeButton = await page.find(`calcite-modal >>> .${CSS.close}`); + await closeButton.click(); + await page.waitForChanges(); - it("should handle rejected 'beforeClose' promise'", async () => { - const page = await newE2EPage(); - await skipAnimations(page); + expect(mockCallBack).toHaveBeenCalledTimes(1); + expect(await modal.getProperty("opened")).toBe(false); + }); - const mockCallBack = vi.fn().mockReturnValue(() => Promise.reject()); - await page.exposeFunction("beforeClose", mockCallBack); + it("calls the beforeClose method prior to closing via ESC key", async () => { + const mockCallBack = vi.fn(); + await page.exposeFunction("beforeClose", mockCallBack); + await page.$eval( + "calcite-modal", + (el: Modal["el"]) => + (el.beforeClose = (window as GlobalTestProps<{ beforeClose: Modal["el"]["beforeClose"] }>).beforeClose), + ); + await page.waitForChanges(); - await page.setContent(``); + expect(await modal.getProperty("opened")).toBe(true); - await page.$eval( - "calcite-modal", - (elm: Modal["el"]) => (elm.beforeClose = (window as typeof window & Pick).beforeClose), - ); + await page.keyboard.press("Escape"); + await page.waitForChanges(); + expect(mockCallBack).toHaveBeenCalledTimes(1); + expect(await modal.getProperty("opened")).toBe(false); + }); - const modal = await page.find("calcite-modal"); - modal.setProperty("open", false); - await page.waitForChanges(); + it("calls the beforeClose method prior to closing via attribute", async () => { + const mockCallBack = vi.fn(); + await page.exposeFunction("beforeClose", mockCallBack); + await page.$eval( + "calcite-modal", + (el: Modal["el"]) => + (el.beforeClose = (window as GlobalTestProps<{ beforeClose: Modal["el"]["beforeClose"] }>).beforeClose), + ); + await page.waitForChanges(); - expect(mockCallBack).toHaveBeenCalledTimes(1); - }); + expect(await modal.getProperty("opened")).toBe(true); - it("should remain open with rejected 'beforeClose' promise'", async () => { - const page = await newE2EPage(); - await page.setContent(``); - await skipAnimations(page); - await page.exposeFunction("beforeClose", () => Promise.reject()); + modal.removeAttribute("open"); + await page.waitForChanges(); - await page.$eval( - "calcite-modal", - (elm: Modal["el"]) => (elm.beforeClose = (window as typeof window & Pick).beforeClose), - ); + expect(mockCallBack).toHaveBeenCalledTimes(1); + expect(await modal.getProperty("opened")).toBe(false); + }); - const modal = await page.find("calcite-modal"); - modal.setProperty("open", false); - await page.waitForChanges(); + it("should handle rejected 'beforeClose' promise'", async () => { + const mockCallBack = vi.fn().mockReturnValue(() => Promise.reject()); + await page.exposeFunction("beforeClose", mockCallBack); + await page.$eval( + "calcite-modal", + (elm: Modal["el"]) => + (elm.beforeClose = (window as typeof window & Pick).beforeClose), + ); + await page.waitForChanges(); - expect(await modal.getProperty("open")).toBe(true); - expect(await modal.getProperty("opened")).toBe(true); - expect(modal.getAttribute("open")).toBe(""); // Makes sure attribute is added back + modal.setProperty("open", false); + await page.waitForChanges(); + + expect(mockCallBack).toHaveBeenCalledTimes(1); + }); + + it("should remain open with rejected 'beforeClose' promise'", async () => { + await page.exposeFunction("beforeClose", () => Promise.reject()); + await page.$eval( + "calcite-modal", + (elm: Modal["el"]) => + (elm.beforeClose = (window as typeof window & Pick).beforeClose), + ); + + modal.setProperty("open", false); + await page.waitForChanges(); + + expect(await modal.getProperty("open")).toBe(true); + expect(await modal.getProperty("opened")).toBe(true); + expect(modal.getAttribute("open")).toBe(""); // Makes sure attribute is added back + }); }); describe("calcite-modal accessibility checks", () => { From 3d2ee27890fe17ccb74a8b865c8374e04a5dd442 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 27 May 2025 23:39:36 -0700 Subject: [PATCH 33/49] stabilize action-menu tests --- .../components/action-menu/action-menu.e2e.ts | 152 ++++++++++-------- 1 file changed, 82 insertions(+), 70 deletions(-) diff --git a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts index 4d12e3a0eff..d58360501aa 100755 --- a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts +++ b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts @@ -14,7 +14,7 @@ import { themed, } from "../../tests/commonTests"; import { CSS as TooltipCSS, TOOLTIP_OPEN_DELAY_MS } from "../tooltip/resources"; -import { findAll, isElementFocused, skipAnimations } from "../../tests/utils/puppeteer"; +import { findAll, isElementFocused, skipAnimations, waitForAnimationFrame } from "../../tests/utils/puppeteer"; import type { Action } from "../action/action"; import { mockConsole } from "../../tests/utils/logging"; import { activeAttr, CSS, SLOTS } from "./resources"; @@ -111,21 +111,20 @@ describe("calcite-action-menu", () => { }); it("should emit 'calciteActionMenuOpen' event", async () => { - const page = await newE2EPage({ - html: ` - - `, - }); - - await page.waitForChanges(); - + const page = await newE2EPage(); + await page.setContent( + html` + + `, + ); + await skipAnimations(page); const clickSpy = await page.spyOnEvent("calciteActionMenuOpen"); - const actionMenu = await page.find("calcite-action-menu"); + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); actionMenu.setProperty("open", true); - await page.waitForChanges(); + await openEvent; expect(clickSpy).toHaveReceivedEventTimes(1); }); @@ -151,21 +150,27 @@ describe("calcite-action-menu", () => { } it("should close menu if clicked outside", async () => { - const page = await newE2EPage({ - html: ` - - - - -
+ const page = await newE2EPage(); + await page.setContent(html` + + + + + +
-
`, - }); - +
+ `); + await skipAnimations(page); const actionMenu = await page.find("calcite-action-menu"); const popover = await page.find("calcite-action-menu >>> calcite-popover"); const outside = await page.find("#outside"); + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + actionMenu.setProperty("open", true); + await page.waitForChanges(); + await openEvent; + expect(await popover.getProperty("autoClose")).toBe(true); expect(await popover.getProperty("open")).toBe(true); expect(await actionMenu.getProperty("open")).toBe(true); @@ -181,7 +186,7 @@ describe("calcite-action-menu", () => { it("should close menu if slotted action is clicked", async () => { const page = await newE2EPage(); await page.setContent(html` - + @@ -191,11 +196,17 @@ describe("calcite-action-menu", () => { await page.waitForChanges(); const actionMenu = await page.find("calcite-action-menu"); + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + actionMenu.setProperty("open", true); + await page.waitForChanges(); + await openEvent; + expect(await actionMenu.getProperty("open")).toBe(true); const action = await page.find("#slottedAction"); await action.click(); await page.waitForChanges(); + await waitForActionMenuClose(page); expect(await actionMenu.getProperty("open")).toBe(false); @@ -252,7 +263,6 @@ describe("calcite-action-menu", () => { it("should honor scale of expand icon", async () => { const page = await newE2EPage({ html: `` }); - const trigger = await page.find(`calcite-action-menu >>> .${CSS.defaultTrigger}`); expect(await trigger.getProperty("scale")).toBe("l"); @@ -260,7 +270,6 @@ describe("calcite-action-menu", () => { it("should close tooltip when open", async () => { const page = await newE2EPage(); - await page.setContent(html` @@ -268,9 +277,7 @@ describe("calcite-action-menu", () => { `); - await skipAnimations(page); - const actionMenu = await page.find("calcite-action-menu"); const tooltipPositionContainer = await page.find(`calcite-tooltip >>> .${TooltipCSS.positionContainer}`); const trigger = await page.find("#trigger"); @@ -282,15 +289,16 @@ describe("calcite-action-menu", () => { expect(await tooltipPositionContainer.isVisible()).toBe(true); + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); actionMenu.setProperty("open", true); await page.waitForChanges(); + await openEvent; expect(await tooltipPositionContainer.isVisible()).toBe(false); }); it("should stop propagation of popover events", async () => { const page = await newE2EPage(); - await page.setContent(html` @@ -298,7 +306,6 @@ describe("calcite-action-menu", () => { `); - await skipAnimations(page); const actionMenu = await page.find("calcite-action-menu"); @@ -308,8 +315,10 @@ describe("calcite-action-menu", () => { const popoverOpen = await actionMenu.spyOnEvent("calcitePopoverOpen"); const popoverClose = await actionMenu.spyOnEvent("calcitePopoverClose"); + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); await trigger.click(); await page.waitForChanges(); + await openEvent; expect(await actionMenu.getProperty("open")).toBe(true); @@ -325,16 +334,15 @@ describe("calcite-action-menu", () => { describe("Keyboard navigation", () => { it("should handle ArrowDown navigation", async () => { - const page = await newE2EPage({ - html: html` + const page = await newE2EPage(); + await page.setContent(html` + - `, - }); - - await page.waitForChanges(); - + + `); + await skipAnimations(page); const actionMenu = await page.find("calcite-action-menu"); const actions = await findAll(page, "calcite-action"); const trigger = await page.find(`calcite-action-menu >>> .${CSS.defaultTrigger}`); @@ -343,10 +351,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); - await page.waitForTimeout(0); await page.waitForChanges(); + await openEvent; expect(await trigger.getProperty("active")).toBe(true); expect(await actionMenu.getProperty("open")).toBe(true); @@ -355,7 +363,7 @@ describe("calcite-action-menu", () => { expect(actions[2].getAttribute(activeAttr)).toBe(null); await page.keyboard.press("ArrowDown"); - await page.waitForTimeout(0); + await waitForAnimationFrame(page); await page.waitForChanges(); expect(actions[0].getAttribute(activeAttr)).toBe(null); @@ -364,17 +372,16 @@ describe("calcite-action-menu", () => { }); it("should handle ArrowDown navigation with disabled/hidden items", async () => { - const page = await newE2EPage({ - html: html` + const page = await newE2EPage(); + await page.setContent(html` + - `, - }); - - await page.waitForChanges(); - + + `); + await skipAnimations(page); const actionMenu = await page.find("calcite-action-menu"); const actions = await findAll(page, "calcite-action"); const trigger = await page.find(`calcite-action-menu >>> .${CSS.defaultTrigger}`); @@ -383,9 +390,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); + await openEvent; expect(await trigger.getProperty("active")).toBe(true); expect(await actionMenu.getProperty("open")).toBe(true); @@ -395,6 +403,7 @@ describe("calcite-action-menu", () => { expect(actions[3].getAttribute(activeAttr)).toBe(null); await page.keyboard.press("ArrowDown"); + await waitForAnimationFrame(page); await page.waitForChanges(); expect(actions[0].getAttribute(activeAttr)).toBe(null); @@ -404,16 +413,15 @@ describe("calcite-action-menu", () => { }); it("should handle ArrowUp navigation", async () => { - const page = await newE2EPage({ - html: html` + const page = await newE2EPage(); + await page.setContent( + html` - `, - }); - - await page.waitForChanges(); - + `, + ); + await skipAnimations(page); const actionMenu = await page.find("calcite-action-menu"); const actions = await findAll(page, "calcite-action"); const trigger = await page.find(`calcite-action-menu >>> .${CSS.defaultTrigger}`); @@ -423,10 +431,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowUp"); - await page.waitForTimeout(0); await page.waitForChanges(); + await openEvent; expect(await trigger.getProperty("active")).toBe(true); expect(await actionMenu.getProperty("open")).toBe(true); @@ -435,7 +443,7 @@ describe("calcite-action-menu", () => { expect(actions[2].getAttribute(activeAttr)).toBe(""); await page.keyboard.press("ArrowUp"); - await page.waitForTimeout(0); + await waitForAnimationFrame(page); await page.waitForChanges(); expect(actions[0].getAttribute(activeAttr)).toBe(null); @@ -444,16 +452,15 @@ describe("calcite-action-menu", () => { }); it("should handle Enter, Home, End and ESC navigation", async () => { - const page = await newE2EPage({ - html: html` + const page = await newE2EPage(); + await page.setContent( + html` - `, - }); - - await page.waitForChanges(); - + `, + ); + await skipAnimations(page); const actionMenu = await page.find("calcite-action-menu"); const actions = await findAll(page, "calcite-action"); const trigger = await page.find(`calcite-action-menu >>> .${CSS.defaultTrigger}`); @@ -463,9 +470,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); await page.keyboard.press("Enter"); await page.waitForChanges(); + await openEvent; expect(await actionMenu.getProperty("open")).toBe(true); expect(await trigger.getProperty("active")).toBe(true); @@ -474,7 +482,7 @@ describe("calcite-action-menu", () => { expect(actions[2].getAttribute(activeAttr)).toBe(null); await page.keyboard.press("ArrowDown"); - + await waitForAnimationFrame(page); await page.waitForChanges(); expect(actions[0].getAttribute(activeAttr)).toBe(null); @@ -482,7 +490,6 @@ describe("calcite-action-menu", () => { expect(actions[2].getAttribute(activeAttr)).toBe(null); await page.keyboard.press("Home"); - await page.waitForChanges(); expect(actions[0].getAttribute(activeAttr)).toBe(""); @@ -490,7 +497,6 @@ describe("calcite-action-menu", () => { expect(actions[2].getAttribute(activeAttr)).toBe(null); await page.keyboard.press("End"); - await page.waitForChanges(); expect(actions[0].getAttribute(activeAttr)).toBe(null); @@ -498,7 +504,6 @@ describe("calcite-action-menu", () => { expect(actions[2].getAttribute(activeAttr)).toBe(""); await page.keyboard.press("Escape"); - await page.waitForChanges(); expect(await actionMenu.getProperty("open")).toBe(false); @@ -523,8 +528,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); + await openEvent; expect(await actionMenu.getProperty("open")).toBe(true); expect(actions[0].getAttribute(activeAttr)).toBe(""); @@ -533,6 +540,7 @@ describe("calcite-action-menu", () => { await page.keyboard.press("Tab"); await page.waitForChanges(); + await waitForActionMenuClose(page); expect(await actionMenu.getProperty("open")).toBe(false); }); @@ -547,7 +555,6 @@ describe("calcite-action-menu", () => { `, ); await skipAnimations(page); - await page.waitForChanges(); const actionMenu = await page.find("calcite-action-menu"); const actions = await findAll(page, "calcite-action"); @@ -555,8 +562,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); + await openEvent; const clickSpy = await actions[0].spyOnEvent("click"); @@ -567,6 +576,7 @@ describe("calcite-action-menu", () => { await page.keyboard.press("Enter"); await page.waitForChanges(); + await waitForActionMenuClose(page); expect(await actionMenu.getProperty("open")).toBe(false); expect(clickSpy).toHaveReceivedEventTimes(1); @@ -582,7 +592,6 @@ describe("calcite-action-menu", () => { `, ); await skipAnimations(page); - await page.waitForChanges(); const actionMenu = await page.find("calcite-action-menu"); const actions = await findAll(page, "calcite-action"); @@ -590,8 +599,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); + const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); + await openEvent; const clickSpy = await actions[0].spyOnEvent("click"); @@ -605,6 +616,7 @@ describe("calcite-action-menu", () => { el.click(), ); await page.waitForChanges(); + await waitForActionMenuClose(page); expect(await actionMenu.getProperty("open")).toBe(false); expect(clickSpy).toHaveReceivedEventTimes(1); From 6fa2afe1fc7d0cc0d02080a6703cff16606b01f7 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Tue, 27 May 2025 23:51:42 -0700 Subject: [PATCH 34/49] tidy up sheet tests following modal --- .../src/components/sheet/sheet.e2e.ts | 185 +++++++++--------- 1 file changed, 91 insertions(+), 94 deletions(-) diff --git a/packages/calcite-components/src/components/sheet/sheet.e2e.ts b/packages/calcite-components/src/components/sheet/sheet.e2e.ts index f3835647612..5ded72639b7 100644 --- a/packages/calcite-components/src/components/sheet/sheet.e2e.ts +++ b/packages/calcite-components/src/components/sheet/sheet.e2e.ts @@ -1,6 +1,6 @@ // @ts-strict-ignore -import { newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; -import { describe, expect, it, vi } from "vitest"; +import { E2EElement, E2EPage, newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { html } from "../../../support/formatting"; import { accessible, defaults, focusable, hidden, openClose, reflects, renders, themed } from "../../tests/commonTests"; import { GlobalTestProps, skipAnimations } from "../../tests/utils/puppeteer"; @@ -234,112 +234,109 @@ describe("calcite-sheet", () => { expect(style).toEqual("600px"); }); - it("calls the beforeClose method prior to closing via click", async () => { - const page = await newE2EPage(); - const mockCallBack = vi.fn(); - await page.exposeFunction("beforeClose", mockCallBack); - await page.setContent(` - - `); - const sheet = await page.find("calcite-sheet"); - await page.$eval( - "calcite-sheet", - (elm: Sheet["el"]) => - (elm.beforeClose = (window as GlobalTestProps<{ beforeClose: Sheet["el"]["beforeClose"] }>).beforeClose), - ); - await page.waitForChanges(); - expect(await sheet.getProperty("opened")).toBe(true); - const scrim = await page.find(`calcite-sheet >>> calcite-scrim`); - await scrim.click(); - await page.waitForChanges(); - expect(mockCallBack).toHaveBeenCalledTimes(1); - expect(await sheet.getProperty("opened")).toBe(false); - }); + describe("beforeClose", () => { + let page: E2EPage; + let sheet: E2EElement; - it("calls the beforeClose method prior to closing via escape", async () => { - const page = await newE2EPage(); - const mockCallBack = vi.fn(); - await page.exposeFunction("beforeClose", mockCallBack); - await page.setContent(` - - `); - const sheet = await page.find("calcite-sheet"); - await page.$eval( - "calcite-sheet", - (elm: Sheet["el"]) => - (elm.beforeClose = (window as GlobalTestProps<{ beforeClose: Sheet["el"]["beforeClose"] }>).beforeClose), - ); - await skipAnimations(page); - await page.waitForEvent("calciteSheetOpen"); - expect(await sheet.getProperty("opened")).toBe(true); + beforeEach(async () => { + page = await newE2EPage(); + await page.setContent(html``); + await skipAnimations(page); + sheet = await page.find("calcite-sheet"); + const openEvent = page.waitForEvent("calciteSheetOpen"); + sheet.setProperty("open", true); + await page.waitForChanges(); + await openEvent; + }); - await page.keyboard.press("Escape"); - await page.waitForChanges(); + it("calls the beforeClose method prior to closing via click", async () => { + const mockCallBack = vi.fn(); + await page.exposeFunction("beforeClose", mockCallBack); + await page.$eval( + "calcite-sheet", + (el: Sheet["el"]) => + (el.beforeClose = (window as GlobalTestProps<{ beforeClose: Sheet["el"]["beforeClose"] }>).beforeClose), + ); + await page.waitForChanges(); - expect(mockCallBack).toHaveBeenCalledTimes(1); - expect(await sheet.getProperty("opened")).toBe(false); - }); + expect(await sheet.getProperty("opened")).toBe(true); - it("calls the beforeClose method prior to closing via attribute", async () => { - const page = await newE2EPage(); - const mockCallBack = vi.fn(); - await page.exposeFunction("beforeClose", mockCallBack); - await page.setContent(` - - `); - const sheet = await page.find("calcite-sheet"); - await page.$eval( - "calcite-sheet", - (elm: Sheet["el"]) => - (elm.beforeClose = (window as GlobalTestProps<{ beforeClose: Sheet["el"]["beforeClose"] }>).beforeClose), - ); - await page.waitForChanges(); - sheet.setProperty("open", true); - await page.waitForChanges(); - expect(await sheet.getProperty("opened")).toBe(true); - sheet.removeAttribute("open"); - await page.waitForChanges(); - expect(mockCallBack).toHaveBeenCalledTimes(1); - expect(await sheet.getProperty("opened")).toBe(false); - }); + const scrim = await page.find(`calcite-sheet >>> calcite-scrim`); + await scrim.click(); + await page.waitForChanges(); - it("should handle rejected 'beforeClose' promise'", async () => { - const page = await newE2EPage(); + expect(mockCallBack).toHaveBeenCalledTimes(1); + expect(await sheet.getProperty("opened")).toBe(false); + }); - const mockCallBack = vi.fn().mockReturnValue(() => Promise.reject()); - await page.exposeFunction("beforeClose", mockCallBack); + it("calls the beforeClose method prior to closing via escape", async () => { + const mockCallBack = vi.fn(); + await page.exposeFunction("beforeClose", mockCallBack); + await page.$eval( + "calcite-sheet", + (el: Sheet["el"]) => + (el.beforeClose = (window as GlobalTestProps<{ beforeClose: Sheet["el"]["beforeClose"] }>).beforeClose), + ); + await page.waitForChanges(); - await page.setContent(``); + expect(await sheet.getProperty("opened")).toBe(true); - await page.$eval( - "calcite-sheet", - (elm: Sheet["el"]) => (elm.beforeClose = (window as typeof window & Pick).beforeClose), - ); + await page.keyboard.press("Escape"); + await page.waitForChanges(); + expect(mockCallBack).toHaveBeenCalledTimes(1); + expect(await sheet.getProperty("opened")).toBe(false); + }); - const sheet = await page.find("calcite-sheet"); - sheet.setProperty("open", false); - await page.waitForChanges(); + it("calls the beforeClose method prior to closing via attribute", async () => { + const mockCallBack = vi.fn(); + await page.exposeFunction("beforeClose", mockCallBack); + await page.$eval( + "calcite-sheet", + (el: Sheet["el"]) => + (el.beforeClose = (window as GlobalTestProps<{ beforeClose: Sheet["el"]["beforeClose"] }>).beforeClose), + ); + await page.waitForChanges(); - expect(mockCallBack).toHaveBeenCalledTimes(1); - }); + expect(await sheet.getProperty("opened")).toBe(true); - it("should remain open with rejected 'beforeClose' promise'", async () => { - const page = await newE2EPage(); - await page.setContent(``); - await page.exposeFunction("beforeClose", () => Promise.reject()); - const sheet = await page.find("calcite-sheet"); + sheet.removeAttribute("open"); + await page.waitForChanges(); - await page.$eval( - "calcite-sheet", - (elm: Sheet["el"]) => (elm.beforeClose = (window as typeof window & Pick).beforeClose), - ); + expect(mockCallBack).toHaveBeenCalledTimes(1); + expect(await sheet.getProperty("opened")).toBe(false); + }); - sheet.setProperty("open", false); - await page.waitForChanges(); + it("should handle rejected 'beforeClose' promise'", async () => { + const mockCallBack = vi.fn().mockReturnValue(() => Promise.reject()); + await page.exposeFunction("beforeClose", mockCallBack); + await page.$eval( + "calcite-sheet", + (elm: Sheet["el"]) => + (elm.beforeClose = (window as typeof window & Pick).beforeClose), + ); + await page.waitForChanges(); - expect(await sheet.getProperty("open")).toBe(true); - expect(await sheet.getProperty("opened")).toBe(true); - expect(sheet.getAttribute("open")).toBe(""); // Makes sure attribute is added back + sheet.setProperty("open", false); + await page.waitForChanges(); + + expect(mockCallBack).toHaveBeenCalledTimes(1); + }); + + it("should remain open with rejected 'beforeClose' promise'", async () => { + await page.exposeFunction("beforeClose", () => Promise.reject()); + await page.$eval( + "calcite-sheet", + (elm: Sheet["el"]) => + (elm.beforeClose = (window as typeof window & Pick).beforeClose), + ); + + sheet.setProperty("open", false); + await page.waitForChanges(); + + expect(await sheet.getProperty("open")).toBe(true); + expect(await sheet.getProperty("opened")).toBe(true); + expect(sheet.getAttribute("open")).toBe(""); // Makes sure attribute is added back + }); }); it("has correct aria role/attribute", async () => { From d29784c5561daee7736474872ce55a047d50c85b Mon Sep 17 00:00:00 2001 From: JC Franco Date: Wed, 28 May 2025 16:41:56 -0700 Subject: [PATCH 35/49] disable parallelism and isolation to help CI debugging process --- packages/calcite-components/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/calcite-components/package.json b/packages/calcite-components/package.json index e9364125a2e..20539c63d5a 100644 --- a/packages/calcite-components/package.json +++ b/packages/calcite-components/package.json @@ -55,10 +55,10 @@ "screenshot-tests:publish": "npm run screenshot-tests && storybook-to-ghpages --existing-output-dir=docs", "start": "npm run util:clean-js-files && concurrently --kill-others --raw \"trap 'npm run util:clean-js-files' INT TERM EXIT >/dev/null 2>&1 || true && tsc --project ./tsconfig-demos.json --watch\" \"npm run build:watch-dev\"", "test": "concurrently --passthrough-arguments \"npm:test:stable -- {@}\" \"npm:test:experimental -- {@}\" --", - "test:stable": "vitest run", + "test:stable": "vitest run --no-file-parallelism --no-isolate", "test:experimental": "npm run util:ensure-playwright-workaround && EXPERIMENTAL_TESTS=true vitest run --browser.headless", "test:watch": "concurrently --passthrough-arguments \"npm run test:watch:stable -- {@}\" \"npm run test:watch:experimental -- {@}\" --", - "test:watch:stable": "vitest watch", + "test:watch:stable": "vitest watch --no-file-parallelism --no-isolate", "test:watch:experimental": "npm run util:ensure-playwright-workaround && EXPERIMENTAL_TESTS=true vitest watch --browser.headless", "util:clean-js-files": "rimraf --glob -- *.js {src,.storybook,support}/**/*.js", "util:ensure-playwright-workaround": "npx playwright install", From 4999478396671d79f67b70e433ca6e57b83cb869 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 30 May 2025 13:11:37 -0700 Subject: [PATCH 36/49] skip spec tests failing due to isolation for troubleshooting --- packages/calcite-components/src/utils/config.spec.ts | 2 +- packages/calcite-components/src/utils/locale.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/calcite-components/src/utils/config.spec.ts b/packages/calcite-components/src/utils/config.spec.ts index b8bfc6ed030..58f7ad0db89 100644 --- a/packages/calcite-components/src/utils/config.spec.ts +++ b/packages/calcite-components/src/utils/config.spec.ts @@ -1,7 +1,7 @@ // @ts-strict-ignore import { describe, expect, it, afterEach, beforeEach, vi } from "vitest"; -describe("config", () => { +describe.skip("config", () => { let config: typeof import("./config"); /** Need to load the config at runtime to allow test to specify custom configuration if needed. */ diff --git a/packages/calcite-components/src/utils/locale.spec.ts b/packages/calcite-components/src/utils/locale.spec.ts index e4d9ba3a0f8..56c79527cb0 100644 --- a/packages/calcite-components/src/utils/locale.spec.ts +++ b/packages/calcite-components/src/utils/locale.spec.ts @@ -14,7 +14,7 @@ import { numberStringFormatter, } from "./locale"; -describe("NumberStringFormat", () => { +describe.skip("NumberStringFormat", () => { it("NumberFormat formatter is not initialized until necessary", () => { const num = "123.456"; From ad30cedc42a36d0c4723ff30474ffb7a2334b21c Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 30 May 2025 16:32:09 -0700 Subject: [PATCH 37/49] fix ignored promises --- .../calcite-components/src/components/list/list.e2e.ts | 6 ++++-- .../calcite-components/src/components/meter/meter.e2e.ts | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/calcite-components/src/components/list/list.e2e.ts b/packages/calcite-components/src/components/list/list.e2e.ts index 710d9effd1b..196e14006cf 100755 --- a/packages/calcite-components/src/components/list/list.e2e.ts +++ b/packages/calcite-components/src/components/list/list.e2e.ts @@ -1,5 +1,5 @@ // @ts-strict-ignore -import { E2EElement, E2EPage, newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; +import { E2EPage, newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting"; import { describe, expect, it } from "vitest"; import { accessible, @@ -2271,6 +2271,8 @@ describe("calcite-list", () => { async function assertDescendantItems(page: E2EPage, groupSelector: string, visibility: boolean): Promise { const items = await findAll(page, `calcite-list-item-group${groupSelector} > calcite-list-item`); - items.forEach(async (item: E2EElement) => expect(await item.isVisible()).toBe(visibility)); + for (const item of items) { + expect(await item.isVisible()).toBe(visibility); + } } }); diff --git a/packages/calcite-components/src/components/meter/meter.e2e.ts b/packages/calcite-components/src/components/meter/meter.e2e.ts index 846c4d04245..5886b09acbf 100644 --- a/packages/calcite-components/src/components/meter/meter.e2e.ts +++ b/packages/calcite-components/src/components/meter/meter.e2e.ts @@ -105,7 +105,7 @@ describe("calcite-meter", () => { html: html``, }); const meter = await page.find(`calcite-meter`); - page.waitForChanges(); + await page.waitForChanges(); expect(await meter.getProperty("min")).toBe(0); expect(await meter.getProperty("max")).toBe(100); expect(await meter.getProperty("low")).toBe(0); @@ -118,7 +118,7 @@ describe("calcite-meter", () => { html: html``, }); const meter = await page.find(`calcite-meter`); - page.waitForChanges(); + await page.waitForChanges(); expect(await meter.getProperty("min")).toBe(2000); expect(await meter.getProperty("max")).toBe(10000); expect(await meter.getProperty("low")).toBe(2000); @@ -131,7 +131,7 @@ describe("calcite-meter", () => { html: html``, }); const meter = await page.find(`calcite-meter`); - page.waitForChanges(); + await page.waitForChanges(); expect(await meter.getProperty("min")).toBe(10); expect(await meter.getProperty("max")).toBe(25); expect(await meter.getProperty("low")).toBe(10); @@ -157,7 +157,7 @@ describe("calcite-meter", () => { html: html``, }); const meter = await page.find(`calcite-meter`); - page.waitForChanges(); + await page.waitForChanges(); expect(await meter.getProperty("min")).toBe(10); expect(await meter.getProperty("max")).toBe(25); expect(await meter.getProperty("low")).toBe(10); From 1de9087979ce6147b8e4254d19eca23c16fa0709 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 30 May 2025 16:33:03 -0700 Subject: [PATCH 38/49] restore debugging config --- packages/calcite-components/package.json | 4 ++-- packages/calcite-components/src/utils/config.spec.ts | 2 +- packages/calcite-components/src/utils/locale.spec.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/calcite-components/package.json b/packages/calcite-components/package.json index 20539c63d5a..e9364125a2e 100644 --- a/packages/calcite-components/package.json +++ b/packages/calcite-components/package.json @@ -55,10 +55,10 @@ "screenshot-tests:publish": "npm run screenshot-tests && storybook-to-ghpages --existing-output-dir=docs", "start": "npm run util:clean-js-files && concurrently --kill-others --raw \"trap 'npm run util:clean-js-files' INT TERM EXIT >/dev/null 2>&1 || true && tsc --project ./tsconfig-demos.json --watch\" \"npm run build:watch-dev\"", "test": "concurrently --passthrough-arguments \"npm:test:stable -- {@}\" \"npm:test:experimental -- {@}\" --", - "test:stable": "vitest run --no-file-parallelism --no-isolate", + "test:stable": "vitest run", "test:experimental": "npm run util:ensure-playwright-workaround && EXPERIMENTAL_TESTS=true vitest run --browser.headless", "test:watch": "concurrently --passthrough-arguments \"npm run test:watch:stable -- {@}\" \"npm run test:watch:experimental -- {@}\" --", - "test:watch:stable": "vitest watch --no-file-parallelism --no-isolate", + "test:watch:stable": "vitest watch", "test:watch:experimental": "npm run util:ensure-playwright-workaround && EXPERIMENTAL_TESTS=true vitest watch --browser.headless", "util:clean-js-files": "rimraf --glob -- *.js {src,.storybook,support}/**/*.js", "util:ensure-playwright-workaround": "npx playwright install", diff --git a/packages/calcite-components/src/utils/config.spec.ts b/packages/calcite-components/src/utils/config.spec.ts index 58f7ad0db89..b8bfc6ed030 100644 --- a/packages/calcite-components/src/utils/config.spec.ts +++ b/packages/calcite-components/src/utils/config.spec.ts @@ -1,7 +1,7 @@ // @ts-strict-ignore import { describe, expect, it, afterEach, beforeEach, vi } from "vitest"; -describe.skip("config", () => { +describe("config", () => { let config: typeof import("./config"); /** Need to load the config at runtime to allow test to specify custom configuration if needed. */ diff --git a/packages/calcite-components/src/utils/locale.spec.ts b/packages/calcite-components/src/utils/locale.spec.ts index 56c79527cb0..e4d9ba3a0f8 100644 --- a/packages/calcite-components/src/utils/locale.spec.ts +++ b/packages/calcite-components/src/utils/locale.spec.ts @@ -14,7 +14,7 @@ import { numberStringFormatter, } from "./locale"; -describe.skip("NumberStringFormat", () => { +describe("NumberStringFormat", () => { it("NumberFormat formatter is not initialized until necessary", () => { const num = "123.456"; From 67ca9dc5765d855631f7e44eed26b15cd938fb8b Mon Sep 17 00:00:00 2001 From: JC Franco Date: Sat, 31 May 2025 15:18:51 -0700 Subject: [PATCH 39/49] chore(eslint): ban waitForEvent to avoid unstable pattern --- packages/calcite-components/eslint.config.mjs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/calcite-components/eslint.config.mjs b/packages/calcite-components/eslint.config.mjs index 0e73115b3d8..3e9bc422520 100644 --- a/packages/calcite-components/eslint.config.mjs +++ b/packages/calcite-components/eslint.config.mjs @@ -48,6 +48,10 @@ export default tseslint.config( property: "findAll", message: "Use custom findAll test util for more predictable (non-empty) result usage.", }, + { + property: "waitForEvent", + message: "Use spyOnEvent and await on its next property instead for more reliable async event handling.", + }, ], "unused-imports/no-unused-imports": "error", From fe8450e36ff9263875e71bf02b3376f4cec542a0 Mon Sep 17 00:00:00 2001 From: JC Franco Date: Sat, 31 May 2025 15:19:43 -0700 Subject: [PATCH 40/49] use next from event spies to wait for events instead of problematic waitForEvent pattern --- .../components/action-bar/action-bar.e2e.ts | 7 +- .../components/action-menu/action-menu.e2e.ts | 49 ++++---- .../components/block-group/block-group.e2e.ts | 5 +- .../src/components/block/block.e2e.ts | 16 +-- .../components/card-group/card-group.e2e.ts | 75 ++++------- .../src/components/carousel/carousel.e2e.ts | 103 ++++++++------- .../src/components/combobox/combobox.e2e.ts | 119 ++++++++---------- .../src/components/dialog/dialog.e2e.ts | 43 ++++--- .../dropdown-item/dropdown-item.e2e.ts | 14 +-- .../src/components/dropdown/dropdown.e2e.ts | 86 +++++++------ .../src/components/filter/filter.e2e.ts | 12 +- .../src/components/handle/handle.e2e.ts | 7 +- .../inline-editable/inline-editable.e2e.ts | 8 +- .../input-date-picker.e2e.ts | 26 ++-- .../input-time-picker.e2e.ts | 19 ++- .../src/components/list/list.e2e.ts | 22 ++-- .../src/components/modal/modal.e2e.ts | 106 ++++++++-------- .../src/components/popover/popover.e2e.ts | 25 ++-- .../src/components/sheet/sheet.e2e.ts | 23 ++-- .../src/components/shell/shell.e2e.ts | 12 +- .../components/sort-handle/sort-handle.e2e.ts | 8 +- .../split-button/split-button.e2e.ts | 9 +- .../src/components/tab-nav/tab-nav.e2e.ts | 26 ++-- .../src/components/tabs/tabs.e2e.ts | 5 +- .../src/components/text-area/text-area.e2e.ts | 8 +- .../src/components/tooltip/tooltip.e2e.ts | 24 ++-- .../src/tests/commonTests/focusTrap.ts | 8 +- .../src/tests/commonTests/openClose.ts | 35 +++--- .../src/tests/stackedFocusTrap.e2e.ts | 30 +++-- 29 files changed, 429 insertions(+), 501 deletions(-) diff --git a/packages/calcite-components/src/components/action-bar/action-bar.e2e.ts b/packages/calcite-components/src/components/action-bar/action-bar.e2e.ts index c4dcc532a9d..2f59f14f9b5 100755 --- a/packages/calcite-components/src/components/action-bar/action-bar.e2e.ts +++ b/packages/calcite-components/src/components/action-bar/action-bar.e2e.ts @@ -375,17 +375,14 @@ describe("calcite-action-bar", () => { expect(await groups[0].getProperty("menuOpen")).toBe(false); expect(await groups[1].getProperty("menuOpen")).toBe(true); - const calciteActionMenuOpenEvent = page.waitForEvent("calciteActionMenuOpen"); - + const calciteActionMenuOpenEventSpy = await page.spyOnEvent("calciteActionMenuOpen"); await page.$eval("calcite-action-group", (firstActionGroup: ActionGroup["el"]) => { firstActionGroup.menuOpen = true; const event = new CustomEvent("calciteActionMenuOpen", { bubbles: true }); firstActionGroup.dispatchEvent(event); }); - - await calciteActionMenuOpenEvent; - await page.waitForChanges(); + await calciteActionMenuOpenEventSpy.next(); expect(groups).toHaveLength(2); expect(await groups[0].getProperty("menuOpen")).toBe(true); diff --git a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts index d58360501aa..dc3c06ba0d8 100755 --- a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts +++ b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts @@ -121,10 +121,10 @@ describe("calcite-action-menu", () => { const clickSpy = await page.spyOnEvent("calciteActionMenuOpen"); const actionMenu = await page.find("calcite-action-menu"); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); actionMenu.setProperty("open", true); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(clickSpy).toHaveReceivedEventTimes(1); }); @@ -166,10 +166,10 @@ describe("calcite-action-menu", () => { const popover = await page.find("calcite-action-menu >>> calcite-popover"); const outside = await page.find("#outside"); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); actionMenu.setProperty("open", true); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(await popover.getProperty("autoClose")).toBe(true); expect(await popover.getProperty("open")).toBe(true); @@ -196,10 +196,10 @@ describe("calcite-action-menu", () => { await page.waitForChanges(); const actionMenu = await page.find("calcite-action-menu"); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); actionMenu.setProperty("open", true); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(await actionMenu.getProperty("open")).toBe(true); @@ -289,10 +289,10 @@ describe("calcite-action-menu", () => { expect(await tooltipPositionContainer.isVisible()).toBe(true); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); actionMenu.setProperty("open", true); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(await tooltipPositionContainer.isVisible()).toBe(false); }); @@ -315,10 +315,9 @@ describe("calcite-action-menu", () => { const popoverOpen = await actionMenu.spyOnEvent("calcitePopoverOpen"); const popoverClose = await actionMenu.spyOnEvent("calcitePopoverClose"); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); await trigger.click(); - await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(await actionMenu.getProperty("open")).toBe(true); @@ -351,10 +350,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(await trigger.getProperty("active")).toBe(true); expect(await actionMenu.getProperty("open")).toBe(true); @@ -390,10 +389,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(await trigger.getProperty("active")).toBe(true); expect(await actionMenu.getProperty("open")).toBe(true); @@ -431,10 +430,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowUp"); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(await trigger.getProperty("active")).toBe(true); expect(await actionMenu.getProperty("open")).toBe(true); @@ -470,10 +469,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); await page.keyboard.press("Enter"); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(await actionMenu.getProperty("open")).toBe(true); expect(await trigger.getProperty("active")).toBe(true); @@ -528,10 +527,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); expect(await actionMenu.getProperty("open")).toBe(true); expect(actions[0].getAttribute(activeAttr)).toBe(""); @@ -562,10 +561,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); const clickSpy = await actions[0].spyOnEvent("click"); @@ -599,10 +598,10 @@ describe("calcite-action-menu", () => { await actionMenu.callMethod("setFocus"); await page.waitForChanges(); - const openEvent = actionMenu.waitForEvent("calciteActionMenuOpen"); + const openEventSpy = await actionMenu.spyOnEvent("calciteActionMenuOpen"); await page.keyboard.press("ArrowDown"); await page.waitForChanges(); - await openEvent; + await openEventSpy.next(); const clickSpy = await actions[0].spyOnEvent("click"); diff --git a/packages/calcite-components/src/components/block-group/block-group.e2e.ts b/packages/calcite-components/src/components/block-group/block-group.e2e.ts index d05929fae5e..1eb5b19f9fb 100755 --- a/packages/calcite-components/src/components/block-group/block-group.e2e.ts +++ b/packages/calcite-components/src/components/block-group/block-group.e2e.ts @@ -461,7 +461,7 @@ describe("calcite-block-group", () => { ): Promise { const component = await page.find("calcite-block-group"); const eventName = `calciteSortHandleReorder`; - const event = component.waitForEvent(eventName); + const eventSpy = await component.spyOnEvent(eventName); await page.$eval( `calcite-block[heading="one"]`, (item1: Block["el"], reorder, eventName) => { @@ -470,8 +470,8 @@ describe("calcite-block-group", () => { reorder, eventName, ); - await event; await page.waitForChanges(); + await eventSpy.next(); const itemsAfter = await findAll(page, "calcite-block"); expect(itemsAfter.length).toBe(3); @@ -571,6 +571,7 @@ describe("calcite-block-group", () => { ): Promise { const component = await page.find(`#${componentItemId}`); const eventName = `calciteSortHandleMove`; + // eslint-disable-next-line no-restricted-properties -- workaround for spyOnEvent throwing errors due to circular JSON structures when serializing the event payload const event = component.waitForEvent(eventName); await page.$eval( `#${componentItemId}`, diff --git a/packages/calcite-components/src/components/block/block.e2e.ts b/packages/calcite-components/src/components/block/block.e2e.ts index 3eb518e5a04..a968f63a933 100644 --- a/packages/calcite-components/src/components/block/block.e2e.ts +++ b/packages/calcite-components/src/components/block/block.e2e.ts @@ -253,9 +253,9 @@ describe("calcite-block", () => { expect(toggle.getAttribute("aria-expanded")).toBe("false"); expect(toggle.getAttribute("title")).toBe(messages.expand); - const openEvent = element.waitForEvent("calciteBlockOpen"); + const openEventSpy = await element.spyOnEvent("calciteBlockOpen"); await toggle.click(); - await openEvent; + await openEventSpy.next(); expect(toggleSpy).toHaveReceivedEventTimes(1); expect(openSpy).toHaveReceivedEventTimes(1); @@ -263,9 +263,9 @@ describe("calcite-block", () => { expect(toggle.getAttribute("aria-expanded")).toBe("true"); expect(toggle.getAttribute("title")).toBe(messages.collapse); - const closeEvent = element.waitForEvent("calciteBlockClose"); + const closeEventSpy = await element.spyOnEvent("calciteBlockClose"); await toggle.click(); - await closeEvent; + await closeEventSpy.next(); expect(toggleSpy).toHaveReceivedEventTimes(2); expect(closeSpy).toHaveReceivedEventTimes(1); @@ -345,12 +345,12 @@ describe("calcite-block", () => { expect(blockToggleSpy).toHaveReceivedEventTimes(0); expect(blockCloseSpy).toHaveReceivedEventTimes(0); - const openEvent = page.waitForEvent("calciteBlockOpen"); - const closeEvent = page.waitForEvent("calciteBlockClose"); + const openEventSpy = await page.spyOnEvent("calciteBlockOpen"); + const closeEventSpy = await page.spyOnEvent("calciteBlockClose"); await block.click(); - await openEvent; + await openEventSpy.next(); await block.click(); - await closeEvent; + await closeEventSpy.next(); expect(blockToggleSpy).toHaveReceivedEventTimes(2); expect(blockOpenSpy).toHaveReceivedEventTimes(1); diff --git a/packages/calcite-components/src/components/card-group/card-group.e2e.ts b/packages/calcite-components/src/components/card-group/card-group.e2e.ts index 3748a1a5b17..27e1e900f90 100644 --- a/packages/calcite-components/src/components/card-group/card-group.e2e.ts +++ b/packages/calcite-components/src/components/card-group/card-group.e2e.ts @@ -90,10 +90,9 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card2.id]); - let selectEvent = page.waitForEvent("calciteCardSelect"); - card1CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + const selectEventSpy = await page.spyOnEvent("calciteCardSelect"); + await card1CheckAction.click(); + await selectEventSpy.next(); expect(await cardGroupSelectSpy).toHaveReceivedEventTimes(1); expect(await cardSelectSpy1).toHaveReceivedEventTimes(1); @@ -103,10 +102,8 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card1.id]); - selectEvent = page.waitForEvent("calciteCardSelect"); - card2CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + await card2CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(2); expect(cardSelectSpy1).toHaveReceivedEventTimes(1); @@ -116,10 +113,8 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card2.id]); - selectEvent = page.waitForEvent("calciteCardSelect"); - card2CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + await card2CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(3); expect(cardSelectSpy1).toHaveReceivedEventTimes(1); @@ -157,10 +152,9 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card1.id]); - let selectEvent = page.waitForEvent("calciteCardSelect"); - card1CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + const selectEventSpy = await page.spyOnEvent("calciteCardSelect"); + await card1CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(1); expect(await card1.getProperty("selected")).toBe(true); @@ -168,10 +162,8 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card1.id]); - selectEvent = page.waitForEvent("calciteCardSelect"); - card2CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + await card2CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(2); expect(await card1.getProperty("selected")).toBe(false); @@ -179,10 +171,8 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card2.id]); - selectEvent = page.waitForEvent("calciteCardSelect"); - card2CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + await card2CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(3); expect(await card1.getProperty("selected")).toBe(false); @@ -221,10 +211,9 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toEqual([]); await selectedItemAsserter([]); - let selectEvent = page.waitForEvent("calciteCardSelect"); - card1CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + const selectEventSpy = await page.spyOnEvent("calciteCardSelect"); + await card1CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(1); expect(await card1.getProperty("selected")).toBe(true); @@ -233,10 +222,8 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card1.id]); - selectEvent = page.waitForEvent("calciteCardSelect"); - card2CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + await card2CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(2); expect(await card1.getProperty("selected")).toBe(true); @@ -245,10 +232,8 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(2); await selectedItemAsserter([card1.id, card2.id]); - selectEvent = page.waitForEvent("calciteCardSelect"); - card3CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + await card3CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(3); expect(await card1.getProperty("selected")).toBe(true); @@ -257,10 +242,8 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(3); await selectedItemAsserter([card1.id, card2.id, card3.id]); - selectEvent = page.waitForEvent("calciteCardSelect"); - card1CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + await card1CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(4); expect(await card1.getProperty("selected")).toBe(false); @@ -269,10 +252,8 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(2); await selectedItemAsserter([card2.id, card3.id]); - selectEvent = page.waitForEvent("calciteCardSelect"); - card2CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + await card2CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(5); expect(await card1.getProperty("selected")).toBe(false); @@ -281,10 +262,8 @@ describe("calcite-card-group", () => { expect(await element.getProperty("selectedItems")).toHaveLength(1); await selectedItemAsserter([card3.id]); - selectEvent = page.waitForEvent("calciteCardSelect"); - card3CheckAction.click(); - await page.waitForChanges(); - await selectEvent; + await card3CheckAction.click(); + await selectEventSpy.next(); expect(cardGroupSelectSpy).toHaveReceivedEventTimes(6); expect(await card1.getProperty("selected")).toBe(false); diff --git a/packages/calcite-components/src/components/carousel/carousel.e2e.ts b/packages/calcite-components/src/components/carousel/carousel.e2e.ts index c877138e6d7..c8ec9489873 100644 --- a/packages/calcite-components/src/components/carousel/carousel.e2e.ts +++ b/packages/calcite-components/src/components/carousel/carousel.e2e.ts @@ -1034,7 +1034,7 @@ describe("calcite-carousel", () => { }); }); - it("item slide animation finishes between paging/selection", async () => { + it.only("item slide animation finishes between paging/selection", async () => { const page = await newE2EPage(); await page.setContent( html`