add support for nested shadow dom (#834)

* fix: can't record shadow host and shadow dom in incremental mutations

* enable to record newly added shadow dom

* Revert "enable to record newly added shadow dom"

This reverts commit cf7c0ad551ac457f00e3f754702c1464314f6a86.

* Revert "fix: can't record shadow host and shadow dom in incremental mutations"

This reverts commit 8b25cc97f83cbc333702c0ba73684e54eeadaabe.

* fix: can't record shadow host and shadow dom in incremental mutations

* add support for nested shadow root and add integration test

* fix test error

* enable to record shadow-dom in iframes

* add an integration test case for nested iframes and shadow-doms

* use the patch function
This commit is contained in:
Yun Feng
2026-04-01 12:00:00 +08:00
committed by GitHub
parent 39eed78dad
commit c67a48df70
7 changed files with 497 additions and 4 deletions

View File

@@ -530,6 +530,56 @@ describe('record integration tests', function (this: ISuite) {
.then(() => {
(shadowRoot.lastChild!.childNodes[0] as HTMLElement).innerText =
'123';
const nestedShadowElement = shadowRoot.lastChild!
.childNodes[0] as HTMLElement;
nestedShadowElement.attachShadow({
mode: 'open',
});
nestedShadowElement.shadowRoot!.appendChild(
document.createElement('span'),
);
(nestedShadowElement.shadowRoot!.lastChild as HTMLElement).innerText =
'nested shadow dom';
});
});
await page.waitForTimeout(50);
const snapshots = await page.evaluate('window.snapshots');
assertSnapshot(snapshots);
});
it('should record nested iframes and shadow doms', async () => {
const page: puppeteer.Page = await browser.newPage();
await page.goto('about:blank');
await page.setContent(getHtml.call(this, 'frame2.html'));
await page.evaluate(() => {
const sleep = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));
let iframe: HTMLIFrameElement;
sleep(10)
.then(() => {
// get contentDocument of iframe five
const contentDocument1 = document.querySelector('iframe')!
.contentDocument!;
// create shadow dom #1
contentDocument1.body.attachShadow({ mode: 'open' });
contentDocument1.body.shadowRoot!.appendChild(
document.createElement('div'),
);
const div = contentDocument1.body.shadowRoot!.childNodes[0];
iframe = contentDocument1.createElement('iframe');
// append an iframe to shadow dom #1
div.appendChild(iframe);
return sleep(10);
})
.then(() => {
const contentDocument2 = iframe.contentDocument!;
// create shadow dom #2 in the iframe
contentDocument2.body.attachShadow({ mode: 'open' });
contentDocument2.body.shadowRoot!.appendChild(
document.createElement('span'),
);
});
});
await page.waitForTimeout(50);