blob: 35116660fd7de6116b9e0ac9e6a88a2eebb94f91 [file]
// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {assert} from 'chai';
import sinon from 'sinon';
import type * as Protocol from '../../generated/protocol.js';
import {describeWithEnvironment} from '../../testing/EnvironmentHelpers.js';
import {MockCDPConnection} from '../../testing/MockCDPConnection.js';
import {getMainFrame} from '../../testing/ResourceTreeHelpers.js';
import {TestUniverse} from '../../testing/TestUniverse.js';
import * as Common from '../common/common.js';
import * as Platform from '../platform/platform.js';
import * as TextUtils from '../text_utils/text_utils.js';
import * as SDK from './sdk.js';
const {urlString} = Platform.DevToolsPath;
describeWithEnvironment('Resource', () => {
let universe: TestUniverse;
beforeEach(() => {
universe = new TestUniverse();
});
it('returns content data from network request if available', async () => {
const target = universe.createTarget();
const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel)!;
const frame = getMainFrame(target);
const url = urlString`https://example.com/script.js`;
const request = SDK.NetworkRequest.NetworkRequest.createWithoutBackendRequest('requestId', url, url, null);
const contentData = new TextUtils.ContentData.ContentData('console.log("hello");', false, 'text/javascript');
const requestContentDataStub = sinon.stub(request, 'requestContentData').resolves(contentData);
const resource = new SDK.Resource.Resource(resourceTreeModel, request, url, url, frame.id, null,
Common.ResourceType.resourceTypes.Script, 'text/javascript', null, null);
const result = await resource.requestContentData();
assert.deepEqual(result, contentData);
sinon.assert.calledOnce(requestContentDataStub);
});
it('returns content data from pageAgent if network request is not available', async () => {
const connection = new MockCDPConnection();
const target = universe.createTarget({connection});
const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel)!;
const frame = getMainFrame(target);
const url = urlString`https://example.com/script.js`;
const content = 'console.log("hello");';
connection.setSuccessHandler('Page.getResourceContent', () => {
return {
content,
base64Encoded: false,
};
});
const resource = new SDK.Resource.Resource(resourceTreeModel, null, url, url, frame.id, null,
Common.ResourceType.resourceTypes.Script, 'text/javascript', null, null);
const result = await resource.requestContentData();
assert.isFalse(TextUtils.ContentData.ContentData.isError(result));
assert.strictEqual((result as TextUtils.ContentData.ContentData).text, content);
});
it('waits for network request to finish if called before it is finished', async () => {
const connection = new MockCDPConnection();
const target = universe.createTarget({connection});
const networkManager = target.model(SDK.NetworkManager.NetworkManager)!;
const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel)!;
const frame = getMainFrame(target);
const url = urlString`https://example.com/script.js`;
const requestId = 'requestId' as Protocol.Network.RequestId;
// 1. Dispatch the requestWillBeSent event.
networkManager.dispatcher.requestWillBeSent({
requestId,
request: {
url,
},
type: 'Script',
} as unknown as Protocol.Network.RequestWillBeSentEvent);
const request = networkManager.requestForId(requestId);
assert.exists(request);
assert.isNotTrue(request.finished);
const resource = new SDK.Resource.Resource(resourceTreeModel, request, url, url, frame.id, null,
Common.ResourceType.resourceTypes.Script, 'text/javascript', null, null);
// Mock Network.getResponseBody to return the content.
const content = 'console.log("hello");';
connection.setSuccessHandler('Network.getResponseBody', () => {
return {
body: content,
base64Encoded: false,
};
});
// 2. Call requestContentData, which should not resolve yet.
let resolved = false;
const promise = resource.requestContentData().then(result => {
resolved = true;
return result;
});
// Wait a bit to ensure it does not resolve eagerly.
await new Promise(resolve => setTimeout(resolve, 10));
assert.isFalse(resolved);
// 3. Dispatch the loadingFinished event.
networkManager.dispatcher.loadingFinished({
requestId,
timestamp: 0,
encodedDataLength: content.length,
});
// 4. Now the promise should resolve.
const result = await promise;
assert.isTrue(resolved);
assert.isFalse(TextUtils.ContentData.ContentData.isError(result));
assert.strictEqual((result as TextUtils.ContentData.ContentData).text, content);
});
});