From 9adf5986fc480f8312a297cabdcef23f7dd864b3 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Sat, 2 Aug 2025 14:37:12 -0400 Subject: [PATCH 1/9] test(angular): migrate to playwright --- .../test/base/e2e/utils/drag-element.ts | 23 +++ .../test/base/e2e/utils/test-helpers.ts | 168 ++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 packages/angular/test/base/e2e/utils/drag-element.ts create mode 100644 packages/angular/test/base/e2e/utils/test-helpers.ts diff --git a/packages/angular/test/base/e2e/utils/drag-element.ts b/packages/angular/test/base/e2e/utils/drag-element.ts new file mode 100644 index 00000000000..a481effc2b6 --- /dev/null +++ b/packages/angular/test/base/e2e/utils/drag-element.ts @@ -0,0 +1,23 @@ +import type { Locator, Page } from '@playwright/test'; + +export const dragElementBy = async ( + element: Locator, + page: Page, + dragByX = 0, + dragByY = 0 +) => { + const boundingBox = await element.boundingBox(); + if (!boundingBox) { + throw new Error('Element not visible'); + } + + const startX = boundingBox.x + boundingBox.width / 2; + const startY = boundingBox.y + boundingBox.height / 2; + const endX = startX + dragByX; + const endY = startY + dragByY; + + await page.mouse.move(startX, startY); + await page.mouse.down(); + await page.mouse.move(endX, endY); + await page.mouse.up(); +}; diff --git a/packages/angular/test/base/e2e/utils/test-helpers.ts b/packages/angular/test/base/e2e/utils/test-helpers.ts new file mode 100644 index 00000000000..183c88da832 --- /dev/null +++ b/packages/angular/test/base/e2e/utils/test-helpers.ts @@ -0,0 +1,168 @@ +import { expect, type Page, type Locator } from '@playwright/test'; + +export async function testStack(page: Page, selector: string, expectedStack: string[]) { + const elements = page.locator(`${selector} > *`); + const count = await elements.count(); + + // Ensure we have at least the expected number of elements + expect(count).toBeGreaterThanOrEqual(expectedStack.length); + + for (let i = 0; i < expectedStack.length; i++) { + const element = elements.nth(i); + // Check that the element tag name matches the expected component name + const tagName = await element.evaluate(el => el.tagName.toLowerCase()); + expect(tagName).toBe(expectedStack[i]); + } +} + +export async function testLifeCycle(page: Page, selector: string, expectedCounts: Record) { + for (const [event, count] of Object.entries(expectedCounts)) { + // Look for text content within the specific selector + await expect(page.locator(selector).locator(`text=${event}: ${count}`)).toBeVisible(); + } +} + +export async function ionPageVisible(page: Page, selector: string) { + await expect(page.locator(selector)).toBeVisible(); + await expect(page.locator(selector)).not.toHaveAttribute('aria-hidden', 'true'); +} + +export async function ionPageHidden(page: Page, selector: string) { + await expect(page.locator(selector)).toHaveAttribute('aria-hidden', 'true'); +} + +export async function ionPageDoesNotExist(page: Page, selector: string) { + // Check that no visible elements with this selector exist + const visibleElements = page.locator(`${selector}:visible`); + await expect(visibleElements).toHaveCount(0); +} + +export async function ionTabClick(page: Page, tabName: string) { + await page.locator(`ion-tab-button`).filter({ hasText: tabName }).click(); +} + +export async function ionSwipeToGoBack(page: Page, shouldGoBack = false) { + // Simulate swipe gesture for going back + const viewport = page.viewportSize(); + if (!viewport) return; + + const startX = 50; + const endX = shouldGoBack ? viewport.width - 50 : 50; + const y = viewport.height / 2; + + await page.mouse.move(startX, y); + await page.mouse.down(); + await page.mouse.move(endX, y); + await page.mouse.up(); +} + +export async function testTabTitle(page: Page, title: string) { + const tab = await getSelectedTab(page); + await expect(tab.locator('ion-title')).toHaveText(title); + return getSelectedTab(page); +} + +export async function getSelectedTab(page: Page): Promise { + // Wait for tab navigation to stabilize + await page.waitForTimeout(200); + + // Look for tabs that are visible and have content + const tabs = page.locator('ion-tabs ion-router-outlet > *:not(.ion-page-hidden)'); + const count = await tabs.count(); + + // If there's only one tab, return it + if (count === 1) { + return tabs.first(); + } + + // If there are multiple tabs, find the one that's actually visible and has content + for (let i = 0; i < count; i++) { + const tab = tabs.nth(i); + const isVisible = await tab.isVisible(); + if (isVisible) { + return tab; + } + } + + // Fallback to the first tab if none are explicitly visible + return tabs.first(); +} + +export async function testState(page: Page, count: number, tab: string) { + + await expect(page.locator('#tabs-state')).toHaveText(`${count}.${tab}`); +} + +export async function testUrlContains(page: Page, urlFragment: string) { + // Escape special regex characters in the URL fragment + const escapedFragment = urlFragment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + await expect(page).toHaveURL(new RegExp(escapedFragment)); +} + +export async function testUrlEquals(page: Page, url: string) { + await expect(page).toHaveURL(url); +} + +export async function testForward(page: Page) { + await testStack(page, 'ion-router-outlet', ['app-router-link', 'app-router-link-page']); + await testLifeCycle(page, 'app-router-link-page', { + ionViewWillEnter: 1, + ionViewDidEnter: 1, + ionViewWillLeave: 0, + ionViewDidLeave: 0, + }); + await expect(page.locator('app-router-link-page #canGoBack')).toHaveText('true'); + + await page.goBack(); + await testStack(page, 'ion-router-outlet', ['app-router-link']); + await testLifeCycle(page, 'app-router-link', { + ionViewWillEnter: 2, + ionViewDidEnter: 2, + ionViewWillLeave: 1, + ionViewDidLeave: 1, + }); +} + +export async function testRoot(page: Page) { + await testStack(page, 'ion-router-outlet', ['app-router-link-page']); + await testLifeCycle(page, 'app-router-link-page', { + ionViewWillEnter: 1, + ionViewDidEnter: 1, + ionViewWillLeave: 0, + ionViewDidLeave: 0, + }); + await expect(page.locator('app-router-link-page #canGoBack')).toHaveText('false'); + + await page.goBack(); + await page.waitForTimeout(100); // Wait for back navigation to complete + await testStack(page, 'ion-router-outlet', ['app-router-link']); + await testLifeCycle(page, 'app-router-link', { + ionViewWillEnter: 1, + ionViewDidEnter: 1, + ionViewWillLeave: 0, + ionViewDidLeave: 0, + }); +} + +export async function testBack(page: Page) { + // First check that we're on the router-link-page + await testStack(page, 'ion-router-outlet', ['app-router-link-page']); + await testLifeCycle(page, 'app-router-link-page', { + ionViewWillEnter: 1, + ionViewDidEnter: 1, + ionViewWillLeave: 0, + ionViewDidLeave: 0, + }); + await expect(page.locator('app-router-link-page #canGoBack')).toHaveText('false'); + + // Then go back + await page.goBack(); + await page.waitForTimeout(100); + await testStack(page, 'ion-router-outlet', ['app-router-link']); + await testLifeCycle(page, 'app-router-link', { + ionViewWillEnter: 1, + ionViewDidEnter: 1, + ionViewWillLeave: 0, + ionViewDidLeave: 0, + }); +} From 7a06582b6f0c1f98f0911648436cc8c6025b65c3 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Sat, 2 Aug 2025 16:10:48 -0400 Subject: [PATCH 2/9] test(angular): fix regexp --- packages/angular/test/base/e2e/src/lazy/router-link.spec.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts b/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts index d3fbd4bb13b..05dbe31422f 100644 --- a/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts +++ b/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts @@ -6,6 +6,11 @@ function escapeRegExp(string: string): string { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } +// Helper function to escape regex special characters +function escapeRegExp(string: string): string { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + test.describe('Router Link', () => { test.beforeEach(async ({ page }) => { await page.goto('/lazy/router-link?ionic:_testing=true'); From 9ed80c8654fc5b2e5246bffafd935cd544354392 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Sat, 2 Aug 2025 16:58:35 -0400 Subject: [PATCH 3/9] test(angular): rename utils --- .../test/base/e2e/utils/drag-element.ts | 23 --- .../test/base/e2e/utils/test-helpers.ts | 168 ------------------ 2 files changed, 191 deletions(-) delete mode 100644 packages/angular/test/base/e2e/utils/drag-element.ts delete mode 100644 packages/angular/test/base/e2e/utils/test-helpers.ts diff --git a/packages/angular/test/base/e2e/utils/drag-element.ts b/packages/angular/test/base/e2e/utils/drag-element.ts deleted file mode 100644 index a481effc2b6..00000000000 --- a/packages/angular/test/base/e2e/utils/drag-element.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { Locator, Page } from '@playwright/test'; - -export const dragElementBy = async ( - element: Locator, - page: Page, - dragByX = 0, - dragByY = 0 -) => { - const boundingBox = await element.boundingBox(); - if (!boundingBox) { - throw new Error('Element not visible'); - } - - const startX = boundingBox.x + boundingBox.width / 2; - const startY = boundingBox.y + boundingBox.height / 2; - const endX = startX + dragByX; - const endY = startY + dragByY; - - await page.mouse.move(startX, startY); - await page.mouse.down(); - await page.mouse.move(endX, endY); - await page.mouse.up(); -}; diff --git a/packages/angular/test/base/e2e/utils/test-helpers.ts b/packages/angular/test/base/e2e/utils/test-helpers.ts deleted file mode 100644 index 183c88da832..00000000000 --- a/packages/angular/test/base/e2e/utils/test-helpers.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { expect, type Page, type Locator } from '@playwright/test'; - -export async function testStack(page: Page, selector: string, expectedStack: string[]) { - const elements = page.locator(`${selector} > *`); - const count = await elements.count(); - - // Ensure we have at least the expected number of elements - expect(count).toBeGreaterThanOrEqual(expectedStack.length); - - for (let i = 0; i < expectedStack.length; i++) { - const element = elements.nth(i); - // Check that the element tag name matches the expected component name - const tagName = await element.evaluate(el => el.tagName.toLowerCase()); - expect(tagName).toBe(expectedStack[i]); - } -} - -export async function testLifeCycle(page: Page, selector: string, expectedCounts: Record) { - for (const [event, count] of Object.entries(expectedCounts)) { - // Look for text content within the specific selector - await expect(page.locator(selector).locator(`text=${event}: ${count}`)).toBeVisible(); - } -} - -export async function ionPageVisible(page: Page, selector: string) { - await expect(page.locator(selector)).toBeVisible(); - await expect(page.locator(selector)).not.toHaveAttribute('aria-hidden', 'true'); -} - -export async function ionPageHidden(page: Page, selector: string) { - await expect(page.locator(selector)).toHaveAttribute('aria-hidden', 'true'); -} - -export async function ionPageDoesNotExist(page: Page, selector: string) { - // Check that no visible elements with this selector exist - const visibleElements = page.locator(`${selector}:visible`); - await expect(visibleElements).toHaveCount(0); -} - -export async function ionTabClick(page: Page, tabName: string) { - await page.locator(`ion-tab-button`).filter({ hasText: tabName }).click(); -} - -export async function ionSwipeToGoBack(page: Page, shouldGoBack = false) { - // Simulate swipe gesture for going back - const viewport = page.viewportSize(); - if (!viewport) return; - - const startX = 50; - const endX = shouldGoBack ? viewport.width - 50 : 50; - const y = viewport.height / 2; - - await page.mouse.move(startX, y); - await page.mouse.down(); - await page.mouse.move(endX, y); - await page.mouse.up(); -} - -export async function testTabTitle(page: Page, title: string) { - const tab = await getSelectedTab(page); - await expect(tab.locator('ion-title')).toHaveText(title); - return getSelectedTab(page); -} - -export async function getSelectedTab(page: Page): Promise { - // Wait for tab navigation to stabilize - await page.waitForTimeout(200); - - // Look for tabs that are visible and have content - const tabs = page.locator('ion-tabs ion-router-outlet > *:not(.ion-page-hidden)'); - const count = await tabs.count(); - - // If there's only one tab, return it - if (count === 1) { - return tabs.first(); - } - - // If there are multiple tabs, find the one that's actually visible and has content - for (let i = 0; i < count; i++) { - const tab = tabs.nth(i); - const isVisible = await tab.isVisible(); - if (isVisible) { - return tab; - } - } - - // Fallback to the first tab if none are explicitly visible - return tabs.first(); -} - -export async function testState(page: Page, count: number, tab: string) { - - await expect(page.locator('#tabs-state')).toHaveText(`${count}.${tab}`); -} - -export async function testUrlContains(page: Page, urlFragment: string) { - // Escape special regex characters in the URL fragment - const escapedFragment = urlFragment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - await expect(page).toHaveURL(new RegExp(escapedFragment)); -} - -export async function testUrlEquals(page: Page, url: string) { - await expect(page).toHaveURL(url); -} - -export async function testForward(page: Page) { - await testStack(page, 'ion-router-outlet', ['app-router-link', 'app-router-link-page']); - await testLifeCycle(page, 'app-router-link-page', { - ionViewWillEnter: 1, - ionViewDidEnter: 1, - ionViewWillLeave: 0, - ionViewDidLeave: 0, - }); - await expect(page.locator('app-router-link-page #canGoBack')).toHaveText('true'); - - await page.goBack(); - await testStack(page, 'ion-router-outlet', ['app-router-link']); - await testLifeCycle(page, 'app-router-link', { - ionViewWillEnter: 2, - ionViewDidEnter: 2, - ionViewWillLeave: 1, - ionViewDidLeave: 1, - }); -} - -export async function testRoot(page: Page) { - await testStack(page, 'ion-router-outlet', ['app-router-link-page']); - await testLifeCycle(page, 'app-router-link-page', { - ionViewWillEnter: 1, - ionViewDidEnter: 1, - ionViewWillLeave: 0, - ionViewDidLeave: 0, - }); - await expect(page.locator('app-router-link-page #canGoBack')).toHaveText('false'); - - await page.goBack(); - await page.waitForTimeout(100); // Wait for back navigation to complete - await testStack(page, 'ion-router-outlet', ['app-router-link']); - await testLifeCycle(page, 'app-router-link', { - ionViewWillEnter: 1, - ionViewDidEnter: 1, - ionViewWillLeave: 0, - ionViewDidLeave: 0, - }); -} - -export async function testBack(page: Page) { - // First check that we're on the router-link-page - await testStack(page, 'ion-router-outlet', ['app-router-link-page']); - await testLifeCycle(page, 'app-router-link-page', { - ionViewWillEnter: 1, - ionViewDidEnter: 1, - ionViewWillLeave: 0, - ionViewDidLeave: 0, - }); - await expect(page.locator('app-router-link-page #canGoBack')).toHaveText('false'); - - // Then go back - await page.goBack(); - await page.waitForTimeout(100); - await testStack(page, 'ion-router-outlet', ['app-router-link']); - await testLifeCycle(page, 'app-router-link', { - ionViewWillEnter: 1, - ionViewDidEnter: 1, - ionViewWillLeave: 0, - ionViewDidLeave: 0, - }); -} From 4c0671847b95d763064b957e171e3bce76e81acd Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Fri, 1 Aug 2025 17:30:54 -0400 Subject: [PATCH 4/9] fix(reorder-group): fallback to children if __children is undefined --- core/src/components/reorder-group/reorder-group.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/components/reorder-group/reorder-group.tsx b/core/src/components/reorder-group/reorder-group.tsx index c9deba6f205..918beebd99a 100644 --- a/core/src/components/reorder-group/reorder-group.tsx +++ b/core/src/components/reorder-group/reorder-group.tsx @@ -153,7 +153,7 @@ export class ReorderGroup implements ComponentInterface { const heights = this.cachedHeights; heights.length = 0; const el = this.el; - const children: any = el.__children; + const children: any = el.__children || el.children; if (!children || children.length === 0) { return; } @@ -259,7 +259,7 @@ export class ReorderGroup implements ComponentInterface { private completeReorder(listOrReorder?: boolean | any[]): any { const selectedItemEl = this.selectedItemEl; if (selectedItemEl && this.state === ReorderGroupState.Complete) { - const children: any = this.el.__children; + const children: any = this.el.__children || this.el.children; const len = children.length; const toIndex = this.lastToIndex; const fromIndex = indexForItem(selectedItemEl); @@ -309,7 +309,7 @@ export class ReorderGroup implements ComponentInterface { /********* DOM WRITE ********* */ private reorderMove(fromIndex: number, toIndex: number) { const itemHeight = this.selectedItemHeight; - const children: any = this.el.__children; + const children: any = this.el.__children || this.el.children; for (let i = 0; i < children.length; i++) { const style = (children[i] as any).style; let value = ''; From 671f6564596f0f0dabad03e3cf232738bd42f926 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Sat, 2 Aug 2025 15:23:26 -0400 Subject: [PATCH 5/9] test(angular): add reorder-group test --- .../e2e/src/standalone/reorder-group.spec.ts | 25 +++++++++++++ .../standalone/app-standalone/app.routes.ts | 1 + .../home-page/home-page.component.html | 5 +++ .../reorder-group/reorder-group.component.ts | 36 +++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 packages/angular/test/base/e2e/src/standalone/reorder-group.spec.ts create mode 100644 packages/angular/test/base/src/app/standalone/reorder-group/reorder-group.component.ts diff --git a/packages/angular/test/base/e2e/src/standalone/reorder-group.spec.ts b/packages/angular/test/base/e2e/src/standalone/reorder-group.spec.ts new file mode 100644 index 00000000000..3ab35f6fff3 --- /dev/null +++ b/packages/angular/test/base/e2e/src/standalone/reorder-group.spec.ts @@ -0,0 +1,25 @@ +import { expect } from '@playwright/test'; +import { test } from '@playwright/test'; +import { dragElementBy } from '../../utils/drag-element'; + +test.describe('reorder-group: angular standalone', () => { + test('should reorder the items', async ({ page }) => { + await page.goto('/standalone/reorder-group'); + + // Get initial order + const initialItems = await page.locator('ion-item').allTextContents(); + expect(initialItems).toEqual(['Item 1', 'Item 2', 'Item 3']); + + const reorderGroup = page.locator('ion-reorder-group'); + + // Drag the first item down to move it to the end (below Item 3) + await dragElementBy(reorderGroup.locator('ion-reorder').first(), page, 0, 300); + + // Wait for the reorder to complete + await page.waitForTimeout(500); + + // Verify the new order - Item 1 should now be at the end + const finalItems = await page.locator('ion-item').allTextContents(); + expect(finalItems).toEqual(['Item 2', 'Item 3', 'Item 1']); + }); +}); diff --git a/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts b/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts index 8b267987ebd..ae6ee66193c 100644 --- a/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts +++ b/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts @@ -19,6 +19,7 @@ export const routes: Routes = [ { path: 'providers', loadComponent: () => import('../providers/providers.component').then(c => c.ProvidersComponent) }, { path: 'overlay-controllers', loadComponent: () => import('../overlay-controllers/overlay-controllers.component').then(c => c.OverlayControllersComponent) }, { path: 'button', loadComponent: () => import('../button/button.component').then(c => c.ButtonComponent) }, + { path: 'reorder-group', loadComponent: () => import('../reorder-group/reorder-group.component').then(c => c.ReorderGroupComponent) }, { path: 'icon', loadComponent: () => import('../icon/icon.component').then(c => c.IconComponent) }, { path: 'split-pane', redirectTo: '/standalone/split-pane/inbox', pathMatch: 'full' }, { diff --git a/packages/angular/test/base/src/app/standalone/home-page/home-page.component.html b/packages/angular/test/base/src/app/standalone/home-page/home-page.component.html index cc99a1439da..163e438d42c 100644 --- a/packages/angular/test/base/src/app/standalone/home-page/home-page.component.html +++ b/packages/angular/test/base/src/app/standalone/home-page/home-page.component.html @@ -28,6 +28,11 @@ Icon Test + + + Reorder Group Test + + diff --git a/packages/angular/test/base/src/app/standalone/reorder-group/reorder-group.component.ts b/packages/angular/test/base/src/app/standalone/reorder-group/reorder-group.component.ts new file mode 100644 index 00000000000..528ee343022 --- /dev/null +++ b/packages/angular/test/base/src/app/standalone/reorder-group/reorder-group.component.ts @@ -0,0 +1,36 @@ +import { Component } from "@angular/core"; +import { IonItem, IonLabel, IonReorder, IonReorderGroup } from '@ionic/angular/standalone'; +import { ReorderEndCustomEvent } from "@ionic/angular"; + +@Component({ + selector: 'app-reorder-group', + template: ` + + + + Item 1 + + + + Item 2 + + + + Item 3 + + + `, + standalone: true, + imports: [IonItem, IonLabel, IonReorder, IonReorderGroup] +}) +export class ReorderGroupComponent { + onReorderEnd(event: ReorderEndCustomEvent) { + if (event.detail.from !== event.detail.to) { + console.log('ionReorderEnd: Dragged from index', event.detail.from, 'to', event.detail.to); + } else { + console.log('ionReorderEnd: No position change occurred'); + } + + event.detail.complete(); + } +} From 2ff7d238cb4e3e2351e8d2582edace584f160f7c Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Mon, 4 Aug 2025 13:23:42 -0400 Subject: [PATCH 6/9] test(angular): renamed utils file --- .../angular/test/base/e2e/src/standalone/reorder-group.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/test/base/e2e/src/standalone/reorder-group.spec.ts b/packages/angular/test/base/e2e/src/standalone/reorder-group.spec.ts index 3ab35f6fff3..094d912d09a 100644 --- a/packages/angular/test/base/e2e/src/standalone/reorder-group.spec.ts +++ b/packages/angular/test/base/e2e/src/standalone/reorder-group.spec.ts @@ -1,6 +1,6 @@ import { expect } from '@playwright/test'; import { test } from '@playwright/test'; -import { dragElementBy } from '../../utils/drag-element'; +import { dragElementBy } from '../../utils/drag-utils'; test.describe('reorder-group: angular standalone', () => { test('should reorder the items', async ({ page }) => { From 01f43fe6ead68d401c712744139c778d52c3d497 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Mon, 4 Aug 2025 14:02:39 -0400 Subject: [PATCH 7/9] test(react): add reorder-group test --- packages/react/test/base/src/App.tsx | 2 + packages/react/test/base/src/pages/Main.tsx | 3 + .../test/base/src/pages/ReorderGroup.tsx | 58 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 packages/react/test/base/src/pages/ReorderGroup.tsx diff --git a/packages/react/test/base/src/App.tsx b/packages/react/test/base/src/App.tsx index 291acf7524f..475e4fdcd76 100644 --- a/packages/react/test/base/src/App.tsx +++ b/packages/react/test/base/src/App.tsx @@ -36,6 +36,7 @@ import IonPopoverNested from './pages/overlay-components/IonPopoverNested'; import KeepContentsMounted from './pages/overlay-components/KeepContentsMounted'; import OverlayComponents from './pages/overlay-components/OverlayComponents'; import OverlayHooks from './pages/overlay-hooks/OverlayHooks'; +import ReorderGroup from './pages/ReorderGroup'; setupIonicReact(); @@ -67,6 +68,7 @@ const App: React.FC = () => ( + diff --git a/packages/react/test/base/src/pages/Main.tsx b/packages/react/test/base/src/pages/Main.tsx index 5595c0d6307..d7fc30c3767 100644 --- a/packages/react/test/base/src/pages/Main.tsx +++ b/packages/react/test/base/src/pages/Main.tsx @@ -46,6 +46,9 @@ const Main: React.FC = () => { Inputs + + Reorder Group + diff --git a/packages/react/test/base/src/pages/ReorderGroup.tsx b/packages/react/test/base/src/pages/ReorderGroup.tsx new file mode 100644 index 00000000000..29dc50273b4 --- /dev/null +++ b/packages/react/test/base/src/pages/ReorderGroup.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import { + IonBackButton, + IonButtons, + IonContent, + IonHeader, + IonItem, + IonLabel, + IonPage, + IonReorder, + IonReorderGroup, + IonTitle, + IonToolbar, +} from '@ionic/react'; +import type { ReorderEndCustomEvent } from '@ionic/react'; + +const ReorderGroup: React.FC = () => { + const onReorderEnd = (event: ReorderEndCustomEvent) => { + if (event.detail.from !== event.detail.to) { + console.log('ionReorderEnd: Dragged from index', event.detail.from, 'to', event.detail.to); + } else { + console.log('ionReorderEnd: No position change occurred'); + } + + event.detail.complete(); + }; + + return ( + + + + + + + Reorder Group + + + + + + + Item 1 + + + + Item 2 + + + + Item 3 + + + + + ); +}; + +export default ReorderGroup; From c8be6121130ed294022ecb3a4055fe3fb1851a04 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Mon, 4 Aug 2025 14:07:04 -0400 Subject: [PATCH 8/9] test(vue): add reorder-group test --- packages/vue/test/base/src/router/index.ts | 4 + packages/vue/test/base/src/views/Home.vue | 3 + .../vue/test/base/src/views/ReorderGroup.vue | 78 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 packages/vue/test/base/src/views/ReorderGroup.vue diff --git a/packages/vue/test/base/src/router/index.ts b/packages/vue/test/base/src/router/index.ts index 5e344988313..13d4e919ad6 100644 --- a/packages/vue/test/base/src/router/index.ts +++ b/packages/vue/test/base/src/router/index.ts @@ -86,6 +86,10 @@ const routes: Array = [ path: '/components/range', component: () => import('@/views/Range.vue') }, + { + path: '/reorder-group', + component: () => import('@/views/ReorderGroup.vue') + }, { path: '/nested', component: () => import('@/views/RouterOutlet.vue'), diff --git a/packages/vue/test/base/src/views/Home.vue b/packages/vue/test/base/src/views/Home.vue index 853832bd8c6..d4d88e61a3f 100644 --- a/packages/vue/test/base/src/views/Home.vue +++ b/packages/vue/test/base/src/views/Home.vue @@ -29,6 +29,9 @@ Navigation + + Reorder Group + Routing diff --git a/packages/vue/test/base/src/views/ReorderGroup.vue b/packages/vue/test/base/src/views/ReorderGroup.vue new file mode 100644 index 00000000000..48ccab650ec --- /dev/null +++ b/packages/vue/test/base/src/views/ReorderGroup.vue @@ -0,0 +1,78 @@ + + + From 390ee141a9dc741fb2e54eb787436ca04e8db7b2 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Tue, 5 Aug 2025 10:16:29 -0400 Subject: [PATCH 9/9] revert --- packages/angular/test/base/e2e/src/lazy/router-link.spec.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts b/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts index 05dbe31422f..d3fbd4bb13b 100644 --- a/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts +++ b/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts @@ -6,11 +6,6 @@ function escapeRegExp(string: string): string { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } -// Helper function to escape regex special characters -function escapeRegExp(string: string): string { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -} - test.describe('Router Link', () => { test.beforeEach(async ({ page }) => { await page.goto('/lazy/router-link?ionic:_testing=true');