Skip to content

Commit d1af7f0

Browse files
Natallia HarshunovaOrKoN
authored andcommitted
Add request parsing from issue details
1 parent 5db74ed commit d1af7f0

File tree

5 files changed

+100
-14
lines changed

5 files changed

+100
-14
lines changed

src/formatters/consoleFormatter.ts

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ interface IssueDetailsWithResources {
7373
violatingNodeId?: number;
7474
nodeId?: number;
7575
documentNodeId?: number;
76+
request?: {
77+
requestId?: string;
78+
url: string;
79+
};
7680
}
7781
export function formatIssue(
7882
issue: AggregatedIssue,
@@ -96,20 +100,29 @@ export function formatIssue(
96100
}
97101
}
98102

99-
const issues: Array<{details?: () => IssueDetailsWithResources}> = [
103+
const issues: Array<{details?: () => IssueDetailsWithResources, getDetails?: () => IssueDetailsWithResources}> = [
104+
...issue.getCorsIssues(),
105+
...issue.getMixedContentIssues(),
100106
...issue.getGenericIssues(),
101107
...issue.getLowContrastIssues(),
102108
...issue.getElementAccessibilityIssues(),
103109
...issue.getQuirksModeIssues(),
104-
// ...issue.getAttributionReportingIssues(), // Uncomment when AttributionReportingIssue has details()
105110
];
106-
const affectedElement: Array<{uid?: string; data?: object}> = [];
111+
const affectedResources: Array<{
112+
uid?: string;
113+
data?: object;
114+
request?: string|number;
115+
}> = [];
107116
for (const singleIssue of issues) {
108-
if (!singleIssue.details) break;
117+
if (!singleIssue.details && !singleIssue.getDetails) continue;
118+
119+
let details =
120+
singleIssue.details?.() as unknown as IssueDetailsWithResources;
121+
if (!details) details = singleIssue.getDetails?.() as unknown as IssueDetailsWithResources;
122+
if (!details) continue;
109123

110-
const details =
111-
singleIssue.details() as unknown as IssueDetailsWithResources;
112124
let uid;
125+
let request: number | string | undefined;
113126
if (details.violatingNodeId && context) {
114127
uid = context.resolveCdpElementId(details.violatingNodeId);
115128
}
@@ -120,22 +133,45 @@ export function formatIssue(
120133
uid = context.resolveCdpElementId(details.documentNodeId);
121134
}
122135

136+
if (details.request) {
137+
request = details.request.url;
138+
if (details.request.requestId && context) {
139+
const resolvedId = context.resolveCdpRequestId(
140+
details.request.requestId,
141+
);
142+
if (resolvedId) {
143+
request = resolvedId;
144+
}
145+
}
146+
}
147+
123148
// eslint-disable-next-line
124149
const data = structuredClone(details) as any;
125150
delete data.violatingNodeId;
151+
delete data.nodeId;
152+
delete data.documentNodeId;
126153
delete data.errorType;
127154
delete data.frameId;
128-
affectedElement.push({uid, data: data});
155+
delete data.request;
156+
affectedResources.push({
157+
uid,
158+
data: data,
159+
request
160+
});
129161
}
130-
if (affectedElement.length) {
162+
if (affectedResources.length) {
131163
result.push('### Affected resources');
132164
}
133165
result.push(
134-
...affectedElement.map(item => {
135-
return `uid=${item.uid} data=${JSON.stringify(item.data)}`;
166+
...affectedResources.map(item => {
167+
const details = [];
168+
if(item.uid) details.push(`uid=${item.uid}`);
169+
if(item.data) details.push(`data=${JSON.stringify(item.data)}`);
170+
if(item.request) details.push((typeof item.request === 'number' ? `reqid=` : 'url=') + item.request);
171+
return details.join(' ');
136172
}),
137173
);
138174
if (result.length === 0)
139175
return 'No details provided for the issue ' + issue.code();
140176
return result.join('\n');
141-
}
177+
}

tests/formatters/consoleFormatter.test.js.snapshot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,5 @@ Learn more:
4444
[Learn more](http://example.com/learnmore)
4545
[Learn more 2](http://example.com/another-learnmore)
4646
### Affected resources
47-
uid=undefined data={"violatingNodeAttribute":"test"}
47+
data={"violatingNodeAttribute":"test"}
4848
`;

tests/tools/console.test.js.snapshot

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
exports[`console > get_console_message > issues type > gets issue details 1`] = `
1+
exports[`console > get_console_message > issues type > gets issue details with node id parsing 1`] = `
22
# test response
33
ID: 1
44
Message: issue> An element doesn't have an autocomplete attribute
@@ -11,3 +11,19 @@ Learn more:
1111
### Affected resources
1212
uid=1_1 data={"violatingNodeAttribute":"name"}
1313
`;
14+
15+
exports[`console > get_console_message > issues type > gets issue details with request id parsing 1`] = `
16+
# test response
17+
ID: 1
18+
Message: issue> Ensure CORS response header values are valid
19+
20+
A cross-origin resource sharing (CORS) request was blocked because of invalid or missing response headers of the request or the associated [preflight request](issueCorsPreflightRequest).
21+
22+
To fix this issue, ensure the response to the CORS request and/or the associated [preflight request](issueCorsPreflightRequest) are not missing headers and use valid header values.
23+
24+
Note that if an opaque response is sufficient, the request's mode can be set to \`no-cors\` to fetch the resource with CORS disabled; that way CORS headers are not required but the response content is inaccessible (opaque).
25+
Learn more:
26+
[Cross-Origin Resource Sharing (\`CORS\`)](https://web.dev/cross-origin-resource-sharing)
27+
### Affected resources
28+
reqid=1 data={"corsErrorStatus":{"corsError":"PreflightMissingAllowOriginHeader","failedParameter":""},"isWarning":false,"initiatorOrigin":"","clientSecurityState":{"initiatorIsSecureContext":false,"initiatorIPAddressSpace":"Loopback","privateNetworkRequestPolicy":"BlockFromInsecureToMorePrivate"}}
29+
`;

tests/tools/console.test.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ describe('console', () => {
159159
setIssuesEnabled(false);
160160
});
161161

162-
it('gets issue details', async t => {
162+
it('gets issue details with node id parsing', async t => {
163163
await withBrowser(async (response, context) => {
164164
const page = await context.newPage();
165165
const issuePromise = new Promise<void>(resolve => {
@@ -181,6 +181,38 @@ describe('console', () => {
181181
t.assert.snapshot?.(formattedResponse[0].text);
182182
});
183183
});
184+
it('gets issue details with request id parsing', async t => {
185+
await withBrowser(async (response, context) => {
186+
const page = await context.newPage();
187+
const issuePromise = new Promise<void>(resolve => {
188+
page.once('issue', () => {
189+
resolve();
190+
});
191+
});
192+
await page.setContent(`
193+
<script>
194+
fetch('https://example.com/data.json', {
195+
method: 'GET',
196+
headers: {
197+
'Content-Type': 'application/json',
198+
'X-Custom-Header': 'MyValue'
199+
}
200+
});
201+
</script>
202+
`);
203+
await context.createTextSnapshot();
204+
await issuePromise;
205+
await listConsoleMessages.handler({params: {}}, response, context);
206+
const response2 = new McpResponse();
207+
await getConsoleMessage.handler(
208+
{params: {msgid: 1}},
209+
response2,
210+
context,
211+
);
212+
const formattedResponse = await response2.handle('test', context);
213+
t.assert.snapshot?.(formattedResponse[0].text);
214+
});
215+
});
184216
});
185217
});
186218
});

tests/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,5 +189,7 @@ export function getMockAggregatedIssue(): sinon.SinonStubbedInstance<AggregatedI
189189
mockAggregatedIssue.getLowContrastIssues.returns(new Set());
190190
mockAggregatedIssue.getElementAccessibilityIssues.returns(new Set());
191191
mockAggregatedIssue.getQuirksModeIssues.returns(new Set());
192+
mockAggregatedIssue.getCorsIssues.returns(new Set());
193+
mockAggregatedIssue.getMixedContentIssues.returns(new Set());
192194
return mockAggregatedIssue;
193195
}

0 commit comments

Comments
 (0)