chrome-devtools-frontend
Version:
Chrome DevTools UI
143 lines (129 loc) • 5.42 kB
text/typescript
// Copyright 2025 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as Common from '../core/common/common.js';
import * as Host from '../core/host/host.js';
import * as Platform from '../core/platform/platform.js';
import * as SDK from '../core/sdk/sdk.js';
import type * as Protocol from '../generated/protocol.js';
import * as Logs from '../models/logs/logs.js';
import type * as Workspace from '../models/workspace/workspace.js';
import {
createTarget,
} from './EnvironmentHelpers.js';
import {createContentProviderUISourceCodes} from './UISourceCodeHelpers.js';
function createMockAidaClient(fetch: Host.AidaClient.AidaClient['fetch']): Host.AidaClient.AidaClient {
const fetchStub = sinon.stub();
const registerClientEventStub = sinon.stub();
return {
fetch: fetchStub.callsFake(fetch),
registerClientEvent: registerClientEventStub,
};
}
type MockAidaResponse =
Omit<Host.AidaClient.AidaResponse, 'completed'|'metadata'>&{metadata?: Host.AidaClient.AidaResponseMetadata};
/**
* Creates a mock AIDA client that responds using `data`.
*
* Each first-level item of `data` is a single response.
* Each second-level item of `data` is a chunk of a response.
* The last chunk sets completed flag to true;
*/
export function mockAidaClient(data: Array<[MockAidaResponse, ...MockAidaResponse[]]> = []):
Host.AidaClient.AidaClient {
let callId = 0;
async function* provideAnswer(_: Host.AidaClient.AidaRequest, options?: {signal?: AbortSignal}) {
if (!data[callId]) {
throw new Error('No data provided to the mock client');
}
for (const [idx, chunk] of data[callId].entries()) {
if (options?.signal?.aborted) {
throw new Host.AidaClient.AidaAbortError();
}
const metadata = chunk.metadata ?? {};
if (metadata?.attributionMetadata?.attributionAction === Host.AidaClient.RecitationAction.BLOCK) {
throw new Host.AidaClient.AidaBlockError();
}
yield {
...chunk,
metadata,
completed: idx === data[callId].length - 1,
};
}
callId++;
}
return createMockAidaClient(provideAnswer);
}
export async function createUISourceCode(options?: {
content?: string,
mimeType?: string,
url?: Platform.DevToolsPath.UrlString,
resourceType?: Common.ResourceType.ResourceType,
requestContentData?: boolean,
}): Promise<Workspace.UISourceCode.UISourceCode> {
const url = options?.url ?? Platform.DevToolsPath.urlString`http://example.test/script.js`;
const {project} = createContentProviderUISourceCodes({
items: [
{
url,
mimeType: options?.mimeType ?? 'application/javascript',
resourceType: options?.resourceType ?? Common.ResourceType.resourceTypes.Script,
content: options?.content ?? undefined,
},
],
target: createTarget(),
});
const uiSourceCode = project.uiSourceCodeForURL(url);
if (!uiSourceCode) {
throw new Error('Failed to create a test uiSourceCode');
}
if (!uiSourceCode.contentType().isTextType()) {
uiSourceCode?.setContent('binary', true);
}
if (options?.requestContentData) {
await uiSourceCode.requestContentData();
}
return uiSourceCode;
}
export function createNetworkRequest(): SDK.NetworkRequest.NetworkRequest {
const networkRequest = SDK.NetworkRequest.NetworkRequest.create(
'requestId' as Protocol.Network.RequestId, Platform.DevToolsPath.urlString`https://www.example.com/script.js`,
Platform.DevToolsPath.urlString``, null, null, null);
networkRequest.statusCode = 200;
networkRequest.setRequestHeaders([{name: 'content-type', value: 'bar1'}]);
networkRequest.responseHeaders = [{name: 'content-type', value: 'bar2'}, {name: 'x-forwarded-for', value: 'bar3'}];
const initiatorNetworkRequest = SDK.NetworkRequest.NetworkRequest.create(
'requestId' as Protocol.Network.RequestId, Platform.DevToolsPath.urlString`https://www.initiator.com`,
Platform.DevToolsPath.urlString``, null, null, null);
const initiatedNetworkRequest1 = SDK.NetworkRequest.NetworkRequest.create(
'requestId' as Protocol.Network.RequestId, Platform.DevToolsPath.urlString`https://www.example.com/1`,
Platform.DevToolsPath.urlString``, null, null, null);
const initiatedNetworkRequest2 = SDK.NetworkRequest.NetworkRequest.create(
'requestId' as Protocol.Network.RequestId, Platform.DevToolsPath.urlString`https://www.example.com/2`,
Platform.DevToolsPath.urlString``, null, null, null);
sinon.stub(Logs.NetworkLog.NetworkLog.instance(), 'initiatorGraphForRequest')
.withArgs(networkRequest)
.returns({
initiators: new Set([networkRequest, initiatorNetworkRequest]),
initiated: new Map([
[networkRequest, initiatorNetworkRequest],
[initiatedNetworkRequest1, networkRequest],
[initiatedNetworkRequest2, networkRequest],
]),
})
.withArgs(initiatedNetworkRequest1)
.returns({
initiators: new Set([]),
initiated: new Map([
[initiatedNetworkRequest1, networkRequest],
]),
})
.withArgs(initiatedNetworkRequest2)
.returns({
initiators: new Set([]),
initiated: new Map([
[initiatedNetworkRequest2, networkRequest],
]),
});
return networkRequest;
}