Skip to content

Commit e681558

Browse files
committed
test(item-sliding): add a test for the CDN issue with side
1 parent 630d4ea commit e681558

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

core/src/components/item-sliding/test/async/item-sliding.e2e.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { expect } from '@playwright/test';
22
import { configs, test } from '@utils/test/playwright';
33

4+
/**
5+
* This behavior does not vary across modes/directions
6+
*/
47
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
58
test.describe(title('item-sliding: async'), () => {
69
test.beforeEach(async ({ page }) => {
@@ -35,5 +38,83 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
3538

3639
await expect(itemSlidingEl).toHaveClass(/item-sliding-active-slide/);
3740
});
41+
42+
test('should not throw errors when adding multiple items with side="end" using the Ionic CDN', async ({ page }, testInfo) => {
43+
testInfo.annotations.push({
44+
type: 'issue',
45+
description: 'https://github.com/ionic-team/ionic-framework/issues/29499',
46+
});
47+
48+
const errors: string[] = [];
49+
page.on('console', msg => {
50+
if (msg.type() === 'error') {
51+
errors.push(msg.text());
52+
}
53+
});
54+
page.on('pageerror', error => {
55+
errors.push(error.message);
56+
});
57+
58+
// This issue only happens when using a CDN version of Ionic
59+
// so we need to use the CDN by passing the `importIonicFromCDN` option
60+
// to setContent.
61+
await page.setContent(`
62+
<ion-header>
63+
<ion-toolbar>
64+
<ion-title>Item Sliding</ion-title>
65+
<ion-buttons slot="end">
66+
<ion-button id="addItem" onclick="addItem()">ADD ITEM</ion-button>
67+
</ion-buttons>
68+
</ion-toolbar>
69+
</ion-header>
70+
<ion-content>
71+
<ion-list id="list"></ion-list>
72+
</ion-content>
73+
74+
<script>
75+
let itemList = [];
76+
function generateItem() {
77+
const currentItem = itemList.length + 1;
78+
const item = \`
79+
<ion-item-sliding id="item-\${currentItem}">
80+
<ion-item>
81+
<ion-label>Sliding Item \${currentItem}</ion-label>
82+
</ion-item>
83+
<ion-item-options side="end">
84+
<ion-item-option color="danger" id="delete-item-\${currentItem}">Delete</ion-item-option>
85+
</ion-item-options>
86+
</ion-item-sliding>
87+
\`;
88+
itemList.push(item);
89+
return item;
90+
}
91+
function addItem() {
92+
const list = document.getElementById('list');
93+
list.innerHTML += generateItem();
94+
const currentItem = itemList.length;
95+
const deleteId = \`#delete-item-\${currentItem}\`;
96+
const itemId = \`#item-\${currentItem}\`;
97+
document.querySelector(deleteId).addEventListener('click', (ev) => {
98+
document.querySelector(itemId).remove();
99+
});
100+
}
101+
</script>
102+
`, { ...config, importIonicFromCDN: true });
103+
104+
// Click the button enough times to reproduce the issue
105+
const addButton = page.locator('#addItem');
106+
await addButton.click();
107+
await addButton.click();
108+
await addButton.click();
109+
110+
await page.waitForChanges();
111+
112+
// Check that the items have been added
113+
const items = page.locator('ion-item-sliding');
114+
expect(await items.count()).toBe(3);
115+
116+
// Check that no errors have been logged
117+
expect(errors.length).toBe(0);
118+
});
38119
});
39120
});

core/src/utils/test/playwright/page/utils/set-content.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,33 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o
3333

3434
const baseUrl = process.env.PLAYWRIGHT_TEST_BASE_URL;
3535

36+
// The Ionic bundle is included locally by default unless the test
37+
// config passes in the importIonicFromCDN option. This is useful
38+
// when testing with the CDN version of Ionic.
39+
let ionicImports = `
40+
<link href="${baseUrl}/css/ionic.bundle.css" rel="stylesheet" />
41+
<script type="module" src="${baseUrl}/dist/ionic/ionic.esm.js"></script>
42+
`;
43+
44+
if (options?.importIonicFromCDN) {
45+
ionicImports = `
46+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css" />
47+
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"></script>
48+
<script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js"></script>
49+
`;
50+
}
51+
3652
const output = `
3753
<!DOCTYPE html>
3854
<html dir="${direction}" lang="en">
3955
<head>
4056
<title>Ionic Playwright Test</title>
4157
<meta charset="UTF-8" />
4258
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
43-
<link href="${baseUrl}/css/ionic.bundle.css" rel="stylesheet" />
4459
<link href="${baseUrl}/scripts/testing/styles.css" rel="stylesheet" />
4560
${palette !== 'light' ? `<link href="${baseUrl}/css/palettes/${palette}.always.css" rel="stylesheet" />` : ''}
4661
<script src="${baseUrl}/scripts/testing/scripts.js"></script>
47-
<script type="module" src="${baseUrl}/dist/ionic/ionic.esm.js"></script>
62+
${ionicImports}
4863
<script>
4964
window.Ionic = {
5065
config: {

core/src/utils/test/playwright/playwright-declarations.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ interface PageOptions {
3131
* - `'commit'` - consider operation to be finished when network response is received and the document started loading.
3232
*/
3333
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle' | 'commit';
34+
35+
/**
36+
* If true, the default Ionic imports will be included
37+
* via the CDN instead of the local bundle.
38+
*/
39+
importIonicFromCDN?: boolean;
3440
}
3541

3642
export interface E2EPage extends Page {

0 commit comments

Comments
 (0)