Skip to the content

All runs

Test run 2026-10-09-142458-31e4ef4

Date
9 Oct 2026, 14:24 UTC
Commit
31e4ef4
Branch
main

1,821 tests in 18 suites.

@mark1russell7/lag: unit tests in node

Suite core-unit-node. 999 passed. Duration 9.57 s.

packages/lag/src/BaselineConfirmation.test.ts18 passed
StatusTestDuration
PassedBaselineConfirmation › needs a check from the start: a probe before the first window can start a check3.1 ms
PassedBaselineConfirmation › has no value at first, and asks for a check at the end of the first window1.4 ms
PassedBaselineConfirmation › confirms a value with an idle probe, 3 steps and an idle closing probe0.82 ms
PassedBaselineConfirmation › ignores the steps that are not in a check0.37 ms
PassedBaselineConfirmation › asks for a check at each window after a busy probe, until a check confirms a value0.96 ms
PassedBaselineConfirmation › discards a check when the closing probe is busy, and asks again at the next window0.38 ms
PassedBaselineConfirmation › discards a check whose steps do not agree0.28 ms
PassedBaselineConfirmation › asks for no probe while a check operates0.35 ms
PassedBaselineConfirmation › starts a new check when a probe comes before the end of a check0.31 ms
PassedBaselineConfirmation › uses the confirmed value while the recent baseline is more than max(1 ms, 10%) above it0.51 ms
PassedBaselineConfirmation › lowers the confirmed value to the highest recent baseline of the last 3 windows0.8 ms
PassedBaselineConfirmation › keeps the confirmed value after a short decrease of the recent baseline0.3 ms
PassedBaselineConfirmation › ignores a probe of a row when no check is necessary0.3 ms
PassedBaselineConfirmation › keeps the confirmed value when the check agrees with it, and gives the limit of the load0.47 ms
PassedBaselineConfirmation › gives no limit when the closing probe is busy, or when the steps do not agree0.52 ms
PassedBaselineConfirmation › confirms a larger value when the check agrees with the recent baseline0.49 ms
PassedBaselineConfirmation › sets a new granularity with accept(), and ends a check0.75 ms
PassedBaselineConfirmation › does not confirm a first value with accept(): only a check does0.26 ms
packages/lag/src/BrowserReportMonitor.test.ts9 passed
StatusTestDuration
PassedBrowserReportMonitor › gets the reports from before its start, and after stop() and start() no report a second time5 ms
PassedBrowserReportMonitor › asks for the buffered reports again when the first start failed2.2 ms
PassedBrowserReportMonitor › observes interventions and deprecations, including buffered reports0.71 ms
PassedBrowserReportMonitor › reports the fields of each report body0.64 ms
PassedBrowserReportMonitor › logs a warning when ReportingObserver is not available0.54 ms
PassedBrowserReportMonitor › isolates a report callback that throws0.51 ms
PassedBrowserReportMonitor › disconnects on stop and can start again, without the buffered reports0.56 ms
PassedBrowserReportMonitor › start() while the monitor observes makes no second observer, and stop() works after a start that failed1.4 ms
PassedBrowserReportMonitor › names the error and the monitor in its logs0.88 ms
packages/lag/src/BusyTimeProbe.test.ts8 passed
StatusTestDuration
PassedBusyTimeProbe › measures no busy time on an idle thread10 ms
PassedBusyTimeProbe › measures the tasks that keep the thread busy: each task delays one message7.1 ms
PassedBusyTimeProbe › counts the wait of the message that did not start when it stops0.64 ms
PassedBusyTimeProbe › counts only the waits of more than 2 ms0.36 ms
PassedBusyTimeProbe › gives 0 without a measurement, and after a measurement stopped0.25 ms
PassedBusyTimeProbe › ignores a message of an earlier measurement1.7 ms
PassedBusyTimeProbe › starts again from 0 when start() comes during a measurement0.22 ms
PassedBusyTimeProbe › stops the chain: after stop(), a message posts no other message0.3 ms
packages/lag/src/ClockDriftMonitor.test.ts18 passed
StatusTestDuration
PassedClockDriftMonitor › samples every second by default and reports a skew near 0 while both clocks agree11 ms
PassedClockDriftMonitor › tolerates gradual correction of the wall clock1.3 ms
PassedClockDriftMonitor › scales the threshold with the interval: 3% of the time between samples2.9 ms
PassedClockDriftMonitor › classifies a forward jump of 1 s or more as a suspend0.98 ms
PassedClockDriftMonitor › classifies a smaller forward jump as a step0.75 ms
PassedClockDriftMonitor › classifies a backward jump as a step0.6 ms
PassedClockDriftMonitor › classifies a forward jump during a late timer as a suspend too, because timers are late in a hidden page0.72 ms
PassedClockDriftMonitor › finds a sleep in a hidden page in which the browser runs the timer one time each minute0.78 ms
PassedClockDriftMonitor › finds no discontinuity when both clocks continue, as in a Windows sleep or a blocked thread0.68 ms
PassedClockDriftMonitor › ignores a sample when the thread stopped between the two reads of the monotonic clock0.8 ms
PassedClockDriftMonitor › measures drift from the restart, not across a stopped period1 ms
PassedClockDriftMonitor › stops its timer0.58 ms
PassedClockDriftMonitor › logs instead of throwing when report throws0.92 ms
PassedClockDriftMonitor › start() while the monitor operates adds no second interval0.46 ms
PassedClockDriftMonitor › keeps a reading whose two reads of the monotonic clock are 1 ms apart0.54 ms
PassedClockDriftMonitor › compares the first sample with nothing when the reading at the start was not valid0.6 ms
PassedClockDriftMonitor › does not count a drift of exactly the limit as a jump0.45 ms
PassedClockDriftMonitor › classifies a forward jump of exactly 1000 ms as a suspend0.67 ms
packages/lag/src/ClockReliabilityChecker.test.ts10 passed
StatusTestDuration
PassedClockReliabilityChecker › detects clock resolution from rapid samples3.1 ms
PassedClockReliabilityChecker › detects a coarse clock that stays flat across many consecutive reads3.9 ms
PassedClockReliabilityChecker › reports high resolution for a cross-origin-isolated clock (5μs)0.23 ms
PassedClockReliabilityChecker › reports low resolution for a 1ms clock2.7 ms
PassedClockReliabilityChecker › measures once and caches the result0.2 ms
PassedClockReliabilityChecker › samples again after a call where the clock never ticked8.4 ms
PassedClockReliabilityChecker › exposes the time origin from performance0.29 ms
PassedClockReliabilityChecker › returns 0 and is not high-resolution for a clock that never advances10 ms
PassedClockReliabilityChecker › is not high-resolution at a resolution of exactly 50 μs0.75 ms
PassedClockReliabilityChecker › measures the resolution from the smallest of the first 5 ticks of the clock0.29 ms
packages/lag/src/ClsCalculator.test.ts13 passed
StatusTestDuration
PassedClsCalculator boundaries › starts a new window at a gap of exactly 1000 ms and at a length of exactly 5000 ms, as web-vitals does2.5 ms
PassedClsCalculator › sums shifts in one session window0.34 ms
PassedClsCalculator › starts a new window after a gap of more than 1 s0.16 ms
PassedClsCalculator › starts a new window when a window is longer than 5 s0.16 ms
PassedClsCalculator › keeps the sources of the largest shift in the worst window0.84 ms
PassedClsCalculator › counts the 5 s length of a window from its first shift, also when the first shift is late0.22 ms
PassedClsCalculator › starts the first window after reset() at the first shift0.19 ms
PassedClsCalculator › gives no sources for a shift without sources0.16 ms
PassedClsCalculator › keeps the largest shift of a window when a smaller shift follows0.87 ms
PassedClsCalculator › names the later of two shifts with the same score in a window, as web-vitals does0.18 ms
PassedClsCalculator › keeps the first of two windows with the same score as the worst window, as web-vitals does0.29 ms
PassedClsCalculator › reset() clears everything0.28 ms
PassedClsCalculator › agrees with the reference definition for any sequence of shifts (property test)25 ms
packages/lag/src/ComputePressureMonitor.test.ts15 passed
StatusTestDuration
PassedComputePressureMonitor › constructs a PressureObserver and observes the configured sources6.2 ms
PassedComputePressureMonitor › reports records with state ordinals1.4 ms
PassedComputePressureMonitor › tracks the latest state per source0.48 ms
PassedComputePressureMonitor › getWorstStateOrdinal returns the max across sources0.49 ms
PassedComputePressureMonitor › returns -1 worst ordinal before any samples0.96 ms
PassedComputePressureMonitor › logs a warning if observe() rejects (unsupported source)0.76 ms
PassedComputePressureMonitor › logs a warning if PressureObserver constructor throws0.35 ms
PassedComputePressureMonitor › disconnects on stop and clears state0.48 ms
PassedComputePressureMonitor › prevents double-start0.43 ms
PassedComputePressureMonitor › rules of the observer › observes again after stop() and start()0.46 ms
PassedComputePressureMonitor › rules of the observer › stop() works, and the monitor logs the reason, when the browser has no PressureObserver1.3 ms
PassedComputePressureMonitor › rules of the observer › logs the source that the browser does not support0.51 ms
PassedComputePressureMonitor › rules of the observer › gives the most severe state of all sources, also when a less severe record comes last0.25 ms
PassedComputePressureMonitor › rules of the observer › logs no warning when stop() rejects the pending observe() calls, also after a new start3.4 ms
PassedComputePressureMonitor › rules of the observer › logs an error from the report function and continues with the next record0.8 ms
packages/lag/src/DriftLag.granularity.test.ts19 passed
StatusTestDuration
PassedDriftLag when the timer granularity changes › reports no lag on an idle thread after the steps change from 6 ms to 16 ms25 ms
PassedDriftLag when the timer granularity changes › adapts the baseline to the new granularity in about one second9.7 ms
PassedDriftLag when the timer granularity changes › gives no lag when the change comes at the end of a window: the window waits for the row3.2 ms
PassedDriftLag when the timer granularity changes › ends the window at the step that accepts the new granularity1.3 ms
PassedDriftLag when the timer granularity changes › gives the old baseline to the steps of the window before the row of a finer granularity2.5 ms
PassedDriftLag when the timer granularity changes › follows a change to a finer granularity, and then measures a block correctly8.8 ms
PassedDriftLag when the timer granularity changes › keeps a row of long steps (more than 40 ms) as lag: no granularity is that coarse8.5 ms
PassedDriftLag when the timer granularity changes › keeps a row of steps that do not agree with each other as lag9.1 ms
PassedDriftLag baseline › is the mean of the steps that are not longer than the median plus max(4 ms, half the median)4.4 ms
PassedDriftLag baseline › leaves out a block, also when the block comes before shorter steps0.83 ms
PassedDriftLag baseline of a short window of steps › uses the mean of the two middle steps as the median of an even number of steps1.6 ms
PassedDriftLag baseline of a short window of steps › uses the middle step as the median of an odd number of steps, and keeps a step at the limit0.68 ms
PassedDriftLag rules for a change of the granularity › accepts a new granularity after exactly 10 steps in a row11 ms
PassedDriftLag rules for a change of the granularity › starts a new row of steps after a restart4.7 ms
PassedDriftLag rules for a change of the granularity › does not change the baseline for a row that a normal step interrupts5 ms
PassedDriftLag rules for a change of the granularity › does not start a row with steps that are longer than the baseline by exactly the jitter limit (4 ms)2.3 ms
PassedDriftLag rules for a change of the granularity › accepts a row of steps of exactly 40 ms as a new granularity3.7 ms
PassedDriftLag rules for a change of the granularity › accepts a row of steps that differ by 20 % of their mean as one granularity3.2 ms
PassedDriftLag rules for a change of the granularity › ends a window not more than 10 steps after its normal length while rows of steps start and end2.7 ms
packages/lag/src/DriftLag.load.test.ts35 passed
StatusTestDuration
PassedDriftLag during a sustained load › reports equal tasks of 20 ms as lag, also after 5 s16 ms
PassedDriftLag during a sustained load › reported the same load as a new granularity without a probe9.3 ms
PassedDriftLag during a sustained load › reports equal timer tasks of 30 ms, 5 ms apart, as lag8.9 ms
PassedDriftLag during a sustained load › reports equal tasks of 20 ms as lag when the idle step takes 15.6 ms12 ms
PassedDriftLag during a sustained load › reported less lag without a probe when the idle step takes 15.6 ms5.7 ms
PassedDriftLag during a sustained load › reports no lag after the load, and the probes stop13 ms
PassedDriftLag during a sustained load › measures a block after the load correctly11 ms
PassedDriftLag during a sustained load › finds the idle baseline when the monitor starts during a load2.7 ms
PassedDriftLag during a sustained load › removes the busy steps with one check after a load, when the busy steps are in the jitter limit6.9 ms
PassedDriftLag during a sustained load › finds the idle baseline of 15.6 ms when the monitor starts during a load of 20 ms tasks3.2 ms
PassedDriftLag with a probe when the timer granularity changes › accepts a coarser granularity on an idle thread after 10 steps, with no lag4.6 ms
PassedDriftLag with a probe when the timer granularity changes › accepts the new granularity two steps later than without a probe: the probed step and the next step are not in the row4.8 ms
PassedDriftLag with a probe when the timer granularity changes › accepts a finer granularity with no probe4.3 ms
PassedDriftLag with a probe when the timer granularity changes › confirms a small increase of the granularity with a probe4.1 ms
PassedDriftLag with a probe when the timer granularity changes › does one check on an idle thread, after the first window2 ms
PassedDriftLag with a probe when the timer granularity changes › adds the first step to the recent steps0.22 ms
PassedDriftLag with a probe when the timer granularity changes › stops a probe when the monitor stops0.41 ms
PassedDriftLag when the granularity changes at any time in a window › gives no lag on an idle thread when the steps change from 15.6 ms to 5.7 ms (probe: true)485 ms
PassedDriftLag when the granularity changes at any time in a window › gives no lag on an idle thread when the steps change from 15.6 ms to 5.7 ms (probe: false)220 ms
PassedDriftLag when the granularity changes at any time in a window › gives no lag on an idle thread when the steps change from 5.7 ms to 15.6 ms (probe: true)578 ms
PassedDriftLag when the granularity changes at any time in a window › gives no lag on an idle thread when the steps change from 5.7 ms to 15.6 ms (probe: false)292 ms
PassedDriftLag when the granularity changes at any time in a window › measures a block of 100 ms just before a change to a coarser granularity266 ms
PassedDriftLag with the timer tick of Windows after a start › measures a block in the first window, and ends the first window after 20 steps (probe: true)53 ms
PassedDriftLag with the timer tick of Windows after a start › measures a block in the first window, and ends the first window after 20 steps (probe: false)12 ms
PassedDriftLag with the timer tick of Windows after a start › measures a block after a restart in which the granularity changed38 ms
PassedDriftLag probe rules › probes the step after the 5th step of a row of longer steps2.1 ms
PassedDriftLag probe rules › does not use the probe of an earlier row for a new row4.2 ms
PassedDriftLag probe rules › ends the row when it accepts a new granularity: the next windows have their normal length3.2 ms
PassedDriftLag probe rules › lowers the confirmed value with the baseline: a later small increase needs a probe5.3 ms
PassedDriftLag with a probe that changes the timing › confirms the idle duration from steps that were not probed, when a probe makes a step shorter2.8 ms
PassedDriftLag with a probe that changes the timing › confirms a new idle duration also when the step after a probe is longer4.3 ms
PassedDriftLag with a probe that changes the timing › operates as without a probe when each message waits8.8 ms
PassedDriftLag without a probe › has no confirmed value: after a row of shorter steps, the baseline follows a small increase3.3 ms
PassedDriftLag without a probe › operates with the default options1.1 ms
PassedDriftLag without a probe › clears the timer one time when it stops two times1.7 ms
packages/lag/src/DriftLag.power.test.ts25 passed
StatusTestDuration
PassedDriftLag with the timer alignment of WebKit › gives steps of 8 ms with the normal alignment of 4 ms (offset 0)19 ms
PassedDriftLag with the timer alignment of WebKit › follows the alignment of 30 ms of Low Power Mode, and still measures a block (offset 0)8.2 ms
PassedDriftLag with the timer alignment of WebKit › gives no lag after a restart in a task, with a grid of 4 ms (offset 0)9.8 ms
PassedDriftLag with the timer alignment of WebKit › measures a block during the warm-up after a restart, with a grid of 4 ms (offset 0)9.6 ms
PassedDriftLag with the timer alignment of WebKit › gives no lag after a restart in a task, with a grid of 30 ms (offset 0)9.8 ms
PassedDriftLag with the timer alignment of WebKit › measures a block during the warm-up after a restart, with a grid of 30 ms (offset 0)6.1 ms
PassedDriftLag with the timer alignment of WebKit › gives no lag when the grid changes out of Low Power Mode at any time in a window (offset 0)322 ms
PassedDriftLag with the timer alignment of WebKit › gives not more than the jitter limit of lag when the grid changes into Low Power Mode at any time in a window (offset 0)338 ms
PassedDriftLag with the timer alignment of WebKit › gives steps of 8 ms with the normal alignment of 4 ms (offset 0.37)2.5 ms
PassedDriftLag with the timer alignment of WebKit › follows the alignment of 30 ms of Low Power Mode, and still measures a block (offset 0.37)3.3 ms
PassedDriftLag with the timer alignment of WebKit › gives no lag after a restart in a task, with a grid of 4 ms (offset 0.37)2.9 ms
PassedDriftLag with the timer alignment of WebKit › measures a block during the warm-up after a restart, with a grid of 4 ms (offset 0.37)3.3 ms
PassedDriftLag with the timer alignment of WebKit › gives no lag after a restart in a task, with a grid of 30 ms (offset 0.37)7.5 ms
PassedDriftLag with the timer alignment of WebKit › measures a block during the warm-up after a restart, with a grid of 30 ms (offset 0.37)3.9 ms
PassedDriftLag with the timer alignment of WebKit › gives no lag when the grid changes out of Low Power Mode at any time in a window (offset 0.37)352 ms
PassedDriftLag with the timer alignment of WebKit › gives not more than the jitter limit of lag when the grid changes into Low Power Mode at any time in a window (offset 0.37)369 ms
PassedDriftLag with the timer alignment of WebKit › gives steps of 8 ms with the normal alignment of 4 ms (offset 0.9)1.6 ms
PassedDriftLag with the timer alignment of WebKit › follows the alignment of 30 ms of Low Power Mode, and still measures a block (offset 0.9)2.3 ms
PassedDriftLag with the timer alignment of WebKit › gives no lag after a restart in a task, with a grid of 4 ms (offset 0.9)2.4 ms
PassedDriftLag with the timer alignment of WebKit › measures a block during the warm-up after a restart, with a grid of 4 ms (offset 0.9)2.1 ms
PassedDriftLag with the timer alignment of WebKit › gives no lag after a restart in a task, with a grid of 30 ms (offset 0.9)2 ms
PassedDriftLag with the timer alignment of WebKit › measures a block during the warm-up after a restart, with a grid of 30 ms (offset 0.9)2.2 ms
PassedDriftLag with the timer alignment of WebKit › gives no lag when the grid changes out of Low Power Mode at any time in a window (offset 0.9)338 ms
PassedDriftLag with the timer alignment of WebKit › gives not more than the jitter limit of lag when the grid changes into Low Power Mode at any time in a window (offset 0.9)361 ms
PassedDriftLag with the timer alignment of WebKit › follows a change into Low Power Mode and out of it6.4 ms
packages/lag/src/DriftLag.test.ts14 passed
StatusTestDuration
PassedDriftLag › reports no lag on an idle thread with exact timers12 ms
PassedDriftLag › subtracts the timer granularity: an idle thread with 16 ms steps has no lag3.3 ms
PassedDriftLag › changes the number of steps so that a window stays near the expected length1.5 ms
PassedDriftLag › reports the length of a block in the window1.3 ms
PassedDriftLag › keeps the baseline when one step is long2.7 ms
PassedDriftLag › uses the requested step as the baseline before the first step0.69 ms
PassedDriftLag › requests the same step delay for every step, with or without lag2.6 ms
PassedDriftLag › logs errors and continues monitoring when report throws2.8 ms
PassedDriftLag › stop() right after construction clears the pending timer2 ms
PassedDriftLag › stop() from inside report stops the loop0.84 ms
PassedDriftLag › start() after stop() measures from the restart, not across the stopped time1.1 ms
PassedDriftLag › start() while running does not add a second timer chain0.64 ms
PassedDriftLag › stop() + start() from inside report leaves exactly one timer chain0.98 ms
PassedDriftLag › uses whole steps for a window: 103 ms gives 20 steps of 5 ms0.98 ms
packages/lag/src/EventTimingMonitor.test.ts24 passed
StatusTestDuration
PassedEventTimingMonitor › reports decomposed event timing7.8 ms
PassedEventTimingMonitor › ignores events with interactionId=00.64 ms
PassedEventTimingMonitor › calculates INP as p98 of interaction durations1.9 ms
PassedEventTimingMonitor › returns 0 INP with no interactions0.43 ms
PassedEventTimingMonitor › tracks worst interaction duration per interactionId0.46 ms
PassedEventTimingMonitor › resets on stop0.49 ms
PassedEventTimingMonitor › asks the browser for events down to 16ms (default threshold is 104ms)1.3 ms
PassedEventTimingMonitor › keeps INP correct while tracking only the longest few interactions7.2 ms
PassedEventTimingMonitor › counts an interaction once across its several events2.2 ms
PassedEventTimingMonitor › clamps presentationDelay at 0 when rounding makes it negative0.37 ms
PassedEventTimingMonitor › uses performance.interactionCount when the browser supplies it1.3 ms
PassedEventTimingMonitor › counts the interactions from the start of the page, as the buffered candidates from before the start do0.62 ms
PassedEventTimingMonitor › counts the interactions it saw when the browser count is missing0.46 ms
PassedEventTimingMonitor › processes the buffered entries that the browser delivers inside observe(), as old Safari did0.97 ms
PassedEventTimingMonitor › gives the event keydown the interaction type keyboard0.29 ms
PassedEventTimingMonitor › gives the event keyup the interaction type keyboard0.14 ms
PassedEventTimingMonitor › gives the event pointerdown the interaction type pointer0.16 ms
PassedEventTimingMonitor › gives the event mousedown the interaction type pointer0.11 ms
PassedEventTimingMonitor › gives the event click the interaction type pointer0.1 ms
PassedEventTimingMonitor › gives the event auxclick the interaction type pointer0.12 ms
PassedEventTimingMonitor › gives the event contextmenu the interaction type pointer0.11 ms
PassedEventTimingMonitor › gives the event touchstart the interaction type pointer0.1 ms
PassedEventTimingMonitor › gives the event dblclick the interaction type other0.1 ms
PassedEventTimingMonitor › gives the event input the interaction type other0.13 ms
packages/lag/src/FrameTimingMonitor.test.ts26 passed
StatusTestDuration
PassedFrameTimingMonitor › schedules an animation frame on construction4.9 ms
PassedFrameTimingMonitor › does not report on the first frame (no previous baseline)1.9 ms
PassedFrameTimingMonitor › reports zero dropped frames for an on-time frame1.3 ms
PassedFrameTimingMonitor › reports exact dropped frame count for a delayed frame0.75 ms
PassedFrameTimingMonitor › counts a 100ms gap as 5 dropped frames at 60fps0.28 ms
PassedFrameTimingMonitor › tolerates slightly-late frames (16.67 → 17ms)0.27 ms
PassedFrameTimingMonitor › tracks total dropped frames and dropped frame rate0.52 ms
PassedFrameTimingMonitor › resets counters1.5 ms
PassedFrameTimingMonitor › cancels pending frame on stop1.2 ms
PassedFrameTimingMonitor › respects custom target FPS0.42 ms
PassedFrameTimingMonitor › stop() + start() inside report: one rAF chain, and no frame spanning the pause1.7 ms
PassedFrameTimingMonitor › automatic frame interval › follows a 120 Hz display0.76 ms
PassedFrameTimingMonitor › automatic frame interval › does not count a 30 fps limit (power saving) as dropped frames0.65 ms
PassedFrameTimingMonitor › automatic frame interval › keeps the estimate through a burst of jank1.7 ms
PassedFrameTimingMonitor › automatic frame interval › ignores deltas too short to be a refresh interval0.39 ms
PassedFrameTimingMonitor › automatic frame interval › keeps the interval when one gap is short: a late frame and then an on-time frame3 ms
PassedFrameTimingMonitor › automatic frame interval › measures the gaps between the frame timestamps, not the times at which the callbacks run1.1 ms
PassedFrameTimingMonitor › automatic frame interval › reads the clock when the callback gets no frame timestamp0.51 ms
PassedFrameTimingMonitor › rules of the frame interval › uses 60 Hz before the first frames0.55 ms
PassedFrameTimingMonitor › rules of the frame interval › estimates the interval for the target fps "auto"0.39 ms
PassedFrameTimingMonitor › rules of the frame interval › uses 60 Hz until the window has five deltas0.67 ms
PassedFrameTimingMonitor › rules of the frame interval › accepts a delta of 4 ms as a frame interval0.26 ms
PassedFrameTimingMonitor › rules of the frame interval › uses the fifth-shortest delta, thus four short deltas do not change the interval0.37 ms
PassedFrameTimingMonitor › rules of the frame interval › follows a change from 60 Hz to 120 Hz at the fifth short delta0.33 ms
PassedFrameTimingMonitor › rules of the frame interval › follows a change from 120 Hz to 60 Hz after 600 frames15 ms
PassedFrameTimingMonitor › rules of the frame interval › logs an error from the report function and continues with the next frame1.8 ms
packages/lag/src/GCSignalDetector.test.ts10 passed
StatusTestDuration
PassedGCSignalDetector › arms exactly one canary on construction4.2 ms
PassedGCSignalDetector › records a GC event when the canary is collected, and re-arms3 ms
PassedGCSignalDetector › counts one event per GC cycle, however long the gap between cycles0.43 ms
PassedGCSignalDetector › didGCRecently returns true only within the window0.63 ms
PassedGCSignalDetector › getRecentGCEvents counts events in window0.73 ms
PassedGCSignalDetector › respects the historySize ring buffer0.52 ms
PassedGCSignalDetector › ignores collections after stop and doesn't re-arm0.35 ms
PassedGCSignalDetector › re-arms on restart, without doubling up when the old canary is still pending0.47 ms
PassedGCSignalDetector › logs an error and keeps detecting if the cleanup callback throws1.4 ms
PassedGCSignalDetector › counts a GC exactly at the edge of the window0.4 ms
packages/lag/src/IdleAvailabilityMonitor.test.ts12 passed
StatusTestDuration
PassedIdleAvailabilityMonitor › schedules an idle callback on construction4.8 ms
PassedIdleAvailabilityMonitor › reports timeRemaining and didTimeout1.6 ms
PassedIdleAvailabilityMonitor › reports timeSinceLastIdleMs as 0 on first fire1.1 ms
PassedIdleAvailabilityMonitor › reports time gap between idle fires0.28 ms
PassedIdleAvailabilityMonitor › tracks timeout rate0.36 ms
PassedIdleAvailabilityMonitor › returns zero timeout rate before any fires0.36 ms
PassedIdleAvailabilityMonitor › resets counters0.26 ms
PassedIdleAvailabilityMonitor › cancels pending idle callback on stop0.3 ms
PassedIdleAvailabilityMonitor › rules of the gaps and of the callback chain › gives a gap of 0 for the first callback after a restart0.77 ms
PassedIdleAvailabilityMonitor › rules of the gaps and of the callback chain › measures the gap from a callback at the time 00.32 ms
PassedIdleAvailabilityMonitor › rules of the gaps and of the callback chain › logs an error from the report function and continues with the next callback1.1 ms
PassedIdleAvailabilityMonitor › rules of the gaps and of the callback chain › leaves one waiting callback when report() stops and starts the monitor0.44 ms
packages/lag/src/InpCalculator.test.ts11 passed
StatusTestDuration
PassedInpCalculator › returns 0 without interactions3.5 ms
PassedInpCalculator › ignores entries without an interactionId0.55 ms
PassedInpCalculator › uses the longest event of an interaction0.39 ms
PassedInpCalculator › counts interactions since the start when the browser supplies a count0.27 ms
PassedInpCalculator › reset() starts a new calculation and a new count baseline0.4 ms
PassedInpCalculator › reset() with a baseline counts from that baseline0.24 ms
PassedInpCalculator › reset() without a browser count clears the calculation0.25 ms
PassedInpCalculator › counts the events of one interaction as one candidate, also at 50 or more interactions0.35 ms
PassedInpCalculator › gives the shortest kept interaction when the number of outliers is larger than the number of kept interactions0.49 ms
PassedInpCalculator › gives 0 as the longest duration without interactions0.22 ms
PassedInpCalculator › agrees with the reference definition for any sequence of entries (property test)25 ms
packages/lag/src/LagLogger.test.ts16 passed
StatusTestDuration
PassedLagLogger › should not log anything if utilization remains low6.5 ms
PassedLagLogger › should ignore all measurements if the tab was hidden0.42 ms
PassedLagLogger › should log warnings for both short and long-term violations if utilization is high enough3.8 ms
PassedLagLogger › should reset its internal state after reporting5.3 ms
PassedLagLogger › uses the interval of each measurement, for example windows of 93 ms3.7 ms
PassedLagLogger › should handle buffer size correctly without unbounded growth4 ms
PassedLagLogger › 'short-term' lag detection › should log a warning when average lag exceeds 100% over 2000ms1.4 ms
PassedLagLogger › 'short-term' lag detection › should not log if utilization is below $threshold %1.3 ms
PassedLagLogger › 'long-term' lag detection › should log a warning when average lag exceeds 50% over 5000ms1.4 ms
PassedLagLogger › 'long-term' lag detection › should not log if utilization is below $threshold %0.82 ms
PassedLagLogger › rules of the periods › warns for a 2 s period of high lag that comes after 10 s of low lag2 ms
PassedLagLogger › rules of the periods › averages the lag of the most recent samples that cover the period, and no older sample1.4 ms
PassedLagLogger › rules of the periods › does not warn for an average of exactly the threshold2.4 ms
PassedLagLogger › rules of the periods › does not warn for one long sample that the 2 s period averages below 100 %1.3 ms
PassedLagLogger › rules of the periods › warns for a 5 s period at the start of each report period3.1 ms
PassedLagLogger › rules of the periods › uses the measurement interval when a measurement gives an interval of 01.5 ms
packages/lag/src/LayoutShiftMonitor.test.ts9 passed
StatusTestDuration
PassedLayoutShiftMonitor › reports individual shift values6.6 ms
PassedLayoutShiftMonitor › excludes shifts with hadRecentInput=true0.67 ms
PassedLayoutShiftMonitor › accumulates session values within 1s gap0.61 ms
PassedLayoutShiftMonitor › starts new session after 1s gap0.35 ms
PassedLayoutShiftMonitor › starts new session after 5s max duration0.37 ms
PassedLayoutShiftMonitor › tracks worst session value as CLS0.3 ms
PassedLayoutShiftMonitor › resets on stop0.53 ms
PassedLayoutShiftMonitor › reports the sources of each shift, and no sources for a shift without them1.4 ms
PassedLayoutShiftMonitor › processes the buffered shifts that the browser delivers inside observe(), as old Safari did1.2 ms
packages/lag/src/LongAnimationFrameMonitor.test.ts8 passed
StatusTestDuration
PassedLongAnimationFrameMonitor › reports blockingDuration and duration from LoAF entries8.2 ms
PassedLongAnimationFrameMonitor › calculates renderDuration from renderStart to the end of the frame0.52 ms
PassedLongAnimationFrameMonitor › reports renderDuration 0 for frames that did not render0.27 ms
PassedLongAnimationFrameMonitor › detects forced layout from scripts0.4 ms
PassedLongAnimationFrameMonitor › reports hasForceLayout=false when no forced layout0.23 ms
PassedLongAnimationFrameMonitor › rules of the script attribution › reports no scripts for an entry without a list of scripts0.39 ms
PassedLongAnimationFrameMonitor › rules of the script attribution › names the first of the longest scripts with its function name, and finds a forced layout in any script0.91 ms
PassedLongAnimationFrameMonitor › rules of the script attribution › gives an empty function name for a script without one0.34 ms
packages/lag/src/MacrotaskLag.test.ts12 passed
StatusTestDuration
PassedMacrotaskLag › constructor › sets up an interval with the specified period8.1 ms
PassedMacrotaskLag › measure() › returns a promise that resolves with the macrotask schedulng delay0.9 ms
PassedMacrotaskLag › measure() › schedules a macrotask with zero delay to measure event loop lag0.66 ms
PassedMacrotaskLag › interval callback › measures and reports lag value when interval fires0.66 ms
PassedMacrotaskLag › interval callback › logs an error when the report function throws but continues monitoring1.3 ms
PassedMacrotaskLag › interval callback › handles multiple interval cycles independently0.57 ms
PassedMacrotaskLag › stop() › clears the interval it created in the constructor0.41 ms
PassedMacrotaskLag › stop() › drops a sample that was in flight when stop() was called0.61 ms
PassedMacrotaskLag › stop() › drops a sample that was in flight across stop() and start()1.8 ms
PassedMacrotaskLag › stop() › start() while the monitor operates adds no second interval0.48 ms
PassedMacrotaskLag › stop() › can be restarted0.51 ms
PassedMacrotaskLag › postTask › starts the measurement in the posted task, so that the timer nesting clamp does not apply0.76 ms
packages/lag/src/MemoryMonitor.test.ts14 passed
StatusTestDuration
PassedMemoryMonitor › samples legacy memory immediately on start11 ms
PassedMemoryMonitor › uses modern API when available and ignores legacy54 ms
PassedMemoryMonitor › falls back to legacy when modern API rejects52 ms
PassedMemoryMonitor › schedules periodic samples on the configured interval4.1 ms
PassedMemoryMonitor › handles missing source methods gracefully0.79 ms
PassedMemoryMonitor › clears the interval on stop0.99 ms
PassedMemoryMonitor › drops a modern sample that resolves after stop()0.77 ms
PassedMemoryMonitor › does not start a new sample while one is still pending0.69 ms
PassedMemoryMonitor › stops calling the modern API after it fails once103 ms
PassedMemoryMonitor › rules of the sources › start() while the monitor operates adds no second interval1.3 ms
PassedMemoryMonitor › rules of the sources › logs an error from the report function and continues with the next sample1.5 ms
PassedMemoryMonitor › rules of the sources › logs the failure of the standard API at debug level, and reports nothing without a legacy API1.1 ms
PassedMemoryMonitor › rules of the sources › reports nothing, and logs nothing, when the legacy API gives no value0.53 ms
PassedMemoryMonitor › rules of the sources › gives no usage for a heap limit of 01.4 ms
packages/lag/src/ObserverMonitor.test.ts13 passed
StatusTestDuration
PassedObserverMonitor › creates a PerformanceObserver and calls observe with buffered6.8 ms
PassedObserverMonitor › processes entries via processEntry0.89 ms
PassedObserverMonitor › logs warning when observe throws (unsupported type)2.5 ms
PassedObserverMonitor › logs error when processEntry throws1.5 ms
PassedObserverMonitor › disconnects on stop0.49 ms
PassedObserverMonitor › prevents double-start0.53 ms
PassedObserverMonitor › skips observing types missing from supportedEntryTypes0.67 ms
PassedObserverMonitor › can retry start() after observe threw0.52 ms
PassedObserverMonitor › takeRecords() processes the entries that the browser has not delivered yet0.57 ms
PassedObserverMonitor › takeRecords() does nothing without an observer or without browser support0.32 ms
PassedObserverMonitor › gives the buffered entries that the browser delivers inside observe() to the subclass in a microtask, as for old Safari1.9 ms
PassedObserverMonitor › drops a delivery from inside observe() when stop() comes before the microtask0.34 ms
PassedObserverMonitor › stop() works after a start that failed, and the warning names the entry type and the error2.1 ms
packages/lag/src/PeerHangWatch.test.ts60 passed
StatusTestDuration
PassedPeerHangWatch › uses the channel name and the lock names of the protocol, which pages of other versions also use9.8 ms
PassedPeerHangWatch › sends a heartbeat when it gets its lock, then one each interval, and none after it becomes hidden2 ms
PassedPeerHangWatch › says away only when it was visible1.2 ms
PassedPeerHangWatch › reports a page that hangs after its first heartbeat3.4 ms
PassedPeerHangWatch › waits 1 s by default for a late message of a page2.3 ms
PassedPeerHangWatch › reports the page when the wait is shorter than the delay of its last message1.9 ms
PassedPeerHangWatch › stops all its timers and closes its channel1.6 ms
PassedPeerHangWatch › starts no wait for a page that ends after the stop1.6 ms
PassedPeerHangWatch › holds the lock of a visible page, and releases it when the page becomes hidden1.2 ms
PassedPeerHangWatch › reports a page that closes during a hang, with the time of its last heartbeat1.8 ms
PassedPeerHangWatch › reports nothing when the page survives its hang1.8 ms
PassedPeerHangWatch › reports nothing when a page closes or becomes hidden normally1.4 ms
PassedPeerHangWatch › reports nothing when a page ends soon after its last heartbeat (a crash, not a hang)2.9 ms
PassedPeerHangWatch › reports a hang of 5 s or more, and nothing for a shorter silence2 ms
PassedPeerHangWatch › lets one page only report a hang, when many pages watch it8.1 ms
PassedPeerHangWatch › waits for the last messages of a page after its lock comes free1.1 ms
PassedPeerHangWatch › takes the record of the worker of the hung page from the journal, and then needs no mark1.6 ms
PassedPeerHangWatch › uses its own times when the journal fails, and marks the report, because the journal can still have the record1.7 ms
PassedPeerHangWatch › reports nothing and puts the record back when it stops while it takes the record from the journal1.3 ms
PassedPeerHangWatch › logs nothing when it stops during the take, and the journal has no record or cannot put the record back1.9 ms
PassedPeerHangWatch › watches the others while hidden, but sends no heartbeat and holds no lock0.87 ms
PassedPeerHangWatch › watches a page again after it becomes visible again1.6 ms
PassedPeerHangWatch › watches a page again at once when the page becomes visible again during the wait for its last messages1.6 ms
PassedPeerHangWatch › keeps a late heartbeat that the page sent before its lock came free with the earlier entry1.9 ms
PassedPeerHangWatch › does not use a lock that it got after the page became hidden again0.65 ms
PassedPeerHangWatch › stops: it says away, releases its locks, and reports nothing more1.5 ms
PassedPeerHangWatch › reports nothing when it stops while it waits for the last messages of a page1.7 ms
PassedPeerHangWatch › releases the claim when it stops3.1 ms
PassedPeerHangWatch › keeps the claim for PEER_CLAIM_HOLD_MS, and then releases it3.3 ms
PassedPeerHangWatch › reports the hang, but does not keep the claim, when it goes into the back/forward cache during the take of the record1.7 ms
PassedPeerHangWatch › does not keep the claim when the watch stops in the report1.6 ms
PassedPeerHangWatch › releases the claim when it goes into the back/forward cache1.9 ms
PassedPeerHangWatch › ignores messages that are not its own, and its own messages4.1 ms
PassedPeerHangWatch › logs a failed lock request and a failed message, and continues1.4 ms
PassedPeerHangWatch › logs a message that the channel cannot send1.2 ms
PassedPeerHangWatch in the back/forward cache › closes its channel while it is suspended, and gets no message then1.5 ms
PassedPeerHangWatch in the back/forward cache › reports no hang for a page that closed normally while it was suspended1.3 ms
PassedPeerHangWatch in the back/forward cache › cancels its waiting lock requests when it is suspended, thus it has one request for each page1.4 ms
PassedPeerHangWatch in the back/forward cache › gets no lock while it is frozen, thus a page that becomes hidden and visible again gets its own lock1 ms
PassedPeerHangWatch in the back/forward cache › cancels its waiting lock requests when it stops1.1 ms
PassedPeerHangWatch in the back/forward cache › watches without AbortController, but then it cannot cancel its waiting lock requests1.8 ms
PassedPeerHangWatch in the back/forward cache › opens its channel again when it resumes, and watches again1.6 ms
PassedPeerHangWatch in the back/forward cache › opens no channel after a stop, and logs a channel that it cannot open1.5 ms
PassedPeerHangWatch, the own page at its close › removes the record of its worker from the journal, and marks its report, as in Firefox1.1 ms
PassedPeerHangWatch, the own page at its close › reports its own hang also when the journal cannot remove the record0.92 ms
PassedPeerHangWatch, the own page at its close › reports its own hang when it closes at the end of a hang, as in Safari0.85 ms
PassedPeerHangWatch, the own page at its close › reports its own hang when a heartbeat comes between the hang and the close, as in Firefox0.9 ms
PassedPeerHangWatch, the own page at its close › reports nothing at a normal close, or at a close some time after a hang1.1 ms
PassedPeerHangWatch, the own page at its close › reports nothing that the worker monitor counted already1 ms
PassedPeerHangWatch, the own page at its close › reports a later hang, also after the worker monitor counted an earlier one0.75 ms
PassedPeerHangWatch, the own page at its close › reports nothing when it becomes hidden, or when it closes while hidden or before its first heartbeat0.75 ms
PassedPeerHangWatch, the own page at its close › measures the gaps again after the page was hidden1.9 ms
PassedPeerHangWatch, the own page at its close › reports a silence of exactly the threshold0.77 ms
PassedPeerHangWatch, the own page at its close › reports a gap of exactly the threshold before the last heartbeat0.74 ms
PassedPeerHangWatch, the own page at its close › reports nothing when the page operated for a heartbeat interval after the gap0.89 ms
PassedPeerHangWatch, the own page at its close › reports nothing for a close exactly one heartbeat interval after the heartbeat that ended the gap0.87 ms
PassedPeerHangWatch, the own page at its close › counts a hang that the worker monitor counted at the time of the last heartbeat as counted0.81 ms
PassedPeerHangWatch, the own page at its close › reports nothing for a gap of less than the threshold1.1 ms
PassedisPeerMessage › accepts the two messages of the watch0.59 ms
PassedisPeerMessage › refuses other values0.86 ms
packages/lag/src/SchedulingFairnessMonitor.test.ts11 passed
StatusTestDuration
PassedSchedulingFairnessMonitor › starts measurement loop on construction12 ms
PassedSchedulingFairnessMonitor › reports a SchedulingMeasurement when all three primitives complete4.1 ms
PassedSchedulingFairnessMonitor › stops the measurement loop on stop()1.2 ms
PassedSchedulingFairnessMonitor › logs an error and does not start when the MessageChannel cannot be constructed1.3 ms
PassedSchedulingFairnessMonitor › drops a cycle that was still in flight across stop() and start()1.1 ms
PassedSchedulingFairnessMonitor › starts setTimeout(0) from a message task, not from the setInterval callback1.2 ms
PassedSchedulingFairnessMonitor › closes its channel on stop()1.5 ms
PassedSchedulingFairnessMonitor › rules of the measurement loop › start() while the monitor operates adds no second interval1.8 ms
PassedSchedulingFairnessMonitor › rules of the measurement loop › stop() works after a start that could not make the MessageChannel1.8 ms
PassedSchedulingFairnessMonitor › rules of the measurement loop › logs an error when the report function throws, and continues with the next cycle2.3 ms
PassedSchedulingFairnessMonitor › rules of the measurement loop › logs an error when a cycle cannot start, and continues with the next cycle1.9 ms
packages/lag/src/SharedLivenessMonitor.test.ts7 passed
StatusTestDuration
PassedSharedLivenessMonitor › gives the buffer to the worker at construction, with a threshold of 50 ms and a poll interval of 5 ms5.1 ms
PassedSharedLivenessMonitor › gives the worker the threshold and the poll interval of the options0.81 ms
PassedSharedLivenessMonitor › reports the duration of each block that the worker saw0.73 ms
PassedSharedLivenessMonitor › ignores the other messages of the worker0.76 ms
PassedSharedLivenessMonitor › logs an error from the report function and continues with the next block1.6 ms
PassedSharedLivenessMonitor › stop() removes the listener and stops the watcher of the worker, and a second stop() does nothing0.57 ms
PassedSharedLivenessMonitor › start() after stop() starts the watcher again, and start() while the monitor operates does nothing0.47 ms
packages/lag/src/TimerThrottleDetector.test.ts12 passed
StatusTestDuration
PassedTimerThrottleDetector › reports not throttled when timers fire on time6.2 ms
PassedTimerThrottleDetector › reports throttled when timers are delayed2.6 ms
PassedTimerThrottleDetector › transitions from throttled to not throttled2 ms
PassedTimerThrottleDetector › stops calibration when stop() is called0.68 ms
PassedTimerThrottleDetector › prevents double-start0.83 ms
PassedTimerThrottleDetector › restarting does not leave a second calibration chain running0.98 ms
PassedTimerThrottleDetector › stop() from inside the logger (on a throttle change) sticks0.87 ms
PassedTimerThrottleDetector › reports every calibration round0.86 ms
PassedTimerThrottleDetector › rules of a calibration round › does not count a sample of exactly the threshold as throttled1.2 ms
PassedTimerThrottleDetector › rules of a calibration round › is not throttled when exactly half of the samples are throttled0.57 ms
PassedTimerThrottleDetector › rules of a calibration round › logs an error from the report function and starts the next round0.73 ms
PassedTimerThrottleDetector › rules of a calibration round › logs the start of the throttling and its end one time each0.7 ms
packages/lag/src/WorkerClockSync.test.ts10 passed
StatusTestDuration
PassedWorkerClockSync › estimates the offset from the exchange with the shortest round trip6.5 ms
PassedWorkerClockSync › treats an offset inside the uncertainty as 00.49 ms
PassedWorkerClockSync › has no correction before a synchronization finished0.39 ms
PassedWorkerClockSync › keeps the most accurate result of all synchronizations1.7 ms
PassedWorkerClockSync › uses 8 exchanges by default2 ms
PassedWorkerClockSync › ignores replies with an unknown ID1.3 ms
PassedWorkerClockSync › rules of the exchanges › ignores a reply to a synchronization that a new synchronization replaced0.66 ms
PassedWorkerClockSync › rules of the exchanges › counts a reply that comes two times only one time0.73 ms
PassedWorkerClockSync › rules of the exchanges › keeps the result of a later synchronization with a shorter round trip3.4 ms
PassedWorkerClockSync › rules of the exchanges › corrects by an offset that is larger than half the round trip plus 1 ms, but not by an offset of that size1.4 ms
packages/lag/src/WorkerLagMonitor.test.ts25 passed
StatusTestDuration
PassedWorkerLagMonitor › starts the worker's heartbeat loop with hang options and listens on construction9.9 ms
PassedWorkerLagMonitor › reports how long each heartbeat waited for the main thread, and acknowledges it2.7 ms
PassedWorkerLagMonitor › reports each queued heartbeat's wait after a block0.81 ms
PassedWorkerLagMonitor › clamps tiny negative delays from clock rounding to zero0.82 ms
PassedWorkerLagMonitor › synchronizes the clocks and corrects the delay by the measured offset1.2 ms
PassedWorkerLagMonitor › synchronizes the clocks again after the interval1.6 ms
PassedWorkerLagMonitor › reports a system stall when the worker itself was late by 5 s or more1.1 ms
PassedWorkerLagMonitor › ends the system stall when the worker sent the heartbeat, not when the main thread got it0.64 ms
PassedWorkerLagMonitor › passes hang-ended messages on0.67 ms
PassedWorkerLagMonitor › stops the worker loop and the sync timer on stop, keeps one listener, and can restart2.1 ms
PassedWorkerLagMonitor › passes on the end of a hang while it is stopped, but ignores heartbeats1.1 ms
PassedWorkerLagMonitor › removes its listener on dispose()1.6 ms
PassedWorkerLagMonitor › ignores unknown messages0.52 ms
PassedWorkerLagMonitor › logs instead of throwing when report throws1 ms
PassedWorkerLagMonitor › sends its page ID with start, and the page context to the worker1.2 ms
PassedWorkerLagMonitor › watchdog › warns when the worker sends no heartbeat in two checks2.7 ms
PassedWorkerLagMonitor › watchdog › does not warn after a heartbeat, also when the heartbeat comes after the first check1.1 ms
PassedWorkerLagMonitor › watchdog › stops with the monitor0.65 ms
PassedWorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › handles a clock synchronization, the end of a hang and a system stall without event listeners, and logs no error1.1 ms
PassedWorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › reports a system stall at a self lag of exactly 5 s0.58 ms
PassedWorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › ignores a message without data, also while it is stopped0.45 ms
PassedWorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › start() while the monitor operates sends nothing0.56 ms
PassedWorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › keeps the context while it is stopped and sends it at the next start0.67 ms
PassedWorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › listens again at start() after dispose()0.54 ms
PassedWorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › waits five heartbeat intervals for each watchdog check when that is longer than 5 s0.8 ms
packages/lag/src/absolute-clock.test.ts1 passed
StatusTestDuration
PassedcreateAbsoluteClock › reads timeOrigin one time, so that a later change of timeOrigin does not move the clock3.7 ms
packages/lag/src/drift-baseline.test.ts17 passed
StatusTestDuration
PassedidleStepMs › is the step when there is one step3.2 ms
PassedidleStepMs › leaves out a block that is longer than the median plus half the median0.3 ms
PassedstepsUpTo › keeps the steps that are not longer than the limit, in the same sequence1.5 ms
PassedspreadMs › is 2 ms, or 20% of the step if that is more0.47 ms
PassedoutsideStepMs › is the step between the two baselines, for a coarser and for a finer granularity0.34 ms
PassedoutsideStepMs › is not less than the shorter baseline and not more than the longer baseline0.39 ms
PassedusedBaselineMs › is the recent baseline without a confirmed value0.25 ms
PassedusedBaselineMs › is the recent baseline if it is not more than 1 ms above a confirmed value of less than 10 ms0.28 ms
PassedusedBaselineMs › permits an increase of 10% above a confirmed value of more than 10 ms0.35 ms
PassedisIdleStep › is true for a busy time of less than 2 ms when the step is not longer than the baseline0.3 ms
PassedisIdleStep › is true for a busy time of less than half of the extra duration of the step1.2 ms
PassedinterpretCheck › gives no finding when the steps do not agree with each other0.56 ms
PassedinterpretCheck › confirms the recent baseline as the first value0.44 ms
PassedinterpretCheck › confirms the lower of the recent baseline and the idle duration when the idle duration agrees better with the recent baseline0.34 ms
PassedinterpretCheck › gives the limit of the load when the idle duration agrees better with the confirmed value0.23 ms
PassedinterpretCheck › gives the limit of the load when the idle duration is as near to the confirmed value as to the recent baseline0.21 ms
PassedinterpretCheck › uses the larger limit: the confirmed value plus its spread, or the idle duration plus its spread0.39 ms
packages/lag/src/events.test.ts7 passed
StatusTestDuration
PassedwithEventContext › adds the context attributes to each event, and reads the context for each event4.8 ms
PassedwithEventContext › gives the options of the event to the sink, and no options when the event has none0.53 ms
PassedwithEventContext › gives priority to the attributes of the event1.9 ms
PassedplaceEventTime › gives the time of the occurrence when it is no more than 30 minutes from the time of the call0.81 ms
PassedplaceEventTime › gives no time, but the attribute lag.event.time, for an occurrence farther from the time of the call0.47 ms
PassedplaceEventTime › gives nothing for an unknown time or a time that is not a finite number0.43 ms
PassedcreateNoopEventSink › accepts events and does nothing1.6 ms
packages/lag/src/forwarding-meter.test.ts14 passed
StatusTestDuration
Passedforwarding meter › creates the instruments on the other side with their first records, with their options13 ms
Passedforwarding meter › sends records in batches at the flush interval2.5 ms
Passedforwarding meter › sends at once when the buffer is full0.62 ms
Passedforwarding meter › sends no empty batches0.57 ms
Passedforwarding meter › dispose() sends the rest and stops the timer0.94 ms
Passedforwarding meter › the receiver ignores records for unknown instruments1.2 ms
Passedforwarding meter › sends the kind of each instrument in the batch of its first record, with the ID of the sender0.54 ms
Passedforwarding meter › gives each forwarding meter its own random sender ID0.81 ms
Passedforwarding meter › keeps the instruments of two senders apart in one receiver0.94 ms
Passedforwarding meter › gives the records to a receiver that starts to listen after the creation of the instruments0.63 ms
Passedforwarding meter › creates each instrument one time, also when a batch comes two times1.8 ms
Passedforwarding meter › ignores the records after dispose()0.69 ms
Passedforwarding meter › flushes at the interval of the options0.59 ms
Passedforwarding meter › sends each record in one batch only, and no batch when no record came after the last batch0.63 ms
packages/lag/src/hang-journal.test.ts22 passed
StatusTestDuration
PassedcreateMemoryHangJournal › takes a record that was seen exactly at the limit3.1 ms
PassedcreateMemoryHangJournal › keeps one record for each page, and the newest write wins7.5 ms
PassedcreateMemoryHangJournal › removes a record0.33 ms
PassedcreateMemoryHangJournal › takes a stale record one time, and does not take a record that somebody updated after the limit0.4 ms
PassedcreateMemoryHangJournal › keeps a copy of the attributes, not the object of the caller0.31 ms
PassedcreateIndexedDbHangJournal › takes a record that was seen exactly at the limit5.9 ms
PassedcreateIndexedDbHangJournal › keeps one record for each page, and the newest write wins1.5 ms
PassedcreateIndexedDbHangJournal › removes a record0.69 ms
PassedcreateIndexedDbHangJournal › takes a stale record one time, and does not take a record that somebody updated after the limit1.2 ms
PassedcreateIndexedDbHangJournal › keeps a copy of the attributes, not the object of the caller0.36 ms
PassedcreateIndexedDbHangJournal › shares the records between two journals of the same database, as a page and its worker do0.83 ms
PassedcreateIndexedDbHangJournal › gives a record to only one of two journals that take it at the same time, as two pages do0.81 ms
PassedcreateIndexedDbHangJournal › ignores records that are not hang records0.54 ms
PassedcreateIndexedDbHangJournal › ignores and does not take the records whose fields have the wrong type1.6 ms
PassedcreateIndexedDbHangJournal › closes its connection when a page deletes the database, and opens the database again at the next operation1.5 ms
PassedcreateIndexedDbHangJournal › closes its connection when a later version of the library opens the database2.4 ms
PassedcreateIndexedDbHangJournal › opens the database again after the browser closed the connection1.4 ms
PassedcreateIndexedDbHangJournal › rejects when the database cannot open, and tries again at the next operation0.82 ms
PassedfindAbandonedHangs › finds the records that nobody updated for the stale time, except the own page0.38 ms
PassedcreateStorageHangReportMarks › gives a mark one time, with the key of the protocol0.89 ms
PassedcreateStorageHangReportMarks › removes the old marks of pages without a record, and keeps the others0.7 ms
PassedcreateStorageHangReportMarks › does nothing when the storage refuses an operation0.63 ms
packages/lag/src/index.test.ts1 passed
StatusTestDuration
Passedthe public API › exports the dependency groups that the public functions use2 ms
packages/lag/src/lag-worker.test.ts33 passed
StatusTestDuration
Passedlag-worker handler › stays idle until told to start8.4 ms
Passedlag-worker handler › posts a timestamped heartbeat every interval once started2.8 ms
Passedlag-worker handler › reports how late its own timer fired as workerSelfLagMs1 ms
Passedlag-worker handler › answers a sync request with its absolute time0.52 ms
Passedlag-worker handler › stops the loop on stop and can be restarted0.96 ms
Passedlag-worker handler › restarting with a new interval replaces the old loop instead of adding one0.69 ms
Passedlag-worker handler › hang detection › reports a hang when acks stop, and the end when they resume3.7 ms
Passedlag-worker handler › hang detection › reports each hang once0.83 ms
Passedlag-worker handler › hang detection › does not report a hang while the main thread acknowledges heartbeats1.1 ms
Passedlag-worker handler › hang detection › reports no hang while the main thread acknowledges each heartbeat, also with an interval of the threshold or more1.4 ms
Passedlag-worker handler › hang detection › reports no hang when its own timer is late by less than the threshold, and the main thread acknowledges each heartbeat0.8 ms
Passedlag-worker handler › hang detection › measures the wait from the oldest heartbeat without an acknowledgement0.84 ms
Passedlag-worker handler › hang detection › measures the wait again from an acknowledgement of an earlier heartbeat1.3 ms
Passedlag-worker handler › hang detection › does not blame the main thread for time in which the worker itself did not run0.71 ms
Passedlag-worker handler › hang detection › does not add the time in which the worker itself did not run to a hang in progress1.1 ms
Passedlag-worker handler › hang detection › ends a hang in progress at a stop, because the main thread sent the stop0.83 ms
Passedlag-worker handler › hang detection › does not blame the main thread when the worker itself was late by exactly the threshold0.62 ms
Passedlag-worker handler › hang detection › does not detect hangs without hang options2 ms
Passedlag-worker handler › page context and hang journal › adds the last context to its hang reports1.1 ms
Passedlag-worker handler › page context and hang journal › writes a record when a hang starts, writes it again each second, and removes it when the hang ends2.9 ms
Passedlag-worker handler › page context and hang journal › removes the record when it stops during a hang1.5 ms
Passedlag-worker handler › page context and hang journal › writes the wall-clock time of the start of the hang to the journal0.82 ms
Passedlag-worker handler › page context and hang journal › uses Date.now() for the times of the journal when the dependencies have no wall clock1.2 ms
Passedlag-worker handler › page context and hang journal › writes no record while the main thread acknowledges the heartbeats1.4 ms
Passedlag-worker handler › page context and hang journal › removes no record at the end of a hang without a page ID0.84 ms
Passedlag-worker handler › page context and hang journal › keeps no record without a page ID0.62 ms
Passedlag-worker handler › page context and hang journal › continues the heartbeats when the journal fails1 ms
Passedlag-worker handler › shared-memory liveness › starts a watcher at liveness-start, and posts each block that the watcher sees1.8 ms
Passedlag-worker handler › shared-memory liveness › uses the threshold and the poll interval of the liveness-start message1.1 ms
Passedlag-worker handler › shared-memory liveness › stops the watcher at liveness-stop1 ms
Passedlag-worker handler › shared-memory liveness › replaces the watcher at a second liveness-start1.3 ms
Passedlag-worker handler › shared-memory liveness › ignores liveness-stop when no watcher operates1.5 ms
Passedlag-worker handler › shared-memory liveness › does not watch without both interval functions0.78 ms
packages/lag/src/measurement-conditions.test.ts31 passed
StatusTestDuration
PassedcreateMeasurementConditions › validator › records a normal sample at once9.9 ms
PassedcreateMeasurementConditions › validator › discards a sample whose window overlaps a hidden period2.2 ms
PassedcreateMeasurementConditions › validator › keeps the first window after the page becomes visible again0.73 ms
PassedcreateMeasurementConditions › validator › discards a sample when the page is hidden but visibilitychange has not fired yet0.66 ms
PassedcreateMeasurementConditions › validator › waits for late evidence before it records an outlier, then records it as a hang1.7 ms
PassedcreateMeasurementConditions › validator › reports the stall samples of one block as one episode, with the longest sample1.4 ms
PassedcreateMeasurementConditions › validator › reports separate blocks as separate episodes0.81 ms
PassedcreateMeasurementConditions › validator › gives an episode the kind suspend when one of its samples gets suspend evidence during the wait0.81 ms
PassedcreateMeasurementConditions › validator › discards a sample at once when the evidence exists before the sample, and counts a suspend stall0.85 ms
PassedcreateMeasurementConditions › validator › gives the same result when the sample comes before the suspend evidence or after it1.1 ms
PassedcreateMeasurementConditions › validator › uses the suspend evidence when a window overlaps a hidden interval and a suspend0.83 ms
PassedcreateMeasurementConditions › validator › counts no stall for a long sample in a hidden interval0.64 ms
PassedcreateMeasurementConditions › validator › dispose() reports the episodes that wait2.7 ms
PassedcreateMeasurementConditions › validator › discards an outlier when suspend evidence arrives during the wait0.85 ms
PassedcreateMeasurementConditions › validator › uses the configured outlier threshold and wait0.73 ms
PassedcreateMeasurementConditions › validator › dispose() cancels outliers that wait0.65 ms
PassedcreateMeasurementConditions › validator › waits for late evidence before it records a sample at the outlier threshold0.6 ms
PassedcreateMeasurementConditions › validator › counts a suspend stall for a discarded sample at the outlier threshold0.59 ms
PassedcreateMeasurementConditions › validator › reports a stall sample that does not overlap the waiting episode as a separate episode0.76 ms
PassedcreateMeasurementConditions › validator › adds a stall sample whose window starts at the end of the waiting episode to the episode0.6 ms
PassedcreateMeasurementConditions › validator › extends an episode with each sample that it gets, so that a later sample can overlap the extension0.66 ms
PassedcreateMeasurementConditions › validator › gives a hang episode the kind suspend when a sample with suspend evidence joins it0.63 ms
PassedcreateMeasurementConditions › validator › works without stall and discard listeners0.77 ms
PassedcreateMeasurementConditions › validator › works without a lifecycle0.7 ms
PassedcreateMeasurementConditions › lifecycle intervals › opens an interval at creation when the page is hidden0.55 ms
PassedcreateMeasurementConditions › lifecycle intervals › records frozen periods with their own reason0.53 ms
PassedcreateMeasurementConditions › lifecycle intervals › dispose() stops following the lifecycle and closes the open interval0.51 ms
PassedcreateMeasurementConditions › pauseWhileHidden › stops a monitor while hidden and starts it again when visible0.63 ms
PassedcreateMeasurementConditions › pauseWhileHidden › stops a monitor at once when the page is hidden at the start0.47 ms
PassedcreateMeasurementConditions › pauseWhileHidden › does not stop or start a monitor when the page loses the focus or gets it again0.7 ms
PassedcreateMeasurementConditions › pauseWhileHidden › does not start a monitor when a hidden page becomes frozen and resumes, but starts it when the page is visible0.78 ms
packages/lag/src/message-task.test.ts3 passed
StatusTestDuration
PassedcreateMessageTaskQueue › runs the callbacks later, in the sequence in which they were posted5.7 ms
PassedcreateMessageTaskQueue › drops the callbacks that did not run when it closes, and closes the ports1.4 ms
PassedcreateMessageTaskQueue › closes a channel whose ports have no close()1.5 ms
packages/lag/src/metric-catalog.test.ts16 passed
StatusTestDuration
Passedmetric catalog › has unique metric names3.2 ms
Passedmetric catalog › uses the naming rules: lag_ prefix; histograms end in _histogram, counters do not2.9 ms
Passedmetric catalog › gives every metric a description, a unit and a closed set of attribute values4.2 ms
Passedmetric catalog › has unique event names with attributes0.7 ms
Passedmetric catalog › creates instruments of the declared kind and unit1.5 ms
Passedmetric catalog › gives the bucket boundaries of the catalog to the SDK as advice, as a copy2.1 ms
Passedmetric catalog › refuses to create an instrument of the wrong kind1.4 ms
Passedmetric catalog › permits exactly the values of the types of the monitors as attribute values1.3 ms
Passedmetric catalog › names a monitor of the package for each metric and each event2.7 ms
Passedmetric catalog › gives every event a description0.36 ms
Passedmetric catalog › has unique span names with the lag. prefix, attributes, a description and a monitor of the package0.73 ms
Passedhistogram buckets › gives each histogram ascending, unique bucket boundaries, and no counter6 ms
Passedhistogram buckets › selects the boundaries from the unit, and the ordinal boundaries for the pressure state1.1 ms
Passedhistogram buckets › makes the thresholds of the Web Vitals bucket boundaries, thus the buckets give the exact ratings2 ms
Passedhistogram buckets › puts the typical values of each type of histogram into different buckets0.67 ms
Passedhistogram buckets › gives exactly the documented boundaries0.74 ms
packages/lag/src/monitor-registry.test.ts6 passed
StatusTestDuration
PassedMonitorRegistry › adds handles and returns them unchanged2.4 ms
PassedMonitorRegistry › looks up handles by name0.51 ms
PassedMonitorRegistry › stopAll() calls stop on every handle in LIFO order0.98 ms
PassedMonitorRegistry › stopAll() isolates errors — one bad stop doesn't prevent others2.3 ms
PassedMonitorRegistry › stopAll() clears the registry0.38 ms
PassedMonitorRegistry › getAll() returns all handles in registration order0.34 ms
packages/lag/src/noop-meter.test.ts1 passed
StatusTestDuration
PassedcreateNoopMeter › gives histograms and counters that accept values and record nothing3 ms
packages/lag/src/otel-logger-adapter.test.ts15 passed
StatusTestDuration
PassedcreateOtelLoggerAdapter › emits log records with severityText and body8.6 ms
PassedcreateOtelLoggerAdapter › maps known severity levels to OTel SeverityNumber1.1 ms
PassedcreateOtelLoggerAdapter › defaults to INFO severity for unknown levels0.45 ms
PassedcreateOtelLoggerAdapter › merges object args into attributes0.51 ms
PassedcreateOtelLoggerAdapter › wraps non-object args under 'args' key0.31 ms
PassedcreateOtelLoggerAdapter › gives the string of an argument that is not a primitive and not an object0.37 ms
PassedcreateOtelLoggerAdapter › handles null/undefined args without throwing0.35 ms
PassedcreateTeeLogger › forwards calls to all loggers1.3 ms
PassedcreateTeeLogger › isolates logger errors so one failure doesn't break others1.8 ms
PassedcreateOtelLoggerAdapter attribute encoding › turns an Error into semantic-convention exception attributes5 ms
PassedcreateOtelLoggerAdapter attribute encoding › JSON-encodes nested objects and keeps primitive arrays1.1 ms
PassedcreateOtelLoggerAdapter attribute encoding › keeps booleans, numbers and strings, and leaves out the attributes that are undefined or null0.4 ms
PassedcreateOtelLoggerAdapter attribute encoding › JSON-encodes an array with values of different types or with objects0.35 ms
PassedcreateOtelLoggerAdapter attribute encoding › leaves out the stack trace of an Error that has no stack0.3 ms
PassedcreateOtelLoggerAdapter attribute encoding › gives the string of an object that JSON cannot encode0.3 ms
packages/lag/src/random-id.test.ts3 passed
StatusTestDuration
PassedcreateRandomId › gives the bytes of crypto.getRandomValues as 32 hexadecimal digits2.8 ms
PassedcreateRandomId › uses Math.random when the environment has no crypto.getRandomValues1.6 ms
PassedcreateRandomId › gives a different ID at each use4.9 ms
packages/lag/src/reliability.test.ts10 passed
StatusTestDuration
PassedReliabilityTracker › finds a closed interval that overlaps a window4.3 ms
PassedReliabilityTracker › does not count a window that only touches a closed interval0.52 ms
PassedReliabilityTracker › counts an open interval for every window that ends after it starts, including one that ends at its start0.99 ms
PassedReliabilityTracker › closes an interval only once0.39 ms
PassedReliabilityTracker › ignores an interval that ends before it starts0.29 ms
PassedReliabilityTracker › forgets closed intervals after the retention time, but keeps open ones0.6 ms
PassedReliabilityTracker › notifies subscribers of each new interval until they unsubscribe2.6 ms
PassedReliabilityTracker › counts a closed interval of zero length inside a window1.9 ms
PassedReliabilityTracker › is unreliable now while one interval is open, also when other intervals are closed1 ms
PassedReliabilityTracker › forgets an old closed interval before it searches0.27 ms
packages/lag/src/setup-all-monitors.test.ts44 passed
StatusTestDuration
PassedsetupAllMonitors › registers every monitor when all capabilities are present41 ms
PassedsetupAllMonitors › feeds every metric of the catalog that normal activity produces185 ms
PassedsetupAllMonitors › creates only catalog instruments, with the catalog kind, unit and attribute values182 ms
PassedsetupAllMonitors › emits attribution events without query strings140 ms
PassedsetupAllMonitors › gives the ID of the current page view to the worker, for its hang reports1.7 ms
PassedsetupAllMonitors › sends only the event attributes that the catalog lists135 ms
PassedsetupAllMonitors › gives the ID of the current page view to the events of the other monitors140 ms
PassedsetupAllMonitors › flush() records the pending Web Vitals, for the before-flush hook of an exporter101 ms
PassedsetupAllMonitors › records each Web Vital once for each page view, and sends events with the semantic-convention names92 ms
PassedsetupAllMonitors › measures main-thread lag through DriftLag and the worker's delivery delay7.4 ms
PassedsetupAllMonitors › synchronizes the worker clock and records the offset2.3 ms
PassedsetupAllMonitors › discards a lag sample that overlaps a system suspend, after the worker reports it79 ms
PassedsetupAllMonitors › detects a main-thread hang in the worker, and records it when the main thread runs again142 ms
PassedsetupAllMonitors › counts samples that it discards because the page was hidden28 ms
PassedsetupAllMonitors › records clock jumps208 ms
PassedsetupAllMonitors › stop() releases every timer, listener, observer and worker loop120 ms
PassedsetupAllMonitors › pauses timer-driven monitors while the page is hidden174 ms
PassedsetupAllMonitors › keeps the first sample after the page becomes visible again21 ms
PassedsetupAllMonitors › gives each monitor of the registry through its typed getter2.9 ms
PassedsetupAllMonitors › gives the ID of the current page view to the hang reports of the worker92 ms
PassedsetupAllMonitors › stop() reports the stall episode that waits, with its kind33 ms
PassedsetupAllMonitors › counts lifecycle transitions1.5 ms
PassedsetupAllMonitors › emits the start of the page view and each lifecycle transition, with the page-view ID and a time of the absolute clock1.4 ms
PassedsetupAllMonitors with shared memory › adds the shared-memory liveness monitor, and DriftLag beats the counter8.3 ms
PassedsetupAllMonitors degradation › runs the core monitors with only the required deps1.2 ms
PassedsetupAllMonitors degradation › skips the worker monitor, with a warning, when performance is missing2.6 ms
PassedsetupAllMonitors degradation › keeps the timer-driven monitors when the page lifecycle cannot start1.6 ms
PassedsetupAllMonitors degradation › keeps going when one monitor fails to construct1.5 ms
PassedsetupAllMonitors degradation › registers no monitor whose dependencies are not complete, and logs no warning1.9 ms
PassedsetupAllMonitors degradation › registers no page-view context without the page-view vitals2.6 ms
PassedsetupAllMonitors degradation › gives the page-view ID to the crash-report context of the browser, also without a worker1.5 ms
PassedsetupAllMonitors degradation › counts a stall without an event sink56 ms
PassedsetupAllMonitors degradation › sends the stall events without a page-view ID when the page-view vitals are missing73 ms
PassedsetupAllMonitors with BroadcastChannel and the Web Locks API › adds the peer hang watch, which sends the ID of the current page view in its heartbeats16 ms
PassedsetupAllMonitors with BroadcastChannel and the Web Locks API › gives the worker and the watch one page ID12 ms
PassedsetupAllMonitors with BroadcastChannel and the Web Locks API › tells the watch about each hang that the worker monitor counts as ended, not about an abandoned hang of the journal123 ms
PassedsetupAllMonitors with BroadcastChannel and the Web Locks API › gives the journal to the watch of a page without a worker, but the page does not read the journal at its start106 ms
PassedsetupAllMonitors with BroadcastChannel and the Web Locks API › needs the wall clock, BroadcastChannel and the Web Locks API for the watch6 ms
PassedsetupAllMonitors with BroadcastChannel and the Web Locks API › counts a hang of the worker monitor without an event sink, with the watch164 ms
PassedsetupAllMonitors with an exporter that gets the pagehide event first › without the event, the final export misses the end of the page2.5 ms
PassedsetupAllMonitors with an exporter that gets the pagehide event first › flush(event) records the end of the page before the export, and the listener of the monitors does not record it again1.9 ms
PassedsetupAllMonitors with a span sink › makes one trace for each page view, with the spans of the monitors in the span of the view124 ms
PassedsetupAllMonitors with a span sink › gives the identity of the span of the view to the hang reports of the worker, for the trace of an abandoned hang82 ms
PassedsetupAllMonitors with a span sink › makes no spans without a span sink8.5 ms
packages/lag/src/shared-liveness.test.ts11 passed
StatusTestDuration
Passedshared-memory liveness › reports nothing while the main thread beats11 ms
Passedshared-memory liveness › reports a block when the counter stops changing, when it changes again2.4 ms
Passedshared-memory liveness › ignores quiet periods shorter than the threshold0.95 ms
Passedshared-memory liveness › does not report time in which the watcher itself did not run0.85 ms
Passedshared-memory liveness › stops polling on stop()0.88 ms
Passedshared-memory liveness › beatingSetTimeout beats before each callback1.9 ms
Passedshared-memory liveness › uses a threshold of 50 ms and a poll interval of 5 ms by default2.7 ms
Passedshared-memory liveness › start() while the watcher operates adds no second poll0.5 ms
Passedshared-memory liveness › reports a quiet period of exactly the threshold1.1 ms
Passedshared-memory liveness › measures a block also when one poll of the watcher is late by less than the threshold1.9 ms
Passedshared-memory liveness › does not count the time in which the watcher itself was late by exactly the threshold1.2 ms
packages/lag/src/spans.test.ts10 passed
StatusTestDuration
PassedcreateNoopSpanSink › records nothing, and its spans have no identity2.2 ms
PassedisSpanIdentity › accepts the trace ID and the span ID of the W3C trace context0.51 ms
PassedisSpanIdentity › rejects missing, malformed and all-zero IDs0.59 ms
PassedcreateOtelSpanSink › starts an open span at its start time in the root context, without the attributes that have no value3 ms
PassedcreateOtelSpanSink › records an ended span in the context of its parent, sampled and remote, with its links1.9 ms
PassedcreateOtelSpanSink › gives an unsampled span the identity sampled: false, and its children the context of an unsampled parent0.58 ms
PassedcreateOtelSpanSink › gives no links option to a span without links1.1 ms
PassedcreatePageViewSpans › starts the span of a view at its start, and ends it at the final report with the values of the vitals1.5 ms
PassedcreatePageViewSpans › ends the span of a view at the start of the next view, and ignores the end of a view that is not open0.45 ms
PassedcreatePageViewSpans › uses Date.now() without a clock3.1 ms
packages/lag/src/support.test.ts13 passed
StatusTestDuration
PassedRateLimiter › permits `limit` actions in each window4.3 ms
PassedstripUrlParameters › removes the query string and the fragment0.65 ms
PassedOTLP JSON encoding › converts milliseconds to a nanosecond string, rounded to microseconds0.36 ms
PassedOTLP JSON encoding › encodes log records as an ExportLogsServiceRequest1.3 ms
PassedOTLP JSON encoding › gives a record the observed time of the input, or the time of the occurrence0.33 ms
PassedOTLP JSON encoding › encodes only safe integers as intValue, and other numbers as doubleValue0.63 ms
Passedevent sinks › the OTel event sink emits a log record with the event name, without empty attributes3.2 ms
Passedevent sinks › gives each event a different body, so that Loki keeps events of the same millisecond0.61 ms
Passedevent sinks › the OTel event sink gives the time of the occurrence to the record2.8 ms
Passedevent sinks › the OTel event sink keeps the time of the call for an occurrence that is too old for Loki, and keeps its time as an attribute1.5 ms
Passedevent sinks › the OTel event sink compares the times with Date.now by default0.59 ms
Passedevent sinks › the OTel event sink leaves out the attributes that are null0.52 ms
Passedevent sinks › the no-op event sink accepts events2.3 ms
packages/lag/src/browser/browser-deps.test.ts22 passed
StatusTestDuration
PassedcreateBrowserDeps › binds each browser function to its object5.1 ms
PassedcreateBrowserDeps › leaves out the deps of an API that the browser does not have0.64 ms
PassedcreateBrowserDeps › uses shared memory only in a cross-origin-isolated page, and only if the option permits it0.96 ms
PassedcreateBrowserDeps › finds the legacy and the standard memory APIs1.4 ms
PassedcreateBrowserDeps › observes the cpu pressure source by default1.2 ms
PassedcreateBrowserDeps › passes the options through1.7 ms
PassedcreateBrowserDeps › uses IndexedDB for the hang journal only with a worker or the peer hang watch, and only if the option permits it1.3 ms
PassedcreateBrowserDeps › marks the reports of the peer hang watch in localStorage, with the conditions of the hang journal0.97 ms
PassedcreateBrowserDeps › uses BroadcastChannel and the Web Locks API for the peer hang watch, if the option permits it3.4 ms
PassedcreateBrowserDeps › uses the crash-report context of the browser where it exists0.54 ms
PassedcreateBrowserDeps › gives setupAllMonitors the monitors that the browser can support14 ms
PassedcreateBrowserDeps › adapts the timer functions of the browser: each one passes the callback and the delay, and gives the handle of the browser0.65 ms
PassedcreateBrowserDeps › leaves out PerformanceObserver when the browser does not have it0.24 ms
PassedcreateBrowserDeps › reads the wall clock from Date.now()0.81 ms
PassedcreateBrowserDeps › gives requestIdleCallback and cancelIdleCallback, bound to the window, only when the browser has both0.58 ms
PassedcreateBrowserDeps › gives MessageChannel with queueMicrotask, and leaves out an API that is not a function0.59 ms
PassedcreateBrowserDeps › leaves out requestAnimationFrame when the browser has no cancelAnimationFrame0.23 ms
PassedcreateBrowserDeps › finds one memory API without the other, and leaves out a memory object that is null0.48 ms
PassedcreateBrowserDeps › uses a crash-report object only when it has a set() function0.28 ms
PassedcreateBrowserDeps › gives FinalizationRegistry and ReportingObserver when the browser has them0.26 ms
PassedcreateBrowserDeps and the shared lifecycle tracker › gives the shared tracker of the page when the globals are the global object0.79 ms
PassedcreateBrowserDeps and the shared lifecycle tracker › gives no shared tracker with sharedLifecycle: false, or for other globals (as in a test)0.35 ms
packages/lag/src/browser/page-source.test.ts8 passed
StatusTestDuration
PassedcreatePageSource › gives the navigation entry, with web-vitals navigation types5 ms
PassedcreatePageSource › uses 0 when the entry has no activationStart0.59 ms
PassedcreatePageSource › ignores an entry with a responseStart that is 0, missing, or not before now0.48 ms
PassedcreatePageSource › gives no entry when the browser has no getEntriesByType or the call fails0.6 ms
PassedcreatePageSource › gives the start times of the hidden visibility-state entries0.31 ms
PassedcreatePageSource › reads the prerender and discard state of the document0.46 ms
PassedcreatePageSource › gives the URL of the document from location.href, and no URL without a location0.71 ms
PassedcreatePageSource › listens to prerenderingchange in the capture phase, and the return value removes the listener2.3 ms
packages/lag/src/instrumented/browser-reports.test.ts4 passed
StatusTestDuration
PassedcreateInstrumentedBrowserReports › counts each report by its type, and sends an event without the query of the source file11 ms
PassedcreateInstrumentedBrowserReports › sends an event without a time when it has no clock3.5 ms
PassedcreateInstrumentedBrowserReports › sends no more than 10 events each minute, but counts all reports0.67 ms
PassedcreateInstrumentedBrowserReports › counts the reports without an event sink0.52 ms
packages/lag/src/instrumented/clock-drift.test.ts4 passed
StatusTestDuration
PassedcreateInstrumentedClockDrift › adds a suspend to the measurement conditions, over the interval in which it occurred12 ms
PassedcreateInstrumentedClockDrift › adds nothing for a clock step5.6 ms
PassedcreateInstrumentedClockDrift › counts a clock jump without an event sink and without measurement conditions1.6 ms
PassedcreateInstrumentedClockDrift › records each kind of jump with the attribute values of the catalog, and events with the attributes of the catalog4.9 ms
packages/lag/src/instrumented/clock-reliability.test.ts3 passed
StatusTestDuration
PassedcreateInstrumentedClockReliability › records the resolution of the clock one time, 5 s after the setup8.1 ms
PassedcreateInstrumentedClockReliability › records nothing when the clock did not advance during the measurement8.4 ms
PassedcreateInstrumentedClockReliability › stop() before the measurement cancels it0.88 ms
packages/lag/src/instrumented/compute-pressure.test.ts3 passed
StatusTestDuration
PassedcreateInstrumentedComputePressure › observes the cpu source each second by default, and records the state ordinal with the source7.6 ms
PassedcreateInstrumentedComputePressure › emits an event for each change of the state of a source, at the time of the record2.7 ms
PassedcreateInstrumentedComputePressure › observes the sources and the sample interval of the dependencies0.32 ms
packages/lag/src/instrumented/drift-lag.test.ts3 passed
StatusTestDuration
PassedcreateInstrumentedDriftLag › records the lag and the baseline of each window, and logs sustained lag through the lag logger62 ms
PassedcreateInstrumentedDriftLag › stop() cancels the windows that wait for evidence3.1 ms
PassedcreateInstrumentedDriftLag with MessageChannel › probes through a message queue, and closes the queue when it stops7.8 ms
packages/lag/src/instrumented/event-timing.test.ts3 passed
StatusTestDuration
PassedcreateInstrumentedEventTiming › records the duration and the three phases of each interaction event, with the interaction type10 ms
PassedcreateInstrumentedEventTiming › records 0 for a phase that the clock rounding makes negative0.7 ms
PassedcreateInstrumentedEventTiming › gives the monitor the interaction count of the page2.6 ms
packages/lag/src/instrumented/frame-timing.test.ts4 passed
StatusTestDuration
PassedcreateInstrumentedFrameTiming › records the time between two frames, and counts the delivered frames and the dropped frames12 ms
PassedcreateInstrumentedFrameTiming › with measurement conditions, waits for late evidence before it records a frame gap of 5 s or more3.2 ms
PassedcreateInstrumentedFrameTiming › with measurement conditions, stops while the page is hidden and starts again when it is visible4.1 ms
PassedcreateInstrumentedFrameTiming › stop() cancels the frame gaps that wait for evidence, and the page lifecycle does not start the monitor again1.4 ms
packages/lag/src/instrumented/idle-availability.test.ts4 passed
StatusTestDuration
PassedcreateInstrumentedIdleAvailability › records the idle time, the gap after the first callback, and counts the callbacks by timeout14 ms
PassedcreateInstrumentedIdleAvailability › with measurement conditions, waits for late evidence before it records a gap of 5 s or more3.6 ms
PassedcreateInstrumentedIdleAvailability › with measurement conditions, stops while the page is hidden and starts again when it is visible1.9 ms
PassedcreateInstrumentedIdleAvailability › stop() cancels the gaps that wait for evidence, and the page lifecycle does not start the monitor again1.5 ms
packages/lag/src/instrumented/lifecycle.test.ts6 passed
StatusTestDuration
PassedcreateInstrumentedLifecycle › counts each transition, and emits an event at the time of the browser event8.8 ms
PassedcreateInstrumentedLifecycle › emits the events without a time when it has no clock, and stops with the machine1.4 ms
PassedcreateInstrumentedLifecycle with spans › records each hidden and frozen period as a span in the current page view, to the next transition1.2 ms
PassedcreateInstrumentedLifecycle with spans › ends the open period at stop(), and records no period after the stop0.41 ms
PassedcreateInstrumentedLifecycle with spans › uses Date.now() without a clock, also at stop(), and starts a new trace without page-view spans2.7 ms
PassedcreateInstrumentedLifecycle with a tracker that the page shares › subscribes to the tracker, and at stop() it unsubscribes but does not dispose of the tracker0.94 ms
packages/lag/src/instrumented/loaf.test.ts12 passed
StatusTestDuration
PassedcreateInstrumentedLoaf › records each frame, and sends an event only for a frame that blocks for 150 ms or more8.3 ms
PassedcreateInstrumentedLoaf › sends no more than 10 events each minute2.2 ms
PassedcreateInstrumentedLoaf › records the frames without an event sink1.2 ms
PassedcreateInstrumentedLoaf › names the longest script in the event, without the query of its URL2.3 ms
PassedcreateInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type classic-script0.58 ms
PassedcreateInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type module-script0.34 ms
PassedcreateInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type event-listener0.34 ms
PassedcreateInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type event-listener0.23 ms
PassedcreateInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type user-callback0.25 ms
PassedcreateInstrumentedLoaf with spans › records a span from the start to the end of each frame that gets an event, in the current page view1.4 ms
PassedcreateInstrumentedLoaf with spans › records no span without a clock, because the frame has no absolute time0.36 ms
PassedcreateInstrumentedLoaf with spans › records the spans without an event sink, with the same limit of 10 each minute0.64 ms
packages/lag/src/instrumented/macrotask-lag.test.ts2 passed
StatusTestDuration
PassedcreateInstrumentedMacrotaskLag › records the time that a zero-delay timeout waited, one time in 5 s13 ms
PassedcreateInstrumentedMacrotaskLag › stop() cancels the samples that wait for evidence2.6 ms
packages/lag/src/instrumented/memory.test.ts3 passed
StatusTestDuration
PassedcreateInstrumentedMemory › records the used heap with its source, and the usage ratio of the legacy source10 ms
PassedcreateInstrumentedMemory › records no usage ratio for the modern source, because it gives no limit3.7 ms
PassedcreateInstrumentedMemory › samples at the interval of the dependencies1.1 ms
packages/lag/src/instrumented/page-view-context.test.ts10 passed
StatusTestDuration
PassedcreateInstrumentedPageViewContext › gives the current page view ID to each receiver, now and at each new view5.5 ms
PassedcreateInstrumentedPageViewContext › adds the attributes of the app, and reads them again at each new view0.48 ms
PassedcreateInstrumentedPageViewContext › logs a failure of the function of the app and continues with the page-view ID2.3 ms
PassedcreateInstrumentedPageViewContext › initializes the crash-report context, sets the view ID, and deletes it on stop4.5 ms
PassedcreateInstrumentedPageViewContext › still sets the context when an other script initialized the crash-report context first2 ms
PassedcreateInstrumentedPageViewContext › logs a failure of the crash-report context at debug level and continues0.71 ms
PassedcreateInstrumentedPageViewContext › still sets the context when initialize() of the crash-report context throws an error3.8 ms
PassedcreateInstrumentedPageViewContext › logs nothing without a crash-report context2.7 ms
PassedcreateInstrumentedPageViewContext with page-view spans › gives the identity of the span of the current view to the receivers, at each new view0.55 ms
PassedcreateInstrumentedPageViewContext with page-view spans › gives no span identity for a span that the SDK did not sample0.4 ms
packages/lag/src/instrumented/page-view-vitals.test.ts16 passed
StatusTestDuration
PassedcreateInstrumentedPageViewVitals › records each vital of a view one time, also when a flush comes after the final report (Firefox and WebKit)12 ms
PassedcreateInstrumentedPageViewVitals › records each vital of a view one time with the event sequence of the specification1 ms
PassedcreateInstrumentedPageViewVitals › records each vital of a view one time when stop() comes after the final report0.86 ms
PassedcreateInstrumentedPageViewVitals › sends events whose deltas add up to the value0.89 ms
PassedcreateInstrumentedPageViewVitals › sends a second event with the change of the value when the value of a view changes, but records the first value only5.3 ms
PassedcreateInstrumentedPageViewVitals › sends the attributes of the semantic conventions with the attribution, and no URL attribute for a view without a URL5 ms
PassedcreateInstrumentedPageViewVitals › makes the LCP final at a trusted click on the window of the dependencies1.3 ms
PassedcreateInstrumentedPageViewVitals › records the vitals without an event sink1.6 ms
PassedcreateInstrumentedPageViewVitals › counts the interactions of the page with performance.interactionCount0.93 ms
PassedcreateInstrumentedPageViewVitals › records the FCP of a restore from the animation frames, with the navigation type of the restore2.3 ms
PassedcreateInstrumentedPageViewVitals › sends a lag.page_view.start event for the load and for each later view, at the start of the view2.1 ms
PassedcreateInstrumentedPageViewVitals › sends each vital at the time of its occurrence, not at the time of the report1 ms
PassedcreateInstrumentedPageViewVitals › observes soft navigations when the dependencies enable them0.55 ms
PassedcreateInstrumentedPageViewVitals › records the vitals of each navigation type with an attribute value that the catalog permits3.2 ms
PassedcreateInstrumentedPageViewVitals with page-view spans › starts the span of the load, and ends it when the page is hidden for the first time, with the values at that time2.8 ms
PassedcreateInstrumentedPageViewVitals with page-view spans › starts a new trace for a restore from the back/forward cache2.8 ms
packages/lag/src/instrumented/peer-hang-watch.test.ts11 passed
StatusTestDuration
PassedcreateInstrumentedPeerHangWatch › records a page that closed during a hang as an abandoned hang, with the context of that page16 ms
PassedcreateInstrumentedPeerHangWatch › takes the record of the worker from the hang journal2.1 ms
PassedcreateInstrumentedPeerHangWatch › holds the lock only while the page is visible2.6 ms
PassedcreateInstrumentedPeerHangWatch › records the hang without an event sink, and stops listening to the lifecycle2.2 ms
PassedcreateInstrumentedPeerHangWatch › records the hang of its own page with the source self, when the page closes at the end of a hang1.2 ms
PassedcreateInstrumentedPeerHangWatch › counts its own hang one time, also when its worker leaves the record in the journal7.9 ms
PassedcreateInstrumentedPeerHangWatch › does not record a hang when the page becomes hidden at the end of a hang1.4 ms
PassedcreateInstrumentedPeerHangWatch › does not record a hang when the page goes into the back/forward cache0.79 ms
PassedcreateInstrumentedPeerHangWatch › makes a page ID when it gets none4.7 ms
PassedcreateInstrumentedPeerHangWatch › gives an empty handle when the construction fails1.1 ms
PassedcreateInstrumentedPeerHangWatch with spans › puts the span of the hang of a closed page into the trace of the page view that hung, with a link to the view that reports it3.6 ms
packages/lag/src/instrumented/scheduling-fairness.test.ts4 passed
StatusTestDuration
PassedcreateInstrumentedSchedulingFairness › records the latency of each of the three primitives of a cycle11 ms
PassedcreateInstrumentedSchedulingFairness › with measurement conditions, validates a cycle by its longest latency3.7 ms
PassedcreateInstrumentedSchedulingFairness › with measurement conditions, stops while the page is hidden and starts again when it is visible1.8 ms
PassedcreateInstrumentedSchedulingFairness › stop() cancels the cycles that wait for evidence, and the page lifecycle does not start the monitor again1.6 ms
packages/lag/src/instrumented/shared-liveness.test.ts3 passed
StatusTestDuration
PassedcreateInstrumentedSharedLiveness › records the duration of each block that the worker saw7.9 ms
PassedcreateInstrumentedSharedLiveness › with measurement conditions, stops the watcher while the page is hidden, and does not record a block that overlaps the hidden period5.4 ms
PassedcreateInstrumentedSharedLiveness › stop() stops the watcher, cancels the blocks that wait for evidence, and ends the pause2.6 ms
packages/lag/src/instrumented/shared.test.ts9 passed
StatusTestDuration
PassedvalidatedRecorder › records each sample at once with its window, without measurement conditions7.2 ms
PassedvalidatedRecorder › gives each sample to a validator of the measurement conditions, and dispose() cancels the samples that wait2.7 ms
PassedcreateHandle › gives a handle with the monitor and the stop function of the build function1.6 ms
Passedthe span helpers › pageViewSpanOf reads the span of the page view from the context attributes, if it is valid0.74 ms
Passedthe span helpers › puts the span of an abandoned hang into the trace of the page that hung, with a link to the view that reports it1.9 ms
Passedthe span helpers › gives no link when the page that hung is this view, or when this page has no open view0.98 ms
Passedthe span helpers › puts a hang into the current view when the record of the page that hung has no span, or when there is no record0.49 ms
Passedthe span helpers › recordSpan records a span of a monitor in the current view, or as a new trace without an open view0.77 ms
Passedthe span helpers › does nothing without a span sink0.99 ms
packages/lag/src/instrumented/throttle-detector.test.ts1 passed
StatusTestDuration
PassedcreateInstrumentedThrottleDetector › counts each calibration round with the attribute throttled14 ms
packages/lag/src/instrumented/worker-lag.test.ts21 passed
StatusTestDuration
PassedcreateInstrumentedWorkerLag with a hang journal › reports the hangs that earlier pages did not survive, and removes their records16 ms
PassedcreateInstrumentedWorkerLag with a hang journal › puts the span of an abandoned hang into the trace of the page view that hung, with a link to this view1.5 ms
PassedcreateInstrumentedWorkerLag with a hang journal › sends its page ID to the worker1.8 ms
PassedcreateInstrumentedWorkerLag with a hang journal › sends no page ID without a journal, so that the worker writes no journal either1.6 ms
PassedcreateInstrumentedWorkerLag with a hang journal › reports nothing after stop()0.87 ms
PassedcreateInstrumentedWorkerLag: two pages of the origin start at the same time (a session restore) › reports an abandoned hang one time with a journal in memory11 ms
PassedcreateInstrumentedWorkerLag: two pages of the origin start at the same time (a session restore) › reports an abandoned hang one time with IndexedDB209 ms
PassedcreateInstrumentedWorkerLag with a real worker handler › counts a hang that ends while the page is hidden (the user changed the tab during the hang)12 ms
PassedcreateInstrumentedWorkerLag with a real worker handler and a main thread that is not blocked › counts no hang in 60 s, also with a heartbeat interval of the hang threshold or more9.4 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › gives the hang report target to the worker1.6 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › counts a hang that the worker ended, with the outcome ended, and records its duration3.4 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › handles a system stall and the end of a hang without measurement conditions and without an event sink1.3 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › stop() cancels the heartbeat delays that wait for evidence1.2 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › uses Date.now() to find the abandoned hangs when the dependencies have no wall clock1 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › reports an abandoned hang without an event sink0.93 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › does not report a hang whose record another page updated after the read, because the hang continues1.1 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › skips a record that another page took first1.1 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › puts a record back for the next page when the monitor stops while it takes the record1.1 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › removes the record of a hang that the peer hang watch reported, but does not count the hang again4.1 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › removes the old marks of pages without a record, and keeps the marks that the journal can still need1.1 ms
PassedcreateInstrumentedWorkerLag with the messages of a worker › logs a warning when it cannot read the hang journal1 ms
packages/lag/src/vitals/PageViewVitals.test.ts74 passed
StatusTestDuration
PassedPageViewVitals › a load › reports TTFB, FCP, LCP, INP and CLS when the page becomes hidden20 ms
PassedPageViewVitals › a load › keeps the last LCP candidate of the browser, also when its start time (the load time) is earlier2.1 ms
PassedPageViewVitals › a load › makes the LCP final at a click that gives no Event Timing entry, as the DOM listener of web-vitals does1.1 ms
PassedPageViewVitals › a load › makes the LCP final at a key press that gives no Event Timing entry0.66 ms
PassedPageViewVitals › a load › ignores a synthetic click (isTrusted false), and removes its listeners at stop()1.1 ms
PassedPageViewVitals › a load › ignores the LCP candidates that paint after the first click or key press, as web-vitals does0.7 ms
PassedPageViewVitals › a load › counts the interactions of the load from the start of the page, also when the monitors start later0.73 ms
PassedPageViewVitals › a load › observes the event entries with the smallest threshold that browsers permit0.49 ms
PassedPageViewVitals › a load › reports the final values when the page terminates1.5 ms
PassedPageViewVitals › a load › ignores the paints after the page was hidden for the first time1 ms
PassedPageViewVitals › a load › takes the first hidden time from the visibility-state entries1.3 ms
PassedPageViewVitals › a load › thinks that a page that is hidden at the start was hidden from the start0.45 ms
PassedPageViewVitals › a load › uses the navigation type restore for a page that the browser discarded0.86 ms
PassedPageViewVitals › a load › uses navigate and gives no TTFB without a navigation entry0.8 ms
PassedPageViewVitals › a load › works without a page source0.68 ms
PassedPageViewVitals › a load › gets the buffered FCP and layout shifts, also when observe() delivers them at once (old Safari: false)1.5 ms
PassedPageViewVitals › a load › gets the buffered FCP and layout shifts, also when observe() delivers them at once (old Safari: true)0.78 ms
PassedPageViewVitals › a load › makes no report at a checkpoint when there are no values0.5 ms
PassedPageViewVitals › a prerendered page › starts at the activation and measures the load metrics from the activation2.1 ms
PassedPageViewVitals › a restore from the back/forward cache › ends the view and starts a new one, with TTFB 0 and paint times from two animation frames2.6 ms
PassedPageViewVitals › a restore from the back/forward cache › starts a new view with the event sequence of Chromium, in which the page is visible before pageshow1.7 ms
PassedPageViewVitals › a restore from the back/forward cache › gives an INP of 8 ms when there were interactions after the restore but no entries0.54 ms
PassedPageViewVitals › soft navigations › are off by default, as in web-vitals0.42 ms
PassedPageViewVitals › soft navigations › start a new view with TTFB 0, FCP from the presentation time and LCP from the interaction paints1.6 ms
PassedPageViewVitals › soft navigations › gives the paints that the browser did not deliver yet to the new view, after the largest paint of the entry0.83 ms
PassedPageViewVitals › soft navigations › gives an interaction after the start of the soft navigation to the new view, also when its observer did not deliver it yet0.76 ms
PassedPageViewVitals › soft navigations › keeps an entry that the browser delivered before the soft-navigation entry in the earlier view, also when it starts later, as web-vitals does0.74 ms
PassedPageViewVitals › soft navigations › ignores the paints of the navigation after the next click, as web-vitals makes the LCP final at the next input0.59 ms
PassedPageViewVitals › soft navigations › need the soft-navigation and interaction-contentful-paint entry types0.41 ms
PassedPageViewVitals › checkpoints › process the entries that the browser has not delivered yet0.47 ms
PassedPageViewVitals › checkpoints › split the pending entries at a pending soft navigation, in the sequence of their start times0.97 ms
PassedPageViewVitals › checkpoints › log an error from the report function and continue1.7 ms
PassedPageViewVitals › subscribe() › calls the listener at each new view, until the listener is removed1 ms
PassedPageViewVitals › subscribe() › logs an error from a listener and continues0.69 ms
PassedPageViewVitals › flush() › reports the current values now, as a checkpoint that is not final0.62 ms
PassedPageViewVitals › flush() › does nothing before the activation of a prerendered page or after stop()0.82 ms
PassedPageViewVitals › stop() › reports the final values, stops the observers and ignores later changes0.76 ms
PassedPageViewVitals › stop() › gives no value for a vital whose entry type the browser does not have, as web-vitals0.61 ms
PassedPageViewVitals › stop() › makes no observer for an entry type that the browser does not have, and no warning0.69 ms
PassedPageViewVitals › view IDs › makes an ID of the form lag-<time>-<13 random digits> without an ID function, and a new ID for each view4.7 ms
PassedPageViewVitals › rules of the load metrics › uses the describeNode function of the dependencies for the attribution0.72 ms
PassedPageViewVitals › rules of the load metrics › describes a node with the selector of web-vitals when the dependencies have no describeNode function1.2 ms
PassedPageViewVitals › rules of the load metrics › ignores a first-paint entry: only first-contentful-paint gives FCP0.71 ms
PassedPageViewVitals › rules of the load metrics › ignores a paint at the time at which the page became hidden, as web-vitals does0.57 ms
PassedPageViewVitals › rules of the load metrics › keeps the first hidden time when the page becomes hidden again0.44 ms
PassedPageViewVitals › rules of the load metrics › takes the earliest hidden time of the visibility-state entries0.5 ms
PassedPageViewVitals › rules of the load metrics › thinks that a page that is hidden at the start was hidden from the start, also without a page source0.5 ms
PassedPageViewVitals › rules of the load metrics › ignores the hidden times before the activation of a prerendered page0.52 ms
PassedPageViewVitals › rules of the load metrics › counts a hidden time at the activation of a prerendered page, as web-vitals does0.34 ms
PassedPageViewVitals › rules of the load metrics › uses the navigation type prerender for a page that the browser activated before the monitors started0.4 ms
PassedPageViewVitals › rules of the load metrics › makes the LCP final at a key press1.4 ms
PassedPageViewVitals › rules of the load metrics › does not make the LCP final at a pointer event without a click0.58 ms
PassedPageViewVitals › rules of the load metrics › processes the entries that the other observers did not deliver yet before a later entry0.53 ms
PassedPageViewVitals › rules of the load metrics › counts the first input for INP, also when the event entries do not contain it0.55 ms
PassedPageViewVitals › rules of the load metrics › gives FCP and LCP entries only to the load: a restored view gets these values from the animation frames0.47 ms
PassedPageViewVitals › rules of soft navigations › observes no soft navigations when the browser gives no list of supported entry types0.37 ms
PassedPageViewVitals › rules of soft navigations › does not make the LCP final at the interaction that started the soft navigation0.42 ms
PassedPageViewVitals › rules of soft navigations › does not make the LCP of a soft navigation final at an input at the start time of the navigation0.75 ms
PassedPageViewVitals › rules of soft navigations › ignores the paints of other interactions, also when they come last0.42 ms
PassedPageViewVitals › rules of soft navigations › counts an interaction paint without an interaction ID for the current soft navigation0.48 ms
PassedPageViewVitals › rules of soft navigations › ignores an interaction paint before the first soft navigation0.43 ms
PassedPageViewVitals › rules of soft navigations › ignores an interaction paint at or after the time at which the page became hidden0.6 ms
PassedPageViewVitals › rules of soft navigations › starts a view for an entry without a largest paint, and logs no error0.79 ms
PassedPageViewVitals › rules of soft navigations › logs no error for an interaction paint without a paint0.45 ms
PassedPageViewVitals › rules of soft navigations › does not take the paint times of a soft navigation from the animation frames0.64 ms
PassedPageViewVitals › rules of restores and of the end of a view › gives no TTFB to a restored view when the load had no navigation entry0.36 ms
PassedPageViewVitals › rules of restores and of the end of a view › gives the pending entries before a restore to the view that ends, and the other entries to the new view0.78 ms
PassedPageViewVitals › rules of restores and of the end of a view › gives a restored view the URL of the document at the restore, without the query string and the fragment0.62 ms
PassedPageViewVitals › rules of restores and of the end of a view › gives a restored view the URL of the load when the page source gives no URL0.46 ms
PassedPageViewVitals › rules of restores and of the end of a view › gives a restored view no URL when the load had no URL0.77 ms
PassedPageViewVitals › rules of restores and of the end of a view › makes no report when a prerendered page terminates before the activation0.43 ms
PassedPageViewVitals › rules of restores and of the end of a view › makes no report after the final report of a view, also at a later lifecycle event0.68 ms
PassedPageViewVitals › rules of restores and of the end of a view › observes each entry type one time, also when the page source reports the activation two times0.47 ms
PassedPageViewVitals › rules of restores and of the end of a view › stop() removes its activation listener from the page source2.7 ms
packages/lag/src/vitals/ViewCollector.test.ts35 passed
StatusTestDuration
PassedViewCollector › INP › is 0 for a first input with the duration 0, as in web-vitals4.1 ms
PassedViewCollector › INP › counts the interactions of a view that starts at 0 (the load) from 0, and of a later view from its start0.71 ms
PassedViewCollector › INP › is the longest interaction when there are fewer than 500.3 ms
PassedViewCollector › INP › uses the longest entry of each interaction0.29 ms
PassedViewCollector › INP › counts the first-input entry as a candidate, because the browser always delivers it0.31 ms
PassedViewCollector › INP › ignores entries without an interaction ID and entries from before the view0.26 ms
PassedViewCollector › INP › gives the target, the type and the three phases of the INP interaction1.2 ms
PassedViewCollector › INP › caps the processing at the next paint, for example after alert()0.38 ms
PassedViewCollector › INP › spans the processing over the entries of the interaction in the same frame0.37 ms
PassedViewCollector › INP › leaves out the interaction that started a soft navigation, also when its entry comes late0.33 ms
PassedViewCollector › INP › counts the processing of other events in the frame, as web-vitals does1.2 ms
PassedViewCollector › INP › starts the processing at the interaction at the earliest0.3 ms
PassedViewCollector › INP › leaves out the entries of the interaction that end in a different frame0.25 ms
PassedViewCollector › INP › keeps the entry details only for the interactions that can be INP2.6 ms
PassedViewCollector › INP › gives 8 ms after a restore when there were interactions but no entries0.41 ms
PassedViewCollector › CLS › reports a load only after FCP, and then includes the shifts from before FCP0.62 ms
PassedViewCollector › CLS › reports a restore and a soft navigation from the start, at 00.27 ms
PassedViewCollector › CLS › ignores shifts after recent input and shifts from before the view0.2 ms
PassedViewCollector › CLS › names the largest shift of the worst session window0.33 ms
PassedViewCollector › CLS › makes the selector of the largest shift at the time of the shift, while the node is in the document1.6 ms
PassedViewCollector › CLS › names the first source with an element node, as web-vitals does, also when a text node comes first0.23 ms
PassedViewCollector › CLS › names the first source when no source has an element node, as web-vitals does0.31 ms
PassedViewCollector › the time of each value › is the time of the occurrence that gave the value, also in a view that starts later0.47 ms
PassedViewCollector › the time of each value › is undefined for an INP estimate and for a CLS without shifts0.29 ms
PassedViewCollector › paint and network metrics › keeps the first FCP, the last LCP, and never a value below 00.31 ms
PassedViewCollector › paint and network metrics › leaves out the vitals that have no value0.2 ms
PassedViewCollector › rules of the entries › counts an event and a layout shift that start at the start of the view0.27 ms
PassedViewCollector › rules of the entries › gives 8 ms after a soft navigation when there were interactions but no entries0.23 ms
PassedViewCollector › rules of the entries › keeps no more than 16 entries of one interaction for the attribution0.28 ms
PassedViewCollector › rules of the entries › uses the longest entry of an interaction for the attribution, and the first one of entries with the same duration, as web-vitals does0.28 ms
PassedViewCollector › rules of the entries › puts the entries whose render times are 8 ms apart into one frame0.19 ms
PassedViewCollector › rules of the entries › gives no interaction target when the target of the event is null or when no entry has a target0.28 ms
PassedViewCollector › rules of the entries › names the first source with an element node, also after a source without a node0.23 ms
PassedViewCollector › rules of the entries › gives no CLS target when the largest shift has no source0.2 ms
PassedViewCollector › rules of the entries › keeps an LCP that paints at the time at which the LCP became final, and ignores a later paint0.24 ms
packages/lag/src/vitals/selector.test.ts7 passed
StatusTestDuration
PasseddescribeNode › joins the parts from the root down with >3.3 ms
PasseddescribeNode › stops at the first element with an ID0.53 ms
PasseddescribeNode › keeps the selector at 100 characters or less, and gives the deepest part when no part fits0.59 ms
PasseddescribeNode › names text nodes in upper case without the number sign0.31 ms
PasseddescribeNode › gives an empty string for an empty value or an object that throws0.39 ms
PasseddescribeNode › describes an element without a node name by its classes0.23 ms
PasseddescribeNode › keeps a selector of exactly the maximum length, and stops before a longer one0.66 ms
packages/lag/src/vitals/types.test.ts5 passed
StatusTestDuration
PassedrateVital › rates INP as good up to 200 and as poor above 500, as web-vitals does3.6 ms
PassedrateVital › rates CLS as good up to 0.1 and as poor above 0.25, as web-vitals does0.47 ms
PassedrateVital › rates LCP as good up to 2500 and as poor above 4000, as web-vitals does0.31 ms
PassedrateVital › rates FCP as good up to 1800 and as poor above 3000, as web-vitals does0.32 ms
PassedrateVital › rates TTFB as good up to 800 and as poor above 1800, as web-vitals does0.57 ms

@lag/integration-tests: browser tests in chromium

Suite integration-bfcache-chromium. 2 passed. Duration 8.61 s.

packages/lag-integration-tests/src/bfcache/back-forward-cache.test.ts2 passed
StatusTestDuration
Passedthe back/forward cache with the peer hang watch › removes a page with an open channel of the watch from the cache: the check of this test operates3.78 s
Passedthe back/forward cache with the peer hang watch › keeps a page with the library in the cache, and the page watches again after the restore4.84 s

@lag/integration-tests: browser tests in chrome

Suite integration-browser-chrome. 55 passed, 2 skipped. Duration 3 min 47 s.

packages/lag-integration-tests/src/browser-apis.test.ts6 passed
StatusTestDuration
PassedMonitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports80 ms
PassedMonitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source2.02 s
PassedMonitors of engine-specific APIs › the page source reads the visibility-state entries0.3 ms
PassedMonitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events0.3 ms
PassedMonitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page1.01 s
PassedMonitors of engine-specific APIs › MemoryMonitor reads performance.memory51 ms
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
StatusTestDuration
PassedFacts of the engines › gives the entry types of the research1.3 ms
PassedFacts of the engines › starts the listeners at window in the order of experiment E10.4 ms
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
StatusTestDuration
PassedDriftLag accuracy › reports approximately 0 on an idle page and the length of a block4.31 s
packages/lag-integration-tests/src/drift-load.test.ts2 passed
StatusTestDuration
PassedDriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load8.43 s
PassedDriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load8.44 s
packages/lag-integration-tests/src/hang-journal.test.ts1 passed
StatusTestDuration
Passedhang journal in a browser › keeps the record of a hang that did not end7.02 s
packages/lag-integration-tests/src/lag-monitors.test.ts13 passed
StatusTestDuration
PassedLag Monitor Integration › registers a monitor for each API that the browser has, and no other8.8 ms
PassedLag Monitor Integration › DriftLag measures a blocked main thread711 ms
PassedLag Monitor Integration › the worker measures main-thread blocking from outside the main thread1.31 s
PassedLag Monitor Integration › FrameTimingMonitor records frames0.6 ms
PassedLag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports654 ms
PassedLag Monitor Integration › PageViewVitals measures the load of the page and a real click808 ms
PassedLag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle1.51 s
PassedLag Monitor Integration › MemoryMonitor samples the heap through performance.memory0.5 ms
PassedLag Monitor Integration › ClockReliabilityChecker reports the clock resolution0.9 ms
PassedLag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure1.12 s
PassedLag Monitor Integration › emits a synthetic log to verify the Loki bridge0.4 ms
PassedLag Monitor Integration › stop() halts all reporting1.75 s
PassedLag Monitor Integration › flushes metrics to the OTLP endpoint8.41 s
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
StatusTestDuration
PassedLifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier0.8 ms
PassedLifecycleStateMachine in a browser › uses the time of the event for the transition0.7 ms
PassedLifecycleStateMachine in a browser › removes every listener when it is disposed0.2 ms
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
StatusTestDuration
Passedthe peer hang watch in a browser › reports a page that closes during a hang: the other page reports it, or the page itself at its close12.47 s
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
StatusTestDuration
Passedexperiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held8.01 s
Passedexperiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang2.76 s
packages/lag-integration-tests/src/soft-navigation.test.ts1 passed
StatusTestDuration
PassedPageViewVitals with a real soft navigation › starts a new page view with its own LCP, and keeps the click in the INP of the first view2.87 s
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
StatusTestDuration
PassedLag Monitor Stress Tests › light load profile completes and reports few events20.63 s
PassedLag Monitor Stress Tests › moderate load profile triggers measurable lag19.59 s
PassedLag Monitor Stress Tests › heavy load profile drives the system hard18.92 s
PassedLag Monitor Stress Tests › bursty load produces both small and huge events (bimodal)18.87 s
PassedLag Monitor Stress Tests › evolutionary load drifts upward over time19.04 s
PassedLag Monitor Stress Tests › kitchen sink profile exercises all generators18.63 s
SkippedLag Monitor Stress Tests › exports the heavy profile to Mimir
Skipped: Needs the Grafana stack: run pnpm test:e2e.
–
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
StatusTestDuration
PassedPageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly508 ms
PassedPageViewVitals agrees with web-vitals › CLS agrees exactly1.7 s
SkippedPageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does
Skipped: This browser measures layout shifts.
–
PassedPageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases1.5 s
packages/lag-integration-tests/src/worker-io.test.ts11 passed
StatusTestDuration
Passedthe input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit2.03 s
Passedthe input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit2.02 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a service worker complete during the block, except in WebKit3.02 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a shared worker complete during the block, except in WebKit2.96 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation completes during the block2.29 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation completes during the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation completes during the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation completes during the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation completes during the block2.21 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation completes during the block2.21 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives during the block2.53 s
packages/lag-integration-tests/src/worker.test.ts3 passed
StatusTestDuration
PassedWorker Lag Monitor Integration › receives heartbeats from a real Web Worker1.51 s
PassedWorker Lag Monitor Integration › detects main thread blocking1.6 s
PassedWorker Lag Monitor Integration › stops and restarts the worker's heartbeat loop1.2 s

@lag/integration-tests: browser tests in chromium

Suite integration-browser-chromium. 54 passed, 3 skipped. Duration 3 min 44 s.

packages/lag-integration-tests/src/browser-apis.test.ts6 passed
StatusTestDuration
PassedMonitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports76 ms
PassedMonitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source2.03 s
PassedMonitors of engine-specific APIs › the page source reads the visibility-state entries1.1 ms
PassedMonitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events0.7 ms
PassedMonitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page1 s
PassedMonitors of engine-specific APIs › MemoryMonitor reads performance.memory51 ms
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
StatusTestDuration
PassedFacts of the engines › gives the entry types of the research2.7 ms
PassedFacts of the engines › starts the listeners at window in the order of experiment E10.9 ms
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
StatusTestDuration
PassedDriftLag accuracy › reports approximately 0 on an idle page and the length of a block4.31 s
packages/lag-integration-tests/src/drift-load.test.ts2 passed
StatusTestDuration
PassedDriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load8.42 s
PassedDriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load8.42 s
packages/lag-integration-tests/src/hang-journal.test.ts1 passed
StatusTestDuration
Passedhang journal in a browser › keeps the record of a hang that did not end7.01 s
packages/lag-integration-tests/src/lag-monitors.test.ts13 passed
StatusTestDuration
PassedLag Monitor Integration › registers a monitor for each API that the browser has, and no other10 ms
PassedLag Monitor Integration › DriftLag measures a blocked main thread661 ms
PassedLag Monitor Integration › the worker measures main-thread blocking from outside the main thread1.32 s
PassedLag Monitor Integration › FrameTimingMonitor records frames0.8 ms
PassedLag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports663 ms
PassedLag Monitor Integration › PageViewVitals measures the load of the page and a real click752 ms
PassedLag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle1.62 s
PassedLag Monitor Integration › MemoryMonitor samples the heap through performance.memory0.4 ms
PassedLag Monitor Integration › ClockReliabilityChecker reports the clock resolution1.4 ms
PassedLag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure1.11 s
PassedLag Monitor Integration › emits a synthetic log to verify the Loki bridge0.3 ms
PassedLag Monitor Integration › stop() halts all reporting1.75 s
PassedLag Monitor Integration › flushes metrics to the OTLP endpoint8.88 s
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
StatusTestDuration
PassedLifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier0.9 ms
PassedLifecycleStateMachine in a browser › uses the time of the event for the transition0.6 ms
PassedLifecycleStateMachine in a browser › removes every listener when it is disposed0.2 ms
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
StatusTestDuration
Passedthe peer hang watch in a browser › reports a page that closes during a hang: the other page reports it, or the page itself at its close12.97 s
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
StatusTestDuration
Passedexperiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held7.9 s
Passedexperiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang2.62 s
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
StatusTestDuration
SkippedPageViewVitals with a real soft navigation › starts a new page view with its own LCP, and keeps the click in the INP of the first view
Skipped: This browser has no soft-navigation entries.
–
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
StatusTestDuration
PassedLag Monitor Stress Tests › light load profile completes and reports few events20.19 s
PassedLag Monitor Stress Tests › moderate load profile triggers measurable lag18.29 s
PassedLag Monitor Stress Tests › heavy load profile drives the system hard18.54 s
PassedLag Monitor Stress Tests › bursty load produces both small and huge events (bimodal)18.58 s
PassedLag Monitor Stress Tests › evolutionary load drifts upward over time18.42 s
PassedLag Monitor Stress Tests › kitchen sink profile exercises all generators19.06 s
SkippedLag Monitor Stress Tests › exports the heavy profile to Mimir
Skipped: Needs the Grafana stack: run pnpm test:e2e.
–
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
StatusTestDuration
PassedPageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly583 ms
PassedPageViewVitals agrees with web-vitals › CLS agrees exactly1.69 s
SkippedPageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does
Skipped: This browser measures layout shifts.
–
PassedPageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases1.43 s
packages/lag-integration-tests/src/worker-io.test.ts11 passed
StatusTestDuration
Passedthe input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit2.02 s
Passedthe input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit2.01 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a service worker complete during the block, except in WebKit2.92 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a shared worker complete during the block, except in WebKit2.9 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation completes during the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation completes during the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation completes during the block2.21 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation completes during the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation completes during the block2.21 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation completes during the block2.23 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives during the block2.52 s
packages/lag-integration-tests/src/worker.test.ts3 passed
StatusTestDuration
PassedWorker Lag Monitor Integration › receives heartbeats from a real Web Worker1.5 s
PassedWorker Lag Monitor Integration › detects main thread blocking1.6 s
PassedWorker Lag Monitor Integration › stops and restarts the worker's heartbeat loop1.2 s

@lag/integration-tests: browser tests in firefox

Suite integration-browser-firefox. 47 passed, 10 skipped. Duration 3 min 38 s.

packages/lag-integration-tests/src/browser-apis.test.ts1 passed, 5 skipped
StatusTestDuration
SkippedMonitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports
Skipped: Layout Instability (the layout-shift entry type, CLS) is Chromium-only.
–
SkippedMonitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source
Skipped: The Compute Pressure API (PressureObserver) is Chromium-only.
–
SkippedMonitors of engine-specific APIs › the page source reads the visibility-state entries
Skipped: The visibility-state entry type is Chromium-only.
–
SkippedMonitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events
Skipped: The Page Lifecycle freeze and resume events are Chromium-only.
–
PassedMonitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page1 s
SkippedMonitors of engine-specific APIs › MemoryMonitor reads performance.memory
Skipped: performance.memory is Chromium-only.
–
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
StatusTestDuration
PassedFacts of the engines › gives the entry types of the research2 ms
PassedFacts of the engines › starts the listeners at window in the order of experiment E11 ms
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
StatusTestDuration
PassedDriftLag accuracy › reports approximately 0 on an idle page and the length of a block4.32 s
packages/lag-integration-tests/src/drift-load.test.ts2 passed
StatusTestDuration
PassedDriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load8.42 s
PassedDriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load8.42 s
packages/lag-integration-tests/src/hang-journal.test.ts1 passed
StatusTestDuration
Passedhang journal in a browser › keeps the record of a hang that did not end7.02 s
packages/lag-integration-tests/src/lag-monitors.test.ts11 passed, 2 skipped
StatusTestDuration
PassedLag Monitor Integration › registers a monitor for each API that the browser has, and no other4 ms
PassedLag Monitor Integration › DriftLag measures a blocked main thread656 ms
PassedLag Monitor Integration › the worker measures main-thread blocking from outside the main thread1.31 s
PassedLag Monitor Integration › FrameTimingMonitor records frames1 ms
SkippedLag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports
Skipped: Long Animation Frames (the long-animation-frame entry type) are Chromium-only.
–
PassedLag Monitor Integration › PageViewVitals measures the load of the page and a real click814 ms
PassedLag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle2.23 s
SkippedLag Monitor Integration › MemoryMonitor samples the heap through performance.memory
Skipped: performance.memory is Chromium-only.
–
PassedLag Monitor Integration › ClockReliabilityChecker reports the clock resolution2 ms
PassedLag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure1.08 s
PassedLag Monitor Integration › emits a synthetic log to verify the Loki bridge13 ms
PassedLag Monitor Integration › stop() halts all reporting1.77 s
PassedLag Monitor Integration › flushes metrics to the OTLP endpoint9.24 s
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
StatusTestDuration
PassedLifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier2 ms
PassedLifecycleStateMachine in a browser › uses the time of the event for the transition1 ms
PassedLifecycleStateMachine in a browser › removes every listener when it is disposed1 ms
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
StatusTestDuration
Passedthe peer hang watch in a browser › reports a page that closes during a hang: the other page reports it, or the page itself at its close10.57 s
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
StatusTestDuration
Passedexperiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held8.14 s
Passedexperiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang2.49 s
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
StatusTestDuration
SkippedPageViewVitals with a real soft navigation › starts a new page view with its own LCP, and keeps the click in the INP of the first view
Skipped: This browser has no soft-navigation entries.
–
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
StatusTestDuration
PassedLag Monitor Stress Tests › light load profile completes and reports few events20.28 s
PassedLag Monitor Stress Tests › moderate load profile triggers measurable lag18.23 s
PassedLag Monitor Stress Tests › heavy load profile drives the system hard18.32 s
PassedLag Monitor Stress Tests › bursty load produces both small and huge events (bimodal)18.09 s
PassedLag Monitor Stress Tests › evolutionary load drifts upward over time17.93 s
PassedLag Monitor Stress Tests › kitchen sink profile exercises all generators17.61 s
SkippedLag Monitor Stress Tests › exports the heavy profile to Mimir
Skipped: Needs the Grafana stack: run pnpm test:e2e.
–
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
StatusTestDuration
PassedPageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly518 ms
SkippedPageViewVitals agrees with web-vitals › CLS agrees exactly
Skipped: Layout Instability (the layout-shift entry type, CLS) is Chromium-only.
–
PassedPageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does1 ms
PassedPageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases1.64 s
packages/lag-integration-tests/src/worker-io.test.ts11 passed
StatusTestDuration
Passedthe input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit2.05 s
Passedthe input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit2.04 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a service worker complete during the block, except in WebKit3.03 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a shared worker complete during the block, except in WebKit2.91 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation completes during the block2.25 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation completes during the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation completes during the block2.23 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation completes during the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation waits for the end of the block2.24 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation waits for the end of the block2.25 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives after the block2.55 s
packages/lag-integration-tests/src/worker.test.ts3 passed
StatusTestDuration
PassedWorker Lag Monitor Integration › receives heartbeats from a real Web Worker1.51 s
PassedWorker Lag Monitor Integration › detects main thread blocking1.61 s
PassedWorker Lag Monitor Integration › stops and restarts the worker's heartbeat loop1.21 s

@lag/integration-tests: browser tests in ios

Suite integration-browser-ios. 1 failed, 40 passed, 16 skipped. Duration 3 min 30 s.

packages/lag-integration-tests/src/browser-apis.test.ts6 skipped
StatusTestDuration
SkippedMonitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports
Skipped: Layout Instability (the layout-shift entry type, CLS) is Chromium-only.
–
SkippedMonitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source
Skipped: The Compute Pressure API (PressureObserver) is Chromium-only.
–
SkippedMonitors of engine-specific APIs › the page source reads the visibility-state entries
Skipped: The visibility-state entry type is Chromium-only.
–
SkippedMonitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events
Skipped: The Page Lifecycle freeze and resume events are Chromium-only.
–
SkippedMonitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page
Skipped: requestIdleCallback is not in WebKit.
–
SkippedMonitors of engine-specific APIs › MemoryMonitor reads performance.memory
Skipped: performance.memory is Chromium-only.
–
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
StatusTestDuration
PassedFacts of the engines › gives the entry types of the research4 ms
PassedFacts of the engines › starts the listeners at window in the order of experiment E10 ms
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
StatusTestDuration
PassedDriftLag accuracy › reports approximately 0 on an idle page and the length of a block4.36 s
packages/lag-integration-tests/src/drift-load.test.ts1 failed, 1 passed
StatusTestDuration
PassedDriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load8.47 s
FailedDriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load
assert@http://127.0.0.1:51841/node_modules/.vite/vitest/0f8d25735ff76a079d6c88c1e05650b7dd4f02ee/deps/vitest___@vitest_expect___chai.js:1447:31
@http://127.0.0.1:51841/@fs/Users/runner/work/lag/lag/node_modules/.pnpm/@vitest+expect@4.1.2/node_modules/@vitest/expect/dist/index.js:1155:20
@http://127.0.0.1:51841/node_modules/.vite/vitest/0f8d25735ff76a079d6c88c1e05650b7dd4f02ee/deps/vitest___@vitest_expect___chai.js:1618:30
@[native code]
measureLoad@http://127.0.0.1:51841/Users/runner/work/lag/lag/packages/lag-integration-tests/src/drift-load.test.ts:87:34
8.5 s
packages/lag-integration-tests/src/hang-journal.test.ts1 skipped
StatusTestDuration
Skippedhang journal in a browser › keeps the record of a hang that did not end
Skipped: This browser completes the IndexedDB requests of a worker on the main thread (WebKit), thus the worker cannot write the record during the hang.
–
packages/lag-integration-tests/src/lag-monitors.test.ts10 passed, 3 skipped
StatusTestDuration
PassedLag Monitor Integration › registers a monitor for each API that the browser has, and no other11 ms
PassedLag Monitor Integration › DriftLag measures a blocked main thread831 ms
PassedLag Monitor Integration › the worker measures main-thread blocking from outside the main thread1.31 s
PassedLag Monitor Integration › FrameTimingMonitor records frames0 ms
SkippedLag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports
Skipped: Long Animation Frames (the long-animation-frame entry type) are Chromium-only.
–
SkippedLag Monitor Integration › PageViewVitals measures the load of the page and a real click
Skipped: In the iOS Simulator, the click of safaridriver gives no INP.
–
PassedLag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle2.24 s
SkippedLag Monitor Integration › MemoryMonitor samples the heap through performance.memory
Skipped: performance.memory is Chromium-only.
–
PassedLag Monitor Integration › ClockReliabilityChecker reports the clock resolution0 ms
PassedLag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure1.09 s
PassedLag Monitor Integration › emits a synthetic log to verify the Loki bridge1 ms
PassedLag Monitor Integration › stop() halts all reporting1.76 s
PassedLag Monitor Integration › flushes metrics to the OTLP endpoint8.87 s
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
StatusTestDuration
PassedLifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier2 ms
PassedLifecycleStateMachine in a browser › uses the time of the event for the transition1 ms
PassedLifecycleStateMachine in a browser › removes every listener when it is disposed1 ms
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 skipped
StatusTestDuration
Skippedthe peer hang watch in a browser › reports a page that closes during a hang: the other page reports it, or the page itself at its close
Skipped: Safari on iOS operates only the visible tab: the peer page becomes hidden when the test page is visible again.
–
packages/lag-integration-tests/src/peer-tab.test.ts1 passed, 1 skipped
StatusTestDuration
Skippedexperiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held
Skipped: Safari on iOS operates only the visible tab: the peer page sends no heartbeats while the test page is visible.
–
Passedexperiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang9.05 s
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
StatusTestDuration
SkippedPageViewVitals with a real soft navigation › starts a new page view with its own LCP, and keeps the click in the INP of the first view
Skipped: This browser has no soft-navigation entries.
–
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
StatusTestDuration
PassedLag Monitor Stress Tests › light load profile completes and reports few events20.24 s
PassedLag Monitor Stress Tests › moderate load profile triggers measurable lag18.82 s
PassedLag Monitor Stress Tests › heavy load profile drives the system hard18.47 s
PassedLag Monitor Stress Tests › bursty load produces both small and huge events (bimodal)18.89 s
PassedLag Monitor Stress Tests › evolutionary load drifts upward over time18.96 s
PassedLag Monitor Stress Tests › kitchen sink profile exercises all generators18.22 s
SkippedLag Monitor Stress Tests › exports the heavy profile to Mimir
Skipped: Needs the Grafana stack: run pnpm test:e2e.
–
packages/lag-integration-tests/src/web-vitals-oracle.test.ts2 passed, 2 skipped
StatusTestDuration
PassedPageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly547 ms
SkippedPageViewVitals agrees with web-vitals › CLS agrees exactly
Skipped: Layout Instability (the layout-shift entry type, CLS) is Chromium-only.
–
PassedPageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does0 ms
SkippedPageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases
Skipped: In the iOS Simulator, the click of safaridriver gives no INP in web-vitals and in the library.
–
packages/lag-integration-tests/src/worker-io.test.ts11 passed
StatusTestDuration
Passedthe input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit2.09 s
Passedthe input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit2.05 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a service worker complete during the block, except in WebKit2.99 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a shared worker complete during the block, except in WebKit2.91 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation waits for the end of the block2.28 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation waits for the end of the block2.26 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation waits for the end of the block2.29 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation waits for the end of the block2.26 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation waits for the end of the block2.27 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation waits for the end of the block2.26 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives after the block2.54 s
packages/lag-integration-tests/src/worker.test.ts3 passed
StatusTestDuration
PassedWorker Lag Monitor Integration › receives heartbeats from a real Web Worker1.55 s
PassedWorker Lag Monitor Integration › detects main thread blocking1.61 s
PassedWorker Lag Monitor Integration › stops and restarts the worker's heartbeat loop1.21 s

@lag/integration-tests: browser tests in safari

Suite integration-browser-safari. 45 passed, 12 skipped. Duration 3 min 59 s.

packages/lag-integration-tests/src/browser-apis.test.ts6 skipped
StatusTestDuration
SkippedMonitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports
Skipped: Layout Instability (the layout-shift entry type, CLS) is Chromium-only.
–
SkippedMonitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source
Skipped: The Compute Pressure API (PressureObserver) is Chromium-only.
–
SkippedMonitors of engine-specific APIs › the page source reads the visibility-state entries
Skipped: The visibility-state entry type is Chromium-only.
–
SkippedMonitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events
Skipped: The Page Lifecycle freeze and resume events are Chromium-only.
–
SkippedMonitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page
Skipped: requestIdleCallback is not in WebKit.
–
SkippedMonitors of engine-specific APIs › MemoryMonitor reads performance.memory
Skipped: performance.memory is Chromium-only.
–
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
StatusTestDuration
PassedFacts of the engines › gives the entry types of the research1 ms
PassedFacts of the engines › starts the listeners at window in the order of experiment E10 ms
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
StatusTestDuration
PassedDriftLag accuracy › reports approximately 0 on an idle page and the length of a block4.34 s
packages/lag-integration-tests/src/drift-load.test.ts2 passed
StatusTestDuration
PassedDriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load8.44 s
PassedDriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load8.42 s
packages/lag-integration-tests/src/hang-journal.test.ts1 skipped
StatusTestDuration
Skippedhang journal in a browser › keeps the record of a hang that did not end
Skipped: This browser completes the IndexedDB requests of a worker on the main thread (WebKit), thus the worker cannot write the record during the hang.
–
packages/lag-integration-tests/src/lag-monitors.test.ts11 passed, 2 skipped
StatusTestDuration
PassedLag Monitor Integration › registers a monitor for each API that the browser has, and no other7 ms
PassedLag Monitor Integration › DriftLag measures a blocked main thread748 ms
PassedLag Monitor Integration › the worker measures main-thread blocking from outside the main thread1.75 s
PassedLag Monitor Integration › FrameTimingMonitor records frames3 ms
SkippedLag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports
Skipped: Long Animation Frames (the long-animation-frame entry type) are Chromium-only.
–
PassedLag Monitor Integration › PageViewVitals measures the load of the page and a real click1.36 s
PassedLag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle1.18 s
SkippedLag Monitor Integration › MemoryMonitor samples the heap through performance.memory
Skipped: performance.memory is Chromium-only.
–
PassedLag Monitor Integration › ClockReliabilityChecker reports the clock resolution0 ms
PassedLag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure1.07 s
PassedLag Monitor Integration › emits a synthetic log to verify the Loki bridge1 ms
PassedLag Monitor Integration › stop() halts all reporting1.76 s
PassedLag Monitor Integration › flushes metrics to the OTLP endpoint8.87 s
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
StatusTestDuration
PassedLifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier1 ms
PassedLifecycleStateMachine in a browser › uses the time of the event for the transition1 ms
PassedLifecycleStateMachine in a browser › removes every listener when it is disposed0 ms
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
StatusTestDuration
Passedthe peer hang watch in a browser › reports a page that closes during a hang: the other page reports it, or the page itself at its close17.62 s
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
StatusTestDuration
Passedexperiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held11.6 s
Passedexperiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang20.9 s
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
StatusTestDuration
SkippedPageViewVitals with a real soft navigation › starts a new page view with its own LCP, and keeps the click in the INP of the first view
Skipped: This browser has no soft-navigation entries.
–
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
StatusTestDuration
PassedLag Monitor Stress Tests › light load profile completes and reports few events20.42 s
PassedLag Monitor Stress Tests › moderate load profile triggers measurable lag18.16 s
PassedLag Monitor Stress Tests › heavy load profile drives the system hard18.64 s
PassedLag Monitor Stress Tests › bursty load produces both small and huge events (bimodal)18.87 s
PassedLag Monitor Stress Tests › evolutionary load drifts upward over time18.81 s
PassedLag Monitor Stress Tests › kitchen sink profile exercises all generators18.76 s
SkippedLag Monitor Stress Tests › exports the heavy profile to Mimir
Skipped: Needs the Grafana stack: run pnpm test:e2e.
–
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
StatusTestDuration
PassedPageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly527 ms
SkippedPageViewVitals agrees with web-vitals › CLS agrees exactly
Skipped: Layout Instability (the layout-shift entry type, CLS) is Chromium-only.
–
PassedPageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does0 ms
PassedPageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases1.47 s
packages/lag-integration-tests/src/worker-io.test.ts11 passed
StatusTestDuration
Passedthe input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit2.16 s
Passedthe input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit2.06 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a service worker complete during the block, except in WebKit2.99 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a shared worker complete during the block, except in WebKit2.91 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation waits for the end of the block2.25 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation waits for the end of the block2.24 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation waits for the end of the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation waits for the end of the block2.27 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation waits for the end of the block2.23 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation waits for the end of the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives after the block2.54 s
packages/lag-integration-tests/src/worker.test.ts3 passed
StatusTestDuration
PassedWorker Lag Monitor Integration › receives heartbeats from a real Web Worker1.54 s
PassedWorker Lag Monitor Integration › detects main thread blocking1.61 s
PassedWorker Lag Monitor Integration › stops and restarts the worker's heartbeat loop1.21 s

@lag/integration-tests: browser tests in webkit

Suite integration-browser-webkit. 42 passed, 15 skipped. Duration 3 min 31 s.

packages/lag-integration-tests/src/browser-apis.test.ts6 skipped
StatusTestDuration
SkippedMonitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports
Skipped: Layout Instability (the layout-shift entry type, CLS) is Chromium-only.
–
SkippedMonitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source
Skipped: The Compute Pressure API (PressureObserver) is Chromium-only.
–
SkippedMonitors of engine-specific APIs › the page source reads the visibility-state entries
Skipped: The visibility-state entry type is Chromium-only.
–
SkippedMonitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events
Skipped: The Page Lifecycle freeze and resume events are Chromium-only.
–
SkippedMonitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page
Skipped: requestIdleCallback is not in WebKit.
–
SkippedMonitors of engine-specific APIs › MemoryMonitor reads performance.memory
Skipped: performance.memory is Chromium-only.
–
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
StatusTestDuration
PassedFacts of the engines › gives the entry types of the research2 ms
PassedFacts of the engines › starts the listeners at window in the order of experiment E11 ms
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
StatusTestDuration
PassedDriftLag accuracy › reports approximately 0 on an idle page and the length of a block4.31 s
packages/lag-integration-tests/src/drift-load.test.ts2 passed
StatusTestDuration
PassedDriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load8.42 s
PassedDriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load8.41 s
packages/lag-integration-tests/src/hang-journal.test.ts1 skipped
StatusTestDuration
Skippedhang journal in a browser › keeps the record of a hang that did not end
Skipped: This browser completes the IndexedDB requests of a worker on the main thread (WebKit), thus the worker cannot write the record during the hang.
–
packages/lag-integration-tests/src/lag-monitors.test.ts11 passed, 2 skipped
StatusTestDuration
PassedLag Monitor Integration › registers a monitor for each API that the browser has, and no other13 ms
PassedLag Monitor Integration › DriftLag measures a blocked main thread657 ms
PassedLag Monitor Integration › the worker measures main-thread blocking from outside the main thread1.3 s
PassedLag Monitor Integration › FrameTimingMonitor records frames1 ms
SkippedLag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports
Skipped: Long Animation Frames (the long-animation-frame entry type) are Chromium-only.
–
PassedLag Monitor Integration › PageViewVitals measures the load of the page and a real click998 ms
PassedLag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle2.02 s
SkippedLag Monitor Integration › MemoryMonitor samples the heap through performance.memory
Skipped: performance.memory is Chromium-only.
–
PassedLag Monitor Integration › ClockReliabilityChecker reports the clock resolution6 ms
PassedLag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure1.07 s
PassedLag Monitor Integration › emits a synthetic log to verify the Loki bridge1 ms
PassedLag Monitor Integration › stop() halts all reporting1.77 s
PassedLag Monitor Integration › flushes metrics to the OTLP endpoint9.22 s
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
StatusTestDuration
PassedLifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier2 ms
PassedLifecycleStateMachine in a browser › uses the time of the event for the transition2 ms
PassedLifecycleStateMachine in a browser › removes every listener when it is disposed2 ms
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
StatusTestDuration
Passedthe peer hang watch in a browser › reports a page that closes during a hang: the other page reports it, or the page itself at its close16.11 s
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
StatusTestDuration
Passedexperiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held8.08 s
Passedexperiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang5.6 s
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
StatusTestDuration
SkippedPageViewVitals with a real soft navigation › starts a new page view with its own LCP, and keeps the click in the INP of the first view
Skipped: This browser has no soft-navigation entries.
–
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
StatusTestDuration
PassedLag Monitor Stress Tests › light load profile completes and reports few events21.25 s
PassedLag Monitor Stress Tests › moderate load profile triggers measurable lag18.84 s
PassedLag Monitor Stress Tests › heavy load profile drives the system hard19.3 s
PassedLag Monitor Stress Tests › bursty load produces both small and huge events (bimodal)17.75 s
PassedLag Monitor Stress Tests › evolutionary load drifts upward over time18.61 s
PassedLag Monitor Stress Tests › kitchen sink profile exercises all generators18.22 s
SkippedLag Monitor Stress Tests › exports the heavy profile to Mimir
Skipped: Needs the Grafana stack: run pnpm test:e2e.
–
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
StatusTestDuration
PassedPageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly511 ms
SkippedPageViewVitals agrees with web-vitals › CLS agrees exactly
Skipped: Layout Instability (the layout-shift entry type, CLS) is Chromium-only.
–
PassedPageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does1 ms
PassedPageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases1.49 s
packages/lag-integration-tests/src/worker-io.test.ts8 passed, 3 skipped
StatusTestDuration
Passedthe input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit2.01 s
Passedthe input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit2.01 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a service worker complete during the block, except in WebKit2.92 s
Passedthe input and output of a worker during a main-thread block › the writes and fetches of a shared worker complete during the block, except in WebKit2.91 s
Skippedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation waits for the end of the block
Skipped: The worker of this browser has no API for opfs-sync-access.
–
Skippedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation waits for the end of the block
Skipped: The worker of this browser has no API for opfs-writable.
–
Skippedthe output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation waits for the end of the block
Skipped: The worker of this browser has no API for opfs-lookup.
–
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation waits for the end of the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation waits for the end of the block2.22 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation waits for the end of the block2.23 s
Passedthe output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives after the block2.53 s
packages/lag-integration-tests/src/worker.test.ts3 passed
StatusTestDuration
PassedWorker Lag Monitor Integration › receives heartbeats from a real Web Worker1.51 s
PassedWorker Lag Monitor Integration › detects main thread blocking1.61 s
PassedWorker Lag Monitor Integration › stops and restarts the worker's heartbeat loop1.2 s

@lag/integration-tests: browser tests in chromium

Suite integration-cdp-chromium. 6 passed. Duration 22.59 s.

packages/lag-integration-tests/src/cdp/compute-pressure.test.ts1 passed
StatusTestDuration
PassedComputePressureMonitor with a virtual CPU pressure source › records each state of the source, as ordinals 0 to 3420 ms
packages/lag-integration-tests/src/cdp/cpu-throttling.test.ts1 passed
StatusTestDuration
PassedCPU throttling (CDP Emulation.setCPUThrottlingRate) › 4x throttling of the same work increases the drift and the worker lag8.74 s
packages/lag-integration-tests/src/cdp/freeze.test.ts2 passed
StatusTestDuration
PassedA frozen page (CDP Page.setWebLifecycleState) › the lifecycle state machine sees the freeze and the resume1.07 s
PassedA frozen page (CDP Page.setWebLifecycleState) › timer monitors pause before the freeze, record no stall for it, and continue after the resume5.04 s
packages/lag-integration-tests/src/cdp/visibility.test.ts1 passed
StatusTestDuration
PassedA hidden page (a second page in front) › timer monitors pause while the page is hidden and continue when it is visible4.86 s
packages/lag-integration-tests/src/cdp/vitals-checkpoint.test.ts1 passed
StatusTestDuration
PassedThe page-view vitals at the hidden checkpoint › record one value for each vital, and the events, when the page becomes hidden1.54 s

@lag/integration-tests: browser tests in chromium

Suite integration-coi-chromium. 4 passed. Duration 1.3 s.

packages/lag-integration-tests/src/coi/isolation.test.ts4 passed
StatusTestDuration
PassedA cross-origin-isolated page › is cross-origin isolated and has SharedArrayBuffer2.1 ms
PassedA cross-origin-isolated page › the shared-memory liveness monitor reports a main-thread block1.29 s
PassedA cross-origin-isolated page › the memory monitor uses measureUserAgentSpecificMemory()1.8 ms
PassedA cross-origin-isolated page › performance.now() has a high resolution5.7 ms

@lag/integration-tests: browser tests in firefox

Suite integration-coi-firefox. 3 passed, 1 skipped. Duration 1.26 s.

packages/lag-integration-tests/src/coi/isolation.test.ts3 passed, 1 skipped
StatusTestDuration
PassedA cross-origin-isolated page › is cross-origin isolated and has SharedArrayBuffer1.5 ms
PassedA cross-origin-isolated page › the shared-memory liveness monitor reports a main-thread block1.26 s
SkippedA cross-origin-isolated page › the memory monitor uses measureUserAgentSpecificMemory()
Skipped: performance.measureUserAgentSpecificMemory() needs Chromium in the new headless mode and cross-origin isolation.
–
PassedA cross-origin-isolated page › performance.now() has a high resolution3.5 ms

@lag/integration-tests: browser tests in webkit

Suite integration-coi-webkit. 3 passed, 1 skipped. Duration 1.27 s.

packages/lag-integration-tests/src/coi/isolation.test.ts3 passed, 1 skipped
StatusTestDuration
PassedA cross-origin-isolated page › is cross-origin isolated and has SharedArrayBuffer4.4 ms
PassedA cross-origin-isolated page › the shared-memory liveness monitor reports a main-thread block1.26 s
SkippedA cross-origin-isolated page › the memory monitor uses measureUserAgentSpecificMemory()
Skipped: performance.measureUserAgentSpecificMemory() needs Chromium in the new headless mode and cross-origin isolation.
–
PassedA cross-origin-isolated page › performance.now() has a high resolution2.7 ms

@lag/integration-tests: benchmark tests in chromium

Suite integration-overhead-chromium. 1 passed. Duration 1 min 23 s.

packages/lag-integration-tests/src/overhead/overhead.test.ts1 passed
StatusTestDuration
PassedThe overhead of all monitors on an idle page › stays in the CPU and timer budgets1 min 23 s

@lag/load: unit tests in node

Suite load-unit-node. 15 passed. Duration 65 ms.

packages/load/src/load.test.ts15 passed
StatusTestDuration
Passedload: RNG › is reproducible given the same seed2.1 ms
Passedload: RNG › produces different sequences for different seeds0.51 ms
Passedload: RNG › int() respects bounds inclusively3.4 ms
Passedload: RNG › range() respects bounds (half-open)3.1 ms
Passedload: RNG › normal() produces values approximately centered at 01.9 ms
Passedload: RNG › bool(p) approximates the requested probability1 ms
Passedload: RNG › pick() selects from the array uniformly0.96 ms
Passedload: Distributions › constant always returns the same value0.44 ms
Passedload: Distributions › uniform stays in bounds24 ms
Passedload: Distributions › normal clamps to [min, max]21 ms
Passedload: Distributions › exponential is non-negative and skewed3.2 ms
Passedload: Distributions › powerLaw produces a long tail2.5 ms
Passedload: Distributions › bimodal produces two clusters0.52 ms
Passedload: Distributions › evolutionary drifts as a random walk0.25 ms
Passedload: Distributions › burst alternates between active and idle0.28 ms

@lag/report: unit tests in node

Suite report-unit-node. 12 passed. Duration 15 ms.

packages/report/src/convert.test.ts12 passed
StatusTestDuration
PassedrelativePath › makes Windows and POSIX paths relative to the root, with forward slashes1.7 ms
PassedrelativePath › ignores case on the root, as Windows paths do0.21 ms
PassedrelativePath › keeps paths outside the root0.28 ms
PassedrelativePath › removes the checkout folder of another runner, thus the file names agree in each engine0.33 ms
PassedrelativePath › removes the part before the packages folder of a file from another machine0.32 ms
PassedfromVitestJson › converts files, tests, statuses and timing1.3 ms
PassedfromVitestJson › adds a failed test for a file that failed without a failed test, as Vitest's JSON reporter writes it0.72 ms
PassedfromIstanbulSummary › separates the total from the files and sorts the files7.7 ms
PassedfromStrykerReport › counts mutants and calculates the score from valid mutants only1.5 ms
PassedfromStrykerReport › keeps the commit and the time of the Stryker run0.35 ms
PassedfromStrykerReport › gives no score to a file without valid mutants, and puts it after the files with a score0.39 ms
Passedrun summaries › counts statuses across suites0.49 ms

@lag/scripts: unit tests in node

Suite scripts-unit-node. 33 passed. Duration 851 ms.

packages/scripts/src/package-template.test.ts8 passed
StatusTestDuration
Passedpnpm new › refuses an existing folder, unless --force3.1 ms
Passedpnpm new › refuses the name of a package in another folder, also with --force0.29 ms
Passedpnpm new › adds the devDependencies that the types of each TypeScript config need, with the versions of the workspace1.7 ms
Passedpnpm new › gives a dependency for each `types` entry of the config files3 ms
Passedpnpm new › finds a version in the workspace for each devDependency of each config2.2 ms
Passedpnpm new › takes the range with the highest version when two packages differ0.43 ms
Passedpnpm new › makes the package.json and the tsconfig.json of an ESM and a CommonJS package0.7 ms
Passedpnpm new › fails when no workspace package uses a necessary devDependency0.76 ms
packages/scripts/src/readme-metrics.test.ts4 passed
StatusTestDuration
Passedreadme-metrics › makes one row for each metric of the catalog2.7 ms
Passedreadme-metrics › escapes the pipe character in a description0.22 ms
Passedreadme-metrics › replaces only the text between the markers0.93 ms
Passedreadme-metrics › finds the README in agreement with the catalog0.37 ms
packages/scripts/src/results/model.test.ts16 passed
StatusTestDuration
Passedsuite names › names a suite after the package, the project and the environment5 ms
Passedsuite names › finds the kind of a suite from the project0.51 ms
Passedsuite names › shortens the package names0.3 ms
Passedsuite names › gives each project report a file name without spaces0.64 ms
Passedresults.jsonl › reads the valid records and leaves out the other lines0.63 ms
Passedresults.jsonl › gives each measurement the suite of its project and joins the same name0.64 ms
Passedresults.jsonl › keeps one budget for each name, calculates `pass` again and puts the failed ones first0.56 ms
Passedthe run index › makes a run ID that sorts by time and has the short commit0.66 ms
Passedthe run index › adds the run to the index, oldest first, and replaces a run with the same ID19 ms
Passedthe run index › gives the summary of the new run its budget counts, and keeps an older summary without them0.54 ms
Passedthe run index › starts again from an index that the site cannot read, and keeps at most maxRuns0.61 ms
Passedthe result of the collector › fails when a step gave an exit code that is not 0, also without a failed test0.38 ms
Passedthe result of the collector › fails when a test or a budget failed0.24 ms
Passedthe result of the collector › uses only the files that changed during the run, with a tolerance of 2 s0.28 ms
Passedthe origin of the mutation report › takes the commit and the time from the file of the Pages workflow0.29 ms
Passedthe origin of the mutation report › uses the time of the report file, and no commit, without a valid file0.36 ms
packages/scripts/src/results/project-reporter.test.ts5 passed
StatusTestDuration
Passedproject reporter with Vitest › adds a failed test for a beforeAll hook that failed, and keeps its tests skipped1.6 ms
Passedproject reporter with Vitest › adds a failed test for a file that failed at its import0.27 ms
Passedproject reporter with Vitest › adds a failed test for an afterAll hook that failed, and keeps its tests passed0.4 ms
Passedproject reporter with Vitest › adds nothing to a file that passed, and the counts agree with the exit code of Vitest0.95 ms
Passedproject reporter › adds a failed test for a file that Vitest marks as failed without an error0.53 ms

@lag/site: browser tests in chromium

Suite site-browser-chromium. 92 passed. Duration 29.16 s.

packages/site/src/app/prerender-handoff.browser.test.tsx8 passed
StatusTestDuration
PassedroutePathOf › gives the route of a URL path below the base5.5 ms
PassedisPrerendering › is true only when the prerender sets the flag0.5 ms
PassedmountApp › gives the root element when the page has no HTML from the build0.9 ms
PassedmountApp › removes HTML from the build for a different route1 ms
PassedmountApp › renders hidden after the saved HTML, and shows the app when nothing loads209 ms
PassedmountApp › shows the app after the settle time, also when a live chart changes the DOM all the time252 ms
PassedmountApp › shows the app after the time limit, also when an element still loads203 ms
PassedmountApp › gives React an ID prefix, so the IDs differ from the IDs in the saved HTML24 ms
packages/site/src/app/smoke.browser.test.tsx69 passed
StatusTestDuration
Passedsite routes › renders / without errors740 ms
Passedsite routes › renders /results without errors552 ms
Passedsite routes › renders /results/2026-10-06-f6e5d4c without errors305 ms
Passedsite routes › renders /results/2026-10-06-f6e5d4c/tests without errors288 ms
Passedsite routes › renders /results/2026-10-06-f6e5d4c/tests?status=failed&q=heartbeat without errors180 ms
Passedsite routes › renders /results/2026-10-06-f6e5d4c/coverage without errors254 ms
Passedsite routes › renders /results/2026-10-06-f6e5d4c/mutation without errors174 ms
Passedsite routes › renders /results/2026-10-06-f6e5d4c/budgets without errors155 ms
Passedsite routes › renders /results/2026-10-06-f6e5d4c/measurements without errors262 ms
Passedsite routes › renders /results/2026-10-06-f6e5d4c/measurements?group=browser without errors259 ms
Passedsite routes › renders /results/no-such-run without errors154 ms
Passedsite routes › renders /playground without errors456 ms
Passedsite routes › renders /no/such/page without errors154 ms
Passedsite routes › renders /docs/no-such-page without errors153 ms
Passedsite routes › renders /docs without errors454 ms
Passedsite routes › renders /docs/getting-started without errors457 ms
Passedsite routes › renders /docs/concepts/event-loop without errors963 ms
Passedsite routes › renders /docs/concepts/page-lifecycle without errors660 ms
Passedsite routes › renders /docs/concepts/page-views without errors483 ms
Passedsite routes › renders /docs/concepts/clocks-and-time without errors509 ms
Passedsite routes › renders /docs/concepts/measurement-validity without errors509 ms
Passedsite routes › renders /docs/concepts/statistics without errors449 ms
Passedsite routes › renders /docs/concepts/survivorship without errors491 ms
Passedsite routes › renders /docs/concepts/metrics-model without errors465 ms
Passedsite routes › renders /docs/monitors without errors427 ms
Passedsite routes › renders /docs/monitors/drift-lag without errors455 ms
Passedsite routes › renders /docs/monitors/macrotask-lag without errors454 ms
Passedsite routes › renders /docs/monitors/scheduling-fairness without errors454 ms
Passedsite routes › renders /docs/monitors/worker-lag without errors473 ms
Passedsite routes › renders /docs/monitors/peer-hang-watch without errors468 ms
Passedsite routes › renders /docs/monitors/shared-liveness without errors454 ms
Passedsite routes › renders /docs/monitors/long-animation-frames without errors455 ms
Passedsite routes › renders /docs/monitors/event-timing without errors456 ms
Passedsite routes › renders /docs/monitors/layout-shift without errors454 ms
Passedsite routes › renders /docs/monitors/page-view-vitals without errors460 ms
Passedsite routes › renders /docs/monitors/page-view-context without errors454 ms
Passedsite routes › renders /docs/monitors/frame-timing without errors454 ms
Passedsite routes › renders /docs/monitors/idle-availability without errors453 ms
Passedsite routes › renders /docs/monitors/memory without errors454 ms
Passedsite routes › renders /docs/monitors/compute-pressure without errors454 ms
Passedsite routes › renders /docs/monitors/gc-signal without errors453 ms
Passedsite routes › renders /docs/monitors/lifecycle without errors538 ms
Passedsite routes › renders /docs/monitors/timer-throttle without errors454 ms
Passedsite routes › renders /docs/monitors/clock-reliability without errors454 ms
Passedsite routes › renders /docs/monitors/clock-drift without errors454 ms
Passedsite routes › renders /docs/monitors/browser-reports without errors454 ms
Passedsite routes › renders /docs/architecture without errors649 ms
Passedsite routes › renders /docs/api without errors431 ms
Passedsite routes › renders /docs/operations/opentelemetry without errors454 ms
Passedsite routes › renders /docs/operations/grafana-stack without errors497 ms
Passedsite routes › renders /docs/operations/dashboards without errors457 ms
Passedsite routes › renders /docs/testing/strategy without errors460 ms
Passedsite routes › renders /docs/contributing/writing-style without errors453 ms
Passedsite routes › renders /docs/contributing/development without errors453 ms
Passedsite routes › renders /research without errors453 ms
Passedsite routes › renders /research/browser-support without errors459 ms
Passedsite routes › renders /research/clocks-and-timers without errors456 ms
Passedsite routes › renders /research/local-experiments without errors455 ms
Passedsite routes › renders /research/web-vitals-algorithms without errors455 ms
Passedsite routes › renders /research/rum-landscape without errors423 ms
Passedsite routes › renders /research/otel-browser-metrics without errors455 ms
Passedsite routes › renders /research/writing-standard without errors453 ms
Passedsite routes › renders /research/sources without errors455 ms
Passedsite routes › renders /thesis without errors455 ms
Passedsite routes › draws the measurement charts of almost equal values153 ms
Passedsite routes › shows the title of each content page as its h1185 ms
Passedsite routes › shows the empty state without results52 ms
Passedsite routes › draws the boxes and the arrows of the architecture map263 ms
Passedsite routes › starts the monitors in the playground and stops them on unmount75 ms
packages/site/src/playground/session.browser.test.ts3 passed
StatusTestDuration
Passedbrowser session › records the real monitors and sees a blocked main thread1.55 s
Passedbrowser session › records nothing more after it stops2.01 s
Passedbrowser session › runs only the timer monitors for the home page505 ms
packages/site/src/playground/timeline/Analysis.browser.test.tsx5 passed
StatusTestDuration
PassedEpochPanel › draws the three signals around the blocks222 ms
PassedEpochPanel › changes the time 0 to the end of the blocks50 ms
PassedEpochPanel › tells what to do when there are no blocks, and keeps the place of the charts21 ms
PassedInpScatterPanel › draws one dot for each interaction, with the INP thresholds35 ms
PassedInpScatterPanel › tells that a browser without long animation frames puts all dots at 0 ms28 ms
packages/site/src/playground/timeline/SessionTimeline.browser.test.tsx7 passed
StatusTestDuration
PassedSessionTimeline › draws the tracks, and follows the present time130 ms
PassedSessionTimeline › hides a track when its check box is cleared48 ms
PassedSessionTimeline › zooms, pans and shows all with the keyboard, and stops following68 ms
PassedSessionTimeline › goes to the next item with the keyboard, describes it and announces it91 ms
PassedSessionTimeline › shows a tooltip for the item under the pointer53 ms
PassedSessionTimeline › gives the items of the visible range as a table94 ms
PassedSessionTimeline › keeps the frame rate of an empty timeline with thousands of items3.17 s

@lag/site: unit tests in node

Suite site-unit-node. 307 passed. Duration 10.26 s.

packages/site/build/base.test.ts3 passed
StatusTestDuration
PassednormalizeBase › gives / for an empty value3.7 ms
PassednormalizeBase › adds the slashes at the start and the end1.3 ms
PassednormalizeBase › keeps a full URL0.43 ms
packages/site/build/frontmatter.test.ts7 passed
StatusTestDuration
PassedisFrontmatterRequest › accepts an .mdx ID with the frontmatter query2.5 ms
PassedisFrontmatterRequest › rejects other IDs0.46 ms
PassedstripQuery › removes the query0.33 ms
PassedextractFrontmatter › reads the YAML block at the start of the file12 ms
PassedextractFrontmatter › reads CRLF line endings and a byte order mark1.2 ms
PassedextractFrontmatter › returns an empty object without frontmatter0.65 ms
PassedextractFrontmatter › returns an empty object if the YAML is not a mapping1.4 ms
packages/site/build/head-tags.test.ts10 passed
StatusTestDuration
Passedhead tags › gives an article its canonical URL, Open Graph, the Twitter card and the sitemap16 ms
Passedhead tags › gives the home page the full title, the type website and the site URL0.88 ms
Passedhead tags › uses the fallback description for a page without a description0.53 ms
Passedhead tags › tells search engines not to keep the page of a test run3.5 ms
Passedhead tags › gives the home page a WebSite and a SoftwareSourceCode in TypeScript under the MIT license8 ms
Passedhead tags › gives an article a TechArticle and a BreadcrumbList7.9 ms
Passedhead tags › gives a page of the app a WebPage0.6 ms
Passedhead tags › puts only the parent routes that exist into the breadcrumbs0.52 ms
Passedhead tags › escapes the JSON so that a text cannot close the script element9 ms
Passedhead tags › names the image files and the text alternatives0.75 ms
packages/site/build/og-image.test.ts11 passed
StatusTestDuration
PassedOpen Graph images › gives an article its group, its title and its description8.2 ms
PassedOpen Graph images › gives the home page the language and the license of the library0.94 ms
PassedOpen Graph images › keeps each word with a hyphen on one line, and escapes the title1.7 ms
PassedOpen Graph images › gives the address of the site without the protocol0.27 ms
PassedOpen Graph images › escapes the text, uses the fonts of the site and tells the build when it is ready2.1 ms
Passedlag chart › gives the same values for the same seed, and other values for another seed4 ms
Passedlag chart › has a few long windows and many short windows, for each seed1.4 ms
Passedlag chart › draws one bar for each window, red from 50 ms, the dashed line at 50 ms and the scale1.5 ms
Passedlag chart › draws the site mark with its red frame2.1 ms
Passedprerender switch › is on unless SITE_PRERENDER is 0, false, no or off0.6 ms
Passedfont preload › selects the Latin text font and the Latin code font of the bundle0.43 ms
packages/site/build/rehype-export-toc.test.ts3 passed
StatusTestDuration
PassedcollectToc › collects the h2 and h3 headings that have an id, in order8.9 ms
PassedcreateExportNode › makes an ESM export of the entries5.1 ms
PassedrehypeExportToc › puts the export at the start of the tree1 ms
packages/site/build/remark-mermaid.test.ts4 passed
StatusTestDuration
PassedremarkMermaid › changes a mermaid fence into the Mermaid component, with its title and caption7.8 ms
PassedremarkMermaid › changes fences inside other nodes, for example in a list0.74 ms
PassedremarkMermaid › reads the key-value pairs of the meta string0.46 ms
PassedremarkMermaid › makes MDX code that gives the chart to the component32 ms
packages/site/build/site-url.test.ts6 passed
StatusTestDuration
Passedsite URL › uses SITE_URL, with a slash at the end and a host in lower case3.4 ms
Passedsite URL › uses the fallback when SITE_URL is not set or empty0.62 ms
Passedsite URL › refuses a value that is not an absolute http or https URL1.8 ms
Passedsite URL › gives the absolute URL of a route, as the links of the app give it0.78 ms
Passedsitemap and robots.txt › lists each URL one time, with escapes1.8 ms
Passedsitemap and robots.txt › lets all crawlers read the site and gives the sitemap1.2 ms
packages/site/build/snapshot.test.ts10 passed
StatusTestDuration
Passedcolor tokens › reads the colors of the light theme, and leaves out a color that two tokens have6.9 ms
Passedcolor tokens › finds each color of styles/tokens.css one time, with the ink, the mark and the series colors15 ms
Passedcolor tokens › replaces hex and rgb() colors of tokens, and nothing else0.75 ms
Passedcolor tokens › works with no outside value, thus the prerender can start it in the browser0.37 ms
Passedcolor tokens › makes CSS rules with no specificity for the SVG attributes with a token color0.81 ms
Passedpage HTML › puts the head tags after the title, and keeps the root element empty without a snapshot0.93 ms
Passedpage HTML › puts the snapshot into the root element, with the route, and the text stays as it is0.93 ms
Passedpage HTML › adds the style sheets of the page one time each, after the style sheet of the template2.6 ms
Passedpage HTML › adds the color rules before the style sheets, thus the other rules win1 ms
Passedpage HTML › refuses a template without an empty root element1.2 ms
packages/site/build/social-card.test.ts2 passed
StatusTestDuration
Passedsocial preview › shows the name, the claim, the facts and the chart at 1280 × 640 pixels5.4 ms
Passedsocial preview › escapes the text0.7 ms
packages/site/build/static-routes.test.ts11 passed
StatusTestDuration
Passedstatic routes › gives the content pages the paths, titles and groups of the content registry, in path order63 ms
Passedstatic routes › gives the views of each run, with a unique title, and ignores an unsafe run ID1.4 ms
Passedstatic routes › gives the playground and the list of runs a title and a description4.2 ms
Passedstatic routes › takes the home route from the title and the description of index.html4.2 ms
Passedstatic routes › lists the home page first, then the content pages, the app pages and the runs8.8 ms
Passedstatic routes › has the title of the home page in index.html1 ms
Passedstatic routes › gives each page of the site a unique title and a description of a useful length64 ms
Passedstatic routes › puts the title and the description of the route into the HTML, with escapes1.2 ms
Passedstatic routes › gives the 404 page its title and noindex, and no description0.91 ms
Passedstatic routes › writes a file for the path and a file for the path with a slash at the end0.41 ms
Passedstatic routes › names the sections as the navigation does0.35 ms
packages/site/src/architecture/graph.test.ts4 passed
StatusTestDuration
Passedarchitecture graph › has a unique ID for each node2.2 ms
Passedarchitecture graph › connects only nodes that exist6.8 ms
Passedarchitecture graph › puts children in group nodes that exist0.59 ms
Passedarchitecture graph › links each node to a page that exists1.7 ms
packages/site/src/app/prerender-sessions.test.ts2 passed
StatusTestDuration
PassedsessionsWithoutStart › gives the sessions of the factory, but they do not start the monitors13 ms
PassedsessionsWithoutStart › gives the error of the factory4.7 ms
packages/site/src/app/routes.test.ts2 passed
StatusTestDuration
PassedrouterBasename › removes the slash at the end of the base URL2.9 ms
PassedrouterBasename › uses the path of a full URL0.36 ms
packages/site/src/content/content.test.ts53 passed
StatusTestDuration
Passedsite content › has valid frontmatter on every page8.9 ms
Passedsite content › has every required page17 ms
Passedsite content › gives each page in a section a different order0.65 ms
Passedsite content › compiles /docs with a component and a table of contents130 ms
Passedsite content › compiles /docs/getting-started with a component and a table of contents79 ms
Passedsite content › compiles /docs/concepts/event-loop with a component and a table of contents2.19 s
Passedsite content › compiles /docs/concepts/page-lifecycle with a component and a table of contents99 ms
Passedsite content › compiles /docs/concepts/page-views with a component and a table of contents75 ms
Passedsite content › compiles /docs/concepts/clocks-and-time with a component and a table of contents100 ms
Passedsite content › compiles /docs/concepts/measurement-validity with a component and a table of contents225 ms
Passedsite content › compiles /docs/concepts/statistics with a component and a table of contents178 ms
Passedsite content › compiles /docs/concepts/survivorship with a component and a table of contents168 ms
Passedsite content › compiles /docs/concepts/metrics-model with a component and a table of contents166 ms
Passedsite content › compiles /docs/monitors with a component and a table of contents145 ms
Passedsite content › compiles /docs/monitors/drift-lag with a component and a table of contents108 ms
Passedsite content › compiles /docs/monitors/macrotask-lag with a component and a table of contents38 ms
Passedsite content › compiles /docs/monitors/scheduling-fairness with a component and a table of contents37 ms
Passedsite content › compiles /docs/monitors/worker-lag with a component and a table of contents81 ms
Passedsite content › compiles /docs/monitors/peer-hang-watch with a component and a table of contents47 ms
Passedsite content › compiles /docs/monitors/shared-liveness with a component and a table of contents26 ms
Passedsite content › compiles /docs/monitors/long-animation-frames with a component and a table of contents29 ms
Passedsite content › compiles /docs/monitors/event-timing with a component and a table of contents32 ms
Passedsite content › compiles /docs/monitors/layout-shift with a component and a table of contents47 ms
Passedsite content › compiles /docs/monitors/page-view-vitals with a component and a table of contents84 ms
Passedsite content › compiles /docs/monitors/page-view-context with a component and a table of contents24 ms
Passedsite content › compiles /docs/monitors/frame-timing with a component and a table of contents26 ms
Passedsite content › compiles /docs/monitors/idle-availability with a component and a table of contents24 ms
Passedsite content › compiles /docs/monitors/memory with a component and a table of contents28 ms
Passedsite content › compiles /docs/monitors/compute-pressure with a component and a table of contents26 ms
Passedsite content › compiles /docs/monitors/gc-signal with a component and a table of contents24 ms
Passedsite content › compiles /docs/monitors/lifecycle with a component and a table of contents45 ms
Passedsite content › compiles /docs/monitors/timer-throttle with a component and a table of contents25 ms
Passedsite content › compiles /docs/monitors/clock-reliability with a component and a table of contents22 ms
Passedsite content › compiles /docs/monitors/clock-drift with a component and a table of contents29 ms
Passedsite content › compiles /docs/monitors/browser-reports with a component and a table of contents23 ms
Passedsite content › compiles /docs/architecture with a component and a table of contents30 ms
Passedsite content › compiles /docs/api with a component and a table of contents81 ms
Passedsite content › compiles /docs/operations/opentelemetry with a component and a table of contents45 ms
Passedsite content › compiles /docs/operations/grafana-stack with a component and a table of contents136 ms
Passedsite content › compiles /docs/operations/dashboards with a component and a table of contents181 ms
Passedsite content › compiles /docs/testing/strategy with a component and a table of contents112 ms
Passedsite content › compiles /docs/contributing/writing-style with a component and a table of contents22 ms
Passedsite content › compiles /docs/contributing/development with a component and a table of contents20 ms
Passedsite content › compiles /research with a component and a table of contents25 ms
Passedsite content › compiles /research/browser-support with a component and a table of contents110 ms
Passedsite content › compiles /research/clocks-and-timers with a component and a table of contents256 ms
Passedsite content › compiles /research/local-experiments with a component and a table of contents116 ms
Passedsite content › compiles /research/web-vitals-algorithms with a component and a table of contents92 ms
Passedsite content › compiles /research/rum-landscape with a component and a table of contents60 ms
Passedsite content › compiles /research/otel-browser-metrics with a component and a table of contents91 ms
Passedsite content › compiles /research/writing-standard with a component and a table of contents24 ms
Passedsite content › compiles /research/sources with a component and a table of contents77 ms
Passedsite content › compiles /thesis with a component and a table of contents100 ms
packages/site/src/content/frontmatter.test.ts4 passed
StatusTestDuration
PassedparsePageMeta › accepts valid frontmatter3.7 ms
PassedparsePageMeta › keeps the status optional0.39 ms
PassedparsePageMeta › uses safe values and marks the page as a draft for invalid fields1.5 ms
PassedparsePageMeta › reports a missing frontmatter0.38 ms
packages/site/src/content/registry.test.ts12 passed
StatusTestDuration
PassedparseContentKey › splits a glob key into the section and the file3 ms
PassedparseContentKey › rejects a file that is not in a section folder0.44 ms
PassedslugOf and folderLabel › removes index from the path0.54 ms
PassedslugOf and folderLabel › makes a label from a folder name0.26 ms
PassedcreateContentRegistry › finds pages by section and slug0.71 ms
PassedcreateContentRegistry › lists the sections0.41 ms
PassedcreateContentRegistry › orders the sidebar by order, with each folder as one group0.34 ms
PassedcreateContentRegistry › reads the pages in sidebar order0.35 ms
PassedcreateContentRegistry › gives the previous and the next page0.48 ms
PassedcreateContentRegistry › has no problems for valid entries0.35 ms
PassedcreateContentRegistry › loads a page module only once2.6 ms
PassedcreateContentRegistry › reports invalid frontmatter and duplicate paths2.2 ms
packages/site/src/fixtures/sample-results.test.ts3 passed
StatusTestDuration
Passedsample results › has two valid runs3.9 ms
Passedsample results › covers Node and the three browser engines, with some failures1.7 ms
Passedsample results › is the same each time0.37 ms
packages/site/src/lib/lib.test.ts14 passed
StatusTestDuration
Passedformat › formats durations5.7 ms
Passedformat › rounds a duration of minutes to whole seconds before it divides them0.4 ms
Passedformat › shows 100% and 0% only for exactly 100 and 00.36 ms
Passedformat › formats percentages, bytes, units and counts5 ms
Passedformat › formats dates in UTC0.43 ms
Passedstats › uses the nearest-rank percentile3.1 ms
Passedstats › summarizes values0.47 ms
Passedstats › makes an ECDF and limits its points5.7 ms
Passedstats › bins values on a log(1 + x) scale4.2 ms
Passedstats › gives one bin when the values differ but have the same log(1 + x)0.4 ms
Passedstats › puts each value into a bin, also the maximum, and gives at least one bin0.41 ms
Passedstats › keeps spikes when it reduces a series0.58 ms
PassedmemoizePromise › returns the same promise and tries again after a rejection7 ms
PassedmemoizePromise › keeps one entry for each key0.56 ms
packages/site/src/playground/live-meter.test.ts4 passed
StatusTestDuration
PassedLiveMeter › keeps histogram values with their time and attributes5.9 ms
PassedLiveMeter › sums counter values0.59 ms
PassedLiveMeter › keeps only the newest samples, but counts all of them1 ms
PassedLiveMeter › shares one instrument for the same name0.8 ms
packages/site/src/playground/ring-buffer.test.ts4 passed
StatusTestDuration
PassedRingBuffer › keeps the newest items when it is full3.4 ms
PassedRingBuffer › returns the newest items that pass a test0.58 ms
PassedRingBuffer › can be cleared0.5 ms
PassedRingBuffer › refuses a capacity that is not a positive integer0.66 ms
packages/site/src/playground/session.test.ts11 passed
StatusTestDuration
PassedPlaygroundSession › starts idle6.6 ms
PassedPlaygroundSession › publishes snapshots two times each second while it runs8.8 ms
PassedPlaygroundSession › drops values that are older than the window1 ms
PassedPlaygroundSession › stops the handles, terminates the worker and leaves no timers1.2 ms
PassedPlaygroundSession › starts again with a new meter1.4 ms
PassedPlaygroundSession › reports a runtime that fails to start0.85 ms
PassedPlaygroundSession › runs one load at a time and keeps a history2.1 ms
PassedPlaygroundSession › has no timeline before the start, or without the names of the timeline0.87 ms
PassedPlaygroundSession › makes the timeline from the meter, the recorder and the vitals3.2 ms
PassedPlaygroundSession › shows each load on the timeline, and keeps the timeline after the stop3.3 ms
PassedPlaygroundSession › stops a profile when the session stops3.1 ms
packages/site/src/results/charts.test.ts7 passed
StatusTestDuration
PassedbarInset › keeps a bar at most 24 px thick4.7 ms
PassedbarInset › adds no inset when a band is already thin0.49 ms
PassedsymlogTicks › gives a 1-2-5 series up to the maximum3.2 ms
Passedmeasurement charts › build the histogram and the ECDF of almost equal values9 ms
Passedmeasurement charts › give the ticks short labels, not the precision of a very small domain2.7 ms
Passedlabels › formats a run date in UTC0.38 ms
Passedlabels › keeps the last two parts of a path0.82 ms
packages/site/src/results/report-source.test.ts13 passed
StatusTestDuration
PassedHttpReportSource › reads index.json below the base URL5.2 ms
PassedHttpReportSource › adds the slash after a base URL without one0.49 ms
PassedHttpReportSource › gives an empty index if there is no file0.48 ms
PassedHttpReportSource › gives an empty index for the HTML page of a single-page app fallback0.64 ms
PassedHttpReportSource › fails for a server error and for bad JSON1.9 ms
PassedHttpReportSource › accepts a run without budget counts, and refuses budget counts that are not numbers2 ms
PassedHttpReportSource › fails for an old schema version0.72 ms
PassedHttpReportSource › reads a run file and checks it1.3 ms
PassedHttpReportSource › refuses a run file outside the results folder0.82 ms
PassedisSafeRelativePath › accepts a path in the folder and rejects other paths1.5 ms
PassedMemoryReportSource › makes the index from the runs1.1 ms
PassedMemoryReportSource › can be empty0.31 ms
PassedcachedReportSource › loads each file once and tries again after a failure2.2 ms
packages/site/src/results/run-pages.test.ts2 passed
StatusTestDuration
Passedrun pages › finds the view of a URL path, and the overview for the path of the run3.4 ms
Passedrun pages › gives each view a different title0.47 ms
packages/site/src/theme/theme.test.ts11 passed
StatusTestDuration
Passedtheme preference › reads only light and dark; anything else is system3 ms
Passedtheme preference › cycles system, light, dark0.68 ms
Passedtheme preference › resolves the system preference2.3 ms
Passedpreference stores › keeps values in memory0.48 ms
Passedpreference stores › works with a storage that throws2.8 ms
Passedpreference stores › works when the storage itself cannot be read0.54 ms
Passedpreference stores › works without a storage5.5 ms
PassedmixColor › puts a color with an opacity on a background, as an opaque color1.2 ms
PassedmixColor › gives a color that is not a hex color without a change0.99 ms
Passedcontrast › calculates the relative luminance and the contrast ratio of WCAG 21.1 ms
Passedcontrast › selects the text color with the higher contrast on a fill0.47 ms
packages/site/src/playground/timeline/docs-example.test.ts1 passed
StatusTestDuration
Passedthe simulated session of the documentation › agrees with the text of the statistics page7.5 ms
packages/site/src/playground/timeline/epochs.test.ts13 passed
StatusTestDuration
PassedblockEpisodes › joins a frame, a hang and a stall of the same block into one episode10 ms
PassedblockEpisodes › ignores a frame that blocks less than the threshold, and a stall of a suspend4.8 ms
PassedblockEpisodes › joins blocks that are less than the gap apart2.8 ms
PassedtCritical95 › gives the critical values of the t distribution3.8 ms
PassedbinStat › gives the mean, and the interval only for 3 or more values0.54 ms
PassedepochAverages › averages each signal in its bin9.4 ms
PassedepochAverages › aligns at the end of each block4.1 ms
PassedepochAverages › gives no value for the bins outside the recorded time1.4 ms
PassedepochAverages › gives no blocking value in a browser without long animation frames1.1 ms
PassedepochAverages › counts no epoch whose window is completely outside the recorded time0.41 ms
PassedreportedLagIn › sums the lag of the windows that end in the bin0.18 ms
PassedreportedLagIn › gives 0 ms in a long window, where the monitor reports nothing yet0.14 ms
PassedreportedLagIn › gives no value where no window covers the bin0.15 ms
packages/site/src/playground/timeline/inp-scatter.test.ts4 passed
StatusTestDuration
PassedoverlappingFrames › finds the frames whose time ranges overlap the interaction6.1 ms
PassedoverlappingFrames › does not count a frame that only touches the interaction4.1 ms
PassedinteractionScatter › gives each interaction the blocking time of the frames that overlap it1.3 ms
PassedsummarizeScatter › counts the slow interactions and the interactions with frames3.9 ms
packages/site/src/playground/timeline/items.test.ts16 passed
StatusTestDuration
PassedtimelineItems › gives the items of the visible tracks, sorted by start6.5 ms
PassedtimelineItems › finds the items that overlap the visible range3.1 ms
PassedadjacentItem › goes from the current item to the next and to the previous item0.71 ms
PassedadjacentItem › starts from a time without a current item0.37 ms
PassedhitTest › finds a long animation frame under the pointer0.7 ms
PassedhitTest › finds the hang in the upper row and the stall in the lower row0.32 ms
PassedhitTest › finds the interactions in the lower row, and the marks in the upper row of the vitals3.5 ms
PassedhitTest › finds the nearest drift window, and the lifecycle period1.7 ms
PassedhitTest › finds nothing outside the tracks0.92 ms
PasseddescribeItem › describes a frame with its blocking time1.4 ms
PasseddescribeItem › describes a span with its attributes, and an open span to now1.7 ms
PasseddescribeItem › describes an interaction with its parts and its rating0.48 ms
PasseddescribeItem › gives one sentence for the live region0.43 ms
PasseddescribeItem › gives a key that stays the same for the same item0.31 ms
Passedhelpers › formats a score with more decimals when it is very small0.24 ms
Passedhelpers › finds the first item at or above a value0.21 ms
packages/site/src/playground/timeline/model.test.ts13 passed
StatusTestDuration
PassedbuildTimelineModel › gives all times in seconds since the start of the session5.3 ms
PassedbuildTimelineModel › sorts the spans by name, and an open span ends at the present time1.6 ms
PassedbuildTimelineModel › shows a load that is active until the present time0.47 ms
PassedbuildTimelineModel › shows nothing that is more than 10 minutes before the session0.54 ms
PassedbuildTimelineModel › uses the time of the stop as the present time1 ms
PassedplaceLateWindows › moves a long window that the conditions recorded late to the gap that it fills1.4 ms
PassedplaceLateWindows › keeps a long window that follows its gap0.6 ms
PassedplaceLateWindows › keeps a long window without a gap of its length, and gives each gap to one window only0.6 ms
PassedlifecycleSegments › starts with the state before the first transition, and merges a transition to the same state0.48 ms
PassedlifecycleSegments › uses the current state without transitions, and gives nothing without a state0.45 ms
PassedpressureSegments › makes the periods of each source from its changes0.41 ms
PassedgroupInteractions › joins the entries of one interaction, as INP does1.1 ms
PassedrateDuration › uses the INP thresholds: at or below good is good, above poor is poor0.22 ms
packages/site/src/playground/timeline/recorder.test.ts6 passed
StatusTestDuration
PassedSessionRecorder › records events at the time of the occurrence, on the session clock9.2 ms
PassedSessionRecorder › gives an event without a time (or with a time that is not finite) the time of the call0.8 ms
PassedSessionRecorder › gives each span an identity, and keeps the trace of the parent3 ms
PassedSessionRecorder › changes the attributes and the end of an open span only until it ends0.88 ms
PassedSessionRecorder › keeps the entries of the probes7.8 ms
PassedSessionRecorder › keeps only the newest items of each kind2.1 ms
packages/site/src/playground/timeline/tracks.test.ts3 passed
StatusTestDuration
PassedlayoutTracks › places the visible tracks from top to bottom without gaps5.9 ms
PassedlayoutTracks › has each track once, in a fixed order0.63 ms
PassedlayoutTracks › finds the track at a height0.92 ms
packages/site/src/playground/timeline/viewport.test.ts13 passed
StatusTestDuration
PassedclampViewport › keeps a range in the bounds, with a small space after the present time9.1 ms
PassedclampViewport › limits the length to the minimum and to all the data0.51 ms
PassedclampViewport › starts a range that is longer than a short session at the start of the data0.35 ms
PassedzoomViewport › keeps the anchor at the same place on the screen0.38 ms
PassedzoomViewport › zooms out to all the data at most0.5 ms
PassedpanViewport › moves the range and stops at the bounds0.34 ms
PassedfollowViewport › shows the present time near the right edge0.33 ms
PassedfollowViewport › starts at the earliest data while the session is shorter than the range0.27 ms
PassedfitViewport › shows all data0.46 ms
Passedtime and pixels › converts in both directions0.57 ms
Passedticks › uses steps of 1, 2 or 5 multiplied by a power of 100.55 ms
Passedticks › formats the ticks with the decimals of the step and a minus sign1.1 ms
Passedticks › puts a tick at each multiple of the step in the range3 ms
packages/site/src/results/model/model.test.ts25 passed
StatusTestDuration
Passedtests model › flattens every test with its suite and file5.5 ms
Passedtests model › finds the failed and the slowest tests2.8 ms
Passedtests model › filters by text, status and environment0.97 ms
Passedtests model › groups the matching tests by suite and file3.4 ms
Passedgroup status › shows a group with only skipped tests as skipped, and a group without tests as none, not as passed0.54 ms
Passedgroup status › gives the counts as text0.51 ms
Passedrun summary status › fails a run with a failed budget, also when all tests passed0.72 ms
Passedrun summary status › passes a run whose tests and budgets passed, also from an index without budget counts1.9 ms
Passedenvironment matrix › puts node first, then the engines0.38 ms
Passedenvironment matrix › has one cell for each package and environment2.7 ms
PasseddurationBins › counts in 1-2-5 bins and trims the empty ends2.4 ms
Passedcoverage model › calculates percentages, and undefined for nothing to cover0.33 ms
Passedcoverage model › gives rows for packages and files0.89 ms
Passedmutation model › sorts the files by score and sums the packages1.3 ms
Passedmutation model › puts the files without a score last, and gives them no bar0.47 ms
Passedmutation model › gives the commit and the time of each Stryker run, and its age in days0.49 ms
Passedbudgets model › puts the failed budgets first0.79 ms
Passedmeasurements model › groups measurements by metric1.1 ms
Passedmeasurements model › offers the measurement, the suite and each label as grouping keys2.6 ms
Passedmeasurements model › groups each family by a label that the family has, with browser as the fallback1.2 ms
Passedmeasurements model › joins the values of each group and summarizes them4.8 ms
Passedmeasurements model › folds the smallest groups into Other past the limit0.98 ms
PassedsortRows › sorts numbers and keeps missing values last in both directions4.8 ms
PassedsortRows › changes the direction for the same column0.92 ms
Passedrun trend › orders the runs and makes one row per status0.78 ms

lag: Main-thread responsiveness monitoring for browser apps, exported as OpenTelemetry metrics.

To change a page, edit its file in packages/site/content/. The writing style guide tells you how.

An AI model (Claude, from Anthropic) wrote most of the text and the code of this site and of the library, under the direction of the author. The tests and the STE linter examine them. The writing standard gives the reason for this note.