@@ -17,6 +17,7 @@ import type {
1717 ExampleMetadata , ExecutedExample , IndividualPromptRequestResponse , Logs , PatchTest , RunResult } from '../types' ;
1818
1919import { parseComment , parseFollowUps } from './auto-run-helpers.ts' ;
20+ import { TraceDownloader } from './trace-downloader.ts' ;
2021
2122// eslint-disable-next-line @typescript-eslint/naming-convention
2223const __dirname = path . dirname ( url . fileURLToPath ( import . meta. url ) ) ;
@@ -92,71 +93,6 @@ for (const exampleUrl of userArgs.exampleUrls) {
9293 }
9394}
9495
95- /**
96- * Performance examples have a trace file so that this script does not have to
97- * trigger a trace recording.
98- */
99- class TraceDownloader {
100- static location = path . join ( __dirname , 'performance-trace-downloads' ) ;
101- static ensureLocationExists ( ) {
102- try {
103- fs . mkdirSync ( TraceDownloader . location ) ;
104- } catch {
105- }
106- }
107-
108- /**
109- * @param {string } filename - the filename to look for
110- * @param {number } attempts - the number of attempts we have had to find the file
111- */
112- static async ensureDownloadExists ( filename : string , attempts = 0 ) {
113- if ( attempts === 5 ) {
114- return false ;
115- }
116-
117- if ( fs . existsSync ( path . join ( TraceDownloader . location , filename ) ) ) {
118- return true ;
119- }
120-
121- return await new Promise ( r => {
122- setTimeout ( ( ) => {
123- return r ( TraceDownloader . ensureDownloadExists ( filename , attempts + 1 ) ) ;
124- } , 200 ) ;
125- } ) ;
126- }
127- /**
128- * Downloads a trace file for a given example.
129- * @param {Example } example - the example that is being run
130- * @param {puppeteer.Page } page - the page instance associated with this example
131- * @returns {Promise<string> } - the file name that was downloaded.
132- */
133- static async run ( example : Example , page : Page ) {
134- const url = new URL ( example . url ( ) ) ;
135- const idForUrl = path . basename ( path . dirname ( url . pathname ) ) ;
136- const cdp = await page . createCDPSession ( ) ;
137- await cdp . send ( 'Browser.setDownloadBehavior' , {
138- behavior : 'allow' ,
139- downloadPath : TraceDownloader . location ,
140- } ) ;
141- const fileName = `${ idForUrl } .json.gz` ;
142- const traceUrl = example . url ( ) . replace ( 'index.html' , fileName ) ;
143- // Using page.goto(traceUrl) does download the file, but it also causes a
144- // net::ERR_ABORTED error to be thrown. Doing it this way does not. See
145- // https://github.com/puppeteer/puppeteer/issues/6728#issuecomment-986082241.
146- await page . evaluate ( traceUrl => {
147- location . href = traceUrl ;
148- } , traceUrl ) ;
149- const foundFile = await TraceDownloader . ensureDownloadExists ( fileName ) ;
150- if ( ! foundFile ) {
151- console . error (
152- `Could not find '${ fileName } ' in download location (${ TraceDownloader . location } ). Aborting.` ,
153- ) ;
154- }
155- example . log ( `Downloaded performance trace: ${ fileName } ` ) ;
156- return fileName ;
157- }
158- }
159-
16096class Logger {
16197 #logs: Logs = { } ;
16298 #updateElapsedTimeInterval: NodeJS . Timeout | null = null ;
@@ -184,12 +120,7 @@ class Logger {
184120 }
185121 }
186122
187- /**
188- * Formats an error object for display.
189- * @param {Error } err The error object to format.
190- * @return {string } The formatted error string.
191- */
192- formatError ( err : Error ) {
123+ formatError ( err : Error ) : string {
193124 const stack = typeof err . cause === 'object' && err . cause && 'stack' in err . cause ? err . cause . stack : '' ;
194125 return `${ err . stack } ${ err . cause ? `\n${ stack } ` : '' } ` ;
195126 }
@@ -220,7 +151,7 @@ class Logger {
220151 }
221152}
222153
223- class Example {
154+ export class Example {
224155 #url: string ;
225156 #browser: Browser ;
226157 #ready = false ;
@@ -260,12 +191,7 @@ class Example {
260191 await this . #waitForElementToHaveHeight( canvas , 200 ) ;
261192 }
262193
263- /**
264- * @param {puppeteer.ElementHandle<HTMLElement> } elem
265- * @param {number } height
266- * @param {number } tries
267- */
268- async #waitForElementToHaveHeight( elem : ElementHandle < HTMLElement > , height : number , tries = 0 ) {
194+ async #waitForElementToHaveHeight( elem : ElementHandle < HTMLElement > , height : number , tries = 0 ) : Promise < boolean > {
269195 const h = await elem . evaluate ( e => e . clientHeight ) ;
270196 if ( h > height ) {
271197 return true ;
@@ -278,19 +204,10 @@ class Example {
278204 } ) ;
279205 }
280206
281- /**
282- * Parses out comments from the page.
283- * @param {puppeteer.Page } page
284- * @returns {Promise<string[]> } - the comments on the page.
285- */
286- async #getCommentStringsFromPage( page : Page ) {
287- /** @type {Array<string> } */
207+ async #getCommentStringsFromPage( page : Page ) : Promise < string [ ] > {
288208 const commentStringsFromPage = await page . evaluate ( ( ) => {
289- /**
290- * @param {Node|ShadowRoot } root
291- * @return {Array<{comment: string, commentElement: Comment, targetElement: Element|null}> }
292- */
293- function collectComments ( root : Node | ShadowRoot ) {
209+ function collectComments ( root : Node | ShadowRoot ) :
210+ Array < { comment : string , commentElement : Comment , targetElement : Element | null } > {
294211 const walker = document . createTreeWalker ( root , NodeFilter . SHOW_COMMENT ) ;
295212 const results = [ ] ;
296213 while ( walker . nextNode ( ) ) {
@@ -325,11 +242,7 @@ class Example {
325242 return commentStringsFromPage ;
326243 }
327244
328- /**
329- * @param {puppeteer.Page } devtoolsPage
330- * @returns {Promise<puppeteer.ElementHandle<HTMLElement>> } - the prompt from the annotation, if it exists, or undefined if one was not found.
331- */
332- async #lookForAnnotatedPerformanceEvent( devtoolsPage : Page ) {
245+ async #lookForAnnotatedPerformanceEvent( devtoolsPage : Page ) : Promise < ElementHandle < HTMLElement > > {
333246 const elem = await devtoolsPage . $ (
334247 'devtools-entry-label-overlay >>> [aria-label="Entry label"]' ,
335248 ) ;
@@ -339,22 +252,22 @@ class Example {
339252 ) ;
340253 }
341254
342- const overlay = /** @type {puppeteer.ElementHandle<HTMLElement> } */ ( elem ) ;
343- return overlay ;
255+ return elem as ElementHandle < HTMLElement > ;
344256 }
345257
346258 /**
347259 * Generates the metadata for a given example.
348260 * If we are testing performance, we look for an annotation to give us our target event that we need to select.
349261 * We then also parse the HTML to find the comments which give us our prompt
350262 * and explanation.
351- * @param {puppeteer.Page } page - the target page
352- * @param {puppeteer.Page } devtoolsPage - the DevTools page
353- * @returns {Promise<{idx: number, queries: string[], explanation: string, performanceAnnotation?: puppeteer.ElementHandle<HTMLElement>, rawComment: Record<string, string>}> }
354263 */
355- async #generateMetadata( page : Page , devtoolsPage : Page ) {
356- /** @type {puppeteer.ElementHandle<HTMLElement>|undefined } */
357- let annotation = undefined ;
264+ async #generateMetadata( page : Page , devtoolsPage : Page ) : Promise < {
265+ idx : number ,
266+ queries : string [ ] ,
267+ explanation : string ,
268+ performanceAnnotation ?: ElementHandle < HTMLElement > , rawComment : Record < string , string > ,
269+ } > {
270+ let annotation : ElementHandle < HTMLElement > | undefined = undefined ;
358271 if ( userArgs . testTarget === 'performance-main-thread' ) {
359272 annotation = await this . #lookForAnnotatedPerformanceEvent( devtoolsPage ) ;
360273 }
@@ -384,14 +297,11 @@ class Example {
384297 } ;
385298 }
386299
387- /**
388- * @return {string } the URL of the example
389- */
390- url ( ) {
300+ url ( ) : string {
391301 return this . #url;
392302 }
393303
394- id ( ) {
304+ id ( ) : string {
395305 return this . #url. split ( '/' ) . pop ( ) ?. replace ( '.html' , '' ) ?? 'unknown-id' ;
396306 }
397307
@@ -425,7 +335,7 @@ class Example {
425335 await new Promise ( resolve => setTimeout ( resolve , 2000 ) ) ;
426336 } else {
427337 if ( userArgs . testTarget === 'performance-main-thread' || userArgs . testTarget === 'performance-insights' ) {
428- const fileName = await TraceDownloader . run ( this , page ) ;
338+ const fileName = await TraceDownloader . download ( this , page ) ;
429339 await this . #loadPerformanceTrace( devtoolsPage , fileName ) ;
430340 }
431341
@@ -798,10 +708,8 @@ async function main() {
798708
799709 logger . head ( 'Preparing examples...' ) ;
800710 const examples = exampleUrls . map ( exampleUrl => new Example ( exampleUrl , browser ) ) ;
801- /** @type {import('./types').IndividualPromptRequestResponse[] } */
802- let allExampleResults = [ ] ;
803- /** @type {import('./types').ExampleMetadata[] } */
804- let metadata = [ ] ;
711+ let allExampleResults : IndividualPromptRequestResponse [ ] = [ ] ;
712+ let metadata : ExampleMetadata [ ] = [ ] ;
805713
806714 if ( userArgs . parallel ) {
807715 ( { allExampleResults, metadata} = await runInParallel ( examples ) ) ;
0 commit comments