| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import * as Protocol from '../../generated/protocol.js'; |
| import {createTarget} from '../../testing/EnvironmentHelpers.js'; |
| import { |
| describeWithMockConnection, |
| dispatchEvent, |
| } from '../../testing/MockConnection.js'; |
| import {getMainFrame, navigate} from '../../testing/ResourceTreeHelpers.js'; |
| import * as Platform from '../platform/platform.js'; |
| |
| import * as SDK from './sdk.js'; |
| |
| const {urlString} = Platform.DevToolsPath; |
| |
| describeWithMockConnection('PreloadingModel', () => { |
| it('adds and deletes rule sets and preloading attempts', async () => { |
| const target = createTarget(); |
| const model = target.model(SDK.PreloadingModel.PreloadingModel); |
| assert.exists(model); |
| |
| assert.deepEqual(model.getAllRuleSets(), []); |
| |
| const loaderId = getMainFrame(target).loaderId; |
| |
| dispatchEvent(target, 'Preload.ruleSetUpdated', { |
| ruleSet: { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prefetch":[ |
| { |
| "source": "list", |
| "urls": ["/subresource.js"] |
| } |
| ] |
| } |
| `, |
| }, |
| }); |
| dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', { |
| loaderId, |
| preloadingAttemptSources: [ |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource.js', |
| }, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| ], |
| }); |
| dispatchEvent(target, 'Preload.prefetchStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource.js', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Running, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| } as Protocol.Preload.PrefetchStatusUpdatedEvent); |
| |
| assert.deepEqual(model.getAllRuleSets(), [ |
| { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| value: { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prefetch":[ |
| { |
| "source": "list", |
| "urls": ["/subresource.js"] |
| } |
| ] |
| } |
| `, |
| }, |
| }, |
| ]); |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prefetch:https://example.com/subresource.js:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/subresource.js`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prefetchStatus: null, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| |
| dispatchEvent(target, 'Preload.ruleSetUpdated', { |
| ruleSet: { |
| id: 'ruleSetId:2' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prerender":[ |
| { |
| "source": "list", |
| "urls": ["/page.html"] |
| } |
| ] |
| } |
| `, |
| }, |
| }); |
| dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', { |
| loaderId, |
| preloadingAttemptSources: [ |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource.js', |
| }, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: 'https://example.com/page.html', |
| }, |
| ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [2] as Protocol.DOM.BackendNodeId[], |
| }, |
| ], |
| }); |
| dispatchEvent(target, 'Preload.prerenderStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: 'https://example.com/page.html', |
| }, |
| pipelineId: 'pipelineId:2' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Running, |
| }); |
| |
| assert.deepEqual(model.getAllRuleSets(), [ |
| { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| value: { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prefetch":[ |
| { |
| "source": "list", |
| "urls": ["/subresource.js"] |
| } |
| ] |
| } |
| `, |
| }, |
| }, |
| { |
| id: 'ruleSetId:2' as Protocol.Preload.RuleSetId, |
| value: { |
| |
| id: 'ruleSetId:2' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prerender":[ |
| { |
| "source": "list", |
| "urls": ["/page.html"] |
| } |
| ] |
| } |
| `, |
| }, |
| }, |
| ]); |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prefetch:https://example.com/subresource.js:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/subresource.js`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prefetchStatus: null, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| { |
| id: `${loaderId}:Prerender:https://example.com/page.html:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: urlString`https://example.com/page.html`, |
| }, |
| pipelineId: 'pipelineId:2' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prerenderStatus: null, |
| disallowedMojoInterface: null, |
| mismatchedHeaders: null, |
| ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [2] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| |
| dispatchEvent(target, 'Preload.ruleSetRemoved', { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| }); |
| dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', { |
| loaderId, |
| preloadingAttemptSources: [ |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: 'https://example.com/page.html', |
| }, |
| ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [2] as Protocol.DOM.BackendNodeId[], |
| }, |
| ], |
| }); |
| dispatchEvent(target, 'Preload.prefetchStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource.js', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Failure, |
| prefetchStatus: Protocol.Preload.PrefetchStatus.PrefetchEvictedAfterCandidateRemoved, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| } as Protocol.Preload.PrefetchStatusUpdatedEvent); |
| |
| assert.deepEqual(model.getAllRuleSets(), [ |
| { |
| id: 'ruleSetId:2' as Protocol.Preload.RuleSetId, |
| value: { |
| id: 'ruleSetId:2' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prerender":[ |
| { |
| "source": "list", |
| "urls": ["/page.html"] |
| } |
| ] |
| } |
| `, |
| }, |
| }, |
| ]); |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prerender:https://example.com/page.html:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: urlString`https://example.com/page.html`, |
| }, |
| pipelineId: 'pipelineId:2' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prerenderStatus: null, |
| disallowedMojoInterface: null, |
| mismatchedHeaders: null, |
| ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [2] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| }); |
| |
| it('registers preloading attempt with status NotTriggered', async () => { |
| const target = createTarget(); |
| const model = target.model(SDK.PreloadingModel.PreloadingModel); |
| assert.exists(model); |
| |
| assert.deepEqual(model.getAllRuleSets(), []); |
| |
| const loaderId = getMainFrame(target).loaderId; |
| dispatchEvent(target, 'Preload.ruleSetUpdated', { |
| ruleSet: { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prefetch":[ |
| { |
| "source": "list", |
| "urls": ["/subresource.js"] |
| } |
| ] |
| } |
| `, |
| }, |
| }); |
| dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', { |
| loaderId, |
| preloadingAttemptSources: [ |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource.js', |
| }, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| ], |
| }); |
| |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prefetch:https://example.com/subresource.js:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/subresource.js`, |
| }, |
| pipelineId: null, |
| status: SDK.PreloadingModel.PreloadingStatus.NOT_TRIGGERED, |
| prefetchStatus: null, |
| // Invalid request id |
| requestId: '' as Protocol.Network.RequestId, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| }); |
| |
| it('clears rule sets and preloading attempts for previous pages', async () => { |
| const target = createTarget(); |
| const model = target.model(SDK.PreloadingModel.PreloadingModel); |
| assert.exists(model); |
| |
| assert.deepEqual(model.getAllRuleSets(), []); |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), []); |
| |
| let loaderId = getMainFrame(target).loaderId; |
| |
| dispatchEvent(target, 'Preload.ruleSetUpdated', { |
| ruleSet: { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prefetch": [ |
| { |
| "source": "list", |
| "urls": ["/subresource1.js"] |
| } |
| ] |
| } |
| `, |
| }, |
| }); |
| dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', { |
| loaderId, |
| preloadingAttemptSources: [ |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource1.js', |
| }, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| ], |
| }); |
| dispatchEvent(target, 'Preload.prefetchStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource1.js', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Running, |
| } as Protocol.Preload.PrefetchStatusUpdatedEvent); |
| |
| loaderId = 'loaderId:2' as Protocol.Network.LoaderId; |
| navigate(getMainFrame(target), {loaderId}); |
| |
| dispatchEvent(target, 'Preload.ruleSetUpdated', { |
| ruleSet: { |
| id: 'ruleSetId:2' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prefetch": [ |
| { |
| "source": "list", |
| "urls": ["/subresource2.js"] |
| } |
| ] |
| } |
| `, |
| }, |
| }); |
| dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', { |
| loaderId, |
| preloadingAttemptSources: [ |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource2.js', |
| }, |
| ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [2] as Protocol.DOM.BackendNodeId[], |
| }, |
| ], |
| }); |
| dispatchEvent(target, 'Preload.prefetchStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource2.js', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Running, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| } as Protocol.Preload.PrefetchStatusUpdatedEvent); |
| |
| assert.deepEqual(model.getAllRuleSets(), [ |
| { |
| id: 'ruleSetId:2' as Protocol.Preload.RuleSetId, |
| value: { |
| id: 'ruleSetId:2' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prefetch": [ |
| { |
| "source": "list", |
| "urls": ["/subresource2.js"] |
| } |
| ] |
| } |
| `, |
| }, |
| }, |
| ]); |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prefetch:https://example.com/subresource2.js:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/subresource2.js`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prefetchStatus: null, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [2] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| }); |
| |
| it('filters preloading attempts by rule set id', async () => { |
| const target = createTarget(); |
| const model = target.model(SDK.PreloadingModel.PreloadingModel); |
| assert.exists(model); |
| |
| assert.deepEqual(model.getAllRuleSets(), []); |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), []); |
| |
| const loaderId = getMainFrame(target).loaderId; |
| |
| dispatchEvent(target, 'Preload.ruleSetUpdated', { |
| ruleSet: { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prefetch": [ |
| { |
| "source": "list", |
| "urls": ["/subresource12.js"] |
| } |
| ] |
| } |
| `, |
| }, |
| }); |
| dispatchEvent(target, 'Preload.ruleSetUpdated', { |
| ruleSet: { |
| id: 'ruleSetId:2' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prefetch": [ |
| { |
| "source": "list", |
| "urls": ["/subresource12.js", "/subresource2.js"] |
| } |
| ] |
| } |
| `, |
| }, |
| }); |
| dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', { |
| loaderId, |
| preloadingAttemptSources: [ |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource12.js', |
| }, |
| ruleSetIds: ['ruleSetId:1', 'ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1, 2] as Protocol.DOM.BackendNodeId[], |
| }, |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource2.js', |
| }, |
| ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [2] as Protocol.DOM.BackendNodeId[], |
| }, |
| ], |
| }); |
| dispatchEvent(target, 'Preload.prefetchStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource12.js', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Running, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| } as Protocol.Preload.PrefetchStatusUpdatedEvent); |
| dispatchEvent(target, 'Preload.prefetchStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/subresource2.js', |
| }, |
| pipelineId: 'pipelineId:2' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Running, |
| requestId: 'requestId:2' as Protocol.Network.RequestId, |
| } as Protocol.Preload.PrefetchStatusUpdatedEvent); |
| |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prefetch:https://example.com/subresource12.js:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/subresource12.js`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prefetchStatus: null, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| ruleSetIds: ['ruleSetId:1', 'ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1, 2] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| { |
| id: `${loaderId}:Prefetch:https://example.com/subresource2.js:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/subresource2.js`, |
| }, |
| pipelineId: 'pipelineId:2' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prefetchStatus: null, |
| requestId: 'requestId:2' as Protocol.Network.RequestId, |
| ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [2] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| |
| assert.deepEqual(model.getRepresentativePreloadingAttempts('ruleSetId:1' as Protocol.Preload.RuleSetId), [ |
| { |
| id: `${loaderId}:Prefetch:https://example.com/subresource12.js:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/subresource12.js`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prefetchStatus: null, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| ruleSetIds: ['ruleSetId:1', 'ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1, 2] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| |
| assert.deepEqual(model.getRepresentativePreloadingAttempts('ruleSetId:2' as Protocol.Preload.RuleSetId), [ |
| { |
| id: `${loaderId}:Prefetch:https://example.com/subresource12.js:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/subresource12.js`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prefetchStatus: null, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| ruleSetIds: ['ruleSetId:1', 'ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1, 2] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| { |
| id: `${loaderId}:Prefetch:https://example.com/subresource2.js:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/subresource2.js`, |
| }, |
| pipelineId: 'pipelineId:2' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prefetchStatus: null, |
| requestId: 'requestId:2' as Protocol.Network.RequestId, |
| ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [2] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| }); |
| |
| it('regards attempts with strongest action as representative', async () => { |
| const target = createTarget(); |
| const model = target.model(SDK.PreloadingModel.PreloadingModel); |
| assert.exists(model); |
| |
| assert.deepEqual(model.getAllRuleSets(), []); |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), []); |
| |
| const loaderId = getMainFrame(target).loaderId; |
| |
| dispatchEvent(target, 'Preload.ruleSetUpdated', { |
| ruleSet: { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prerender": [ |
| { |
| "source": "list", |
| "urls": ["/prerendered.html"] |
| } |
| ] |
| } |
| `, |
| }, |
| }); |
| dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', { |
| loaderId, |
| preloadingAttemptSources: [ |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: 'https://example.com/prerendered.html', |
| }, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| ], |
| }); |
| |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prerender:https://example.com/prerendered.html:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: urlString`https://example.com/prerendered.html`, |
| }, |
| pipelineId: null, |
| status: SDK.PreloadingModel.PreloadingStatus.NOT_TRIGGERED, |
| prerenderStatus: null, |
| disallowedMojoInterface: null, |
| mismatchedHeaders: null, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| |
| dispatchEvent(target, 'Preload.prefetchStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/prerendered.html', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Running, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| } as Protocol.Preload.PrefetchStatusUpdatedEvent); |
| |
| // Here, we get two different attemtps, which should sit in the same pipeline actually. |
| // It is because |
| // |
| // - The `NOT_TRIGGERED` entry is synthesized from |
| // `Preload.preloadingAttemptSourcesUpdated` event. |
| // - It is associated with the following entry for *prerender*, not prefetch. |
| // |
| // We admit the phenomenon as prefetch and prerender are triggered simultaneously and we don't |
| // expect the duration is very short that these entries are shown. |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prerender:https://example.com/prerendered.html:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: urlString`https://example.com/prerendered.html`, |
| }, |
| pipelineId: null, |
| status: SDK.PreloadingModel.PreloadingStatus.NOT_TRIGGERED, |
| prerenderStatus: null, |
| disallowedMojoInterface: null, |
| mismatchedHeaders: null, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| { |
| id: `${loaderId}:Prefetch:https://example.com/prerendered.html:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: urlString`https://example.com/prerendered.html`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prefetchStatus: null, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| ruleSetIds: [] as Protocol.Preload.RuleSetId[], |
| nodeIds: [] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| |
| dispatchEvent(target, 'Preload.prerenderStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: 'https://example.com/prerendered.html', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Running, |
| }); |
| |
| // Converges to an entry. |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prerender:https://example.com/prerendered.html:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: urlString`https://example.com/prerendered.html`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prerenderStatus: null, |
| disallowedMojoInterface: null, |
| mismatchedHeaders: null, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| |
| dispatchEvent(target, 'Preload.prefetchStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prefetch, |
| url: 'https://example.com/prerendered.html', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Success, |
| requestId: 'requestId:1' as Protocol.Network.RequestId, |
| } as Protocol.Preload.PrefetchStatusUpdatedEvent); |
| dispatchEvent(target, 'Preload.prerenderStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: 'https://example.com/prerendered.html', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Failure, |
| prerenderStatus: Protocol.Preload.PrerenderFinalStatus.MojoBinderPolicy, |
| disallowedMojoInterface: 'device.mojom.GamepadMonitor', |
| }); |
| |
| // The prerender is the representative of the pipeline even if it failed. |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:Prerender:https://example.com/prerendered.html:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.Prerender, |
| url: urlString`https://example.com/prerendered.html`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.FAILURE, |
| prerenderStatus: Protocol.Preload.PrerenderFinalStatus.MojoBinderPolicy, |
| disallowedMojoInterface: 'device.mojom.GamepadMonitor', |
| mismatchedHeaders: null, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| }); |
| |
| it('adds and deletes a preloading attempt for prerender-until-script', async () => { |
| const target = createTarget(); |
| const model = target.model(SDK.PreloadingModel.PreloadingModel); |
| assert.exists(model); |
| |
| assert.deepEqual(model.getAllRuleSets(), []); |
| |
| const loaderId = getMainFrame(target).loaderId; |
| |
| dispatchEvent(target, 'Preload.ruleSetUpdated', { |
| ruleSet: { |
| id: 'ruleSetId:1' as Protocol.Preload.RuleSetId, |
| loaderId, |
| sourceText: ` |
| { |
| "prerender_until_script":[ |
| { |
| "source": "list", |
| "urls": ["/page.html"] |
| } |
| ] |
| } |
| `, |
| }, |
| }); |
| dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', { |
| loaderId, |
| preloadingAttemptSources: [ |
| { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.PrerenderUntilScript, |
| url: 'https://example.com/page.html', |
| }, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| ], |
| }); |
| dispatchEvent(target, 'Preload.prerenderStatusUpdated', { |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.PrerenderUntilScript, |
| url: 'https://example.com/page.html', |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: Protocol.Preload.PreloadingStatus.Running, |
| }); |
| |
| assert.deepEqual(model.getRepresentativePreloadingAttempts(null), [ |
| { |
| id: `${loaderId}:PrerenderUntilScript:https://example.com/page.html:undefined`, |
| value: { |
| action: Protocol.Preload.SpeculationAction.PrerenderUntilScript, |
| key: { |
| loaderId, |
| action: Protocol.Preload.SpeculationAction.PrerenderUntilScript, |
| url: urlString`https://example.com/page.html`, |
| }, |
| pipelineId: 'pipelineId:1' as Protocol.Preload.PreloadPipelineId, |
| status: SDK.PreloadingModel.PreloadingStatus.RUNNING, |
| prerenderStatus: null, |
| disallowedMojoInterface: null, |
| mismatchedHeaders: null, |
| ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[], |
| nodeIds: [1] as Protocol.DOM.BackendNodeId[], |
| }, |
| }, |
| ]); |
| }); |
| }); |