[go: nahoru, domu]

PreloadingDevTools: Show NotTriggered preloading attempts

Current Preloading panel shows only preloading attempts that are
triggered by renderer and checked eligibility, e.g., started/pending,
and doesn't ones that are not triggered by renderer nor not eligible.
For example, document rules can trigger preloading attempts for matching
anchors, e.g. when they are mousedown-ed. It is convenient to show those
items to tell web developers what URLs are potentially eligible.

This CL adds this feature. Note that, this CL shows only NotTriggered
ones, and leaves not eligible ones to future implementation.

demo: https://drive.google.com/file/d/1SNex7bZkhyJinQbeSosUpErAY4UVBuwX/view?usp=sharing

Bug: 1384419
Change-Id: I40e0fc02abd68ca02b86a5e73025d04929f7e017
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4421957
Reviewed-by: Danil Somsikov <dsv@chromium.org>
Commit-Queue: Ken Okada <kenoss@chromium.org>
diff --git a/front_end/core/sdk/PreloadingModel.ts b/front_end/core/sdk/PreloadingModel.ts
index 585b6f8..a4820c3 100644
--- a/front_end/core/sdk/PreloadingModel.ts
+++ b/front_end/core/sdk/PreloadingModel.ts
@@ -214,21 +214,36 @@
   onPreloadingAttemptSourcesUpdated(event: Protocol.Preload.PreloadingAttemptSourcesUpdatedEvent): void {
     const loaderId = event.loaderId;
     this.ensureDocumentPreloadingData(loaderId);
-    this.documents.get(loaderId)?.sources.update(event.preloadingAttemptSources);
+
+    const document = this.documents.get(loaderId);
+    if (document === undefined) {
+      return;
+    }
+
+    document.sources.update(event.preloadingAttemptSources);
+    document.preloadingAttempts.maybeRegisterNotTriggered(document.sources);
     this.dispatchEventToListeners(Events.ModelUpdated);
   }
 
   onPrefetchStatusUpdated(event: Protocol.Preload.PrefetchStatusUpdatedEvent): void {
     const loaderId = event.key.loaderId;
     this.ensureDocumentPreloadingData(loaderId);
-    this.documents.get(loaderId)?.preloadingAttempts.upsert(event);
+    const attempt = {
+      key: event.key,
+      status: convertPreloadingStatus(event.status),
+    };
+    this.documents.get(loaderId)?.preloadingAttempts.upsert(attempt);
     this.dispatchEventToListeners(Events.ModelUpdated);
   }
 
   onPrerenderStatusUpdated(event: Protocol.Preload.PrerenderStatusUpdatedEvent): void {
     const loaderId = event.key.loaderId;
     this.ensureDocumentPreloadingData(loaderId);
-    this.documents.get(loaderId)?.preloadingAttempts.upsert(event);
+    const attempt = {
+      key: event.key,
+      status: convertPreloadingStatus(event.status),
+    };
+    this.documents.get(loaderId)?.preloadingAttempts.upsert(attempt);
     this.dispatchEventToListeners(Events.ModelUpdated);
   }
 }
@@ -326,18 +341,60 @@
   }
 }
 
+// Protocol.Preload.PreloadingStatus|'NotTriggered'
+//
+// A renderer sends SpeculationCandidate to the browser process and the
+// browser process checks eligibilities, and starts PreloadingAttempt.
+//
+// In the frontend, "NotTriggered" is used to denote that a
+// PreloadingAttempt is waiting for at trigger event (eg:
+// mousedown/mouseover). All PreloadingAttempts will start off as
+// "NotTriggered", but "eager" preloading attempts (attempts not
+// actually waiting for any trigger) will be processed by the browser
+// immediately, and will not stay in this state for long.
+//
+// TODO(https://crbug.com/1384419): Add NotEligible.
+export const enum PreloadingStatus {
+  NotTriggered = 'NotTriggered',
+  Pending = 'Pending',
+  Running = 'Running',
+  Ready = 'Ready',
+  Success = 'Success',
+  Failure = 'Failure',
+  NotSupported = 'NotSupported',
+}
+
+function convertPreloadingStatus(status: Protocol.Preload.PreloadingStatus): PreloadingStatus {
+  switch (status) {
+    case Protocol.Preload.PreloadingStatus.Pending:
+      return PreloadingStatus.Pending;
+    case Protocol.Preload.PreloadingStatus.Running:
+      return PreloadingStatus.Running;
+    case Protocol.Preload.PreloadingStatus.Ready:
+      return PreloadingStatus.Ready;
+    case Protocol.Preload.PreloadingStatus.Success:
+      return PreloadingStatus.Success;
+    case Protocol.Preload.PreloadingStatus.Failure:
+      return PreloadingStatus.Failure;
+    case Protocol.Preload.PreloadingStatus.NotSupported:
+      return PreloadingStatus.NotSupported;
+  }
+
+  throw new Error('unreachable');
+}
+
 export type PreloadingAttemptId = string;
 
 export interface PreloadingAttempt {
   key: Protocol.Preload.PreloadingAttemptKey;
-  status: Protocol.Preload.PreloadingStatus;
+  status: PreloadingStatus;
   ruleSetIds: Protocol.Preload.RuleSetId[];
   nodeIds: Protocol.DOM.BackendNodeId[];
 }
 
 export interface PreloadingAttemptInternal {
   key: Protocol.Preload.PreloadingAttemptKey;
-  status: Protocol.Preload.PreloadingStatus;
+  status: PreloadingStatus;
 }
 
 function makePreloadingAttemptId(key: Protocol.Preload.PreloadingAttemptKey): PreloadingAttemptId {
@@ -416,6 +473,20 @@
     this.map.set(id, attempt);
   }
 
+  maybeRegisterNotTriggered(sources: SourceRegistry): void {
+    for (const [id, {key}] of sources.entries()) {
+      if (this.map.get(id) !== undefined) {
+        continue;
+      }
+
+      const attempt = {
+        key,
+        status: PreloadingStatus.NotTriggered,
+      };
+      this.map.set(id, attempt);
+    }
+  }
+
   mergePrevious(prev: PreloadingAttemptRegistry): void {
     for (const [id, attempt] of this.map.entries()) {
       prev.map.set(id, attempt);
@@ -429,6 +500,10 @@
   private map: Map<PreloadingAttemptId, Protocol.Preload.PreloadingAttemptSource> =
       new Map<PreloadingAttemptId, Protocol.Preload.PreloadingAttemptSource>();
 
+  entries(): IterableIterator<[PreloadingAttemptId, Protocol.Preload.PreloadingAttemptSource]> {
+    return this.map.entries();
+  }
+
   isEmpty(): boolean {
     return this.map.size === 0;
   }
diff --git a/front_end/panels/application/preloading/PreloadingView.ts b/front_end/panels/application/preloading/PreloadingView.ts
index fdba72a..35d068e 100644
--- a/front_end/panels/application/preloading/PreloadingView.ts
+++ b/front_end/panels/application/preloading/PreloadingView.ts
@@ -29,6 +29,10 @@
    */
   validitySomeRulesInvalid: 'Some rules invalid',
   /**
+   *@description Text in grid and details: Preloading attempt is not yet triggered.
+   */
+  statusNotTriggered: 'Not triggered',
+  /**
    *@description Text in grid and details: Preloading attempt is eligible but pending.
    */
   statusPending: 'Pending',
@@ -84,22 +88,24 @@
   static status({status}: SDK.PreloadingModel.PreloadingAttempt): string {
     // See content/public/browser/preloading.h PreloadingAttemptOutcome.
     switch (status) {
-      case Protocol.Preload.PreloadingStatus.Pending:
+      case SDK.PreloadingModel.PreloadingStatus.NotTriggered:
+        return i18nString(UIStrings.statusNotTriggered);
+      case SDK.PreloadingModel.PreloadingStatus.Pending:
         return i18nString(UIStrings.statusPending);
-      case Protocol.Preload.PreloadingStatus.Running:
+      case SDK.PreloadingModel.PreloadingStatus.Running:
         return i18nString(UIStrings.statusRunning);
-      case Protocol.Preload.PreloadingStatus.Ready:
+      case SDK.PreloadingModel.PreloadingStatus.Ready:
         return i18nString(UIStrings.statusReady);
-      case Protocol.Preload.PreloadingStatus.Success:
+      case SDK.PreloadingModel.PreloadingStatus.Success:
         return i18nString(UIStrings.statusSuccess);
-      case Protocol.Preload.PreloadingStatus.Failure:
+      case SDK.PreloadingModel.PreloadingStatus.Failure:
         return i18nString(UIStrings.statusFailure);
       // NotSupported is used to handle unreachable case. For example,
       // there is no code path for
       // PreloadingTriggeringOutcome::kTriggeredButPending in prefetch,
       // which is mapped to NotSupported. So, we regard it as an
       // internal error.
-      case Protocol.Preload.PreloadingStatus.NotSupported:
+      case SDK.PreloadingModel.PreloadingStatus.NotSupported:
         return i18n.i18n.lockedString('Internal error');
     }
   }
diff --git a/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts b/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts
index 36e4bc1..cafdea6 100644
--- a/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts
+++ b/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import type * as SDK from '../../../../core/sdk/sdk.js';
-
 import * as i18n from '../../../../core/i18n/i18n.js';
+import * as SDK from '../../../../core/sdk/sdk.js';
 import * as Protocol from '../../../../generated/protocol.js';
 import * as ComponentHelpers from '../../../../ui/components/helpers/helpers.js';
 import * as Coordinator from '../../../../ui/components/render_coordinator/render_coordinator.js';
@@ -37,6 +36,10 @@
   /**
    *@description Description: status
    */
+  detailedStatusNotTriggered: 'Preloading attempt is not yet triggered.',
+  /**
+   *@description Description: status
+   */
   detailedStatusPending: 'Preloading attempt is eligible but pending.',
   /**
    *@description Description: status
@@ -73,22 +76,24 @@
   static detailedStatus({status}: SDK.PreloadingModel.PreloadingAttempt): string {
     // See content/public/browser/preloading.h PreloadingAttemptOutcome.
     switch (status) {
-      case Protocol.Preload.PreloadingStatus.Pending:
+      case SDK.PreloadingModel.PreloadingStatus.NotTriggered:
+        return i18nString(UIStrings.detailedStatusNotTriggered);
+      case SDK.PreloadingModel.PreloadingStatus.Pending:
         return i18nString(UIStrings.detailedStatusPending);
-      case Protocol.Preload.PreloadingStatus.Running:
+      case SDK.PreloadingModel.PreloadingStatus.Running:
         return i18nString(UIStrings.detailedStatusRunning);
-      case Protocol.Preload.PreloadingStatus.Ready:
+      case SDK.PreloadingModel.PreloadingStatus.Ready:
         return i18nString(UIStrings.detailedStatusReady);
-      case Protocol.Preload.PreloadingStatus.Success:
+      case SDK.PreloadingModel.PreloadingStatus.Success:
         return i18nString(UIStrings.detailedStatusSuccess);
-      case Protocol.Preload.PreloadingStatus.Failure:
+      case SDK.PreloadingModel.PreloadingStatus.Failure:
         return i18nString(UIStrings.detailedStatusFailure);
       // NotSupported is used to handle unreachable case. For example,
       // there is no code path for
       // PreloadingTriggeringOutcome::kTriggeredButPending in prefetch,
       // which is mapped to NotSupported. So, we regard it as an
       // internal error.
-      case Protocol.Preload.PreloadingStatus.NotSupported:
+      case SDK.PreloadingModel.PreloadingStatus.NotSupported:
         return i18n.i18n.lockedString('Internal error');
     }
   }
diff --git a/front_end/panels/application/preloading/components/UsedPreloadingView.ts b/front_end/panels/application/preloading/components/UsedPreloadingView.ts
index 9dc58f4..564e6fc 100644
--- a/front_end/panels/application/preloading/components/UsedPreloadingView.ts
+++ b/front_end/panels/application/preloading/components/UsedPreloadingView.ts
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import type * as SDK from '../../../../core/sdk/sdk.js';
-
 import * as i18n from '../../../../core/i18n/i18n.js';
+import * as SDK from '../../../../core/sdk/sdk.js';
 import * as Protocol from '../../../../generated/protocol.js';
 import * as ComponentHelpers from '../../../../ui/components/helpers/helpers.js';
 import * as Coordinator from '../../../../ui/components/render_coordinator/render_coordinator.js';
@@ -45,7 +44,7 @@
 
   async #render(): Promise<void> {
     await coordinator.write('UsedPreloadingView render', () => {
-      const used = this.#data.filter(attempt => attempt.status === Protocol.Preload.PreloadingStatus.Success);
+      const used = this.#data.filter(attempt => attempt.status === SDK.PreloadingModel.PreloadingStatus.Success);
       const prefetchCount =
           used.filter(attempt => attempt.key.action === Protocol.Preload.SpeculationAction.Prefetch).length;
       const prerenderCount = used.length - prefetchCount;
diff --git a/test/unittests/front_end/core/sdk/PreloadingModel_test.ts b/test/unittests/front_end/core/sdk/PreloadingModel_test.ts
index 68d718b..0919b01 100644
--- a/test/unittests/front_end/core/sdk/PreloadingModel_test.ts
+++ b/test/unittests/front_end/core/sdk/PreloadingModel_test.ts
@@ -72,7 +72,7 @@
         action: Protocol.Preload.SpeculationAction.Prefetch,
         url: 'https://example.com/subresource.js',
       },
-      status: Protocol.Preload.PreloadingStatus.Running,
+      status: SDK.PreloadingModel.PreloadingStatus.Running,
     });
 
     assert.deepEqual(model.getAllRuleSets(), [
@@ -103,7 +103,7 @@
             action: Protocol.Preload.SpeculationAction.Prefetch,
             url: 'https://example.com/subresource.js' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
           nodeIds: [1] as Protocol.DOM.BackendNodeId[],
         },
@@ -155,7 +155,7 @@
         action: Protocol.Preload.SpeculationAction.Prerender,
         url: 'https://example.com/page.html',
       },
-      status: Protocol.Preload.PreloadingStatus.Running,
+      status: SDK.PreloadingModel.PreloadingStatus.Running,
     });
 
     assert.deepEqual(model.getAllRuleSets(), [
@@ -204,7 +204,7 @@
             action: Protocol.Preload.SpeculationAction.Prefetch,
             url: 'https://example.com/subresource.js' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
           nodeIds: [1] as Protocol.DOM.BackendNodeId[],
         },
@@ -217,7 +217,7 @@
             action: Protocol.Preload.SpeculationAction.Prerender,
             url: 'https://example.com/page.html' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[],
           nodeIds: [2] as Protocol.DOM.BackendNodeId[],
         },
@@ -247,7 +247,7 @@
         action: Protocol.Preload.SpeculationAction.Prefetch,
         url: 'https://example.com/subresource.js',
       },
-      status: Protocol.Preload.PreloadingStatus.Failure,
+      status: SDK.PreloadingModel.PreloadingStatus.Failure,
     });
 
     assert.deepEqual(model.getAllRuleSets(), [
@@ -278,7 +278,7 @@
             action: Protocol.Preload.SpeculationAction.Prefetch,
             url: 'https://example.com/subresource.js' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Failure,
+          status: SDK.PreloadingModel.PreloadingStatus.Failure,
           // Note that current implementation doesn't show associated
           // rule sets when preloading is cancelled by rule sets
           // deletion. One can treat this case special, i.e. associated
@@ -298,7 +298,7 @@
             action: Protocol.Preload.SpeculationAction.Prerender,
             url: 'https://example.com/page.html' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[],
           nodeIds: [2] as Protocol.DOM.BackendNodeId[],
         },
@@ -306,6 +306,75 @@
     ]);
   });
 
+  it('registers preloeading attempt with status NotTriggered', async () => {
+    const target = createTarget();
+    const model = target.model(SDK.PreloadingModel.PreloadingModel);
+    assertNotNullOrUndefined(model);
+
+    assert.deepEqual(model.getAllRuleSets(), []);
+
+    dispatchEvent(target, 'Page.frameNavigated', {
+      frame: {
+        id: 'frameId:1',
+        loaderId: 'loaderId:1' as Protocol.Network.LoaderId,
+        url: 'https://example.com/',
+        domainAndRegistry: 'example.com',
+        securityOrigin: 'https://example.com/',
+        mimeType: 'text/html',
+        secureContextType: Protocol.Page.SecureContextType.Secure,
+        crossOriginIsolatedContextType: Protocol.Page.CrossOriginIsolatedContextType.Isolated,
+        gatedAPIFeatures: [],
+      },
+    });
+
+    dispatchEvent(target, 'Preload.ruleSetUpdated', {
+      ruleSet: {
+        id: 'ruleSetId:1',
+        loaderId: 'loaderId:1' as Protocol.Network.LoaderId,
+        sourceText: `
+{
+  "prefetch":[
+    {
+      "source": "list",
+      "urls": ["/subresource.js"]
+    }
+  ]
+}
+`,
+      },
+    });
+    dispatchEvent(target, 'Preload.preloadingAttemptSourcesUpdated', {
+      loaderId: 'loaderId:1',
+      preloadingAttemptSources: [
+        {
+          key: {
+            loaderId: 'loaderId:1',
+            action: Protocol.Preload.SpeculationAction.Prefetch,
+            url: 'https://example.com/subresource.js',
+          },
+          ruleSetIds: ['ruleSetId:1'],
+          nodeIds: [1],
+        },
+      ],
+    });
+
+    assert.deepEqual(model.getPreloadingAttempts(null), [
+      {
+        id: 'loaderId:1:Prefetch:https://example.com/subresource.js:undefined',
+        value: {
+          key: {
+            loaderId: 'loaderId:1' as Protocol.Network.LoaderId,
+            action: Protocol.Preload.SpeculationAction.Prefetch,
+            url: 'https://example.com/subresource.js' as Platform.DevToolsPath.UrlString,
+          },
+          status: SDK.PreloadingModel.PreloadingStatus.NotTriggered,
+          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);
@@ -364,7 +433,7 @@
         action: Protocol.Preload.SpeculationAction.Prefetch,
         url: 'https://example.com/subresource1.js',
       },
-      status: Protocol.Preload.PreloadingStatus.Running,
+      status: SDK.PreloadingModel.PreloadingStatus.Running,
     });
 
     dispatchEvent(target, 'Page.frameNavigated', {
@@ -417,7 +486,7 @@
         action: Protocol.Preload.SpeculationAction.Prefetch,
         url: 'https://example.com/subresource2.js',
       },
-      status: Protocol.Preload.PreloadingStatus.Running,
+      status: SDK.PreloadingModel.PreloadingStatus.Running,
     });
 
     assert.deepEqual(model.getAllRuleSets(), [
@@ -448,7 +517,7 @@
             action: Protocol.Preload.SpeculationAction.Prefetch,
             url: 'https://example.com/subresource2.js' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[],
           nodeIds: [2] as Protocol.DOM.BackendNodeId[],
         },
@@ -539,7 +608,7 @@
         action: Protocol.Preload.SpeculationAction.Prefetch,
         url: 'https://example.com/subresource12.js',
       },
-      status: Protocol.Preload.PreloadingStatus.Running,
+      status: SDK.PreloadingModel.PreloadingStatus.Running,
     });
     dispatchEvent(target, 'Preload.prefetchStatusUpdated', {
       key: {
@@ -547,7 +616,7 @@
         action: Protocol.Preload.SpeculationAction.Prefetch,
         url: 'https://example.com/subresource2.js',
       },
-      status: Protocol.Preload.PreloadingStatus.Running,
+      status: SDK.PreloadingModel.PreloadingStatus.Running,
     });
 
     assert.deepEqual(model.getPreloadingAttempts(null), [
@@ -559,7 +628,7 @@
             action: Protocol.Preload.SpeculationAction.Prefetch,
             url: 'https://example.com/subresource12.js' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:1', 'ruleSetId:2'] as Protocol.Preload.RuleSetId[],
           nodeIds: [1, 2] as Protocol.DOM.BackendNodeId[],
         },
@@ -572,7 +641,7 @@
             action: Protocol.Preload.SpeculationAction.Prefetch,
             url: 'https://example.com/subresource2.js' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[],
           nodeIds: [2] as Protocol.DOM.BackendNodeId[],
         },
@@ -588,7 +657,7 @@
             action: Protocol.Preload.SpeculationAction.Prefetch,
             url: 'https://example.com/subresource12.js' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:1', 'ruleSetId:2'] as Protocol.Preload.RuleSetId[],
           nodeIds: [1, 2] as Protocol.DOM.BackendNodeId[],
         },
@@ -604,7 +673,7 @@
             action: Protocol.Preload.SpeculationAction.Prefetch,
             url: 'https://example.com/subresource12.js' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:1', 'ruleSetId:2'] as Protocol.Preload.RuleSetId[],
           nodeIds: [1, 2] as Protocol.DOM.BackendNodeId[],
         },
@@ -617,7 +686,7 @@
             action: Protocol.Preload.SpeculationAction.Prefetch,
             url: 'https://example.com/subresource2.js' as Platform.DevToolsPath.UrlString,
           },
-          status: Protocol.Preload.PreloadingStatus.Running,
+          status: SDK.PreloadingModel.PreloadingStatus.Running,
           ruleSetIds: ['ruleSetId:2'] as Protocol.Preload.RuleSetId[],
           nodeIds: [2] as Protocol.DOM.BackendNodeId[],
         },
diff --git a/test/unittests/front_end/panels/application/preloading/PreloadingView_test.ts b/test/unittests/front_end/panels/application/preloading/PreloadingView_test.ts
index 950ddfc..a72b2d9 100644
--- a/test/unittests/front_end/panels/application/preloading/PreloadingView_test.ts
+++ b/test/unittests/front_end/panels/application/preloading/PreloadingView_test.ts
@@ -151,11 +151,11 @@
     this.prerenderTarget = null;
     SDK.TargetManager.TargetManager.instance().setScopeTarget(this.primaryTarget);
 
-    // Strictly speaking, we have to emit an event for Protocol.Preload.PreloadingStatus.Ready earlier.
+    // Strictly speaking, we have to emit an event for SDK.PreloadingModel.PreloadingStatus.Ready earlier.
     // It's not so important and omitted.
     dispatchEvent(this.primaryTarget, 'Preload.prerenderStatusUpdated', {
       ...this.prerenderStatusUpdatedEvent,
-      status: Protocol.Preload.PreloadingStatus.Success,
+      status: SDK.PreloadingModel.PreloadingStatus.Success,
     });
   }
 
@@ -202,7 +202,7 @@
         },
         initiatingFrameId: this.frameId,
         prefetchUrl: url,
-        status: Protocol.Preload.PreloadingStatus.Running,
+        status: SDK.PreloadingModel.PreloadingStatus.Running,
       });
     }
 
diff --git a/test/unittests/front_end/panels/application/preloading/components/PreloadingDetailsReportView_test.ts b/test/unittests/front_end/panels/application/preloading/components/PreloadingDetailsReportView_test.ts
index 51eb295..e231609 100644
--- a/test/unittests/front_end/panels/application/preloading/components/PreloadingDetailsReportView_test.ts
+++ b/test/unittests/front_end/panels/application/preloading/components/PreloadingDetailsReportView_test.ts
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import type * as Platform from '../../../../../../../front_end/core/platform/platform.js';
+
 import * as Protocol from '../../../../../../../front_end/generated/protocol.js';
 import * as PreloadingComponents from '../../../../../../../front_end/panels/application/preloading/components/components.js';
+import * as SDK from '../../../../../../../front_end/core/sdk/sdk.js';
 import * as Coordinator from '../../../../../../../front_end/ui/components/render_coordinator/render_coordinator.js';
 import * as ReportView from '../../../../../../../front_end/ui/components/report_view/report_view.js';
-import type * as Platform from '../../../../../../../front_end/core/platform/platform.js';
 import {
   assertShadowRoot,
   getCleanTextContentFromElements,
@@ -57,7 +59,7 @@
           url,
           targetHint: undefined,
         },
-        status: Protocol.Preload.PreloadingStatus.Running,
+        status: SDK.PreloadingModel.PreloadingStatus.Running,
         ruleSetIds: ['ruleSetId'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
@@ -104,7 +106,7 @@
           url,
           targetHint: undefined,
         },
-        status: Protocol.Preload.PreloadingStatus.Failure,
+        status: SDK.PreloadingModel.PreloadingStatus.Failure,
         ruleSetIds: ['ruleSetId'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
diff --git a/test/unittests/front_end/panels/application/preloading/components/UsedPreloadingView_test.ts b/test/unittests/front_end/panels/application/preloading/components/UsedPreloadingView_test.ts
index abded38..a1348db 100644
--- a/test/unittests/front_end/panels/application/preloading/components/UsedPreloadingView_test.ts
+++ b/test/unittests/front_end/panels/application/preloading/components/UsedPreloadingView_test.ts
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import type * as SDK from '../../../../../../../front_end/core/sdk/sdk.js';
+import type * as Platform from '../../../../../../../front_end/core/platform/platform.js';
 
 import * as Protocol from '../../../../../../../front_end/generated/protocol.js';
 import * as PreloadingComponents from '../../../../../../../front_end/panels/application/preloading/components/components.js';
+import * as SDK from '../../../../../../../front_end/core/sdk/sdk.js';
 import * as Coordinator from '../../../../../../../front_end/ui/components/render_coordinator/render_coordinator.js';
-import type * as Platform from '../../../../../../../front_end/core/platform/platform.js';
 import {
   assertShadowRoot,
   renderElementIntoDOM,
@@ -37,7 +37,7 @@
           action: Protocol.Preload.SpeculationAction.Prefetch,
           url: 'https://example.com/subresource1.js' as Platform.DevToolsPath.UrlString,
         },
-        status: Protocol.Preload.PreloadingStatus.Ready,
+        status: SDK.PreloadingModel.PreloadingStatus.Ready,
         ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
@@ -47,7 +47,7 @@
           action: Protocol.Preload.SpeculationAction.Prefetch,
           url: 'https://example.com/subresource2.js' as Platform.DevToolsPath.UrlString,
         },
-        status: Protocol.Preload.PreloadingStatus.Failure,
+        status: SDK.PreloadingModel.PreloadingStatus.Failure,
         ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
@@ -57,7 +57,7 @@
           action: Protocol.Preload.SpeculationAction.Prerender,
           url: 'https://example.com/prerendered.html' as Platform.DevToolsPath.UrlString,
         },
-        status: Protocol.Preload.PreloadingStatus.Ready,
+        status: SDK.PreloadingModel.PreloadingStatus.Ready,
         ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
@@ -77,7 +77,7 @@
           action: Protocol.Preload.SpeculationAction.Prefetch,
           url: 'https://example.com/subresource1.js' as Platform.DevToolsPath.UrlString,
         },
-        status: Protocol.Preload.PreloadingStatus.Success,
+        status: SDK.PreloadingModel.PreloadingStatus.Success,
         ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
@@ -87,7 +87,7 @@
           action: Protocol.Preload.SpeculationAction.Prefetch,
           url: 'https://example.com/subresource2.js' as Platform.DevToolsPath.UrlString,
         },
-        status: Protocol.Preload.PreloadingStatus.Success,
+        status: SDK.PreloadingModel.PreloadingStatus.Success,
         ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
@@ -97,7 +97,7 @@
           action: Protocol.Preload.SpeculationAction.Prerender,
           url: 'https://example.com/prerendered.html' as Platform.DevToolsPath.UrlString,
         },
-        status: Protocol.Preload.PreloadingStatus.Ready,
+        status: SDK.PreloadingModel.PreloadingStatus.Ready,
         ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
@@ -117,7 +117,7 @@
           action: Protocol.Preload.SpeculationAction.Prefetch,
           url: 'https://example.com/subresource1.js' as Platform.DevToolsPath.UrlString,
         },
-        status: Protocol.Preload.PreloadingStatus.Ready,
+        status: SDK.PreloadingModel.PreloadingStatus.Ready,
         ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
@@ -127,7 +127,7 @@
           action: Protocol.Preload.SpeculationAction.Prefetch,
           url: 'https://example.com/subresource2.js' as Platform.DevToolsPath.UrlString,
         },
-        status: Protocol.Preload.PreloadingStatus.Failure,
+        status: SDK.PreloadingModel.PreloadingStatus.Failure,
         ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },
@@ -137,7 +137,7 @@
           action: Protocol.Preload.SpeculationAction.Prerender,
           url: 'https://example.com/prerendered.html' as Platform.DevToolsPath.UrlString,
         },
-        status: Protocol.Preload.PreloadingStatus.Success,
+        status: SDK.PreloadingModel.PreloadingStatus.Success,
         ruleSetIds: ['ruleSetId:1'] as Protocol.Preload.RuleSetId[],
         nodeIds: [1] as Protocol.DOM.BackendNodeId[],
       },