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: selector:
'MemberExpression[object.name="Promise"][property.name="race"]', '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': [ '@typescript-eslint/no-floating-promises': [
'error', 'error',

View File

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

View File

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

View File

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

View File

@ -510,7 +510,7 @@ export async function waitWithTimeout<T>(
timeout, timeout,
}); });
return await Deferred.race([promise, deferred.valueOrThrow()]).finally(() => { return await Deferred.race([promise, deferred]).finally(() => {
deferred.reject(new Error('Cleared')); deferred.reject(new Error('Cleared'));
}); });
} }
@ -627,3 +627,22 @@ export async function setPageContent(
document.close(); document.close();
}, content); }, 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'); ).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 () { describe('Page.setBypassCSP', function () {