From 630d4ea1a6d81d25920504b8101f3d387c149f04 Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Fri, 28 Jun 2024 12:15:36 -0400 Subject: [PATCH 1/5] 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/5] 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 }); + `, + { ...config, importIonicFromCDN: true } + ); // Click the button enough times to reproduce the issue const addButton = page.locator('#addItem'); From 4934bde55eaa1f4601fd3c63896b907a909f51a0 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:26:48 -0400 Subject: [PATCH 5/5] style: remove unnecessary test content --- .../item-sliding/test/async/item-sliding.e2e.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 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 b4c27b489aa..09695de4008 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 @@ -79,12 +79,12 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => function generateItem() { const currentItem = itemList.length + 1; const item = \` - + Sliding Item \${currentItem} - Delete + Delete \`; @@ -95,11 +95,6 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => const list = document.getElementById('list'); list.innerHTML += generateItem(); const currentItem = itemList.length; - const deleteId = \`#delete-item-\${currentItem}\`; - const itemId = \`#item-\${currentItem}\`; - document.querySelector(deleteId).addEventListener('click', (ev) => { - document.querySelector(itemId).remove(); - }); } `,