Skip to content

test(item-sliding): add test for side issue with CDN #30469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions core/src/components/item-sliding/test/async/item-sliding.e2e.ts
Original file line number Diff line number Diff line change
@@ -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 }) => {
Expand Down Expand Up @@ -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(
`
<ion-header>
<ion-toolbar>
<ion-title>Item Sliding</ion-title>
<ion-buttons slot="end">
<ion-button id="addItem" onclick="addItem()">ADD ITEM</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list id="list"></ion-list>
</ion-content>

<script>
let itemList = [];
function generateItem() {
const currentItem = itemList.length + 1;
const item = \`
<ion-item-sliding>
<ion-item>
<ion-label>Sliding Item \${currentItem}</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option>Delete</ion-item-option>
</ion-item-options>
</ion-item-sliding>
\`;
itemList.push(item);
return item;
}
function addItem() {
const list = document.getElementById('list');
list.innerHTML += generateItem();
const currentItem = itemList.length;
}
</script>
`,
{ ...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);
});
});
});
19 changes: 17 additions & 2 deletions core/src/utils/test/playwright/page/utils/set-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,33 @@ 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 = `
<link href="${baseUrl}/css/ionic.bundle.css" rel="stylesheet" />
<script type="module" src="${baseUrl}/dist/ionic/ionic.esm.js"></script>
`;

if (options?.importIonicFromCDN) {
ionicImports = `
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"></script>
<script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js"></script>
`;
}

const output = `
<!DOCTYPE html>
<html dir="${direction}" lang="en">
<head>
<title>Ionic Playwright Test</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
<link href="${baseUrl}/css/ionic.bundle.css" rel="stylesheet" />
<link href="${baseUrl}/scripts/testing/styles.css" rel="stylesheet" />
${palette !== 'light' ? `<link href="${baseUrl}/css/palettes/${palette}.always.css" rel="stylesheet" />` : ''}
<script src="${baseUrl}/scripts/testing/scripts.js"></script>
Comment on lines 59 to 61
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not these as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The testing scripts file is required for Playwright. Without it we would have to set all of the stuff for telling Playwright the app is loaded and determining the document direction, palette, etc: https://github.com/ionic-team/ionic-framework/blob/main/core/scripts/testing/scripts.js

I actually accidentally removed this at first and ran into an issue where none of the test after setContent was executed because window.testAppLoaded = true was never set.

<script type="module" src="${baseUrl}/dist/ionic/ionic.esm.js"></script>
${ionicImports}
<script>
window.Ionic = {
config: {
Expand Down
6 changes: 6 additions & 0 deletions core/src/utils/test/playwright/playwright-declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ interface PageOptions {
* - `'commit'` - consider operation to be finished when network response is received and the document started loading.
*/
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle' | 'commit';

/**
* If true, the default Ionic imports will be included
* via the CDN instead of the local bundle.
*/
importIonicFromCDN?: boolean;
}

export interface E2EPage extends Page {
Expand Down
Loading