44 * SPDX-License-Identifier: Apache-2.0
55 */
66
7- import type * as CdpProtocol from '../node_modules/chrome-devtools-frontend/front_end/generated/protocol-proxy-api.js' ;
87import { IssuesManager , Issue } from '../node_modules/chrome-devtools-frontend/mcp/mcp.js' ;
98
109import {
@@ -45,6 +44,7 @@ export class PageCollector<T> {
4544 collector : ( item : T ) => void ,
4645 ) => ListenerMap < PageEvents > ;
4746 #listeners = new WeakMap < Page , ListenerMap > ( ) ;
47+ #seenIssueKeys = new WeakMap < Page , Set < string > > ( ) ;
4848 #maxNavigationSaved = 3 ;
4949 #includeAllPages?: boolean ;
5050
@@ -124,14 +124,22 @@ export class PageCollector<T> {
124124 }
125125
126126 protected async subscribeForIssues ( page : Page ) {
127+ if ( this instanceof NetworkCollector ) return ;
128+ if ( ! this . #seenIssueKeys. has ( page ) ) {
129+ this . #seenIssueKeys. set ( page , new Set ( ) ) ;
130+ }
127131 const session = await page . createCDPSession ( ) ;
128- session . on ( 'Audits.issueAdded' , ( data ) => { // TODO unsubscribe
132+ session . on ( 'Audits.issueAdded' , data => { // TODO unsubscribe
129133 // @ts -expect-error Types of protocol from Puppeteer and CDP are incopatible for Issues
130- const issue = IssuesManager . createIssuesFromProtocolIssue ( null , data . issue ) [ 0 ] ; // returns issue wrapped in array, need to get first element
131- if ( ! issue ) {
132- return ;
133- }
134- page . emit ( 'issue' , issue ) ;
134+ const issue = IssuesManager . createIssuesFromProtocolIssue ( null , data . issue ) [ 0 ] ; // returns issue wrapped in array, need to get first element
135+ if ( ! issue ) {
136+ return ;
137+ }
138+ const seenKeys = this . #seenIssueKeys. get ( page ) ! ;
139+ const primaryKey = issue . primaryKey ( ) ;
140+ if ( seenKeys . has ( primaryKey ) ) return ;
141+ seenKeys . add ( primaryKey ) ;
142+ page . emit ( 'issue' , issue ) ;
135143 } ) ;
136144 await session . send ( 'Audits.enable' ) ;
137145 }
@@ -154,6 +162,7 @@ export class PageCollector<T> {
154162 }
155163 }
156164 this . storage . delete ( page ) ;
165+ this . #seenIssueKeys. delete ( page ) ;
157166 }
158167
159168 getData ( page : Page , includePreservedData ?: boolean ) : T [ ] {
0 commit comments