Skip to content
Merged
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
14 changes: 14 additions & 0 deletions core/src/components/modal/modal.tsx
Copy link
Contributor

Choose a reason for hiding this comment

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

The ticket mentions that it's hard to create reliable test. Would it be possible to create a controller-based modal, open, then verify that we can still interact with the Angular test app? If it can interact, then it passes?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, that's kind of the thing. This test already "exists", there's e2e tests already doing this exact thing and they didn't break before. That's because the scenario itself is a bit unique and I'm not sure what actually makes it that way.

However, I think this might be a suitable alternative: da1911

In this commit I've created a test that ensures that controller-created modals do not have a mutation observer created for them, which should generally cover the bases here. Note: I had to use this PR as the "issue" because the actual issue is internal.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we can replicate it under the Angular test app instead of the core e2e tests? Regardless, I like your alternative! I'm happy with it. I only made one small suggestion.

Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,20 @@ export class Modal implements ComponentInterface, OverlayInterface {
return;
}

/**
* Don't observe for controller-based modals or when the parent is the
* app root (document.body or ion-app). These parents won't be removed,
* and observing document.body with subtree: true causes performance
* issues with frameworks like Angular during change detection.
*/
if (
this.hasController ||
this.cachedOriginalParent === document.body ||
this.cachedOriginalParent.tagName === 'ION-APP'
) {
return;
}

this.parentRemovalObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList' && mutation.removedNodes.length > 0) {
Expand Down
24 changes: 23 additions & 1 deletion core/src/components/modal/test/basic/modal.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect } from '@playwright/test';
import { configs, test, Viewports } from '@utils/test/playwright';
import type { E2EPage } from '@utils/test/playwright';
import { configs, test, Viewports } from '@utils/test/playwright';

configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
test.describe(title('modal: focus trapping'), () => {
Expand Down Expand Up @@ -104,6 +104,28 @@ configs().forEach(({ title, screenshot, config }) => {
});

configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
test.describe(title('modal: parent removal observer'), () => {
test('should not set up parentRemovalObserver for controller-created modals', async ({ page }, testInfo) => {
testInfo.annotations.push({
type: 'issue',
description: 'FW-6766',
});

await page.goto('/src/components/modal/test/basic', config);
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');

await page.click('#basic-modal');
await ionModalDidPresent.next();

const modal = page.locator('ion-modal');
const hasObserver = await modal.evaluate((el: any) => {
return el.parentRemovalObserver !== undefined;
});

expect(hasObserver).toBe(false);
});
});

test.describe(title('modal: backdrop'), () => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/modal/test/basic', config);
Expand Down
Loading