| // 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 type * as SDK from '../../core/sdk/sdk.js'; |
| import * as Protocol from '../../generated/protocol.js'; |
| import {setupLocaleHooks} from '../../testing/LocaleHelpers.js'; |
| import {MockIssuesManager} from '../../testing/MockIssuesManager.js'; |
| import {MockIssuesModel} from '../../testing/MockIssuesModel.js'; |
| import * as IssuesManager from '../issues_manager/issues_manager.js'; |
| |
| describe('StylesheetLoadingIssue', () => { |
| setupLocaleHooks(); |
| |
| function createProtocolIssue(stylesheetLoadingIssueDetails: Protocol.Audits.StylesheetLoadingIssueDetails): |
| Protocol.Audits.InspectorIssue { |
| return { |
| code: Protocol.Audits.InspectorIssueCode.StylesheetLoadingIssue, |
| details: {stylesheetLoadingIssueDetails}, |
| }; |
| } |
| |
| const mockModel = new MockIssuesModel([]) as unknown as SDK.IssuesModel.IssuesModel; |
| const mockManager = new MockIssuesManager([]) as unknown as IssuesManager.IssuesManager.IssuesManager; |
| |
| it('can be created for failed stylesheet requests', () => { |
| const issueDetails = { |
| sourceCodeLocation: { |
| url: 'http://example.com', |
| lineNumber: 2, |
| columnNumber: 2, |
| }, |
| styleSheetLoadingIssueReason: Protocol.Audits.StyleSheetLoadingIssueReason.RequestFailed, |
| failedRequestInfo: |
| {url: 'http://invalid', failureMessage: 'failureMessage', requestId: '12345' as Protocol.Network.RequestId}, |
| }; |
| const issue = createProtocolIssue(issueDetails); |
| const stylesheetIssues = |
| IssuesManager.StylesheetLoadingIssue.StylesheetLoadingIssue.fromInspectorIssue(mockModel, issue); |
| assert.lengthOf(stylesheetIssues, 1); |
| const stylesheetIssue = stylesheetIssues[0]; |
| |
| assert.strictEqual(stylesheetIssue.getCategory(), IssuesManager.Issue.IssueCategory.OTHER); |
| assert.deepEqual(stylesheetIssue.sources(), [issueDetails.sourceCodeLocation]); |
| const {url, requestId} = issueDetails.failedRequestInfo; |
| assert.deepEqual(stylesheetIssue.requests(), [{url, requestId}]); |
| assert.strictEqual(stylesheetIssue.getKind(), IssuesManager.Issue.IssueKind.PAGE_ERROR); |
| assert.isNotNull(stylesheetIssue.getDescription()); |
| }); |
| |
| it('can be created for late import rules', () => { |
| const issueDetails = { |
| sourceCodeLocation: { |
| url: 'http://example.com', |
| lineNumber: 2, |
| columnNumber: 2, |
| }, |
| styleSheetLoadingIssueReason: Protocol.Audits.StyleSheetLoadingIssueReason.LateImportRule, |
| }; |
| const issue = createProtocolIssue(issueDetails); |
| const stylesheetIssues = |
| IssuesManager.StylesheetLoadingIssue.StylesheetLoadingIssue.fromInspectorIssue(mockModel, issue); |
| assert.lengthOf(stylesheetIssues, 1); |
| const stylesheetIssue = stylesheetIssues[0]; |
| |
| assert.strictEqual(stylesheetIssue.getCategory(), IssuesManager.Issue.IssueCategory.OTHER); |
| assert.deepEqual(stylesheetIssue.sources(), [issueDetails.sourceCodeLocation]); |
| assert.strictEqual(stylesheetIssue.getKind(), IssuesManager.Issue.IssueKind.PAGE_ERROR); |
| assert.isNotNull(stylesheetIssue.getDescription()); |
| }); |
| |
| it('correctly aggregates issues', () => { |
| const issueDetails = [ |
| { |
| sourceCodeLocation: { |
| url: 'http://example.com', |
| lineNumber: 1, |
| columnNumber: 1, |
| }, |
| styleSheetLoadingIssueReason: Protocol.Audits.StyleSheetLoadingIssueReason.LateImportRule, |
| }, |
| { |
| sourceCodeLocation: { |
| url: 'http://example.com', |
| lineNumber: 2, |
| columnNumber: 1, |
| }, |
| styleSheetLoadingIssueReason: Protocol.Audits.StyleSheetLoadingIssueReason.LateImportRule, |
| }, |
| { |
| sourceCodeLocation: { |
| url: 'http://example.com', |
| lineNumber: 1, |
| columnNumber: 2, |
| }, |
| styleSheetLoadingIssueReason: Protocol.Audits.StyleSheetLoadingIssueReason.RequestFailed, |
| failedRequestInfo: {url: 'http://invalid', failureMessage: 'failureMessage'}, |
| }, |
| { |
| sourceCodeLocation: { |
| url: 'http://example.com', |
| lineNumber: 2, |
| columnNumber: 2, |
| }, |
| styleSheetLoadingIssueReason: Protocol.Audits.StyleSheetLoadingIssueReason.RequestFailed, |
| failedRequestInfo: |
| {url: 'http://invalid', failureMessage: 'failureMessage', requestId: '12354' as Protocol.Network.RequestId}, |
| }, |
| ]; |
| |
| const issues = issueDetails |
| .map( |
| details => IssuesManager.StylesheetLoadingIssue.StylesheetLoadingIssue.fromInspectorIssue( |
| mockModel, createProtocolIssue(details))) |
| .flat(); |
| |
| assert.lengthOf(issues, 4); |
| |
| const aggregator = new IssuesManager.IssueAggregator.IssueAggregator(mockManager); |
| for (const issue of issues) { |
| mockManager.dispatchEventToListeners( |
| IssuesManager.IssuesManager.Events.ISSUE_ADDED, {issuesModel: mockModel, issue}); |
| } |
| |
| const aggregatedIssues = Array.from(aggregator.aggregatedIssues()); |
| assert.lengthOf(aggregatedIssues, 2); |
| |
| assert.deepEqual( |
| Array.from(aggregatedIssues[0].sources()), |
| [issueDetails[0].sourceCodeLocation, issueDetails[1].sourceCodeLocation]); |
| assert.deepEqual( |
| Array.from(aggregatedIssues[1].sources()), |
| [issueDetails[2].sourceCodeLocation, issueDetails[3].sourceCodeLocation]); |
| assert.deepEqual(Array.from(aggregatedIssues[0].requests()), []); |
| const {url, requestId} = issueDetails[3].failedRequestInfo as Protocol.Audits.FailedRequestInfo; |
| assert.exists(requestId); |
| assert.deepEqual(Array.from(aggregatedIssues[1].requests()), [{url, requestId}]); |
| }); |
| }); |