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 {WaitForOptions} from '../../api/Page.js';
import PuppeteerUtil from '../../injected/injected.js'; import PuppeteerUtil from '../../injected/injected.js';
import {assert} from '../../util/assert.js'; import {assert} from '../../util/assert.js';
import {Deferred} from '../../util/Deferred.js';
import {stringifyFunction} from '../../util/Function.js'; import {stringifyFunction} from '../../util/Function.js';
import type {CDPSession, Connection as CDPConnection} from '../Connection.js';
import {ProtocolError, TimeoutError} from '../Errors.js'; import {ProtocolError, TimeoutError} from '../Errors.js';
import {EventEmitter} from '../EventEmitter.js'; import {EventEmitter} from '../EventEmitter.js';
import {PuppeteerLifeCycleEvent} from '../LifecycleWatcher.js'; import {PuppeteerLifeCycleEvent} from '../LifecycleWatcher.js';
@ -51,6 +53,54 @@ const lifeCycleToReadinessState = new Map<
['domcontentloaded', 'interactive'], ['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 * @internal
*/ */
@ -59,7 +109,7 @@ export class BrowsingContext extends EventEmitter {
#timeoutSettings: TimeoutSettings; #timeoutSettings: TimeoutSettings;
#id: string; #id: string;
#url = 'about:blank'; #url = 'about:blank';
#cdpSessionId?: string; #cdpSession: CDPSession;
constructor( constructor(
connection: Connection, connection: Connection,
@ -70,6 +120,7 @@ export class BrowsingContext extends EventEmitter {
this.connection = connection; this.connection = connection;
this.#timeoutSettings = timeoutSettings; this.#timeoutSettings = timeoutSettings;
this.#id = info.context; this.#id = info.context;
this.#cdpSession = new CDPSessionWrapper(this);
} }
#puppeteerUtil?: Promise<JSHandle<PuppeteerUtil>>; #puppeteerUtil?: Promise<JSHandle<PuppeteerUtil>>;
@ -96,8 +147,8 @@ export class BrowsingContext extends EventEmitter {
return this.#id; return this.#id;
} }
get cdpSessionId(): string | undefined { get cdpSession(): CDPSession {
return this.#cdpSessionId; return this.#cdpSession;
} }
async goto( async goto(
@ -288,21 +339,9 @@ export class BrowsingContext extends EventEmitter {
async sendCDPCommand<T extends keyof ProtocolMapping.Commands>( async sendCDPCommand<T extends keyof ProtocolMapping.Commands>(
method: T, method: T,
params: ProtocolMapping.Commands[T]['paramsType'][0] = {} ...paramArgs: ProtocolMapping.Commands[T]['paramsType']
): Promise<ProtocolMapping.Commands[T]['returnType']> { ): Promise<ProtocolMapping.Commands[T]['returnType']> {
if (!this.#cdpSessionId) { return this.#cdpSession.send(method, ...paramArgs);
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;
} }
dispose(): void { dispose(): void {

View File

@ -216,8 +216,11 @@ export class Connection extends EventEmitter {
// the CDPSession interface with BiDi?. // the CDPSession interface with BiDi?.
const cdpSessionId = event.params.cdpSession; const cdpSessionId = event.params.cdpSession;
for (const context of this.#browsingContexts.values()) { for (const context of this.#browsingContexts.values()) {
if (context.cdpSessionId === cdpSessionId) { if (context.cdpSession?.id() === cdpSessionId) {
context?.emit(event.params.cdpMethod, event.params.cdpParams); 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 {Deferred} from '../../util/Deferred.js';
import {Accessibility} from '../Accessibility.js'; import {Accessibility} from '../Accessibility.js';
import {ConsoleMessage, ConsoleMessageLocation} from '../ConsoleMessage.js'; import {ConsoleMessage, ConsoleMessageLocation} from '../ConsoleMessage.js';
import {Coverage} from '../Coverage.js';
import {TargetCloseError} from '../Errors.js'; import {TargetCloseError} from '../Errors.js';
import {Handler} from '../EventEmitter.js'; import {Handler} from '../EventEmitter.js';
import {FrameManagerEmittedEvents} from '../FrameManager.js'; import {FrameManagerEmittedEvents} from '../FrameManager.js';
@ -120,6 +121,7 @@ export class Page extends PageBase {
], ],
]); ]);
#tracing: Tracing; #tracing: Tracing;
#coverage: Coverage;
constructor(browserContext: BrowserContext, info: {context: string}) { constructor(browserContext: BrowserContext, info: {context: string}) {
super(); super();
@ -169,13 +171,15 @@ export class Page extends PageBase {
const deferred = Deferred.create(); const deferred = Deferred.create();
this.mainFrame() this.mainFrame()
.context() .context()
.once('Tracing.tracingComplete', event => { .cdpSession.once('Tracing.tracingComplete', event => {
deferred.resolve(event); deferred.resolve(event);
}); });
await this.mainFrame().context().sendCDPCommand('Tracing.end'); await this.mainFrame().context().sendCDPCommand('Tracing.end');
return deferred.valueOrThrow() as Promise<Protocol.Tracing.TracingCompleteEvent>; return deferred.valueOrThrow() as Promise<Protocol.Tracing.TracingCompleteEvent>;
}, },
}); });
this.#coverage = new Coverage(this.mainFrame().context().cdpSession);
} }
override get accessibility(): Accessibility { override get accessibility(): Accessibility {
@ -186,6 +190,10 @@ export class Page extends PageBase {
return this.#tracing; return this.#tracing;
} }
override get coverage(): Coverage {
return this.#coverage;
}
override browser(): Browser { override browser(): Browser {
return this.#browserContext.browser(); return this.#browserContext.browser();
} }

View File

@ -287,6 +287,12 @@
"parameters": ["cdp", "firefox"], "parameters": ["cdp", "firefox"],
"expectations": ["SKIP"] "expectations": ["SKIP"]
}, },
{
"testIdPattern": "[coverage.spec] *",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["PASS"]
},
{ {
"testIdPattern": "[Deferred.spec] DeferredPromise should catch errors", "testIdPattern": "[Deferred.spec] DeferredPromise should catch errors",
"platforms": ["darwin", "linux", "win32"], "platforms": ["darwin", "linux", "win32"],
@ -1073,6 +1079,48 @@
"parameters": ["cdp", "firefox"], "parameters": ["cdp", "firefox"],
"expectations": ["FAIL"] "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", "testIdPattern": "[defaultbrowsercontext.spec] DefaultBrowserContext page.deleteCookie() should work",
"platforms": ["darwin", "linux", "win32"], "platforms": ["darwin", "linux", "win32"],