Skip to content

Commit b2ea06a

Browse files
committed
feat(console): group consecutive identical console messages
1 parent 8d765c0 commit b2ea06a

2 files changed

Lines changed: 99 additions & 4 deletions

File tree

src/McpResponse.ts

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -626,20 +626,23 @@ Call ${handleDialog.name} to handle it before continuing.`);
626626

627627
if (this.#consoleDataOptions?.include) {
628628
const messages = data.consoleMessages ?? [];
629+
const groupedMessages = this.#groupConsoleMessages(messages);
629630

630631
response.push('## Console messages');
631-
if (messages.length) {
632+
if (groupedMessages.length) {
632633
const paginationData = this.#dataWithPagination(
633-
messages,
634+
groupedMessages,
634635
this.#consoleDataOptions.pagination,
635636
);
636637
structuredContent.pagination = paginationData.pagination;
637638
response.push(...paginationData.info);
638639
response.push(
639-
...paginationData.items.map(message => message.toString()),
640+
...paginationData.items.map(message =>
641+
this.#formatGroupedConsoleMessage(message),
642+
),
640643
);
641644
structuredContent.consoleMessages = paginationData.items.map(message =>
642-
message.toJSON(),
645+
this.#toGroupedConsoleMessageJson(message),
643646
);
644647
} else {
645648
response.push('<no console messages found>');
@@ -663,6 +666,61 @@ Call ${handleDialog.name} to handle it before continuing.`);
663666
};
664667
}
665668

669+
#groupConsoleMessages(
670+
messages: Array<ConsoleFormatter | IssueFormatter>,
671+
): Array<{
672+
key: string;
673+
message: ConsoleFormatter | IssueFormatter;
674+
count: number;
675+
}> {
676+
const groupedMessages: Array<{
677+
key: string;
678+
message: ConsoleFormatter | IssueFormatter;
679+
count: number;
680+
}> = [];
681+
682+
for (const message of messages) {
683+
const key = message.toString().replace(/^msgid=\d+\s+/, '');
684+
const lastGroup = groupedMessages.at(-1);
685+
if (lastGroup?.key === key) {
686+
lastGroup.count += 1;
687+
continue;
688+
}
689+
690+
groupedMessages.push({
691+
key,
692+
message,
693+
count: 1,
694+
});
695+
}
696+
697+
return groupedMessages;
698+
}
699+
700+
#formatGroupedConsoleMessage(groupedMessage: {
701+
key: string;
702+
message: ConsoleFormatter | IssueFormatter;
703+
count: number;
704+
}): string {
705+
const text = groupedMessage.message.toString();
706+
if (groupedMessage.count > 1) {
707+
return `${text} [${groupedMessage.count} times]`;
708+
}
709+
return text;
710+
}
711+
712+
#toGroupedConsoleMessageJson(groupedMessage: {
713+
key: string;
714+
message: ConsoleFormatter | IssueFormatter;
715+
count: number;
716+
}): object {
717+
const json = groupedMessage.message.toJSON() as Record<string, unknown>;
718+
if (groupedMessage.count > 1) {
719+
json.occurrences = groupedMessage.count;
720+
}
721+
return json;
722+
}
723+
666724
#dataWithPagination<T>(data: T[], pagination?: PaginationOptions) {
667725
const response = [];
668726
const paginationResult = paginate<T>(data, pagination);

tests/tools/console.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,43 @@ describe('console', () => {
6666
});
6767
});
6868

69+
it('groups consecutive identical messages', async () => {
70+
await withMcpContext(async (response, context) => {
71+
const page = await context.newPage();
72+
await page.setContent(`
73+
<script>
74+
console.log('same');
75+
console.log('same');
76+
console.log('different');
77+
console.log('same');
78+
console.log('same');
79+
</script>
80+
`);
81+
await listConsoleMessages.handler({params: {}}, response, context);
82+
83+
const formattedResponse = await response.handle('test', context);
84+
const textContent = getTextContent(formattedResponse.content[0]);
85+
const messageLines = textContent
86+
.split('\n')
87+
.filter(line => line.startsWith('msgid='));
88+
89+
assert.deepStrictEqual(messageLines.length, 3);
90+
assert.ok(messageLines[0]?.endsWith('[log] same (1 args) [2 times]'));
91+
assert.ok(messageLines[1]?.endsWith('[log] different (1 args)'));
92+
assert.ok(messageLines[2]?.endsWith('[log] same (1 args) [2 times]'));
93+
94+
const groupedConsoleMessages = (
95+
formattedResponse.structuredContent as {
96+
consoleMessages?: Array<Record<string, unknown>>;
97+
}
98+
).consoleMessages;
99+
assert.ok(groupedConsoleMessages);
100+
assert.deepStrictEqual(groupedConsoleMessages.length, 3);
101+
assert.deepStrictEqual(groupedConsoleMessages[0]?.occurrences, 2);
102+
assert.deepStrictEqual(groupedConsoleMessages[2]?.occurrences, 2);
103+
});
104+
});
105+
69106
describe('issues', () => {
70107
it('lists issues', async () => {
71108
await withMcpContext(async (response, context) => {

0 commit comments

Comments
 (0)