fix: content() not showing comments outside html tag (#10293)

This commit is contained in:
Nikolay Vitkov 2023-06-01 21:51:16 +02:00 committed by GitHub
parent 27db1eb4f4
commit 9abd48a062
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 31 deletions

View File

@ -200,6 +200,12 @@ module.exports = {
selector:
'MemberExpression[object.name="Promise"][property.name="race"]',
},
{
message:
'Deferred `valueOrThrow` should not be called in `Deferred.race()` pass deferred directly',
selector:
'CallExpression[callee.object.name="Deferred"][callee.property.name="race"] > ArrayExpression > CallExpression[callee.property.name="valueOrThrow"]',
},
],
'@typescript-eslint/no-floating-promises': [
'error',

View File

@ -22,7 +22,10 @@ import {isErrorLike} from '../util/ErrorLike.js';
import {ElementHandle, BoundingBox, ClickOptions} from './ElementHandle.js';
import type {Page} from './Page.js';
type VisibilityOption = 'hidden' | 'visible' | null;
/**
* @internal
*/
export type VisibilityOption = 'hidden' | 'visible' | null;
/**
* @internal

View File

@ -41,6 +41,7 @@ import {
addPageBinding,
createJSHandle,
debugError,
getPageContent,
setPageContent,
withSourcePuppeteerURLIfNone,
} from './util.js';
@ -272,16 +273,7 @@ export class IsolatedWorld {
}
async content(): Promise<string> {
return await this.evaluate(() => {
let retVal = '';
if (document.doctype) {
retVal = new XMLSerializer().serializeToString(document.doctype);
}
if (document.documentElement) {
retVal += document.documentElement.outerHTML;
}
return retVal;
});
return await this.evaluate(getPageContent);
}
async setContent(
@ -533,12 +525,9 @@ class Mutex {
this.#locked = true;
return Promise.resolve();
}
let resolve!: () => void;
const promise = new Promise<void>(res => {
resolve = res;
});
this.#acquirers.push(resolve);
return promise;
const deferred = Deferred.create<void>();
this.#acquirers.push(deferred.resolve.bind(deferred));
return deferred.valueOrThrow();
}
release(): void {

View File

@ -11,6 +11,7 @@ import {TimeoutSettings} from '../TimeoutSettings.js';
import {EvaluateFunc, HandleFor} from '../types.js';
import {
PuppeteerURL,
getPageContent,
getSourcePuppeteerURLIfAvailable,
isString,
setPageContent,
@ -240,7 +241,7 @@ export class BrowsingContext extends EventEmitter {
timeout = this.#timeoutSettings.navigationTimeout(),
} = options;
const waitUntilCommand = lifeCycleToSubscribedEvent.get(
const waitUntilEvent = lifeCycleToSubscribedEvent.get(
getWaitUntilSingle(waitUntil)
) as string;
@ -248,27 +249,18 @@ export class BrowsingContext extends EventEmitter {
setPageContent(this, html),
waitWithTimeout(
new Promise<void>(resolve => {
this.once(waitUntilCommand, () => {
this.once(waitUntilEvent, () => {
resolve();
});
}),
waitUntilCommand,
waitUntilEvent,
timeout
),
]);
}
async content(): Promise<string> {
return await this.evaluate(() => {
let retVal = '';
if (document.doctype) {
retVal = new XMLSerializer().serializeToString(document.doctype);
}
if (document.documentElement) {
retVal += document.documentElement.outerHTML;
}
return retVal;
});
return await this.evaluate(getPageContent);
}
async sendCDPCommand(

View File

@ -510,7 +510,7 @@ export async function waitWithTimeout<T>(
timeout,
});
return await Deferred.race([promise, deferred.valueOrThrow()]).finally(() => {
return await Deferred.race([promise, deferred]).finally(() => {
deferred.reject(new Error('Cleared'));
});
}
@ -627,3 +627,22 @@ export async function setPageContent(
document.close();
}, content);
}
/**
* @internal
*/
export function getPageContent(): string {
let content = '';
for (const node of document.childNodes) {
switch (node) {
case document.documentElement:
content += document.documentElement.outerHTML;
break;
default:
content += new XMLSerializer().serializeToString(node);
break;
}
}
return content;
}

View File

@ -1555,6 +1555,14 @@ describe('Page', function () {
})
).toBe('\n');
});
it('should work with comments outside HTML tag', async () => {
const {page} = getTestState();
const comment = '<!-- Comment -->';
await page.setContent(`${comment}<div>hello</div>`);
const result = await page.content();
expect(result).toBe(`${comment}${expectedOutput}`);
});
});
describe('Page.setBypassCSP', function () {