@@ -21,16 +21,31 @@ const { ConsoleLogEntry, JavascriptLogEntry, GenericLogEntry } = require('./logE
2121const LOG = {
2222 TYPE_CONSOLE : 'console' ,
2323 TYPE_JS_LOGS : 'javascript' ,
24+ TYPE_JS_EXCEPTION : 'javascriptException' ,
25+ TYPE_LOGS : 'logs' ,
26+ TYPE_CONSOLE_FILTER : 'console_filter' ,
27+ TYPE_JS_LOGS_FILTER : 'javascript_filter' ,
28+ TYPE_JS_EXCEPTION_FILTER : 'javascriptException_filter' ,
29+ TYPE_LOGS_FILTER : 'logs_filter' ,
2430}
2531
2632class LogInspector {
2733 bidi
2834 ws
35+ #callbackId = 0
2936
3037 constructor ( driver , browsingContextIds ) {
3138 this . _driver = driver
3239 this . _browsingContextIds = browsingContextIds
33- this . listener = { }
40+ this . listener = new Map ( )
41+ this . listener . set ( LOG . TYPE_CONSOLE , new Map ( ) )
42+ this . listener . set ( LOG . TYPE_JS_LOGS , new Map ( ) )
43+ this . listener . set ( LOG . TYPE_JS_EXCEPTION , new Map ( ) )
44+ this . listener . set ( LOG . TYPE_LOGS , new Map ( ) )
45+ this . listener . set ( LOG . TYPE_CONSOLE_FILTER , new Map ( ) )
46+ this . listener . set ( LOG . TYPE_JS_LOGS_FILTER , new Map ( ) )
47+ this . listener . set ( LOG . TYPE_JS_EXCEPTION_FILTER , new Map ( ) )
48+ this . listener . set ( LOG . TYPE_LOGS_FILTER , new Map ( ) )
3449 }
3550
3651 /**
@@ -42,26 +57,63 @@ class LogInspector {
4257 await this . bidi . subscribe ( 'log.entryAdded' , this . _browsingContextIds )
4358 }
4459
45- /**
46- * @param kind
47- */
48- logListener ( kind ) {
49- if ( ! ( kind in this . listener ) ) {
50- this . listener [ kind ] = [ ]
60+ addCallback ( eventType , callback ) {
61+ const id = ++ this . #callbackId
62+
63+ const eventCallbackMap = this . listener . get ( eventType )
64+ eventCallbackMap . set ( id , callback )
65+ return id
66+ }
67+
68+ removeCallback ( id ) {
69+ for ( const [ , callbacks ] of this . listener ) {
70+ if ( callbacks . has ( id ) ) {
71+ callbacks . delete ( id )
72+ }
73+ }
74+ }
75+
76+ invokeCallbacks ( eventType , data ) {
77+ const callbacks = this . listener . get ( eventType )
78+ if ( callbacks ) {
79+ for ( const [ , callback ] of callbacks ) {
80+ callback ( data )
81+ }
82+ }
83+ }
84+
85+ invokeCallbacksWithFilter ( eventType , data , filterLevel ) {
86+ const callbacks = this . listener . get ( eventType )
87+ if ( callbacks ) {
88+ for ( const [ , value ] of callbacks ) {
89+ const callback = value . callback
90+ const filter = value . filter
91+ if ( filterLevel === filter . getLevel ( ) ) {
92+ callback ( data )
93+ }
94+ }
5195 }
5296 }
5397
5498 /**
5599 * Listen to Console logs
56100 * @param callback
57101 * @param filterBy
58- * @returns {Promise<void > }
102+ * @returns {Promise<number > }
59103 */
60104 async onConsoleEntry ( callback , filterBy = undefined ) {
61105 if ( filterBy !== undefined && ! ( filterBy instanceof FilterBy ) ) {
62106 throw Error ( `Pass valid FilterBy object. Received: ${ filterBy } ` )
63107 }
64108
109+ let id
110+
111+ if ( filterBy !== undefined ) {
112+ id = this . addCallback ( LOG . TYPE_CONSOLE_FILTER , { callback : callback , filter : filterBy } )
113+ } else {
114+ id = this . addCallback ( LOG . TYPE_CONSOLE , callback )
115+ }
116+
65117 this . ws = await this . bidi . socket
66118
67119 this . ws . on ( 'message' , ( event ) => {
@@ -81,27 +133,37 @@ class LogInspector {
81133
82134 if ( filterBy !== undefined ) {
83135 if ( params ?. level === filterBy . getLevel ( ) ) {
84- callback ( consoleEntry )
136+ this . invokeCallbacksWithFilter ( LOG . TYPE_CONSOLE_FILTER , consoleEntry , filterBy . getLevel ( ) )
85137 }
86138 return
87139 }
88140
89- callback ( consoleEntry )
141+ this . invokeCallbacks ( LOG . TYPE_CONSOLE , consoleEntry )
90142 }
91143 } )
144+
145+ return id
92146 }
93147
94148 /**
95149 * Listen to JS logs
96150 * @param callback
97151 * @param filterBy
98- * @returns {Promise<void > }
152+ * @returns {Promise<number > }
99153 */
100154 async onJavascriptLog ( callback , filterBy = undefined ) {
101155 if ( filterBy !== undefined && ! ( filterBy instanceof FilterBy ) ) {
102156 throw Error ( `Pass valid FilterBy object. Received: ${ filterBy } ` )
103157 }
104158
159+ let id
160+
161+ if ( filterBy !== undefined ) {
162+ id = this . addCallback ( LOG . TYPE_JS_LOGS_FILTER , { callback : callback , filter : filterBy } )
163+ } else {
164+ id = this . addCallback ( LOG . TYPE_JS_LOGS , callback )
165+ }
166+
105167 this . ws = await this . bidi . socket
106168
107169 this . ws . on ( 'message' , ( event ) => {
@@ -118,29 +180,26 @@ class LogInspector {
118180
119181 if ( filterBy !== undefined ) {
120182 if ( params ?. level === filterBy . getLevel ( ) ) {
121- callback ( jsEntry )
183+ this . invokeCallbacksWithFilter ( LOG . TYPE_JS_LOGS_FILTER , jsEntry , filterBy . getLevel ( ) )
122184 }
123185 return
124186 }
125187
126- callback ( jsEntry )
188+ this . invokeCallbacks ( LOG . TYPE_JS_LOGS , jsEntry )
127189 }
128190 } )
191+
192+ return id
129193 }
130194
131195 /**
132196 * Listen to JS Exceptions
133197 * @param callback
134- * @returns {Promise<void > }
198+ * @returns {Promise<number > }
135199 */
136200 async onJavascriptException ( callback ) {
201+ const id = this . addCallback ( LOG . TYPE_JS_EXCEPTION , callback )
137202 this . ws = await this . bidi . socket
138- let enabled = LOG . TYPE_JS_EXCEPTION in this . listener || this . logListener ( LOG . TYPE_JS_EXCEPTION )
139- this . listener [ LOG . TYPE_JS_EXCEPTION ] . push ( callback )
140-
141- if ( enabled ) {
142- return
143- }
144203
145204 this . ws . on ( 'message' , ( event ) => {
146205 const { params } = JSON . parse ( Buffer . from ( event . toString ( ) ) )
@@ -153,24 +212,31 @@ class LogInspector {
153212 params . stackTrace ,
154213 )
155214
156- this . listener [ LOG . TYPE_JS_EXCEPTION ] . forEach ( ( listener ) => {
157- listener ( jsErrorEntry )
158- } )
215+ this . invokeCallbacks ( LOG . TYPE_JS_EXCEPTION , jsErrorEntry )
159216 }
160217 } )
218+
219+ return id
161220 }
162221
163222 /**
164223 * Listen to any logs
165224 * @param callback
166225 * @param filterBy
167- * @returns {Promise<void > }
226+ * @returns {Promise<number > }
168227 */
169228 async onLog ( callback , filterBy = undefined ) {
170229 if ( filterBy !== undefined && ! ( filterBy instanceof FilterBy ) ) {
171230 throw Error ( `Pass valid FilterBy object. Received: ${ filterBy } ` )
172231 }
173232
233+ let id
234+ if ( filterBy !== undefined ) {
235+ id = this . addCallback ( LOG . TYPE_LOGS_FILTER , { callback : callback , filter : filterBy } )
236+ } else {
237+ id = this . addCallback ( LOG . TYPE_LOGS , callback )
238+ }
239+
174240 this . ws = await this . bidi . socket
175241
176242 this . ws . on ( 'message' , ( event ) => {
@@ -191,7 +257,16 @@ class LogInspector {
191257 return
192258 }
193259
194- callback ( jsEntry )
260+ if ( filterBy !== undefined ) {
261+ if ( params ?. level === filterBy . getLevel ( ) ) {
262+ {
263+ this . invokeCallbacksWithFilter ( LOG . TYPE_LOGS_FILTER , jsEntry , filterBy . getLevel ( ) )
264+ }
265+ return
266+ }
267+ }
268+
269+ this . invokeCallbacks ( LOG . TYPE_LOGS , jsEntry )
195270 return
196271 }
197272
@@ -209,12 +284,12 @@ class LogInspector {
209284
210285 if ( filterBy !== undefined ) {
211286 if ( params ?. level === filterBy . getLevel ( ) ) {
212- callback ( consoleEntry )
287+ this . invokeCallbacksWithFilter ( LOG . TYPE_LOGS_FILTER , consoleEntry , filterBy . getLevel ( ) )
213288 }
214289 return
215290 }
216291
217- callback ( consoleEntry )
292+ this . invokeCallbacks ( LOG . TYPE_LOGS , consoleEntry )
218293 return
219294 }
220295
@@ -229,14 +304,19 @@ class LogInspector {
229304
230305 if ( filterBy !== undefined ) {
231306 if ( params ?. level === filterBy . getLevel ( ) ) {
232- callback ( genericEntry )
307+ {
308+ this . invokeCallbacksWithFilter ( LOG . TYPE_LOGS_FILTER , genericEntry , filterBy . getLevel ( ) )
309+ }
310+ return
233311 }
234- return
235312 }
236313
237- callback ( genericEntry )
314+ this . invokeCallbacks ( LOG . TYPE_LOGS , genericEntry )
315+ return
238316 }
239317 } )
318+
319+ return id
240320 }
241321
242322 /**
0 commit comments