From 630d4ea1a6d81d25920504b8101f3d387c149f04 Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Fri, 28 Jun 2024 12:15:36 -0400 Subject: [PATCH 1/3] fix(item-sliding): check for side attribute --- core/src/components/item-sliding/item-sliding.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/components/item-sliding/item-sliding.tsx b/core/src/components/item-sliding/item-sliding.tsx index ef9eaae327c..ba979164c47 100644 --- a/core/src/components/item-sliding/item-sliding.tsx +++ b/core/src/components/item-sliding/item-sliding.tsx @@ -263,7 +263,7 @@ export class ItemSliding implements ComponentInterface { // eslint-disable-next-line custom-rules/no-component-on-ready-method const option = (item as any).componentOnReady !== undefined ? await item.componentOnReady() : item; - const side = isEndSide(option.side) ? 'end' : 'start'; + const side = isEndSide(option.side ?? option.getAttribute('side')) ? 'end' : 'start'; if (side === 'start') { this.leftOptions = option; From e68155869d078349764d1983b3a833f4ece66771 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Tue, 10 Jun 2025 09:21:13 -0400 Subject: [PATCH 2/3] test(item-sliding): add a test for the CDN issue with side --- .../test/async/item-sliding.e2e.ts | 81 +++++++++++++++++++ .../test/playwright/page/utils/set-content.ts | 19 ++++- .../playwright/playwright-declarations.ts | 6 ++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/core/src/components/item-sliding/test/async/item-sliding.e2e.ts b/core/src/components/item-sliding/test/async/item-sliding.e2e.ts index aa44b112924..f02fad6f504 100644 --- a/core/src/components/item-sliding/test/async/item-sliding.e2e.ts +++ b/core/src/components/item-sliding/test/async/item-sliding.e2e.ts @@ -1,6 +1,9 @@ import { expect } from '@playwright/test'; import { configs, test } from '@utils/test/playwright'; +/** + * This behavior does not vary across modes/directions + */ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { test.describe(title('item-sliding: async'), () => { test.beforeEach(async ({ page }) => { @@ -35,5 +38,83 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => await expect(itemSlidingEl).toHaveClass(/item-sliding-active-slide/); }); + + test('should not throw errors when adding multiple items with side="end" using the Ionic CDN', async ({ page }, testInfo) => { + testInfo.annotations.push({ + type: 'issue', + description: 'https://github.com/ionic-team/ionic-framework/issues/29499', + }); + + const errors: string[] = []; + page.on('console', msg => { + if (msg.type() === 'error') { + errors.push(msg.text()); + } + }); + page.on('pageerror', error => { + errors.push(error.message); + }); + + // This issue only happens when using a CDN version of Ionic + // so we need to use the CDN by passing the `importIonicFromCDN` option + // to setContent. + await page.setContent(` + + + Item Sliding + + ADD ITEM + + + + + + + + + `, { ...config, importIonicFromCDN: true }); + + // Click the button enough times to reproduce the issue + const addButton = page.locator('#addItem'); + await addButton.click(); + await addButton.click(); + await addButton.click(); + + await page.waitForChanges(); + + // Check that the items have been added + const items = page.locator('ion-item-sliding'); + expect(await items.count()).toBe(3); + + // Check that no errors have been logged + expect(errors.length).toBe(0); + }); }); }); diff --git a/core/src/utils/test/playwright/page/utils/set-content.ts b/core/src/utils/test/playwright/page/utils/set-content.ts index b844bac81f3..af0ee88ab26 100644 --- a/core/src/utils/test/playwright/page/utils/set-content.ts +++ b/core/src/utils/test/playwright/page/utils/set-content.ts @@ -33,6 +33,22 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o const baseUrl = process.env.PLAYWRIGHT_TEST_BASE_URL; + // The Ionic bundle is included locally by default unless the test + // config passes in the importIonicFromCDN option. This is useful + // when testing with the CDN version of Ionic. + let ionicImports = ` + + + `; + + if (options?.importIonicFromCDN) { + ionicImports = ` + + + + `; + } + const output = ` @@ -40,11 +56,10 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o Ionic Playwright Test - ${palette !== 'light' ? `` : ''} - + ${ionicImports} - `, { ...config, importIonicFromCDN: true }); - - // Click the button enough times to reproduce the issue - const addButton = page.locator('#addItem'); - await addButton.click(); - await addButton.click(); - await addButton.click(); - - await page.waitForChanges(); - - // Check that the items have been added - const items = page.locator('ion-item-sliding'); - expect(await items.count()).toBe(3); - - // Check that no errors have been logged - expect(errors.length).toBe(0); - }); }); }); diff --git a/core/src/utils/test/playwright/page/utils/set-content.ts b/core/src/utils/test/playwright/page/utils/set-content.ts index af0ee88ab26..b844bac81f3 100644 --- a/core/src/utils/test/playwright/page/utils/set-content.ts +++ b/core/src/utils/test/playwright/page/utils/set-content.ts @@ -33,22 +33,6 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o const baseUrl = process.env.PLAYWRIGHT_TEST_BASE_URL; - // The Ionic bundle is included locally by default unless the test - // config passes in the importIonicFromCDN option. This is useful - // when testing with the CDN version of Ionic. - let ionicImports = ` - - - `; - - if (options?.importIonicFromCDN) { - ionicImports = ` - - - - `; - } - const output = ` @@ -56,10 +40,11 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o Ionic Playwright Test + ${palette !== 'light' ? `` : ''} - ${ionicImports} +