diff --git a/src/formatters/consoleFormatter.ts b/src/formatters/consoleFormatter.ts index 7c56d490a..d5bc828e7 100644 --- a/src/formatters/consoleFormatter.ts +++ b/src/formatters/consoleFormatter.ts @@ -69,15 +69,7 @@ function formatArgs(consoleData: ConsoleMessageData): string { return result.join('\n'); } -interface IssueDetailsWithResources { - violatingNodeId?: number; - nodeId?: number; - documentNodeId?: number; - request?: { - requestId?: string; - url: string; - }; -} + export function formatIssue( issue: AggregatedIssue, description?: string, @@ -100,45 +92,37 @@ export function formatIssue( } } - const issues: Array<{ - details?: () => IssueDetailsWithResources; - getDetails?: () => IssueDetailsWithResources; - }> = [ - ...issue.getCorsIssues(), - ...issue.getMixedContentIssues(), - ...issue.getGenericIssues(), - ...issue.getLowContrastIssues(), - ...issue.getElementAccessibilityIssues(), - ...issue.getQuirksModeIssues(), - ]; + const issues = issue.getAllIssues(); const affectedResources: Array<{ uid?: string; data?: object; request?: string | number; }> = []; for (const singleIssue of issues) { - if (!singleIssue.details && !singleIssue.getDetails) continue; - - let details = - singleIssue.details?.() as unknown as IssueDetailsWithResources; - if (!details) - details = - singleIssue.getDetails?.() as unknown as IssueDetailsWithResources; + const details = singleIssue.details(); if (!details) continue; + // We send the remaining details as untyped JSON because the DevTools + // frontend code is currently not re-usable. + // eslint-disable-next-line + const data = structuredClone(details) as any; + let uid; let request: number | string | undefined; - if (details.violatingNodeId && context) { + if ('violatingNodeId' in details && details.violatingNodeId && context) { uid = context.resolveCdpElementId(details.violatingNodeId); + delete data.violatingNodeId; } - if (details.nodeId && context) { + if ('nodeId' in details && details.nodeId && context) { uid = context.resolveCdpElementId(details.nodeId); + delete data.nodeId; } - if (details.documentNodeId && context) { + if ('documentNodeId' in details && details.documentNodeId && context) { uid = context.resolveCdpElementId(details.documentNodeId); + delete data.documentNodeId; } - if (details.request) { + if ('request' in details && details.request) { request = details.request.url; if (details.request.requestId && context) { const resolvedId = context.resolveCdpRequestId( @@ -146,18 +130,14 @@ export function formatIssue( ); if (resolvedId) { request = resolvedId; + delete data.request.requestId; } } } - // eslint-disable-next-line - const data = structuredClone(details) as any; - delete data.violatingNodeId; - delete data.nodeId; - delete data.documentNodeId; + // These fields has no use for the MCP client (redundant or irrelevant). delete data.errorType; delete data.frameId; - delete data.request; affectedResources.push({ uid, data: data, @@ -180,7 +160,6 @@ export function formatIssue( return details.join(' '); }), ); - if (result.length === 0) - return 'No details provided for the issue ' + issue.code(); + if (result.length === 0) return 'No affected resources found'; return result.join('\n'); } diff --git a/tests/formatters/consoleFormatter.test.js.snapshot b/tests/formatters/consoleFormatter.test.js.snapshot index 2052e4352..d6803572e 100644 --- a/tests/formatters/consoleFormatter.test.js.snapshot +++ b/tests/formatters/consoleFormatter.test.js.snapshot @@ -43,6 +43,4 @@ This is a mock issue description Learn more: [Learn more](http://example.com/learnmore) [Learn more 2](http://example.com/another-learnmore) -### Affected resources -data={"violatingNodeAttribute":"test"} `; diff --git a/tests/tools/console.test.js.snapshot b/tests/tools/console.test.js.snapshot index 825eba082..e58e91212 100644 --- a/tests/tools/console.test.js.snapshot +++ b/tests/tools/console.test.js.snapshot @@ -25,5 +25,5 @@ Note that if an opaque response is sufficient, the request's mode can be set to Learn more: [Cross-Origin Resource Sharing (\`CORS\`)](https://web.dev/cross-origin-resource-sharing) ### Affected resources -reqid= data={"corsErrorStatus":{"corsError":"PreflightMissingAllowOriginHeader","failedParameter":""},"isWarning":false,"initiatorOrigin":"","clientSecurityState":{"initiatorIsSecureContext":false,"initiatorIPAddressSpace":"Loopback","privateNetworkRequestPolicy":"BlockFromInsecureToMorePrivate"}} +reqid= data={"corsErrorStatus":{"corsError":"PreflightMissingAllowOriginHeader","failedParameter":""},"isWarning":false,"request":{"url":"http://hostname:port/data.json"},"initiatorOrigin":"","clientSecurityState":{"initiatorIsSecureContext":false,"initiatorIPAddressSpace":"Loopback","privateNetworkRequestPolicy":"BlockFromInsecureToMorePrivate"}} `; diff --git a/tests/tools/console.test.ts b/tests/tools/console.test.ts index 825e46067..4ce0873ba 100644 --- a/tests/tools/console.test.ts +++ b/tests/tools/console.test.ts @@ -239,7 +239,8 @@ describe('console', () => { const rawText = formattedResponse[0].text as string; const sanitizedText = rawText .replaceAll(/ID: \d+/g, 'ID: ') - .replaceAll(/reqid=\d+/g, 'reqid='); + .replaceAll(/reqid=\d+/g, 'reqid=') + .replaceAll(/localhost:\d+/g, 'hostname:port'); t.assert.snapshot?.(sanitizedText); }); }); diff --git a/tests/utils.ts b/tests/utils.ts index 6fefd649c..dc525437c 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -196,12 +196,7 @@ export function stabilizeResponseOutput(text: unknown) { export function getMockAggregatedIssue(): sinon.SinonStubbedInstance { const mockAggregatedIssue = sinon.createStubInstance(AggregatedIssue); - mockAggregatedIssue.getGenericIssues.returns(new Set()); - mockAggregatedIssue.getLowContrastIssues.returns(new Set()); - mockAggregatedIssue.getElementAccessibilityIssues.returns(new Set()); - mockAggregatedIssue.getQuirksModeIssues.returns(new Set()); - mockAggregatedIssue.getCorsIssues.returns(new Set()); - mockAggregatedIssue.getMixedContentIssues.returns(new Set()); + mockAggregatedIssue.getAllIssues.returns([]); return mockAggregatedIssue; }