Skip to content

Commit 74e9718

Browse files
author
Natallia Harshunova
committed
Address comments
1 parent ab7c815 commit 74e9718

File tree

5 files changed

+81
-68
lines changed

5 files changed

+81
-68
lines changed

src/McpResponse.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,15 @@ export class McpResponse implements Response {
319319
}
320320
const markdownAst = Marked.Marked.lexer(rawMarkdown);
321321
const title = findTitleFromMarkdownAst(markdownAst);
322+
if (!title) {
323+
logger('cannot read issue title from ' + filename);
324+
return null;
325+
}
322326
return {
323327
consoleMessageStableId,
324328
type: 'issue',
325-
message: `${title}`,
329+
item,
330+
message: title,
326331
count,
327332
args: [],
328333
};

src/PageCollector.ts

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414

1515
import {FakeIssuesManager} from './DevtoolsUtils.js';
1616
import {logger} from './logger.js';
17-
import type {ConsoleMessage} from './third_party/index.js';
17+
import type {ConsoleMessage, Protocol} from './third_party/index.js';
1818
import {
1919
type Browser,
2020
type Frame,
@@ -96,13 +96,13 @@ export class PageCollector<T> {
9696
}
9797

9898
public addPage(page: Page) {
99-
if (this.storage.has(page)) {
100-
return;
101-
}
10299
this.#initializePage(page);
103100
}
104101

105102
#initializePage(page: Page) {
103+
if (this.storage.has(page)) {
104+
return;
105+
}
106106
const idGenerator = createIdGenerator();
107107
const storedLists: Array<Array<WithSymbolId<T>>> = [[]];
108108
this.storage.set(page, storedLists);
@@ -215,17 +215,13 @@ export class ConsoleCollector extends PageCollector<
215215
#mockIssuesManagers = new WeakMap<Page, FakeIssuesManager>();
216216

217217
override addPage(page: Page): void {
218-
if (this.storage.has(page)) {
219-
return;
220-
}
221218
super.addPage(page);
222219
void this.subscribeForIssues(page);
223220
}
224221
async subscribeForIssues(page: Page) {
225-
if (!this.#seenIssueKeys.has(page)) {
226-
this.#seenIssueKeys.set(page, new Set());
227-
}
222+
if (this.#seenIssueKeys.has(page)) return;
228223

224+
this.#seenIssueKeys.set(page, new Set());
229225
const mockManager = new FakeIssuesManager();
230226
const aggregator = new IssueAggregator(mockManager);
231227
this.#mockIssuesManagers.set(page, mockManager);
@@ -242,36 +238,33 @@ export class ConsoleCollector extends PageCollector<
242238
page.emit('issue', event.data);
243239
},
244240
);
245-
246241
try {
247242
const session = await page.createCDPSession();
248243
session.on('Audits.issueAdded', data => {
249-
// @ts-expect-error Types of protocol from Puppeteer and CDP are incopatible for Issues but it's the same type
250-
const issue = createIssuesFromProtocolIssue(null, data.issue)[0];
251-
if (!issue) {
252-
return;
253-
}
244+
const inspectorIssue =
245+
data.issue satisfies Protocol.Audits.InspectorIssue;
246+
// @ts-expect-error Types of protocol from Puppeteer and CDP are incomparable for InspectorIssueCode, one is union, other is enum
247+
const issue = createIssuesFromProtocolIssue(null, inspectorIssue)[0];
248+
if (!issue) return;
249+
254250
const seenKeys = this.#seenIssueKeys.get(page)!;
255251
const primaryKey = issue.primaryKey();
256252
if (seenKeys.has(primaryKey)) return;
257253
seenKeys.add(primaryKey);
258254

259255
const mockManager = this.#mockIssuesManagers.get(page);
260-
if (mockManager) {
261-
mockManager.dispatchEventToListeners(
262-
IssuesManagerEvents.ISSUE_ADDED,
263-
{
264-
issue,
265-
// @ts-expect-error We don't care that issues model is null
266-
issuesModel: null,
267-
},
268-
);
269-
}
256+
if (!mockManager) return;
257+
258+
mockManager.dispatchEventToListeners(IssuesManagerEvents.ISSUE_ADDED, {
259+
issue,
260+
// @ts-expect-error We don't care that issues model is null
261+
issuesModel: null,
262+
});
270263
});
264+
271265
await session.send('Audits.enable');
272266
} catch (e) {
273-
const errorText = e instanceof Error ? e.message : JSON.stringify(e);
274-
logger(`Error subscribing to issues: ${errorText}`);
267+
logger('Error subscribing to issues', e);
275268
}
276269
}
277270

src/formatters/consoleFormatter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
export interface ConsoleMessageData {
88
consoleMessageStableId: number;
99
type?: string;
10+
item?: unknown;
1011
message?: string;
1112
count?: number;
1213
args?: string[];

tests/PageCollector.test.ts

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
import assert from 'node:assert';
7-
import {describe, it} from 'node:test';
7+
import {beforeEach, describe, it} from 'node:test';
88

99
import type {
1010
Browser,
@@ -13,6 +13,7 @@ import type {
1313
Page,
1414
Target,
1515
CDPSession,
16+
Protocol,
1617
} from 'puppeteer-core';
1718
import sinon from 'sinon';
1819

@@ -343,6 +344,21 @@ describe('NetworkCollector', () => {
343344
});
344345

345346
describe('ConsoleCollector', () => {
347+
let issue: Protocol.Audits.InspectorIssue;
348+
349+
beforeEach(() => {
350+
issue = {
351+
code: 'MixedContentIssue',
352+
details: {
353+
mixedContentIssueDetails: {
354+
insecureURL: 'test.url',
355+
resolutionStatus: 'MixedContentBlocked',
356+
mainResourceURL: '',
357+
},
358+
},
359+
};
360+
});
361+
346362
it('emits issues on page', async () => {
347363
const browser = getMockBrowser();
348364
const page = (await browser.pages())[0];
@@ -359,17 +375,6 @@ describe('ConsoleCollector', () => {
359375
} as ListenerMap;
360376
});
361377
await collector.init();
362-
363-
const issue = {
364-
code: 'MixedContentIssue' as const,
365-
details: {
366-
mixedContentIssueDetails: {
367-
insecureURL: 'test.url',
368-
},
369-
},
370-
};
371-
372-
// @ts-expect-error Types of protocol from Puppeteer and CDP are incopatible for Issues but it's the same type
373378
cdpSession.emit('Audits.issueAdded', {issue});
374379
sinon.assert.calledOnce(onIssuesListener);
375380

@@ -391,26 +396,18 @@ describe('ConsoleCollector', () => {
391396
});
392397
await collector.init();
393398

394-
const issue = {
395-
code: 'MixedContentIssue' as const,
396-
details: {
397-
mixedContentIssueDetails: {
398-
insecureURL: 'test.url',
399-
},
400-
},
401-
};
402399
const issue2 = {
403-
code: 'PropertyRuleIssue' as const,
400+
code: 'ElementAccessibilityIssue' as const,
404401
details: {
405-
propertyRuleIssueDetails: {
406-
test: 'test',
402+
elementAccessibilityIssueDetails: {
403+
nodeId: 1,
404+
elementAccessibilityIssueReason: 'DisallowedSelectChild',
405+
hasDisallowedAttributes: true,
407406
},
408407
},
409-
};
408+
} satisfies Protocol.Audits.InspectorIssue;
410409

411-
// @ts-expect-error Types of protocol from Puppeteer and CDP are incopatible for Issues but it's the same type
412410
cdpSession.emit('Audits.issueAdded', {issue});
413-
// @ts-expect-error Types of protocol from Puppeteer and CDP are incopatible for Issues but it's the same type
414411
cdpSession.emit('Audits.issueAdded', {issue: issue2});
415412
const data = collector.getData(page);
416413
assert.equal(data.length, 2);
@@ -430,20 +427,10 @@ describe('ConsoleCollector', () => {
430427
});
431428
await collector.init();
432429

433-
const issue = {
434-
code: 'MixedContentIssue' as const,
435-
details: {
436-
mixedContentIssueDetails: {
437-
insecureURL: 'test.url',
438-
},
439-
},
440-
};
441-
442-
// @ts-expect-error Types of protocol from Puppeteer and CDP are incopatible for Issues but it's the same type
443430
cdpSession.emit('Audits.issueAdded', {issue});
444-
// @ts-expect-error Types of protocol from Puppeteer and CDP are incopatible for Issues but it's the same type
445431
cdpSession.emit('Audits.issueAdded', {issue});
446-
const collectedIssue = collector.getData(page)[0] as AggregatedIssue;
432+
const collectedIssue = collector.getData(page)[0];
433+
assert(collectedIssue instanceof AggregatedIssue);
447434
assert.equal(collectedIssue.code(), 'MixedContentIssue');
448435
assert.equal(collectedIssue.getAggregatedIssuesCount(), 1);
449436
});

tests/tools/console.test.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
import assert from 'node:assert';
7-
import {describe, it} from 'node:test';
7+
import {before, describe, it} from 'node:test';
88

9+
import {loadIssueDescriptions} from '../../src/issue-descriptions.js';
910
import {
1011
getConsoleMessage,
1112
listConsoleMessages,
@@ -14,6 +15,10 @@ import {withBrowser} from '../utils.js';
1415

1516
describe('console', () => {
1617
describe('list_console_messages', () => {
18+
before(async () => {
19+
await loadIssueDescriptions();
20+
});
21+
1722
it('list messages', async () => {
1823
await withBrowser(async (response, context) => {
1924
await listConsoleMessages.handler({params: {}}, response, context);
@@ -36,6 +41,28 @@ describe('console', () => {
3641
});
3742
});
3843

44+
it('lists issues messages', async () => {
45+
await withBrowser(async (response, context) => {
46+
const page = await context.newPage();
47+
const issuePromise = new Promise<void>(resolve => {
48+
page.on('issue', () => {
49+
resolve();
50+
});
51+
});
52+
53+
await page.setContent('<input type="text" name="username" />');
54+
await issuePromise;
55+
await listConsoleMessages.handler({params: {}}, response, context);
56+
const formattedResponse = await response.handle('test', context);
57+
const textContent = formattedResponse[0] as {text: string};
58+
assert.ok(
59+
textContent.text.includes(
60+
`msgid=1 [issue] An element doesn't have an autocomplete attribute (count: 1)`,
61+
),
62+
);
63+
});
64+
});
65+
3966
it('work with primitive unhandled errors', async () => {
4067
await withBrowser(async (response, context) => {
4168
const page = await context.newPage();

0 commit comments

Comments
 (0)