chore: enable coverage over bidi+ (#10387)

This commit is contained in:
Alex Rudenko 2023-06-15 10:00:14 +02:00 committed by GitHub
parent 93115587c9
commit 853d0dc76f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 20 deletions

View File

@ -4,7 +4,9 @@ import ProtocolMapping from 'devtools-protocol/types/protocol-mapping.js';
import {WaitForOptions} from '../../api/Page.js';
import PuppeteerUtil from '../../injected/injected.js';
import {assert} from '../../util/assert.js';
import {Deferred} from '../../util/Deferred.js';
import {stringifyFunction} from '../../util/Function.js';
import type {CDPSession, Connection as CDPConnection} from '../Connection.js';
import {ProtocolError, TimeoutError} from '../Errors.js';
import {EventEmitter} from '../EventEmitter.js';
import {PuppeteerLifeCycleEvent} from '../LifecycleWatcher.js';
@ -51,6 +53,54 @@ const lifeCycleToReadinessState = new Map<
['domcontentloaded', 'interactive'],
]);
/**
* @internal
*/
export class CDPSessionWrapper extends EventEmitter implements CDPSession {
#context: BrowsingContext;
#sessionId = Deferred.create<string>();
constructor(context: BrowsingContext) {
super();
this.#context = context;
context.connection
.send('cdp.getSession', {
context: context.id,
})
.then(session => {
this.#sessionId.resolve(session.result.cdpSession);
})
.catch(err => {
this.#sessionId.reject(err);
});
}
connection(): CDPConnection | undefined {
return undefined;
}
async send<T extends keyof ProtocolMapping.Commands>(
method: T,
...paramArgs: ProtocolMapping.Commands[T]['paramsType']
): Promise<ProtocolMapping.Commands[T]['returnType']> {
const cdpSession = await this.#sessionId.valueOrThrow();
const result = await this.#context.connection.send('cdp.sendCommand', {
cdpMethod: method,
cdpParams: paramArgs[0] || {},
cdpSession,
});
return result.result;
}
detach(): Promise<void> {
throw new Error('Method not implemented.');
}
id(): string {
const val = this.#sessionId.value();
return val instanceof Error || val === undefined ? '' : val;
}
}
/**
* @internal
*/
@ -59,7 +109,7 @@ export class BrowsingContext extends EventEmitter {
#timeoutSettings: TimeoutSettings;
#id: string;
#url = 'about:blank';
#cdpSessionId?: string;
#cdpSession: CDPSession;
constructor(
connection: Connection,
@ -70,6 +120,7 @@ export class BrowsingContext extends EventEmitter {
this.connection = connection;
this.#timeoutSettings = timeoutSettings;
this.#id = info.context;
this.#cdpSession = new CDPSessionWrapper(this);
}
#puppeteerUtil?: Promise<JSHandle<PuppeteerUtil>>;
@ -96,8 +147,8 @@ export class BrowsingContext extends EventEmitter {
return this.#id;
}
get cdpSessionId(): string | undefined {
return this.#cdpSessionId;
get cdpSession(): CDPSession {
return this.#cdpSession;
}
async goto(
@ -288,21 +339,9 @@ export class BrowsingContext extends EventEmitter {
async sendCDPCommand<T extends keyof ProtocolMapping.Commands>(
method: T,
params: ProtocolMapping.Commands[T]['paramsType'][0] = {}
...paramArgs: ProtocolMapping.Commands[T]['paramsType']
): Promise<ProtocolMapping.Commands[T]['returnType']> {
if (!this.#cdpSessionId) {
const session = await this.connection.send('cdp.getSession', {
context: this.#id,
});
const sessionId = session.result.cdpSession;
this.#cdpSessionId = sessionId;
}
const result = await this.connection.send('cdp.sendCommand', {
cdpMethod: method,
cdpParams: params,
cdpSession: this.#cdpSessionId,
});
return result.result;
return this.#cdpSession.send(method, ...paramArgs);
}
dispose(): void {

View File

@ -216,8 +216,11 @@ export class Connection extends EventEmitter {
// the CDPSession interface with BiDi?.
const cdpSessionId = event.params.cdpSession;
for (const context of this.#browsingContexts.values()) {
if (context.cdpSessionId === cdpSessionId) {
context?.emit(event.params.cdpMethod, event.params.cdpParams);
if (context.cdpSession?.id() === cdpSessionId) {
context.cdpSession!.emit(
event.params.cdpMethod,
event.params.cdpParams
);
}
}
}

View File

@ -29,6 +29,7 @@ import {assert} from '../../util/assert.js';
import {Deferred} from '../../util/Deferred.js';
import {Accessibility} from '../Accessibility.js';
import {ConsoleMessage, ConsoleMessageLocation} from '../ConsoleMessage.js';
import {Coverage} from '../Coverage.js';
import {TargetCloseError} from '../Errors.js';
import {Handler} from '../EventEmitter.js';
import {FrameManagerEmittedEvents} from '../FrameManager.js';
@ -120,6 +121,7 @@ export class Page extends PageBase {
],
]);
#tracing: Tracing;
#coverage: Coverage;
constructor(browserContext: BrowserContext, info: {context: string}) {
super();
@ -169,13 +171,15 @@ export class Page extends PageBase {
const deferred = Deferred.create();
this.mainFrame()
.context()
.once('Tracing.tracingComplete', event => {
.cdpSession.once('Tracing.tracingComplete', event => {
deferred.resolve(event);
});
await this.mainFrame().context().sendCDPCommand('Tracing.end');
return deferred.valueOrThrow() as Promise<Protocol.Tracing.TracingCompleteEvent>;
},
});
this.#coverage = new Coverage(this.mainFrame().context().cdpSession);
}
override get accessibility(): Accessibility {
@ -186,6 +190,10 @@ export class Page extends PageBase {
return this.#tracing;
}
override get coverage(): Coverage {
return this.#coverage;
}
override browser(): Browser {
return this.#browserContext.browser();
}

View File

@ -287,6 +287,12 @@
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[coverage.spec] *",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[Deferred.spec] DeferredPromise should catch errors",
"platforms": ["darwin", "linux", "win32"],
@ -1073,6 +1079,48 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[coverage.spec] Coverage specs CSSCoverage should ignore injected stylesheets",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[coverage.spec] Coverage specs CSSCoverage should work with complicated usecases",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[coverage.spec] Coverage specs CSSCoverage should work with media queries",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[coverage.spec] Coverage specs JSCoverage includeRawScriptCoverage should include rawScriptCoverage field when enabled",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[coverage.spec] Coverage specs JSCoverage includeRawScriptCoverage should not include rawScriptCoverage field when disabled",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[coverage.spec] Coverage specs JSCoverage should ignore pptr internal scripts if reportAnonymousScripts is true",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[coverage.spec] Coverage specs JSCoverage should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[defaultbrowsercontext.spec] DefaultBrowserContext page.deleteCookie() should work",
"platforms": ["darwin", "linux", "win32"],