55 */
66
77import assert from 'node:assert' ;
8- import { describe , it , afterEach } from 'node:test' ;
8+ import { describe , it , afterEach , beforeEach } from 'node:test' ;
99
1010import sinon from 'sinon' ;
1111
@@ -27,6 +27,20 @@ describe('performance', () => {
2727 sinon . restore ( ) ;
2828 } ) ;
2929
30+ beforeEach ( ( ) => {
31+ sinon . stub ( globalThis , 'fetch' ) . callsFake ( async url => {
32+ const cruxEndpoint =
33+ 'https://chromeuxreport.googleapis.com/v1/records:queryRecord' ;
34+ if ( url . toString ( ) . startsWith ( cruxEndpoint ) ) {
35+ return new Response ( JSON . stringify ( cruxResponseFixture ( ) ) , {
36+ status : 200 ,
37+ headers : { 'Content-Type' : 'application/json' } ,
38+ } ) ;
39+ }
40+ throw new Error ( `Unexpected fetch to ${ url } ` ) ;
41+ } ) ;
42+ } ) ;
43+
3044 describe ( 'performance_start_trace' , ( ) => {
3145 it ( 'starts a trace recording' , async ( ) => {
3246 await withMcpContext ( async ( response , context ) => {
@@ -277,3 +291,74 @@ describe('performance', () => {
277291 } ) ;
278292 } ) ;
279293} ) ;
294+
295+ function cruxResponseFixture ( ) {
296+ return {
297+ record : {
298+ key : {
299+ url : 'https://web.dev/' ,
300+ } ,
301+ metrics : {
302+ form_factors : {
303+ fractions : { desktop : 0.5056 , phone : 0.4796 , tablet : 0.0148 } ,
304+ } ,
305+ largest_contentful_paint : {
306+ histogram : [
307+ { start : 0 , end : 2500 , density : 0.7309 } ,
308+ { start : 2500 , end : 4000 , density : 0.163 } ,
309+ { start : 4000 , density : 0.1061 } ,
310+ ] ,
311+ percentiles : { p75 : 2595 } ,
312+ } ,
313+ largest_contentful_paint_image_element_render_delay : {
314+ percentiles : { p75 : 786 } ,
315+ } ,
316+ largest_contentful_paint_image_resource_load_delay : {
317+ percentiles : { p75 : 86 } ,
318+ } ,
319+ largest_contentful_paint_image_time_to_first_byte : {
320+ percentiles : { p75 : 1273 } ,
321+ } ,
322+ cumulative_layout_shift : {
323+ histogram : [
324+ { start : '0.00' , end : '0.10' , density : 0.8665 } ,
325+ { start : '0.10' , end : '0.25' , density : 0.0716 } ,
326+ { start : '0.25' , density : 0.0619 } ,
327+ ] ,
328+ percentiles : { p75 : '0.06' } ,
329+ } ,
330+ interaction_to_next_paint : {
331+ histogram : [
332+ { start : 0 , end : 200 , density : 0.8414 } ,
333+ { start : 200 , end : 500 , density : 0.1081 } ,
334+ { start : 500 , density : 0.0505 } ,
335+ ] ,
336+ percentiles : { p75 : 140 } ,
337+ } ,
338+ largest_contentful_paint_image_resource_load_duration : {
339+ percentiles : { p75 : 451 } ,
340+ } ,
341+ round_trip_time : {
342+ histogram : [
343+ { start : 0 , end : 75 , density : 0.3663 } ,
344+ { start : 75 , end : 275 , density : 0.5089 } ,
345+ { start : 275 , density : 0.1248 } ,
346+ ] ,
347+ percentiles : { p75 : 178 } ,
348+ } ,
349+ first_contentful_paint : {
350+ histogram : [
351+ { start : 0 , end : 1800 , density : 0.5899 } ,
352+ { start : 1800 , end : 3000 , density : 0.2439 } ,
353+ { start : 3000 , density : 0.1662 } ,
354+ ] ,
355+ percentiles : { p75 : 2425 } ,
356+ } ,
357+ } ,
358+ collectionPeriod : {
359+ firstDate : { year : 2025 , month : 12 , day : 8 } ,
360+ lastDate : { year : 2026 , month : 1 , day : 4 } ,
361+ } ,
362+ } ,
363+ } ;
364+ }
0 commit comments