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
| Status | Test | Duration |
|---|---|---|
| Passed | BaselineConfirmation › needs a check from the start: a probe before the first window can start a check | 3.1 ms |
| Passed | BaselineConfirmation › has no value at first, and asks for a check at the end of the first window | 1.4 ms |
| Passed | BaselineConfirmation › confirms a value with an idle probe, 3 steps and an idle closing probe | 0.82 ms |
| Passed | BaselineConfirmation › ignores the steps that are not in a check | 0.37 ms |
| Passed | BaselineConfirmation › asks for a check at each window after a busy probe, until a check confirms a value | 0.96 ms |
| Passed | BaselineConfirmation › discards a check when the closing probe is busy, and asks again at the next window | 0.38 ms |
| Passed | BaselineConfirmation › discards a check whose steps do not agree | 0.28 ms |
| Passed | BaselineConfirmation › asks for no probe while a check operates | 0.35 ms |
| Passed | BaselineConfirmation › starts a new check when a probe comes before the end of a check | 0.31 ms |
| Passed | BaselineConfirmation › uses the confirmed value while the recent baseline is more than max(1 ms, 10%) above it | 0.51 ms |
| Passed | BaselineConfirmation › lowers the confirmed value to the highest recent baseline of the last 3 windows | 0.8 ms |
| Passed | BaselineConfirmation › keeps the confirmed value after a short decrease of the recent baseline | 0.3 ms |
| Passed | BaselineConfirmation › ignores a probe of a row when no check is necessary | 0.3 ms |
| Passed | BaselineConfirmation › keeps the confirmed value when the check agrees with it, and gives the limit of the load | 0.47 ms |
| Passed | BaselineConfirmation › gives no limit when the closing probe is busy, or when the steps do not agree | 0.52 ms |
| Passed | BaselineConfirmation › confirms a larger value when the check agrees with the recent baseline | 0.49 ms |
| Passed | BaselineConfirmation › sets a new granularity with accept(), and ends a check | 0.75 ms |
| Passed | BaselineConfirmation › does not confirm a first value with accept(): only a check does | 0.26 ms |
packages/lag/src/BrowserReportMonitor.test.ts9 passed
| Status | Test | Duration |
|---|---|---|
| Passed | BrowserReportMonitor › gets the reports from before its start, and after stop() and start() no report a second time | 5 ms |
| Passed | BrowserReportMonitor › asks for the buffered reports again when the first start failed | 2.2 ms |
| Passed | BrowserReportMonitor › observes interventions and deprecations, including buffered reports | 0.71 ms |
| Passed | BrowserReportMonitor › reports the fields of each report body | 0.64 ms |
| Passed | BrowserReportMonitor › logs a warning when ReportingObserver is not available | 0.54 ms |
| Passed | BrowserReportMonitor › isolates a report callback that throws | 0.51 ms |
| Passed | BrowserReportMonitor › disconnects on stop and can start again, without the buffered reports | 0.56 ms |
| Passed | BrowserReportMonitor › start() while the monitor observes makes no second observer, and stop() works after a start that failed | 1.4 ms |
| Passed | BrowserReportMonitor › names the error and the monitor in its logs | 0.88 ms |
packages/lag/src/BusyTimeProbe.test.ts8 passed
| Status | Test | Duration |
|---|---|---|
| Passed | BusyTimeProbe › measures no busy time on an idle thread | 10 ms |
| Passed | BusyTimeProbe › measures the tasks that keep the thread busy: each task delays one message | 7.1 ms |
| Passed | BusyTimeProbe › counts the wait of the message that did not start when it stops | 0.64 ms |
| Passed | BusyTimeProbe › counts only the waits of more than 2 ms | 0.36 ms |
| Passed | BusyTimeProbe › gives 0 without a measurement, and after a measurement stopped | 0.25 ms |
| Passed | BusyTimeProbe › ignores a message of an earlier measurement | 1.7 ms |
| Passed | BusyTimeProbe › starts again from 0 when start() comes during a measurement | 0.22 ms |
| Passed | BusyTimeProbe › stops the chain: after stop(), a message posts no other message | 0.3 ms |
packages/lag/src/ClockDriftMonitor.test.ts18 passed
| Status | Test | Duration |
|---|---|---|
| Passed | ClockDriftMonitor › samples every second by default and reports a skew near 0 while both clocks agree | 11 ms |
| Passed | ClockDriftMonitor › tolerates gradual correction of the wall clock | 1.3 ms |
| Passed | ClockDriftMonitor › scales the threshold with the interval: 3% of the time between samples | 2.9 ms |
| Passed | ClockDriftMonitor › classifies a forward jump of 1 s or more as a suspend | 0.98 ms |
| Passed | ClockDriftMonitor › classifies a smaller forward jump as a step | 0.75 ms |
| Passed | ClockDriftMonitor › classifies a backward jump as a step | 0.6 ms |
| Passed | ClockDriftMonitor › classifies a forward jump during a late timer as a suspend too, because timers are late in a hidden page | 0.72 ms |
| Passed | ClockDriftMonitor › finds a sleep in a hidden page in which the browser runs the timer one time each minute | 0.78 ms |
| Passed | ClockDriftMonitor › finds no discontinuity when both clocks continue, as in a Windows sleep or a blocked thread | 0.68 ms |
| Passed | ClockDriftMonitor › ignores a sample when the thread stopped between the two reads of the monotonic clock | 0.8 ms |
| Passed | ClockDriftMonitor › measures drift from the restart, not across a stopped period | 1 ms |
| Passed | ClockDriftMonitor › stops its timer | 0.58 ms |
| Passed | ClockDriftMonitor › logs instead of throwing when report throws | 0.92 ms |
| Passed | ClockDriftMonitor › start() while the monitor operates adds no second interval | 0.46 ms |
| Passed | ClockDriftMonitor › keeps a reading whose two reads of the monotonic clock are 1 ms apart | 0.54 ms |
| Passed | ClockDriftMonitor › compares the first sample with nothing when the reading at the start was not valid | 0.6 ms |
| Passed | ClockDriftMonitor › does not count a drift of exactly the limit as a jump | 0.45 ms |
| Passed | ClockDriftMonitor › classifies a forward jump of exactly 1000 ms as a suspend | 0.67 ms |
packages/lag/src/ClockReliabilityChecker.test.ts10 passed
| Status | Test | Duration |
|---|---|---|
| Passed | ClockReliabilityChecker › detects clock resolution from rapid samples | 3.1 ms |
| Passed | ClockReliabilityChecker › detects a coarse clock that stays flat across many consecutive reads | 3.9 ms |
| Passed | ClockReliabilityChecker › reports high resolution for a cross-origin-isolated clock (5μs) | 0.23 ms |
| Passed | ClockReliabilityChecker › reports low resolution for a 1ms clock | 2.7 ms |
| Passed | ClockReliabilityChecker › measures once and caches the result | 0.2 ms |
| Passed | ClockReliabilityChecker › samples again after a call where the clock never ticked | 8.4 ms |
| Passed | ClockReliabilityChecker › exposes the time origin from performance | 0.29 ms |
| Passed | ClockReliabilityChecker › returns 0 and is not high-resolution for a clock that never advances | 10 ms |
| Passed | ClockReliabilityChecker › is not high-resolution at a resolution of exactly 50 μs | 0.75 ms |
| Passed | ClockReliabilityChecker › measures the resolution from the smallest of the first 5 ticks of the clock | 0.29 ms |
packages/lag/src/ClsCalculator.test.ts13 passed
| Status | Test | Duration |
|---|---|---|
| Passed | ClsCalculator boundaries › starts a new window at a gap of exactly 1000 ms and at a length of exactly 5000 ms, as web-vitals does | 2.5 ms |
| Passed | ClsCalculator › sums shifts in one session window | 0.34 ms |
| Passed | ClsCalculator › starts a new window after a gap of more than 1 s | 0.16 ms |
| Passed | ClsCalculator › starts a new window when a window is longer than 5 s | 0.16 ms |
| Passed | ClsCalculator › keeps the sources of the largest shift in the worst window | 0.84 ms |
| Passed | ClsCalculator › counts the 5 s length of a window from its first shift, also when the first shift is late | 0.22 ms |
| Passed | ClsCalculator › starts the first window after reset() at the first shift | 0.19 ms |
| Passed | ClsCalculator › gives no sources for a shift without sources | 0.16 ms |
| Passed | ClsCalculator › keeps the largest shift of a window when a smaller shift follows | 0.87 ms |
| Passed | ClsCalculator › names the later of two shifts with the same score in a window, as web-vitals does | 0.18 ms |
| Passed | ClsCalculator › keeps the first of two windows with the same score as the worst window, as web-vitals does | 0.29 ms |
| Passed | ClsCalculator › reset() clears everything | 0.28 ms |
| Passed | ClsCalculator › agrees with the reference definition for any sequence of shifts (property test) | 25 ms |
packages/lag/src/ComputePressureMonitor.test.ts15 passed
| Status | Test | Duration |
|---|---|---|
| Passed | ComputePressureMonitor › constructs a PressureObserver and observes the configured sources | 6.2 ms |
| Passed | ComputePressureMonitor › reports records with state ordinals | 1.4 ms |
| Passed | ComputePressureMonitor › tracks the latest state per source | 0.48 ms |
| Passed | ComputePressureMonitor › getWorstStateOrdinal returns the max across sources | 0.49 ms |
| Passed | ComputePressureMonitor › returns -1 worst ordinal before any samples | 0.96 ms |
| Passed | ComputePressureMonitor › logs a warning if observe() rejects (unsupported source) | 0.76 ms |
| Passed | ComputePressureMonitor › logs a warning if PressureObserver constructor throws | 0.35 ms |
| Passed | ComputePressureMonitor › disconnects on stop and clears state | 0.48 ms |
| Passed | ComputePressureMonitor › prevents double-start | 0.43 ms |
| Passed | ComputePressureMonitor › rules of the observer › observes again after stop() and start() | 0.46 ms |
| Passed | ComputePressureMonitor › rules of the observer › stop() works, and the monitor logs the reason, when the browser has no PressureObserver | 1.3 ms |
| Passed | ComputePressureMonitor › rules of the observer › logs the source that the browser does not support | 0.51 ms |
| Passed | ComputePressureMonitor › rules of the observer › gives the most severe state of all sources, also when a less severe record comes last | 0.25 ms |
| Passed | ComputePressureMonitor › rules of the observer › logs no warning when stop() rejects the pending observe() calls, also after a new start | 3.4 ms |
| Passed | ComputePressureMonitor › rules of the observer › logs an error from the report function and continues with the next record | 0.8 ms |
packages/lag/src/DriftLag.granularity.test.ts19 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag when the timer granularity changes › reports no lag on an idle thread after the steps change from 6 ms to 16 ms | 25 ms |
| Passed | DriftLag when the timer granularity changes › adapts the baseline to the new granularity in about one second | 9.7 ms |
| Passed | DriftLag when the timer granularity changes › gives no lag when the change comes at the end of a window: the window waits for the row | 3.2 ms |
| Passed | DriftLag when the timer granularity changes › ends the window at the step that accepts the new granularity | 1.3 ms |
| Passed | DriftLag when the timer granularity changes › gives the old baseline to the steps of the window before the row of a finer granularity | 2.5 ms |
| Passed | DriftLag when the timer granularity changes › follows a change to a finer granularity, and then measures a block correctly | 8.8 ms |
| Passed | DriftLag when the timer granularity changes › keeps a row of long steps (more than 40 ms) as lag: no granularity is that coarse | 8.5 ms |
| Passed | DriftLag when the timer granularity changes › keeps a row of steps that do not agree with each other as lag | 9.1 ms |
| Passed | DriftLag baseline › is the mean of the steps that are not longer than the median plus max(4 ms, half the median) | 4.4 ms |
| Passed | DriftLag baseline › leaves out a block, also when the block comes before shorter steps | 0.83 ms |
| Passed | DriftLag baseline of a short window of steps › uses the mean of the two middle steps as the median of an even number of steps | 1.6 ms |
| Passed | DriftLag 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 limit | 0.68 ms |
| Passed | DriftLag rules for a change of the granularity › accepts a new granularity after exactly 10 steps in a row | 11 ms |
| Passed | DriftLag rules for a change of the granularity › starts a new row of steps after a restart | 4.7 ms |
| Passed | DriftLag rules for a change of the granularity › does not change the baseline for a row that a normal step interrupts | 5 ms |
| Passed | DriftLag 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 |
| Passed | DriftLag rules for a change of the granularity › accepts a row of steps of exactly 40 ms as a new granularity | 3.7 ms |
| Passed | DriftLag rules for a change of the granularity › accepts a row of steps that differ by 20 % of their mean as one granularity | 3.2 ms |
| Passed | DriftLag 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 end | 2.7 ms |
packages/lag/src/DriftLag.load.test.ts35 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag during a sustained load › reports equal tasks of 20 ms as lag, also after 5 s | 16 ms |
| Passed | DriftLag during a sustained load › reported the same load as a new granularity without a probe | 9.3 ms |
| Passed | DriftLag during a sustained load › reports equal timer tasks of 30 ms, 5 ms apart, as lag | 8.9 ms |
| Passed | DriftLag during a sustained load › reports equal tasks of 20 ms as lag when the idle step takes 15.6 ms | 12 ms |
| Passed | DriftLag during a sustained load › reported less lag without a probe when the idle step takes 15.6 ms | 5.7 ms |
| Passed | DriftLag during a sustained load › reports no lag after the load, and the probes stop | 13 ms |
| Passed | DriftLag during a sustained load › measures a block after the load correctly | 11 ms |
| Passed | DriftLag during a sustained load › finds the idle baseline when the monitor starts during a load | 2.7 ms |
| Passed | DriftLag during a sustained load › removes the busy steps with one check after a load, when the busy steps are in the jitter limit | 6.9 ms |
| Passed | DriftLag during a sustained load › finds the idle baseline of 15.6 ms when the monitor starts during a load of 20 ms tasks | 3.2 ms |
| Passed | DriftLag with a probe when the timer granularity changes › accepts a coarser granularity on an idle thread after 10 steps, with no lag | 4.6 ms |
| Passed | DriftLag 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 row | 4.8 ms |
| Passed | DriftLag with a probe when the timer granularity changes › accepts a finer granularity with no probe | 4.3 ms |
| Passed | DriftLag with a probe when the timer granularity changes › confirms a small increase of the granularity with a probe | 4.1 ms |
| Passed | DriftLag with a probe when the timer granularity changes › does one check on an idle thread, after the first window | 2 ms |
| Passed | DriftLag with a probe when the timer granularity changes › adds the first step to the recent steps | 0.22 ms |
| Passed | DriftLag with a probe when the timer granularity changes › stops a probe when the monitor stops | 0.41 ms |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag when the granularity changes at any time in a window › measures a block of 100 ms just before a change to a coarser granularity | 266 ms |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag with the timer tick of Windows after a start › measures a block after a restart in which the granularity changed | 38 ms |
| Passed | DriftLag probe rules › probes the step after the 5th step of a row of longer steps | 2.1 ms |
| Passed | DriftLag probe rules › does not use the probe of an earlier row for a new row | 4.2 ms |
| Passed | DriftLag probe rules › ends the row when it accepts a new granularity: the next windows have their normal length | 3.2 ms |
| Passed | DriftLag probe rules › lowers the confirmed value with the baseline: a later small increase needs a probe | 5.3 ms |
| Passed | DriftLag with a probe that changes the timing › confirms the idle duration from steps that were not probed, when a probe makes a step shorter | 2.8 ms |
| Passed | DriftLag with a probe that changes the timing › confirms a new idle duration also when the step after a probe is longer | 4.3 ms |
| Passed | DriftLag with a probe that changes the timing › operates as without a probe when each message waits | 8.8 ms |
| Passed | DriftLag without a probe › has no confirmed value: after a row of shorter steps, the baseline follows a small increase | 3.3 ms |
| Passed | DriftLag without a probe › operates with the default options | 1.1 ms |
| Passed | DriftLag without a probe › clears the timer one time when it stops two times | 1.7 ms |
packages/lag/src/DriftLag.power.test.ts25 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag with the timer alignment of WebKit › gives steps of 8 ms with the normal alignment of 4 ms (offset 0) | 19 ms |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag with the timer alignment of WebKit › gives steps of 8 ms with the normal alignment of 4 ms (offset 0.37) | 2.5 ms |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag with the timer alignment of WebKit › gives steps of 8 ms with the normal alignment of 4 ms (offset 0.9) | 1.6 ms |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag 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 |
| Passed | DriftLag with the timer alignment of WebKit › follows a change into Low Power Mode and out of it | 6.4 ms |
packages/lag/src/DriftLag.test.ts14 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag › reports no lag on an idle thread with exact timers | 12 ms |
| Passed | DriftLag › subtracts the timer granularity: an idle thread with 16 ms steps has no lag | 3.3 ms |
| Passed | DriftLag › changes the number of steps so that a window stays near the expected length | 1.5 ms |
| Passed | DriftLag › reports the length of a block in the window | 1.3 ms |
| Passed | DriftLag › keeps the baseline when one step is long | 2.7 ms |
| Passed | DriftLag › uses the requested step as the baseline before the first step | 0.69 ms |
| Passed | DriftLag › requests the same step delay for every step, with or without lag | 2.6 ms |
| Passed | DriftLag › logs errors and continues monitoring when report throws | 2.8 ms |
| Passed | DriftLag › stop() right after construction clears the pending timer | 2 ms |
| Passed | DriftLag › stop() from inside report stops the loop | 0.84 ms |
| Passed | DriftLag › start() after stop() measures from the restart, not across the stopped time | 1.1 ms |
| Passed | DriftLag › start() while running does not add a second timer chain | 0.64 ms |
| Passed | DriftLag › stop() + start() from inside report leaves exactly one timer chain | 0.98 ms |
| Passed | DriftLag › uses whole steps for a window: 103 ms gives 20 steps of 5 ms | 0.98 ms |
packages/lag/src/EventTimingMonitor.test.ts24 passed
| Status | Test | Duration |
|---|---|---|
| Passed | EventTimingMonitor › reports decomposed event timing | 7.8 ms |
| Passed | EventTimingMonitor › ignores events with interactionId=0 | 0.64 ms |
| Passed | EventTimingMonitor › calculates INP as p98 of interaction durations | 1.9 ms |
| Passed | EventTimingMonitor › returns 0 INP with no interactions | 0.43 ms |
| Passed | EventTimingMonitor › tracks worst interaction duration per interactionId | 0.46 ms |
| Passed | EventTimingMonitor › resets on stop | 0.49 ms |
| Passed | EventTimingMonitor › asks the browser for events down to 16ms (default threshold is 104ms) | 1.3 ms |
| Passed | EventTimingMonitor › keeps INP correct while tracking only the longest few interactions | 7.2 ms |
| Passed | EventTimingMonitor › counts an interaction once across its several events | 2.2 ms |
| Passed | EventTimingMonitor › clamps presentationDelay at 0 when rounding makes it negative | 0.37 ms |
| Passed | EventTimingMonitor › uses performance.interactionCount when the browser supplies it | 1.3 ms |
| Passed | EventTimingMonitor › counts the interactions from the start of the page, as the buffered candidates from before the start do | 0.62 ms |
| Passed | EventTimingMonitor › counts the interactions it saw when the browser count is missing | 0.46 ms |
| Passed | EventTimingMonitor › processes the buffered entries that the browser delivers inside observe(), as old Safari did | 0.97 ms |
| Passed | EventTimingMonitor › gives the event keydown the interaction type keyboard | 0.29 ms |
| Passed | EventTimingMonitor › gives the event keyup the interaction type keyboard | 0.14 ms |
| Passed | EventTimingMonitor › gives the event pointerdown the interaction type pointer | 0.16 ms |
| Passed | EventTimingMonitor › gives the event mousedown the interaction type pointer | 0.11 ms |
| Passed | EventTimingMonitor › gives the event click the interaction type pointer | 0.1 ms |
| Passed | EventTimingMonitor › gives the event auxclick the interaction type pointer | 0.12 ms |
| Passed | EventTimingMonitor › gives the event contextmenu the interaction type pointer | 0.11 ms |
| Passed | EventTimingMonitor › gives the event touchstart the interaction type pointer | 0.1 ms |
| Passed | EventTimingMonitor › gives the event dblclick the interaction type other | 0.1 ms |
| Passed | EventTimingMonitor › gives the event input the interaction type other | 0.13 ms |
packages/lag/src/FrameTimingMonitor.test.ts26 passed
| Status | Test | Duration |
|---|---|---|
| Passed | FrameTimingMonitor › schedules an animation frame on construction | 4.9 ms |
| Passed | FrameTimingMonitor › does not report on the first frame (no previous baseline) | 1.9 ms |
| Passed | FrameTimingMonitor › reports zero dropped frames for an on-time frame | 1.3 ms |
| Passed | FrameTimingMonitor › reports exact dropped frame count for a delayed frame | 0.75 ms |
| Passed | FrameTimingMonitor › counts a 100ms gap as 5 dropped frames at 60fps | 0.28 ms |
| Passed | FrameTimingMonitor › tolerates slightly-late frames (16.67 → 17ms) | 0.27 ms |
| Passed | FrameTimingMonitor › tracks total dropped frames and dropped frame rate | 0.52 ms |
| Passed | FrameTimingMonitor › resets counters | 1.5 ms |
| Passed | FrameTimingMonitor › cancels pending frame on stop | 1.2 ms |
| Passed | FrameTimingMonitor › respects custom target FPS | 0.42 ms |
| Passed | FrameTimingMonitor › stop() + start() inside report: one rAF chain, and no frame spanning the pause | 1.7 ms |
| Passed | FrameTimingMonitor › automatic frame interval › follows a 120 Hz display | 0.76 ms |
| Passed | FrameTimingMonitor › automatic frame interval › does not count a 30 fps limit (power saving) as dropped frames | 0.65 ms |
| Passed | FrameTimingMonitor › automatic frame interval › keeps the estimate through a burst of jank | 1.7 ms |
| Passed | FrameTimingMonitor › automatic frame interval › ignores deltas too short to be a refresh interval | 0.39 ms |
| Passed | FrameTimingMonitor › automatic frame interval › keeps the interval when one gap is short: a late frame and then an on-time frame | 3 ms |
| Passed | FrameTimingMonitor › automatic frame interval › measures the gaps between the frame timestamps, not the times at which the callbacks run | 1.1 ms |
| Passed | FrameTimingMonitor › automatic frame interval › reads the clock when the callback gets no frame timestamp | 0.51 ms |
| Passed | FrameTimingMonitor › rules of the frame interval › uses 60 Hz before the first frames | 0.55 ms |
| Passed | FrameTimingMonitor › rules of the frame interval › estimates the interval for the target fps "auto" | 0.39 ms |
| Passed | FrameTimingMonitor › rules of the frame interval › uses 60 Hz until the window has five deltas | 0.67 ms |
| Passed | FrameTimingMonitor › rules of the frame interval › accepts a delta of 4 ms as a frame interval | 0.26 ms |
| Passed | FrameTimingMonitor › rules of the frame interval › uses the fifth-shortest delta, thus four short deltas do not change the interval | 0.37 ms |
| Passed | FrameTimingMonitor › rules of the frame interval › follows a change from 60 Hz to 120 Hz at the fifth short delta | 0.33 ms |
| Passed | FrameTimingMonitor › rules of the frame interval › follows a change from 120 Hz to 60 Hz after 600 frames | 15 ms |
| Passed | FrameTimingMonitor › rules of the frame interval › logs an error from the report function and continues with the next frame | 1.8 ms |
packages/lag/src/GCSignalDetector.test.ts10 passed
| Status | Test | Duration |
|---|---|---|
| Passed | GCSignalDetector › arms exactly one canary on construction | 4.2 ms |
| Passed | GCSignalDetector › records a GC event when the canary is collected, and re-arms | 3 ms |
| Passed | GCSignalDetector › counts one event per GC cycle, however long the gap between cycles | 0.43 ms |
| Passed | GCSignalDetector › didGCRecently returns true only within the window | 0.63 ms |
| Passed | GCSignalDetector › getRecentGCEvents counts events in window | 0.73 ms |
| Passed | GCSignalDetector › respects the historySize ring buffer | 0.52 ms |
| Passed | GCSignalDetector › ignores collections after stop and doesn't re-arm | 0.35 ms |
| Passed | GCSignalDetector › re-arms on restart, without doubling up when the old canary is still pending | 0.47 ms |
| Passed | GCSignalDetector › logs an error and keeps detecting if the cleanup callback throws | 1.4 ms |
| Passed | GCSignalDetector › counts a GC exactly at the edge of the window | 0.4 ms |
packages/lag/src/IdleAvailabilityMonitor.test.ts12 passed
| Status | Test | Duration |
|---|---|---|
| Passed | IdleAvailabilityMonitor › schedules an idle callback on construction | 4.8 ms |
| Passed | IdleAvailabilityMonitor › reports timeRemaining and didTimeout | 1.6 ms |
| Passed | IdleAvailabilityMonitor › reports timeSinceLastIdleMs as 0 on first fire | 1.1 ms |
| Passed | IdleAvailabilityMonitor › reports time gap between idle fires | 0.28 ms |
| Passed | IdleAvailabilityMonitor › tracks timeout rate | 0.36 ms |
| Passed | IdleAvailabilityMonitor › returns zero timeout rate before any fires | 0.36 ms |
| Passed | IdleAvailabilityMonitor › resets counters | 0.26 ms |
| Passed | IdleAvailabilityMonitor › cancels pending idle callback on stop | 0.3 ms |
| Passed | IdleAvailabilityMonitor › rules of the gaps and of the callback chain › gives a gap of 0 for the first callback after a restart | 0.77 ms |
| Passed | IdleAvailabilityMonitor › rules of the gaps and of the callback chain › measures the gap from a callback at the time 0 | 0.32 ms |
| Passed | IdleAvailabilityMonitor › rules of the gaps and of the callback chain › logs an error from the report function and continues with the next callback | 1.1 ms |
| Passed | IdleAvailabilityMonitor › rules of the gaps and of the callback chain › leaves one waiting callback when report() stops and starts the monitor | 0.44 ms |
packages/lag/src/InpCalculator.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | InpCalculator › returns 0 without interactions | 3.5 ms |
| Passed | InpCalculator › ignores entries without an interactionId | 0.55 ms |
| Passed | InpCalculator › uses the longest event of an interaction | 0.39 ms |
| Passed | InpCalculator › counts interactions since the start when the browser supplies a count | 0.27 ms |
| Passed | InpCalculator › reset() starts a new calculation and a new count baseline | 0.4 ms |
| Passed | InpCalculator › reset() with a baseline counts from that baseline | 0.24 ms |
| Passed | InpCalculator › reset() without a browser count clears the calculation | 0.25 ms |
| Passed | InpCalculator › counts the events of one interaction as one candidate, also at 50 or more interactions | 0.35 ms |
| Passed | InpCalculator › gives the shortest kept interaction when the number of outliers is larger than the number of kept interactions | 0.49 ms |
| Passed | InpCalculator › gives 0 as the longest duration without interactions | 0.22 ms |
| Passed | InpCalculator › agrees with the reference definition for any sequence of entries (property test) | 25 ms |
packages/lag/src/LagLogger.test.ts16 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LagLogger › should not log anything if utilization remains low | 6.5 ms |
| Passed | LagLogger › should ignore all measurements if the tab was hidden | 0.42 ms |
| Passed | LagLogger › should log warnings for both short and long-term violations if utilization is high enough | 3.8 ms |
| Passed | LagLogger › should reset its internal state after reporting | 5.3 ms |
| Passed | LagLogger › uses the interval of each measurement, for example windows of 93 ms | 3.7 ms |
| Passed | LagLogger › should handle buffer size correctly without unbounded growth | 4 ms |
| Passed | LagLogger › 'short-term' lag detection › should log a warning when average lag exceeds 100% over 2000ms | 1.4 ms |
| Passed | LagLogger › 'short-term' lag detection › should not log if utilization is below $threshold % | 1.3 ms |
| Passed | LagLogger › 'long-term' lag detection › should log a warning when average lag exceeds 50% over 5000ms | 1.4 ms |
| Passed | LagLogger › 'long-term' lag detection › should not log if utilization is below $threshold % | 0.82 ms |
| Passed | LagLogger › rules of the periods › warns for a 2 s period of high lag that comes after 10 s of low lag | 2 ms |
| Passed | LagLogger › rules of the periods › averages the lag of the most recent samples that cover the period, and no older sample | 1.4 ms |
| Passed | LagLogger › rules of the periods › does not warn for an average of exactly the threshold | 2.4 ms |
| Passed | LagLogger › rules of the periods › does not warn for one long sample that the 2 s period averages below 100 % | 1.3 ms |
| Passed | LagLogger › rules of the periods › warns for a 5 s period at the start of each report period | 3.1 ms |
| Passed | LagLogger › rules of the periods › uses the measurement interval when a measurement gives an interval of 0 | 1.5 ms |
packages/lag/src/LayoutShiftMonitor.test.ts9 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LayoutShiftMonitor › reports individual shift values | 6.6 ms |
| Passed | LayoutShiftMonitor › excludes shifts with hadRecentInput=true | 0.67 ms |
| Passed | LayoutShiftMonitor › accumulates session values within 1s gap | 0.61 ms |
| Passed | LayoutShiftMonitor › starts new session after 1s gap | 0.35 ms |
| Passed | LayoutShiftMonitor › starts new session after 5s max duration | 0.37 ms |
| Passed | LayoutShiftMonitor › tracks worst session value as CLS | 0.3 ms |
| Passed | LayoutShiftMonitor › resets on stop | 0.53 ms |
| Passed | LayoutShiftMonitor › reports the sources of each shift, and no sources for a shift without them | 1.4 ms |
| Passed | LayoutShiftMonitor › processes the buffered shifts that the browser delivers inside observe(), as old Safari did | 1.2 ms |
packages/lag/src/LongAnimationFrameMonitor.test.ts8 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LongAnimationFrameMonitor › reports blockingDuration and duration from LoAF entries | 8.2 ms |
| Passed | LongAnimationFrameMonitor › calculates renderDuration from renderStart to the end of the frame | 0.52 ms |
| Passed | LongAnimationFrameMonitor › reports renderDuration 0 for frames that did not render | 0.27 ms |
| Passed | LongAnimationFrameMonitor › detects forced layout from scripts | 0.4 ms |
| Passed | LongAnimationFrameMonitor › reports hasForceLayout=false when no forced layout | 0.23 ms |
| Passed | LongAnimationFrameMonitor › rules of the script attribution › reports no scripts for an entry without a list of scripts | 0.39 ms |
| Passed | LongAnimationFrameMonitor › rules of the script attribution › names the first of the longest scripts with its function name, and finds a forced layout in any script | 0.91 ms |
| Passed | LongAnimationFrameMonitor › rules of the script attribution › gives an empty function name for a script without one | 0.34 ms |
packages/lag/src/MacrotaskLag.test.ts12 passed
| Status | Test | Duration |
|---|---|---|
| Passed | MacrotaskLag › constructor › sets up an interval with the specified period | 8.1 ms |
| Passed | MacrotaskLag › measure() › returns a promise that resolves with the macrotask schedulng delay | 0.9 ms |
| Passed | MacrotaskLag › measure() › schedules a macrotask with zero delay to measure event loop lag | 0.66 ms |
| Passed | MacrotaskLag › interval callback › measures and reports lag value when interval fires | 0.66 ms |
| Passed | MacrotaskLag › interval callback › logs an error when the report function throws but continues monitoring | 1.3 ms |
| Passed | MacrotaskLag › interval callback › handles multiple interval cycles independently | 0.57 ms |
| Passed | MacrotaskLag › stop() › clears the interval it created in the constructor | 0.41 ms |
| Passed | MacrotaskLag › stop() › drops a sample that was in flight when stop() was called | 0.61 ms |
| Passed | MacrotaskLag › stop() › drops a sample that was in flight across stop() and start() | 1.8 ms |
| Passed | MacrotaskLag › stop() › start() while the monitor operates adds no second interval | 0.48 ms |
| Passed | MacrotaskLag › stop() › can be restarted | 0.51 ms |
| Passed | MacrotaskLag › postTask › starts the measurement in the posted task, so that the timer nesting clamp does not apply | 0.76 ms |
packages/lag/src/MemoryMonitor.test.ts14 passed
| Status | Test | Duration |
|---|---|---|
| Passed | MemoryMonitor › samples legacy memory immediately on start | 11 ms |
| Passed | MemoryMonitor › uses modern API when available and ignores legacy | 54 ms |
| Passed | MemoryMonitor › falls back to legacy when modern API rejects | 52 ms |
| Passed | MemoryMonitor › schedules periodic samples on the configured interval | 4.1 ms |
| Passed | MemoryMonitor › handles missing source methods gracefully | 0.79 ms |
| Passed | MemoryMonitor › clears the interval on stop | 0.99 ms |
| Passed | MemoryMonitor › drops a modern sample that resolves after stop() | 0.77 ms |
| Passed | MemoryMonitor › does not start a new sample while one is still pending | 0.69 ms |
| Passed | MemoryMonitor › stops calling the modern API after it fails once | 103 ms |
| Passed | MemoryMonitor › rules of the sources › start() while the monitor operates adds no second interval | 1.3 ms |
| Passed | MemoryMonitor › rules of the sources › logs an error from the report function and continues with the next sample | 1.5 ms |
| Passed | MemoryMonitor › rules of the sources › logs the failure of the standard API at debug level, and reports nothing without a legacy API | 1.1 ms |
| Passed | MemoryMonitor › rules of the sources › reports nothing, and logs nothing, when the legacy API gives no value | 0.53 ms |
| Passed | MemoryMonitor › rules of the sources › gives no usage for a heap limit of 0 | 1.4 ms |
packages/lag/src/ObserverMonitor.test.ts13 passed
| Status | Test | Duration |
|---|---|---|
| Passed | ObserverMonitor › creates a PerformanceObserver and calls observe with buffered | 6.8 ms |
| Passed | ObserverMonitor › processes entries via processEntry | 0.89 ms |
| Passed | ObserverMonitor › logs warning when observe throws (unsupported type) | 2.5 ms |
| Passed | ObserverMonitor › logs error when processEntry throws | 1.5 ms |
| Passed | ObserverMonitor › disconnects on stop | 0.49 ms |
| Passed | ObserverMonitor › prevents double-start | 0.53 ms |
| Passed | ObserverMonitor › skips observing types missing from supportedEntryTypes | 0.67 ms |
| Passed | ObserverMonitor › can retry start() after observe threw | 0.52 ms |
| Passed | ObserverMonitor › takeRecords() processes the entries that the browser has not delivered yet | 0.57 ms |
| Passed | ObserverMonitor › takeRecords() does nothing without an observer or without browser support | 0.32 ms |
| Passed | ObserverMonitor › gives the buffered entries that the browser delivers inside observe() to the subclass in a microtask, as for old Safari | 1.9 ms |
| Passed | ObserverMonitor › drops a delivery from inside observe() when stop() comes before the microtask | 0.34 ms |
| Passed | ObserverMonitor › stop() works after a start that failed, and the warning names the entry type and the error | 2.1 ms |
packages/lag/src/PeerHangWatch.test.ts60 passed
| Status | Test | Duration |
|---|---|---|
| Passed | PeerHangWatch › uses the channel name and the lock names of the protocol, which pages of other versions also use | 9.8 ms |
| Passed | PeerHangWatch › sends a heartbeat when it gets its lock, then one each interval, and none after it becomes hidden | 2 ms |
| Passed | PeerHangWatch › says away only when it was visible | 1.2 ms |
| Passed | PeerHangWatch › reports a page that hangs after its first heartbeat | 3.4 ms |
| Passed | PeerHangWatch › waits 1 s by default for a late message of a page | 2.3 ms |
| Passed | PeerHangWatch › reports the page when the wait is shorter than the delay of its last message | 1.9 ms |
| Passed | PeerHangWatch › stops all its timers and closes its channel | 1.6 ms |
| Passed | PeerHangWatch › starts no wait for a page that ends after the stop | 1.6 ms |
| Passed | PeerHangWatch › holds the lock of a visible page, and releases it when the page becomes hidden | 1.2 ms |
| Passed | PeerHangWatch › reports a page that closes during a hang, with the time of its last heartbeat | 1.8 ms |
| Passed | PeerHangWatch › reports nothing when the page survives its hang | 1.8 ms |
| Passed | PeerHangWatch › reports nothing when a page closes or becomes hidden normally | 1.4 ms |
| Passed | PeerHangWatch › reports nothing when a page ends soon after its last heartbeat (a crash, not a hang) | 2.9 ms |
| Passed | PeerHangWatch › reports a hang of 5 s or more, and nothing for a shorter silence | 2 ms |
| Passed | PeerHangWatch › lets one page only report a hang, when many pages watch it | 8.1 ms |
| Passed | PeerHangWatch › waits for the last messages of a page after its lock comes free | 1.1 ms |
| Passed | PeerHangWatch › takes the record of the worker of the hung page from the journal, and then needs no mark | 1.6 ms |
| Passed | PeerHangWatch › uses its own times when the journal fails, and marks the report, because the journal can still have the record | 1.7 ms |
| Passed | PeerHangWatch › reports nothing and puts the record back when it stops while it takes the record from the journal | 1.3 ms |
| Passed | PeerHangWatch › logs nothing when it stops during the take, and the journal has no record or cannot put the record back | 1.9 ms |
| Passed | PeerHangWatch › watches the others while hidden, but sends no heartbeat and holds no lock | 0.87 ms |
| Passed | PeerHangWatch › watches a page again after it becomes visible again | 1.6 ms |
| Passed | PeerHangWatch › watches a page again at once when the page becomes visible again during the wait for its last messages | 1.6 ms |
| Passed | PeerHangWatch › keeps a late heartbeat that the page sent before its lock came free with the earlier entry | 1.9 ms |
| Passed | PeerHangWatch › does not use a lock that it got after the page became hidden again | 0.65 ms |
| Passed | PeerHangWatch › stops: it says away, releases its locks, and reports nothing more | 1.5 ms |
| Passed | PeerHangWatch › reports nothing when it stops while it waits for the last messages of a page | 1.7 ms |
| Passed | PeerHangWatch › releases the claim when it stops | 3.1 ms |
| Passed | PeerHangWatch › keeps the claim for PEER_CLAIM_HOLD_MS, and then releases it | 3.3 ms |
| Passed | PeerHangWatch › reports the hang, but does not keep the claim, when it goes into the back/forward cache during the take of the record | 1.7 ms |
| Passed | PeerHangWatch › does not keep the claim when the watch stops in the report | 1.6 ms |
| Passed | PeerHangWatch › releases the claim when it goes into the back/forward cache | 1.9 ms |
| Passed | PeerHangWatch › ignores messages that are not its own, and its own messages | 4.1 ms |
| Passed | PeerHangWatch › logs a failed lock request and a failed message, and continues | 1.4 ms |
| Passed | PeerHangWatch › logs a message that the channel cannot send | 1.2 ms |
| Passed | PeerHangWatch in the back/forward cache › closes its channel while it is suspended, and gets no message then | 1.5 ms |
| Passed | PeerHangWatch in the back/forward cache › reports no hang for a page that closed normally while it was suspended | 1.3 ms |
| Passed | PeerHangWatch in the back/forward cache › cancels its waiting lock requests when it is suspended, thus it has one request for each page | 1.4 ms |
| Passed | PeerHangWatch in the back/forward cache › gets no lock while it is frozen, thus a page that becomes hidden and visible again gets its own lock | 1 ms |
| Passed | PeerHangWatch in the back/forward cache › cancels its waiting lock requests when it stops | 1.1 ms |
| Passed | PeerHangWatch in the back/forward cache › watches without AbortController, but then it cannot cancel its waiting lock requests | 1.8 ms |
| Passed | PeerHangWatch in the back/forward cache › opens its channel again when it resumes, and watches again | 1.6 ms |
| Passed | PeerHangWatch in the back/forward cache › opens no channel after a stop, and logs a channel that it cannot open | 1.5 ms |
| Passed | PeerHangWatch, the own page at its close › removes the record of its worker from the journal, and marks its report, as in Firefox | 1.1 ms |
| Passed | PeerHangWatch, the own page at its close › reports its own hang also when the journal cannot remove the record | 0.92 ms |
| Passed | PeerHangWatch, the own page at its close › reports its own hang when it closes at the end of a hang, as in Safari | 0.85 ms |
| Passed | PeerHangWatch, the own page at its close › reports its own hang when a heartbeat comes between the hang and the close, as in Firefox | 0.9 ms |
| Passed | PeerHangWatch, the own page at its close › reports nothing at a normal close, or at a close some time after a hang | 1.1 ms |
| Passed | PeerHangWatch, the own page at its close › reports nothing that the worker monitor counted already | 1 ms |
| Passed | PeerHangWatch, the own page at its close › reports a later hang, also after the worker monitor counted an earlier one | 0.75 ms |
| Passed | PeerHangWatch, the own page at its close › reports nothing when it becomes hidden, or when it closes while hidden or before its first heartbeat | 0.75 ms |
| Passed | PeerHangWatch, the own page at its close › measures the gaps again after the page was hidden | 1.9 ms |
| Passed | PeerHangWatch, the own page at its close › reports a silence of exactly the threshold | 0.77 ms |
| Passed | PeerHangWatch, the own page at its close › reports a gap of exactly the threshold before the last heartbeat | 0.74 ms |
| Passed | PeerHangWatch, the own page at its close › reports nothing when the page operated for a heartbeat interval after the gap | 0.89 ms |
| Passed | PeerHangWatch, the own page at its close › reports nothing for a close exactly one heartbeat interval after the heartbeat that ended the gap | 0.87 ms |
| Passed | PeerHangWatch, the own page at its close › counts a hang that the worker monitor counted at the time of the last heartbeat as counted | 0.81 ms |
| Passed | PeerHangWatch, the own page at its close › reports nothing for a gap of less than the threshold | 1.1 ms |
| Passed | isPeerMessage › accepts the two messages of the watch | 0.59 ms |
| Passed | isPeerMessage › refuses other values | 0.86 ms |
packages/lag/src/SchedulingFairnessMonitor.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | SchedulingFairnessMonitor › starts measurement loop on construction | 12 ms |
| Passed | SchedulingFairnessMonitor › reports a SchedulingMeasurement when all three primitives complete | 4.1 ms |
| Passed | SchedulingFairnessMonitor › stops the measurement loop on stop() | 1.2 ms |
| Passed | SchedulingFairnessMonitor › logs an error and does not start when the MessageChannel cannot be constructed | 1.3 ms |
| Passed | SchedulingFairnessMonitor › drops a cycle that was still in flight across stop() and start() | 1.1 ms |
| Passed | SchedulingFairnessMonitor › starts setTimeout(0) from a message task, not from the setInterval callback | 1.2 ms |
| Passed | SchedulingFairnessMonitor › closes its channel on stop() | 1.5 ms |
| Passed | SchedulingFairnessMonitor › rules of the measurement loop › start() while the monitor operates adds no second interval | 1.8 ms |
| Passed | SchedulingFairnessMonitor › rules of the measurement loop › stop() works after a start that could not make the MessageChannel | 1.8 ms |
| Passed | SchedulingFairnessMonitor › rules of the measurement loop › logs an error when the report function throws, and continues with the next cycle | 2.3 ms |
| Passed | SchedulingFairnessMonitor › rules of the measurement loop › logs an error when a cycle cannot start, and continues with the next cycle | 1.9 ms |
packages/lag/src/SharedLivenessMonitor.test.ts7 passed
| Status | Test | Duration |
|---|---|---|
| Passed | SharedLivenessMonitor › gives the buffer to the worker at construction, with a threshold of 50 ms and a poll interval of 5 ms | 5.1 ms |
| Passed | SharedLivenessMonitor › gives the worker the threshold and the poll interval of the options | 0.81 ms |
| Passed | SharedLivenessMonitor › reports the duration of each block that the worker saw | 0.73 ms |
| Passed | SharedLivenessMonitor › ignores the other messages of the worker | 0.76 ms |
| Passed | SharedLivenessMonitor › logs an error from the report function and continues with the next block | 1.6 ms |
| Passed | SharedLivenessMonitor › stop() removes the listener and stops the watcher of the worker, and a second stop() does nothing | 0.57 ms |
| Passed | SharedLivenessMonitor › start() after stop() starts the watcher again, and start() while the monitor operates does nothing | 0.47 ms |
packages/lag/src/TimerThrottleDetector.test.ts12 passed
| Status | Test | Duration |
|---|---|---|
| Passed | TimerThrottleDetector › reports not throttled when timers fire on time | 6.2 ms |
| Passed | TimerThrottleDetector › reports throttled when timers are delayed | 2.6 ms |
| Passed | TimerThrottleDetector › transitions from throttled to not throttled | 2 ms |
| Passed | TimerThrottleDetector › stops calibration when stop() is called | 0.68 ms |
| Passed | TimerThrottleDetector › prevents double-start | 0.83 ms |
| Passed | TimerThrottleDetector › restarting does not leave a second calibration chain running | 0.98 ms |
| Passed | TimerThrottleDetector › stop() from inside the logger (on a throttle change) sticks | 0.87 ms |
| Passed | TimerThrottleDetector › reports every calibration round | 0.86 ms |
| Passed | TimerThrottleDetector › rules of a calibration round › does not count a sample of exactly the threshold as throttled | 1.2 ms |
| Passed | TimerThrottleDetector › rules of a calibration round › is not throttled when exactly half of the samples are throttled | 0.57 ms |
| Passed | TimerThrottleDetector › rules of a calibration round › logs an error from the report function and starts the next round | 0.73 ms |
| Passed | TimerThrottleDetector › rules of a calibration round › logs the start of the throttling and its end one time each | 0.7 ms |
packages/lag/src/WorkerClockSync.test.ts10 passed
| Status | Test | Duration |
|---|---|---|
| Passed | WorkerClockSync › estimates the offset from the exchange with the shortest round trip | 6.5 ms |
| Passed | WorkerClockSync › treats an offset inside the uncertainty as 0 | 0.49 ms |
| Passed | WorkerClockSync › has no correction before a synchronization finished | 0.39 ms |
| Passed | WorkerClockSync › keeps the most accurate result of all synchronizations | 1.7 ms |
| Passed | WorkerClockSync › uses 8 exchanges by default | 2 ms |
| Passed | WorkerClockSync › ignores replies with an unknown ID | 1.3 ms |
| Passed | WorkerClockSync › rules of the exchanges › ignores a reply to a synchronization that a new synchronization replaced | 0.66 ms |
| Passed | WorkerClockSync › rules of the exchanges › counts a reply that comes two times only one time | 0.73 ms |
| Passed | WorkerClockSync › rules of the exchanges › keeps the result of a later synchronization with a shorter round trip | 3.4 ms |
| Passed | WorkerClockSync › 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 size | 1.4 ms |
packages/lag/src/WorkerLagMonitor.test.ts25 passed
| Status | Test | Duration |
|---|---|---|
| Passed | WorkerLagMonitor › starts the worker's heartbeat loop with hang options and listens on construction | 9.9 ms |
| Passed | WorkerLagMonitor › reports how long each heartbeat waited for the main thread, and acknowledges it | 2.7 ms |
| Passed | WorkerLagMonitor › reports each queued heartbeat's wait after a block | 0.81 ms |
| Passed | WorkerLagMonitor › clamps tiny negative delays from clock rounding to zero | 0.82 ms |
| Passed | WorkerLagMonitor › synchronizes the clocks and corrects the delay by the measured offset | 1.2 ms |
| Passed | WorkerLagMonitor › synchronizes the clocks again after the interval | 1.6 ms |
| Passed | WorkerLagMonitor › reports a system stall when the worker itself was late by 5 s or more | 1.1 ms |
| Passed | WorkerLagMonitor › ends the system stall when the worker sent the heartbeat, not when the main thread got it | 0.64 ms |
| Passed | WorkerLagMonitor › passes hang-ended messages on | 0.67 ms |
| Passed | WorkerLagMonitor › stops the worker loop and the sync timer on stop, keeps one listener, and can restart | 2.1 ms |
| Passed | WorkerLagMonitor › passes on the end of a hang while it is stopped, but ignores heartbeats | 1.1 ms |
| Passed | WorkerLagMonitor › removes its listener on dispose() | 1.6 ms |
| Passed | WorkerLagMonitor › ignores unknown messages | 0.52 ms |
| Passed | WorkerLagMonitor › logs instead of throwing when report throws | 1 ms |
| Passed | WorkerLagMonitor › sends its page ID with start, and the page context to the worker | 1.2 ms |
| Passed | WorkerLagMonitor › watchdog › warns when the worker sends no heartbeat in two checks | 2.7 ms |
| Passed | WorkerLagMonitor › watchdog › does not warn after a heartbeat, also when the heartbeat comes after the first check | 1.1 ms |
| Passed | WorkerLagMonitor › watchdog › stops with the monitor | 0.65 ms |
| Passed | WorkerLagMonitor › 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 error | 1.1 ms |
| Passed | WorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › reports a system stall at a self lag of exactly 5 s | 0.58 ms |
| Passed | WorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › ignores a message without data, also while it is stopped | 0.45 ms |
| Passed | WorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › start() while the monitor operates sends nothing | 0.56 ms |
| Passed | WorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › keeps the context while it is stopped and sends it at the next start | 0.67 ms |
| Passed | WorkerLagMonitor › rules of the messages and of the lifecycle of the monitor › listens again at start() after dispose() | 0.54 ms |
| Passed | WorkerLagMonitor › 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 s | 0.8 ms |
packages/lag/src/absolute-clock.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createAbsoluteClock › reads timeOrigin one time, so that a later change of timeOrigin does not move the clock | 3.7 ms |
packages/lag/src/drift-baseline.test.ts17 passed
| Status | Test | Duration |
|---|---|---|
| Passed | idleStepMs › is the step when there is one step | 3.2 ms |
| Passed | idleStepMs › leaves out a block that is longer than the median plus half the median | 0.3 ms |
| Passed | stepsUpTo › keeps the steps that are not longer than the limit, in the same sequence | 1.5 ms |
| Passed | spreadMs › is 2 ms, or 20% of the step if that is more | 0.47 ms |
| Passed | outsideStepMs › is the step between the two baselines, for a coarser and for a finer granularity | 0.34 ms |
| Passed | outsideStepMs › is not less than the shorter baseline and not more than the longer baseline | 0.39 ms |
| Passed | usedBaselineMs › is the recent baseline without a confirmed value | 0.25 ms |
| Passed | usedBaselineMs › is the recent baseline if it is not more than 1 ms above a confirmed value of less than 10 ms | 0.28 ms |
| Passed | usedBaselineMs › permits an increase of 10% above a confirmed value of more than 10 ms | 0.35 ms |
| Passed | isIdleStep › is true for a busy time of less than 2 ms when the step is not longer than the baseline | 0.3 ms |
| Passed | isIdleStep › is true for a busy time of less than half of the extra duration of the step | 1.2 ms |
| Passed | interpretCheck › gives no finding when the steps do not agree with each other | 0.56 ms |
| Passed | interpretCheck › confirms the recent baseline as the first value | 0.44 ms |
| Passed | interpretCheck › confirms the lower of the recent baseline and the idle duration when the idle duration agrees better with the recent baseline | 0.34 ms |
| Passed | interpretCheck › gives the limit of the load when the idle duration agrees better with the confirmed value | 0.23 ms |
| Passed | interpretCheck › gives the limit of the load when the idle duration is as near to the confirmed value as to the recent baseline | 0.21 ms |
| Passed | interpretCheck › uses the larger limit: the confirmed value plus its spread, or the idle duration plus its spread | 0.39 ms |
packages/lag/src/events.test.ts7 passed
| Status | Test | Duration |
|---|---|---|
| Passed | withEventContext › adds the context attributes to each event, and reads the context for each event | 4.8 ms |
| Passed | withEventContext › gives the options of the event to the sink, and no options when the event has none | 0.53 ms |
| Passed | withEventContext › gives priority to the attributes of the event | 1.9 ms |
| Passed | placeEventTime › gives the time of the occurrence when it is no more than 30 minutes from the time of the call | 0.81 ms |
| Passed | placeEventTime › gives no time, but the attribute lag.event.time, for an occurrence farther from the time of the call | 0.47 ms |
| Passed | placeEventTime › gives nothing for an unknown time or a time that is not a finite number | 0.43 ms |
| Passed | createNoopEventSink › accepts events and does nothing | 1.6 ms |
packages/lag/src/forwarding-meter.test.ts14 passed
| Status | Test | Duration |
|---|---|---|
| Passed | forwarding meter › creates the instruments on the other side with their first records, with their options | 13 ms |
| Passed | forwarding meter › sends records in batches at the flush interval | 2.5 ms |
| Passed | forwarding meter › sends at once when the buffer is full | 0.62 ms |
| Passed | forwarding meter › sends no empty batches | 0.57 ms |
| Passed | forwarding meter › dispose() sends the rest and stops the timer | 0.94 ms |
| Passed | forwarding meter › the receiver ignores records for unknown instruments | 1.2 ms |
| Passed | forwarding meter › sends the kind of each instrument in the batch of its first record, with the ID of the sender | 0.54 ms |
| Passed | forwarding meter › gives each forwarding meter its own random sender ID | 0.81 ms |
| Passed | forwarding meter › keeps the instruments of two senders apart in one receiver | 0.94 ms |
| Passed | forwarding meter › gives the records to a receiver that starts to listen after the creation of the instruments | 0.63 ms |
| Passed | forwarding meter › creates each instrument one time, also when a batch comes two times | 1.8 ms |
| Passed | forwarding meter › ignores the records after dispose() | 0.69 ms |
| Passed | forwarding meter › flushes at the interval of the options | 0.59 ms |
| Passed | forwarding meter › sends each record in one batch only, and no batch when no record came after the last batch | 0.63 ms |
packages/lag/src/hang-journal.test.ts22 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createMemoryHangJournal › takes a record that was seen exactly at the limit | 3.1 ms |
| Passed | createMemoryHangJournal › keeps one record for each page, and the newest write wins | 7.5 ms |
| Passed | createMemoryHangJournal › removes a record | 0.33 ms |
| Passed | createMemoryHangJournal › takes a stale record one time, and does not take a record that somebody updated after the limit | 0.4 ms |
| Passed | createMemoryHangJournal › keeps a copy of the attributes, not the object of the caller | 0.31 ms |
| Passed | createIndexedDbHangJournal › takes a record that was seen exactly at the limit | 5.9 ms |
| Passed | createIndexedDbHangJournal › keeps one record for each page, and the newest write wins | 1.5 ms |
| Passed | createIndexedDbHangJournal › removes a record | 0.69 ms |
| Passed | createIndexedDbHangJournal › takes a stale record one time, and does not take a record that somebody updated after the limit | 1.2 ms |
| Passed | createIndexedDbHangJournal › keeps a copy of the attributes, not the object of the caller | 0.36 ms |
| Passed | createIndexedDbHangJournal › shares the records between two journals of the same database, as a page and its worker do | 0.83 ms |
| Passed | createIndexedDbHangJournal › gives a record to only one of two journals that take it at the same time, as two pages do | 0.81 ms |
| Passed | createIndexedDbHangJournal › ignores records that are not hang records | 0.54 ms |
| Passed | createIndexedDbHangJournal › ignores and does not take the records whose fields have the wrong type | 1.6 ms |
| Passed | createIndexedDbHangJournal › closes its connection when a page deletes the database, and opens the database again at the next operation | 1.5 ms |
| Passed | createIndexedDbHangJournal › closes its connection when a later version of the library opens the database | 2.4 ms |
| Passed | createIndexedDbHangJournal › opens the database again after the browser closed the connection | 1.4 ms |
| Passed | createIndexedDbHangJournal › rejects when the database cannot open, and tries again at the next operation | 0.82 ms |
| Passed | findAbandonedHangs › finds the records that nobody updated for the stale time, except the own page | 0.38 ms |
| Passed | createStorageHangReportMarks › gives a mark one time, with the key of the protocol | 0.89 ms |
| Passed | createStorageHangReportMarks › removes the old marks of pages without a record, and keeps the others | 0.7 ms |
| Passed | createStorageHangReportMarks › does nothing when the storage refuses an operation | 0.63 ms |
packages/lag/src/index.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the public API › exports the dependency groups that the public functions use | 2 ms |
packages/lag/src/lag-worker.test.ts33 passed
| Status | Test | Duration |
|---|---|---|
| Passed | lag-worker handler › stays idle until told to start | 8.4 ms |
| Passed | lag-worker handler › posts a timestamped heartbeat every interval once started | 2.8 ms |
| Passed | lag-worker handler › reports how late its own timer fired as workerSelfLagMs | 1 ms |
| Passed | lag-worker handler › answers a sync request with its absolute time | 0.52 ms |
| Passed | lag-worker handler › stops the loop on stop and can be restarted | 0.96 ms |
| Passed | lag-worker handler › restarting with a new interval replaces the old loop instead of adding one | 0.69 ms |
| Passed | lag-worker handler › hang detection › reports a hang when acks stop, and the end when they resume | 3.7 ms |
| Passed | lag-worker handler › hang detection › reports each hang once | 0.83 ms |
| Passed | lag-worker handler › hang detection › does not report a hang while the main thread acknowledges heartbeats | 1.1 ms |
| Passed | lag-worker handler › hang detection › reports no hang while the main thread acknowledges each heartbeat, also with an interval of the threshold or more | 1.4 ms |
| Passed | lag-worker handler › hang detection › reports no hang when its own timer is late by less than the threshold, and the main thread acknowledges each heartbeat | 0.8 ms |
| Passed | lag-worker handler › hang detection › measures the wait from the oldest heartbeat without an acknowledgement | 0.84 ms |
| Passed | lag-worker handler › hang detection › measures the wait again from an acknowledgement of an earlier heartbeat | 1.3 ms |
| Passed | lag-worker handler › hang detection › does not blame the main thread for time in which the worker itself did not run | 0.71 ms |
| Passed | lag-worker handler › hang detection › does not add the time in which the worker itself did not run to a hang in progress | 1.1 ms |
| Passed | lag-worker handler › hang detection › ends a hang in progress at a stop, because the main thread sent the stop | 0.83 ms |
| Passed | lag-worker handler › hang detection › does not blame the main thread when the worker itself was late by exactly the threshold | 0.62 ms |
| Passed | lag-worker handler › hang detection › does not detect hangs without hang options | 2 ms |
| Passed | lag-worker handler › page context and hang journal › adds the last context to its hang reports | 1.1 ms |
| Passed | lag-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 ends | 2.9 ms |
| Passed | lag-worker handler › page context and hang journal › removes the record when it stops during a hang | 1.5 ms |
| Passed | lag-worker handler › page context and hang journal › writes the wall-clock time of the start of the hang to the journal | 0.82 ms |
| Passed | lag-worker handler › page context and hang journal › uses Date.now() for the times of the journal when the dependencies have no wall clock | 1.2 ms |
| Passed | lag-worker handler › page context and hang journal › writes no record while the main thread acknowledges the heartbeats | 1.4 ms |
| Passed | lag-worker handler › page context and hang journal › removes no record at the end of a hang without a page ID | 0.84 ms |
| Passed | lag-worker handler › page context and hang journal › keeps no record without a page ID | 0.62 ms |
| Passed | lag-worker handler › page context and hang journal › continues the heartbeats when the journal fails | 1 ms |
| Passed | lag-worker handler › shared-memory liveness › starts a watcher at liveness-start, and posts each block that the watcher sees | 1.8 ms |
| Passed | lag-worker handler › shared-memory liveness › uses the threshold and the poll interval of the liveness-start message | 1.1 ms |
| Passed | lag-worker handler › shared-memory liveness › stops the watcher at liveness-stop | 1 ms |
| Passed | lag-worker handler › shared-memory liveness › replaces the watcher at a second liveness-start | 1.3 ms |
| Passed | lag-worker handler › shared-memory liveness › ignores liveness-stop when no watcher operates | 1.5 ms |
| Passed | lag-worker handler › shared-memory liveness › does not watch without both interval functions | 0.78 ms |
packages/lag/src/measurement-conditions.test.ts31 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createMeasurementConditions › validator › records a normal sample at once | 9.9 ms |
| Passed | createMeasurementConditions › validator › discards a sample whose window overlaps a hidden period | 2.2 ms |
| Passed | createMeasurementConditions › validator › keeps the first window after the page becomes visible again | 0.73 ms |
| Passed | createMeasurementConditions › validator › discards a sample when the page is hidden but visibilitychange has not fired yet | 0.66 ms |
| Passed | createMeasurementConditions › validator › waits for late evidence before it records an outlier, then records it as a hang | 1.7 ms |
| Passed | createMeasurementConditions › validator › reports the stall samples of one block as one episode, with the longest sample | 1.4 ms |
| Passed | createMeasurementConditions › validator › reports separate blocks as separate episodes | 0.81 ms |
| Passed | createMeasurementConditions › validator › gives an episode the kind suspend when one of its samples gets suspend evidence during the wait | 0.81 ms |
| Passed | createMeasurementConditions › validator › discards a sample at once when the evidence exists before the sample, and counts a suspend stall | 0.85 ms |
| Passed | createMeasurementConditions › validator › gives the same result when the sample comes before the suspend evidence or after it | 1.1 ms |
| Passed | createMeasurementConditions › validator › uses the suspend evidence when a window overlaps a hidden interval and a suspend | 0.83 ms |
| Passed | createMeasurementConditions › validator › counts no stall for a long sample in a hidden interval | 0.64 ms |
| Passed | createMeasurementConditions › validator › dispose() reports the episodes that wait | 2.7 ms |
| Passed | createMeasurementConditions › validator › discards an outlier when suspend evidence arrives during the wait | 0.85 ms |
| Passed | createMeasurementConditions › validator › uses the configured outlier threshold and wait | 0.73 ms |
| Passed | createMeasurementConditions › validator › dispose() cancels outliers that wait | 0.65 ms |
| Passed | createMeasurementConditions › validator › waits for late evidence before it records a sample at the outlier threshold | 0.6 ms |
| Passed | createMeasurementConditions › validator › counts a suspend stall for a discarded sample at the outlier threshold | 0.59 ms |
| Passed | createMeasurementConditions › validator › reports a stall sample that does not overlap the waiting episode as a separate episode | 0.76 ms |
| Passed | createMeasurementConditions › validator › adds a stall sample whose window starts at the end of the waiting episode to the episode | 0.6 ms |
| Passed | createMeasurementConditions › validator › extends an episode with each sample that it gets, so that a later sample can overlap the extension | 0.66 ms |
| Passed | createMeasurementConditions › validator › gives a hang episode the kind suspend when a sample with suspend evidence joins it | 0.63 ms |
| Passed | createMeasurementConditions › validator › works without stall and discard listeners | 0.77 ms |
| Passed | createMeasurementConditions › validator › works without a lifecycle | 0.7 ms |
| Passed | createMeasurementConditions › lifecycle intervals › opens an interval at creation when the page is hidden | 0.55 ms |
| Passed | createMeasurementConditions › lifecycle intervals › records frozen periods with their own reason | 0.53 ms |
| Passed | createMeasurementConditions › lifecycle intervals › dispose() stops following the lifecycle and closes the open interval | 0.51 ms |
| Passed | createMeasurementConditions › pauseWhileHidden › stops a monitor while hidden and starts it again when visible | 0.63 ms |
| Passed | createMeasurementConditions › pauseWhileHidden › stops a monitor at once when the page is hidden at the start | 0.47 ms |
| Passed | createMeasurementConditions › pauseWhileHidden › does not stop or start a monitor when the page loses the focus or gets it again | 0.7 ms |
| Passed | createMeasurementConditions › pauseWhileHidden › does not start a monitor when a hidden page becomes frozen and resumes, but starts it when the page is visible | 0.78 ms |
packages/lag/src/message-task.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createMessageTaskQueue › runs the callbacks later, in the sequence in which they were posted | 5.7 ms |
| Passed | createMessageTaskQueue › drops the callbacks that did not run when it closes, and closes the ports | 1.4 ms |
| Passed | createMessageTaskQueue › closes a channel whose ports have no close() | 1.5 ms |
packages/lag/src/metric-catalog.test.ts16 passed
| Status | Test | Duration |
|---|---|---|
| Passed | metric catalog › has unique metric names | 3.2 ms |
| Passed | metric catalog › uses the naming rules: lag_ prefix; histograms end in _histogram, counters do not | 2.9 ms |
| Passed | metric catalog › gives every metric a description, a unit and a closed set of attribute values | 4.2 ms |
| Passed | metric catalog › has unique event names with attributes | 0.7 ms |
| Passed | metric catalog › creates instruments of the declared kind and unit | 1.5 ms |
| Passed | metric catalog › gives the bucket boundaries of the catalog to the SDK as advice, as a copy | 2.1 ms |
| Passed | metric catalog › refuses to create an instrument of the wrong kind | 1.4 ms |
| Passed | metric catalog › permits exactly the values of the types of the monitors as attribute values | 1.3 ms |
| Passed | metric catalog › names a monitor of the package for each metric and each event | 2.7 ms |
| Passed | metric catalog › gives every event a description | 0.36 ms |
| Passed | metric catalog › has unique span names with the lag. prefix, attributes, a description and a monitor of the package | 0.73 ms |
| Passed | histogram buckets › gives each histogram ascending, unique bucket boundaries, and no counter | 6 ms |
| Passed | histogram buckets › selects the boundaries from the unit, and the ordinal boundaries for the pressure state | 1.1 ms |
| Passed | histogram buckets › makes the thresholds of the Web Vitals bucket boundaries, thus the buckets give the exact ratings | 2 ms |
| Passed | histogram buckets › puts the typical values of each type of histogram into different buckets | 0.67 ms |
| Passed | histogram buckets › gives exactly the documented boundaries | 0.74 ms |
packages/lag/src/monitor-registry.test.ts6 passed
| Status | Test | Duration |
|---|---|---|
| Passed | MonitorRegistry › adds handles and returns them unchanged | 2.4 ms |
| Passed | MonitorRegistry › looks up handles by name | 0.51 ms |
| Passed | MonitorRegistry › stopAll() calls stop on every handle in LIFO order | 0.98 ms |
| Passed | MonitorRegistry › stopAll() isolates errors — one bad stop doesn't prevent others | 2.3 ms |
| Passed | MonitorRegistry › stopAll() clears the registry | 0.38 ms |
| Passed | MonitorRegistry › getAll() returns all handles in registration order | 0.34 ms |
packages/lag/src/noop-meter.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createNoopMeter › gives histograms and counters that accept values and record nothing | 3 ms |
packages/lag/src/otel-logger-adapter.test.ts15 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createOtelLoggerAdapter › emits log records with severityText and body | 8.6 ms |
| Passed | createOtelLoggerAdapter › maps known severity levels to OTel SeverityNumber | 1.1 ms |
| Passed | createOtelLoggerAdapter › defaults to INFO severity for unknown levels | 0.45 ms |
| Passed | createOtelLoggerAdapter › merges object args into attributes | 0.51 ms |
| Passed | createOtelLoggerAdapter › wraps non-object args under 'args' key | 0.31 ms |
| Passed | createOtelLoggerAdapter › gives the string of an argument that is not a primitive and not an object | 0.37 ms |
| Passed | createOtelLoggerAdapter › handles null/undefined args without throwing | 0.35 ms |
| Passed | createTeeLogger › forwards calls to all loggers | 1.3 ms |
| Passed | createTeeLogger › isolates logger errors so one failure doesn't break others | 1.8 ms |
| Passed | createOtelLoggerAdapter attribute encoding › turns an Error into semantic-convention exception attributes | 5 ms |
| Passed | createOtelLoggerAdapter attribute encoding › JSON-encodes nested objects and keeps primitive arrays | 1.1 ms |
| Passed | createOtelLoggerAdapter attribute encoding › keeps booleans, numbers and strings, and leaves out the attributes that are undefined or null | 0.4 ms |
| Passed | createOtelLoggerAdapter attribute encoding › JSON-encodes an array with values of different types or with objects | 0.35 ms |
| Passed | createOtelLoggerAdapter attribute encoding › leaves out the stack trace of an Error that has no stack | 0.3 ms |
| Passed | createOtelLoggerAdapter attribute encoding › gives the string of an object that JSON cannot encode | 0.3 ms |
packages/lag/src/random-id.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createRandomId › gives the bytes of crypto.getRandomValues as 32 hexadecimal digits | 2.8 ms |
| Passed | createRandomId › uses Math.random when the environment has no crypto.getRandomValues | 1.6 ms |
| Passed | createRandomId › gives a different ID at each use | 4.9 ms |
packages/lag/src/reliability.test.ts10 passed
| Status | Test | Duration |
|---|---|---|
| Passed | ReliabilityTracker › finds a closed interval that overlaps a window | 4.3 ms |
| Passed | ReliabilityTracker › does not count a window that only touches a closed interval | 0.52 ms |
| Passed | ReliabilityTracker › counts an open interval for every window that ends after it starts, including one that ends at its start | 0.99 ms |
| Passed | ReliabilityTracker › closes an interval only once | 0.39 ms |
| Passed | ReliabilityTracker › ignores an interval that ends before it starts | 0.29 ms |
| Passed | ReliabilityTracker › forgets closed intervals after the retention time, but keeps open ones | 0.6 ms |
| Passed | ReliabilityTracker › notifies subscribers of each new interval until they unsubscribe | 2.6 ms |
| Passed | ReliabilityTracker › counts a closed interval of zero length inside a window | 1.9 ms |
| Passed | ReliabilityTracker › is unreliable now while one interval is open, also when other intervals are closed | 1 ms |
| Passed | ReliabilityTracker › forgets an old closed interval before it searches | 0.27 ms |
packages/lag/src/setup-all-monitors.test.ts44 passed
| Status | Test | Duration |
|---|---|---|
| Passed | setupAllMonitors › registers every monitor when all capabilities are present | 41 ms |
| Passed | setupAllMonitors › feeds every metric of the catalog that normal activity produces | 185 ms |
| Passed | setupAllMonitors › creates only catalog instruments, with the catalog kind, unit and attribute values | 182 ms |
| Passed | setupAllMonitors › emits attribution events without query strings | 140 ms |
| Passed | setupAllMonitors › gives the ID of the current page view to the worker, for its hang reports | 1.7 ms |
| Passed | setupAllMonitors › sends only the event attributes that the catalog lists | 135 ms |
| Passed | setupAllMonitors › gives the ID of the current page view to the events of the other monitors | 140 ms |
| Passed | setupAllMonitors › flush() records the pending Web Vitals, for the before-flush hook of an exporter | 101 ms |
| Passed | setupAllMonitors › records each Web Vital once for each page view, and sends events with the semantic-convention names | 92 ms |
| Passed | setupAllMonitors › measures main-thread lag through DriftLag and the worker's delivery delay | 7.4 ms |
| Passed | setupAllMonitors › synchronizes the worker clock and records the offset | 2.3 ms |
| Passed | setupAllMonitors › discards a lag sample that overlaps a system suspend, after the worker reports it | 79 ms |
| Passed | setupAllMonitors › detects a main-thread hang in the worker, and records it when the main thread runs again | 142 ms |
| Passed | setupAllMonitors › counts samples that it discards because the page was hidden | 28 ms |
| Passed | setupAllMonitors › records clock jumps | 208 ms |
| Passed | setupAllMonitors › stop() releases every timer, listener, observer and worker loop | 120 ms |
| Passed | setupAllMonitors › pauses timer-driven monitors while the page is hidden | 174 ms |
| Passed | setupAllMonitors › keeps the first sample after the page becomes visible again | 21 ms |
| Passed | setupAllMonitors › gives each monitor of the registry through its typed getter | 2.9 ms |
| Passed | setupAllMonitors › gives the ID of the current page view to the hang reports of the worker | 92 ms |
| Passed | setupAllMonitors › stop() reports the stall episode that waits, with its kind | 33 ms |
| Passed | setupAllMonitors › counts lifecycle transitions | 1.5 ms |
| Passed | setupAllMonitors › emits the start of the page view and each lifecycle transition, with the page-view ID and a time of the absolute clock | 1.4 ms |
| Passed | setupAllMonitors with shared memory › adds the shared-memory liveness monitor, and DriftLag beats the counter | 8.3 ms |
| Passed | setupAllMonitors degradation › runs the core monitors with only the required deps | 1.2 ms |
| Passed | setupAllMonitors degradation › skips the worker monitor, with a warning, when performance is missing | 2.6 ms |
| Passed | setupAllMonitors degradation › keeps the timer-driven monitors when the page lifecycle cannot start | 1.6 ms |
| Passed | setupAllMonitors degradation › keeps going when one monitor fails to construct | 1.5 ms |
| Passed | setupAllMonitors degradation › registers no monitor whose dependencies are not complete, and logs no warning | 1.9 ms |
| Passed | setupAllMonitors degradation › registers no page-view context without the page-view vitals | 2.6 ms |
| Passed | setupAllMonitors degradation › gives the page-view ID to the crash-report context of the browser, also without a worker | 1.5 ms |
| Passed | setupAllMonitors degradation › counts a stall without an event sink | 56 ms |
| Passed | setupAllMonitors degradation › sends the stall events without a page-view ID when the page-view vitals are missing | 73 ms |
| Passed | setupAllMonitors with BroadcastChannel and the Web Locks API › adds the peer hang watch, which sends the ID of the current page view in its heartbeats | 16 ms |
| Passed | setupAllMonitors with BroadcastChannel and the Web Locks API › gives the worker and the watch one page ID | 12 ms |
| Passed | setupAllMonitors 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 journal | 123 ms |
| Passed | setupAllMonitors 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 start | 106 ms |
| Passed | setupAllMonitors with BroadcastChannel and the Web Locks API › needs the wall clock, BroadcastChannel and the Web Locks API for the watch | 6 ms |
| Passed | setupAllMonitors with BroadcastChannel and the Web Locks API › counts a hang of the worker monitor without an event sink, with the watch | 164 ms |
| Passed | setupAllMonitors with an exporter that gets the pagehide event first › without the event, the final export misses the end of the page | 2.5 ms |
| Passed | setupAllMonitors 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 again | 1.9 ms |
| Passed | setupAllMonitors with a span sink › makes one trace for each page view, with the spans of the monitors in the span of the view | 124 ms |
| Passed | setupAllMonitors 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 hang | 82 ms |
| Passed | setupAllMonitors with a span sink › makes no spans without a span sink | 8.5 ms |
packages/lag/src/shared-liveness.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | shared-memory liveness › reports nothing while the main thread beats | 11 ms |
| Passed | shared-memory liveness › reports a block when the counter stops changing, when it changes again | 2.4 ms |
| Passed | shared-memory liveness › ignores quiet periods shorter than the threshold | 0.95 ms |
| Passed | shared-memory liveness › does not report time in which the watcher itself did not run | 0.85 ms |
| Passed | shared-memory liveness › stops polling on stop() | 0.88 ms |
| Passed | shared-memory liveness › beatingSetTimeout beats before each callback | 1.9 ms |
| Passed | shared-memory liveness › uses a threshold of 50 ms and a poll interval of 5 ms by default | 2.7 ms |
| Passed | shared-memory liveness › start() while the watcher operates adds no second poll | 0.5 ms |
| Passed | shared-memory liveness › reports a quiet period of exactly the threshold | 1.1 ms |
| Passed | shared-memory liveness › measures a block also when one poll of the watcher is late by less than the threshold | 1.9 ms |
| Passed | shared-memory liveness › does not count the time in which the watcher itself was late by exactly the threshold | 1.2 ms |
packages/lag/src/spans.test.ts10 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createNoopSpanSink › records nothing, and its spans have no identity | 2.2 ms |
| Passed | isSpanIdentity › accepts the trace ID and the span ID of the W3C trace context | 0.51 ms |
| Passed | isSpanIdentity › rejects missing, malformed and all-zero IDs | 0.59 ms |
| Passed | createOtelSpanSink › starts an open span at its start time in the root context, without the attributes that have no value | 3 ms |
| Passed | createOtelSpanSink › records an ended span in the context of its parent, sampled and remote, with its links | 1.9 ms |
| Passed | createOtelSpanSink › gives an unsampled span the identity sampled: false, and its children the context of an unsampled parent | 0.58 ms |
| Passed | createOtelSpanSink › gives no links option to a span without links | 1.1 ms |
| Passed | createPageViewSpans › starts the span of a view at its start, and ends it at the final report with the values of the vitals | 1.5 ms |
| Passed | createPageViewSpans › ends the span of a view at the start of the next view, and ignores the end of a view that is not open | 0.45 ms |
| Passed | createPageViewSpans › uses Date.now() without a clock | 3.1 ms |
packages/lag/src/support.test.ts13 passed
| Status | Test | Duration |
|---|---|---|
| Passed | RateLimiter › permits `limit` actions in each window | 4.3 ms |
| Passed | stripUrlParameters › removes the query string and the fragment | 0.65 ms |
| Passed | OTLP JSON encoding › converts milliseconds to a nanosecond string, rounded to microseconds | 0.36 ms |
| Passed | OTLP JSON encoding › encodes log records as an ExportLogsServiceRequest | 1.3 ms |
| Passed | OTLP JSON encoding › gives a record the observed time of the input, or the time of the occurrence | 0.33 ms |
| Passed | OTLP JSON encoding › encodes only safe integers as intValue, and other numbers as doubleValue | 0.63 ms |
| Passed | event sinks › the OTel event sink emits a log record with the event name, without empty attributes | 3.2 ms |
| Passed | event sinks › gives each event a different body, so that Loki keeps events of the same millisecond | 0.61 ms |
| Passed | event sinks › the OTel event sink gives the time of the occurrence to the record | 2.8 ms |
| Passed | event 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 attribute | 1.5 ms |
| Passed | event sinks › the OTel event sink compares the times with Date.now by default | 0.59 ms |
| Passed | event sinks › the OTel event sink leaves out the attributes that are null | 0.52 ms |
| Passed | event sinks › the no-op event sink accepts events | 2.3 ms |
packages/lag/src/browser/browser-deps.test.ts22 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createBrowserDeps › binds each browser function to its object | 5.1 ms |
| Passed | createBrowserDeps › leaves out the deps of an API that the browser does not have | 0.64 ms |
| Passed | createBrowserDeps › uses shared memory only in a cross-origin-isolated page, and only if the option permits it | 0.96 ms |
| Passed | createBrowserDeps › finds the legacy and the standard memory APIs | 1.4 ms |
| Passed | createBrowserDeps › observes the cpu pressure source by default | 1.2 ms |
| Passed | createBrowserDeps › passes the options through | 1.7 ms |
| Passed | createBrowserDeps › uses IndexedDB for the hang journal only with a worker or the peer hang watch, and only if the option permits it | 1.3 ms |
| Passed | createBrowserDeps › marks the reports of the peer hang watch in localStorage, with the conditions of the hang journal | 0.97 ms |
| Passed | createBrowserDeps › uses BroadcastChannel and the Web Locks API for the peer hang watch, if the option permits it | 3.4 ms |
| Passed | createBrowserDeps › uses the crash-report context of the browser where it exists | 0.54 ms |
| Passed | createBrowserDeps › gives setupAllMonitors the monitors that the browser can support | 14 ms |
| Passed | createBrowserDeps › adapts the timer functions of the browser: each one passes the callback and the delay, and gives the handle of the browser | 0.65 ms |
| Passed | createBrowserDeps › leaves out PerformanceObserver when the browser does not have it | 0.24 ms |
| Passed | createBrowserDeps › reads the wall clock from Date.now() | 0.81 ms |
| Passed | createBrowserDeps › gives requestIdleCallback and cancelIdleCallback, bound to the window, only when the browser has both | 0.58 ms |
| Passed | createBrowserDeps › gives MessageChannel with queueMicrotask, and leaves out an API that is not a function | 0.59 ms |
| Passed | createBrowserDeps › leaves out requestAnimationFrame when the browser has no cancelAnimationFrame | 0.23 ms |
| Passed | createBrowserDeps › finds one memory API without the other, and leaves out a memory object that is null | 0.48 ms |
| Passed | createBrowserDeps › uses a crash-report object only when it has a set() function | 0.28 ms |
| Passed | createBrowserDeps › gives FinalizationRegistry and ReportingObserver when the browser has them | 0.26 ms |
| Passed | createBrowserDeps and the shared lifecycle tracker › gives the shared tracker of the page when the globals are the global object | 0.79 ms |
| Passed | createBrowserDeps 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
| Status | Test | Duration |
|---|---|---|
| Passed | createPageSource › gives the navigation entry, with web-vitals navigation types | 5 ms |
| Passed | createPageSource › uses 0 when the entry has no activationStart | 0.59 ms |
| Passed | createPageSource › ignores an entry with a responseStart that is 0, missing, or not before now | 0.48 ms |
| Passed | createPageSource › gives no entry when the browser has no getEntriesByType or the call fails | 0.6 ms |
| Passed | createPageSource › gives the start times of the hidden visibility-state entries | 0.31 ms |
| Passed | createPageSource › reads the prerender and discard state of the document | 0.46 ms |
| Passed | createPageSource › gives the URL of the document from location.href, and no URL without a location | 0.71 ms |
| Passed | createPageSource › listens to prerenderingchange in the capture phase, and the return value removes the listener | 2.3 ms |
packages/lag/src/instrumented/browser-reports.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedBrowserReports › counts each report by its type, and sends an event without the query of the source file | 11 ms |
| Passed | createInstrumentedBrowserReports › sends an event without a time when it has no clock | 3.5 ms |
| Passed | createInstrumentedBrowserReports › sends no more than 10 events each minute, but counts all reports | 0.67 ms |
| Passed | createInstrumentedBrowserReports › counts the reports without an event sink | 0.52 ms |
packages/lag/src/instrumented/clock-drift.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedClockDrift › adds a suspend to the measurement conditions, over the interval in which it occurred | 12 ms |
| Passed | createInstrumentedClockDrift › adds nothing for a clock step | 5.6 ms |
| Passed | createInstrumentedClockDrift › counts a clock jump without an event sink and without measurement conditions | 1.6 ms |
| Passed | createInstrumentedClockDrift › records each kind of jump with the attribute values of the catalog, and events with the attributes of the catalog | 4.9 ms |
packages/lag/src/instrumented/clock-reliability.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedClockReliability › records the resolution of the clock one time, 5 s after the setup | 8.1 ms |
| Passed | createInstrumentedClockReliability › records nothing when the clock did not advance during the measurement | 8.4 ms |
| Passed | createInstrumentedClockReliability › stop() before the measurement cancels it | 0.88 ms |
packages/lag/src/instrumented/compute-pressure.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedComputePressure › observes the cpu source each second by default, and records the state ordinal with the source | 7.6 ms |
| Passed | createInstrumentedComputePressure › emits an event for each change of the state of a source, at the time of the record | 2.7 ms |
| Passed | createInstrumentedComputePressure › observes the sources and the sample interval of the dependencies | 0.32 ms |
packages/lag/src/instrumented/drift-lag.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedDriftLag › records the lag and the baseline of each window, and logs sustained lag through the lag logger | 62 ms |
| Passed | createInstrumentedDriftLag › stop() cancels the windows that wait for evidence | 3.1 ms |
| Passed | createInstrumentedDriftLag with MessageChannel › probes through a message queue, and closes the queue when it stops | 7.8 ms |
packages/lag/src/instrumented/event-timing.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedEventTiming › records the duration and the three phases of each interaction event, with the interaction type | 10 ms |
| Passed | createInstrumentedEventTiming › records 0 for a phase that the clock rounding makes negative | 0.7 ms |
| Passed | createInstrumentedEventTiming › gives the monitor the interaction count of the page | 2.6 ms |
packages/lag/src/instrumented/frame-timing.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedFrameTiming › records the time between two frames, and counts the delivered frames and the dropped frames | 12 ms |
| Passed | createInstrumentedFrameTiming › with measurement conditions, waits for late evidence before it records a frame gap of 5 s or more | 3.2 ms |
| Passed | createInstrumentedFrameTiming › with measurement conditions, stops while the page is hidden and starts again when it is visible | 4.1 ms |
| Passed | createInstrumentedFrameTiming › stop() cancels the frame gaps that wait for evidence, and the page lifecycle does not start the monitor again | 1.4 ms |
packages/lag/src/instrumented/idle-availability.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedIdleAvailability › records the idle time, the gap after the first callback, and counts the callbacks by timeout | 14 ms |
| Passed | createInstrumentedIdleAvailability › with measurement conditions, waits for late evidence before it records a gap of 5 s or more | 3.6 ms |
| Passed | createInstrumentedIdleAvailability › with measurement conditions, stops while the page is hidden and starts again when it is visible | 1.9 ms |
| Passed | createInstrumentedIdleAvailability › stop() cancels the gaps that wait for evidence, and the page lifecycle does not start the monitor again | 1.5 ms |
packages/lag/src/instrumented/lifecycle.test.ts6 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedLifecycle › counts each transition, and emits an event at the time of the browser event | 8.8 ms |
| Passed | createInstrumentedLifecycle › emits the events without a time when it has no clock, and stops with the machine | 1.4 ms |
| Passed | createInstrumentedLifecycle with spans › records each hidden and frozen period as a span in the current page view, to the next transition | 1.2 ms |
| Passed | createInstrumentedLifecycle with spans › ends the open period at stop(), and records no period after the stop | 0.41 ms |
| Passed | createInstrumentedLifecycle with spans › uses Date.now() without a clock, also at stop(), and starts a new trace without page-view spans | 2.7 ms |
| Passed | createInstrumentedLifecycle with a tracker that the page shares › subscribes to the tracker, and at stop() it unsubscribes but does not dispose of the tracker | 0.94 ms |
packages/lag/src/instrumented/loaf.test.ts12 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedLoaf › records each frame, and sends an event only for a frame that blocks for 150 ms or more | 8.3 ms |
| Passed | createInstrumentedLoaf › sends no more than 10 events each minute | 2.2 ms |
| Passed | createInstrumentedLoaf › records the frames without an event sink | 1.2 ms |
| Passed | createInstrumentedLoaf › names the longest script in the event, without the query of its URL | 2.3 ms |
| Passed | createInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type classic-script | 0.58 ms |
| Passed | createInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type module-script | 0.34 ms |
| Passed | createInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type event-listener | 0.34 ms |
| Passed | createInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type event-listener | 0.23 ms |
| Passed | createInstrumentedLoaf › removes the query string and the fragment from a URL in the invoker of the type user-callback | 0.25 ms |
| Passed | createInstrumentedLoaf with spans › records a span from the start to the end of each frame that gets an event, in the current page view | 1.4 ms |
| Passed | createInstrumentedLoaf with spans › records no span without a clock, because the frame has no absolute time | 0.36 ms |
| Passed | createInstrumentedLoaf with spans › records the spans without an event sink, with the same limit of 10 each minute | 0.64 ms |
packages/lag/src/instrumented/macrotask-lag.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedMacrotaskLag › records the time that a zero-delay timeout waited, one time in 5 s | 13 ms |
| Passed | createInstrumentedMacrotaskLag › stop() cancels the samples that wait for evidence | 2.6 ms |
packages/lag/src/instrumented/memory.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedMemory › records the used heap with its source, and the usage ratio of the legacy source | 10 ms |
| Passed | createInstrumentedMemory › records no usage ratio for the modern source, because it gives no limit | 3.7 ms |
| Passed | createInstrumentedMemory › samples at the interval of the dependencies | 1.1 ms |
packages/lag/src/instrumented/page-view-context.test.ts10 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedPageViewContext › gives the current page view ID to each receiver, now and at each new view | 5.5 ms |
| Passed | createInstrumentedPageViewContext › adds the attributes of the app, and reads them again at each new view | 0.48 ms |
| Passed | createInstrumentedPageViewContext › logs a failure of the function of the app and continues with the page-view ID | 2.3 ms |
| Passed | createInstrumentedPageViewContext › initializes the crash-report context, sets the view ID, and deletes it on stop | 4.5 ms |
| Passed | createInstrumentedPageViewContext › still sets the context when an other script initialized the crash-report context first | 2 ms |
| Passed | createInstrumentedPageViewContext › logs a failure of the crash-report context at debug level and continues | 0.71 ms |
| Passed | createInstrumentedPageViewContext › still sets the context when initialize() of the crash-report context throws an error | 3.8 ms |
| Passed | createInstrumentedPageViewContext › logs nothing without a crash-report context | 2.7 ms |
| Passed | createInstrumentedPageViewContext with page-view spans › gives the identity of the span of the current view to the receivers, at each new view | 0.55 ms |
| Passed | createInstrumentedPageViewContext with page-view spans › gives no span identity for a span that the SDK did not sample | 0.4 ms |
packages/lag/src/instrumented/page-view-vitals.test.ts16 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedPageViewVitals › records each vital of a view one time, also when a flush comes after the final report (Firefox and WebKit) | 12 ms |
| Passed | createInstrumentedPageViewVitals › records each vital of a view one time with the event sequence of the specification | 1 ms |
| Passed | createInstrumentedPageViewVitals › records each vital of a view one time when stop() comes after the final report | 0.86 ms |
| Passed | createInstrumentedPageViewVitals › sends events whose deltas add up to the value | 0.89 ms |
| Passed | createInstrumentedPageViewVitals › sends a second event with the change of the value when the value of a view changes, but records the first value only | 5.3 ms |
| Passed | createInstrumentedPageViewVitals › sends the attributes of the semantic conventions with the attribution, and no URL attribute for a view without a URL | 5 ms |
| Passed | createInstrumentedPageViewVitals › makes the LCP final at a trusted click on the window of the dependencies | 1.3 ms |
| Passed | createInstrumentedPageViewVitals › records the vitals without an event sink | 1.6 ms |
| Passed | createInstrumentedPageViewVitals › counts the interactions of the page with performance.interactionCount | 0.93 ms |
| Passed | createInstrumentedPageViewVitals › records the FCP of a restore from the animation frames, with the navigation type of the restore | 2.3 ms |
| Passed | createInstrumentedPageViewVitals › sends a lag.page_view.start event for the load and for each later view, at the start of the view | 2.1 ms |
| Passed | createInstrumentedPageViewVitals › sends each vital at the time of its occurrence, not at the time of the report | 1 ms |
| Passed | createInstrumentedPageViewVitals › observes soft navigations when the dependencies enable them | 0.55 ms |
| Passed | createInstrumentedPageViewVitals › records the vitals of each navigation type with an attribute value that the catalog permits | 3.2 ms |
| Passed | createInstrumentedPageViewVitals 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 time | 2.8 ms |
| Passed | createInstrumentedPageViewVitals with page-view spans › starts a new trace for a restore from the back/forward cache | 2.8 ms |
packages/lag/src/instrumented/peer-hang-watch.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedPeerHangWatch › records a page that closed during a hang as an abandoned hang, with the context of that page | 16 ms |
| Passed | createInstrumentedPeerHangWatch › takes the record of the worker from the hang journal | 2.1 ms |
| Passed | createInstrumentedPeerHangWatch › holds the lock only while the page is visible | 2.6 ms |
| Passed | createInstrumentedPeerHangWatch › records the hang without an event sink, and stops listening to the lifecycle | 2.2 ms |
| Passed | createInstrumentedPeerHangWatch › records the hang of its own page with the source self, when the page closes at the end of a hang | 1.2 ms |
| Passed | createInstrumentedPeerHangWatch › counts its own hang one time, also when its worker leaves the record in the journal | 7.9 ms |
| Passed | createInstrumentedPeerHangWatch › does not record a hang when the page becomes hidden at the end of a hang | 1.4 ms |
| Passed | createInstrumentedPeerHangWatch › does not record a hang when the page goes into the back/forward cache | 0.79 ms |
| Passed | createInstrumentedPeerHangWatch › makes a page ID when it gets none | 4.7 ms |
| Passed | createInstrumentedPeerHangWatch › gives an empty handle when the construction fails | 1.1 ms |
| Passed | createInstrumentedPeerHangWatch 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 it | 3.6 ms |
packages/lag/src/instrumented/scheduling-fairness.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedSchedulingFairness › records the latency of each of the three primitives of a cycle | 11 ms |
| Passed | createInstrumentedSchedulingFairness › with measurement conditions, validates a cycle by its longest latency | 3.7 ms |
| Passed | createInstrumentedSchedulingFairness › with measurement conditions, stops while the page is hidden and starts again when it is visible | 1.8 ms |
| Passed | createInstrumentedSchedulingFairness › stop() cancels the cycles that wait for evidence, and the page lifecycle does not start the monitor again | 1.6 ms |
packages/lag/src/instrumented/shared-liveness.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedSharedLiveness › records the duration of each block that the worker saw | 7.9 ms |
| Passed | createInstrumentedSharedLiveness › with measurement conditions, stops the watcher while the page is hidden, and does not record a block that overlaps the hidden period | 5.4 ms |
| Passed | createInstrumentedSharedLiveness › stop() stops the watcher, cancels the blocks that wait for evidence, and ends the pause | 2.6 ms |
packages/lag/src/instrumented/shared.test.ts9 passed
| Status | Test | Duration |
|---|---|---|
| Passed | validatedRecorder › records each sample at once with its window, without measurement conditions | 7.2 ms |
| Passed | validatedRecorder › gives each sample to a validator of the measurement conditions, and dispose() cancels the samples that wait | 2.7 ms |
| Passed | createHandle › gives a handle with the monitor and the stop function of the build function | 1.6 ms |
| Passed | the span helpers › pageViewSpanOf reads the span of the page view from the context attributes, if it is valid | 0.74 ms |
| Passed | the 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 it | 1.9 ms |
| Passed | the span helpers › gives no link when the page that hung is this view, or when this page has no open view | 0.98 ms |
| Passed | the 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 record | 0.49 ms |
| Passed | the span helpers › recordSpan records a span of a monitor in the current view, or as a new trace without an open view | 0.77 ms |
| Passed | the span helpers › does nothing without a span sink | 0.99 ms |
packages/lag/src/instrumented/throttle-detector.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedThrottleDetector › counts each calibration round with the attribute throttled | 14 ms |
packages/lag/src/instrumented/worker-lag.test.ts21 passed
| Status | Test | Duration |
|---|---|---|
| Passed | createInstrumentedWorkerLag with a hang journal › reports the hangs that earlier pages did not survive, and removes their records | 16 ms |
| Passed | createInstrumentedWorkerLag 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 view | 1.5 ms |
| Passed | createInstrumentedWorkerLag with a hang journal › sends its page ID to the worker | 1.8 ms |
| Passed | createInstrumentedWorkerLag with a hang journal › sends no page ID without a journal, so that the worker writes no journal either | 1.6 ms |
| Passed | createInstrumentedWorkerLag with a hang journal › reports nothing after stop() | 0.87 ms |
| Passed | createInstrumentedWorkerLag: two pages of the origin start at the same time (a session restore) › reports an abandoned hang one time with a journal in memory | 11 ms |
| Passed | createInstrumentedWorkerLag: two pages of the origin start at the same time (a session restore) › reports an abandoned hang one time with IndexedDB | 209 ms |
| Passed | createInstrumentedWorkerLag 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 |
| Passed | createInstrumentedWorkerLag 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 more | 9.4 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › gives the hang report target to the worker | 1.6 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › counts a hang that the worker ended, with the outcome ended, and records its duration | 3.4 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › handles a system stall and the end of a hang without measurement conditions and without an event sink | 1.3 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › stop() cancels the heartbeat delays that wait for evidence | 1.2 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › uses Date.now() to find the abandoned hangs when the dependencies have no wall clock | 1 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › reports an abandoned hang without an event sink | 0.93 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › does not report a hang whose record another page updated after the read, because the hang continues | 1.1 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › skips a record that another page took first | 1.1 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › puts a record back for the next page when the monitor stops while it takes the record | 1.1 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › removes the record of a hang that the peer hang watch reported, but does not count the hang again | 4.1 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › removes the old marks of pages without a record, and keeps the marks that the journal can still need | 1.1 ms |
| Passed | createInstrumentedWorkerLag with the messages of a worker › logs a warning when it cannot read the hang journal | 1 ms |
packages/lag/src/vitals/PageViewVitals.test.ts74 passed
| Status | Test | Duration |
|---|---|---|
| Passed | PageViewVitals › a load › reports TTFB, FCP, LCP, INP and CLS when the page becomes hidden | 20 ms |
| Passed | PageViewVitals › a load › keeps the last LCP candidate of the browser, also when its start time (the load time) is earlier | 2.1 ms |
| Passed | PageViewVitals › a load › makes the LCP final at a click that gives no Event Timing entry, as the DOM listener of web-vitals does | 1.1 ms |
| Passed | PageViewVitals › a load › makes the LCP final at a key press that gives no Event Timing entry | 0.66 ms |
| Passed | PageViewVitals › a load › ignores a synthetic click (isTrusted false), and removes its listeners at stop() | 1.1 ms |
| Passed | PageViewVitals › a load › ignores the LCP candidates that paint after the first click or key press, as web-vitals does | 0.7 ms |
| Passed | PageViewVitals › a load › counts the interactions of the load from the start of the page, also when the monitors start later | 0.73 ms |
| Passed | PageViewVitals › a load › observes the event entries with the smallest threshold that browsers permit | 0.49 ms |
| Passed | PageViewVitals › a load › reports the final values when the page terminates | 1.5 ms |
| Passed | PageViewVitals › a load › ignores the paints after the page was hidden for the first time | 1 ms |
| Passed | PageViewVitals › a load › takes the first hidden time from the visibility-state entries | 1.3 ms |
| Passed | PageViewVitals › a load › thinks that a page that is hidden at the start was hidden from the start | 0.45 ms |
| Passed | PageViewVitals › a load › uses the navigation type restore for a page that the browser discarded | 0.86 ms |
| Passed | PageViewVitals › a load › uses navigate and gives no TTFB without a navigation entry | 0.8 ms |
| Passed | PageViewVitals › a load › works without a page source | 0.68 ms |
| Passed | PageViewVitals › a load › gets the buffered FCP and layout shifts, also when observe() delivers them at once (old Safari: false) | 1.5 ms |
| Passed | PageViewVitals › a load › gets the buffered FCP and layout shifts, also when observe() delivers them at once (old Safari: true) | 0.78 ms |
| Passed | PageViewVitals › a load › makes no report at a checkpoint when there are no values | 0.5 ms |
| Passed | PageViewVitals › a prerendered page › starts at the activation and measures the load metrics from the activation | 2.1 ms |
| Passed | PageViewVitals › a restore from the back/forward cache › ends the view and starts a new one, with TTFB 0 and paint times from two animation frames | 2.6 ms |
| Passed | PageViewVitals › a restore from the back/forward cache › starts a new view with the event sequence of Chromium, in which the page is visible before pageshow | 1.7 ms |
| Passed | PageViewVitals › a restore from the back/forward cache › gives an INP of 8 ms when there were interactions after the restore but no entries | 0.54 ms |
| Passed | PageViewVitals › soft navigations › are off by default, as in web-vitals | 0.42 ms |
| Passed | PageViewVitals › soft navigations › start a new view with TTFB 0, FCP from the presentation time and LCP from the interaction paints | 1.6 ms |
| Passed | PageViewVitals › soft navigations › gives the paints that the browser did not deliver yet to the new view, after the largest paint of the entry | 0.83 ms |
| Passed | PageViewVitals › soft navigations › gives an interaction after the start of the soft navigation to the new view, also when its observer did not deliver it yet | 0.76 ms |
| Passed | PageViewVitals › 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 does | 0.74 ms |
| Passed | PageViewVitals › soft navigations › ignores the paints of the navigation after the next click, as web-vitals makes the LCP final at the next input | 0.59 ms |
| Passed | PageViewVitals › soft navigations › need the soft-navigation and interaction-contentful-paint entry types | 0.41 ms |
| Passed | PageViewVitals › checkpoints › process the entries that the browser has not delivered yet | 0.47 ms |
| Passed | PageViewVitals › checkpoints › split the pending entries at a pending soft navigation, in the sequence of their start times | 0.97 ms |
| Passed | PageViewVitals › checkpoints › log an error from the report function and continue | 1.7 ms |
| Passed | PageViewVitals › subscribe() › calls the listener at each new view, until the listener is removed | 1 ms |
| Passed | PageViewVitals › subscribe() › logs an error from a listener and continues | 0.69 ms |
| Passed | PageViewVitals › flush() › reports the current values now, as a checkpoint that is not final | 0.62 ms |
| Passed | PageViewVitals › flush() › does nothing before the activation of a prerendered page or after stop() | 0.82 ms |
| Passed | PageViewVitals › stop() › reports the final values, stops the observers and ignores later changes | 0.76 ms |
| Passed | PageViewVitals › stop() › gives no value for a vital whose entry type the browser does not have, as web-vitals | 0.61 ms |
| Passed | PageViewVitals › stop() › makes no observer for an entry type that the browser does not have, and no warning | 0.69 ms |
| Passed | PageViewVitals › view IDs › makes an ID of the form lag-<time>-<13 random digits> without an ID function, and a new ID for each view | 4.7 ms |
| Passed | PageViewVitals › rules of the load metrics › uses the describeNode function of the dependencies for the attribution | 0.72 ms |
| Passed | PageViewVitals › rules of the load metrics › describes a node with the selector of web-vitals when the dependencies have no describeNode function | 1.2 ms |
| Passed | PageViewVitals › rules of the load metrics › ignores a first-paint entry: only first-contentful-paint gives FCP | 0.71 ms |
| Passed | PageViewVitals › rules of the load metrics › ignores a paint at the time at which the page became hidden, as web-vitals does | 0.57 ms |
| Passed | PageViewVitals › rules of the load metrics › keeps the first hidden time when the page becomes hidden again | 0.44 ms |
| Passed | PageViewVitals › rules of the load metrics › takes the earliest hidden time of the visibility-state entries | 0.5 ms |
| Passed | PageViewVitals › rules of the load metrics › thinks that a page that is hidden at the start was hidden from the start, also without a page source | 0.5 ms |
| Passed | PageViewVitals › rules of the load metrics › ignores the hidden times before the activation of a prerendered page | 0.52 ms |
| Passed | PageViewVitals › rules of the load metrics › counts a hidden time at the activation of a prerendered page, as web-vitals does | 0.34 ms |
| Passed | PageViewVitals › rules of the load metrics › uses the navigation type prerender for a page that the browser activated before the monitors started | 0.4 ms |
| Passed | PageViewVitals › rules of the load metrics › makes the LCP final at a key press | 1.4 ms |
| Passed | PageViewVitals › rules of the load metrics › does not make the LCP final at a pointer event without a click | 0.58 ms |
| Passed | PageViewVitals › rules of the load metrics › processes the entries that the other observers did not deliver yet before a later entry | 0.53 ms |
| Passed | PageViewVitals › rules of the load metrics › counts the first input for INP, also when the event entries do not contain it | 0.55 ms |
| Passed | PageViewVitals › rules of the load metrics › gives FCP and LCP entries only to the load: a restored view gets these values from the animation frames | 0.47 ms |
| Passed | PageViewVitals › rules of soft navigations › observes no soft navigations when the browser gives no list of supported entry types | 0.37 ms |
| Passed | PageViewVitals › rules of soft navigations › does not make the LCP final at the interaction that started the soft navigation | 0.42 ms |
| Passed | PageViewVitals › rules of soft navigations › does not make the LCP of a soft navigation final at an input at the start time of the navigation | 0.75 ms |
| Passed | PageViewVitals › rules of soft navigations › ignores the paints of other interactions, also when they come last | 0.42 ms |
| Passed | PageViewVitals › rules of soft navigations › counts an interaction paint without an interaction ID for the current soft navigation | 0.48 ms |
| Passed | PageViewVitals › rules of soft navigations › ignores an interaction paint before the first soft navigation | 0.43 ms |
| Passed | PageViewVitals › rules of soft navigations › ignores an interaction paint at or after the time at which the page became hidden | 0.6 ms |
| Passed | PageViewVitals › rules of soft navigations › starts a view for an entry without a largest paint, and logs no error | 0.79 ms |
| Passed | PageViewVitals › rules of soft navigations › logs no error for an interaction paint without a paint | 0.45 ms |
| Passed | PageViewVitals › rules of soft navigations › does not take the paint times of a soft navigation from the animation frames | 0.64 ms |
| Passed | PageViewVitals › rules of restores and of the end of a view › gives no TTFB to a restored view when the load had no navigation entry | 0.36 ms |
| Passed | PageViewVitals › 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 view | 0.78 ms |
| Passed | PageViewVitals › 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 fragment | 0.62 ms |
| Passed | PageViewVitals › 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 URL | 0.46 ms |
| Passed | PageViewVitals › rules of restores and of the end of a view › gives a restored view no URL when the load had no URL | 0.77 ms |
| Passed | PageViewVitals › rules of restores and of the end of a view › makes no report when a prerendered page terminates before the activation | 0.43 ms |
| Passed | PageViewVitals › 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 event | 0.68 ms |
| Passed | PageViewVitals › 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 times | 0.47 ms |
| Passed | PageViewVitals › rules of restores and of the end of a view › stop() removes its activation listener from the page source | 2.7 ms |
packages/lag/src/vitals/ViewCollector.test.ts35 passed
| Status | Test | Duration |
|---|---|---|
| Passed | ViewCollector › INP › is 0 for a first input with the duration 0, as in web-vitals | 4.1 ms |
| Passed | ViewCollector › INP › counts the interactions of a view that starts at 0 (the load) from 0, and of a later view from its start | 0.71 ms |
| Passed | ViewCollector › INP › is the longest interaction when there are fewer than 50 | 0.3 ms |
| Passed | ViewCollector › INP › uses the longest entry of each interaction | 0.29 ms |
| Passed | ViewCollector › INP › counts the first-input entry as a candidate, because the browser always delivers it | 0.31 ms |
| Passed | ViewCollector › INP › ignores entries without an interaction ID and entries from before the view | 0.26 ms |
| Passed | ViewCollector › INP › gives the target, the type and the three phases of the INP interaction | 1.2 ms |
| Passed | ViewCollector › INP › caps the processing at the next paint, for example after alert() | 0.38 ms |
| Passed | ViewCollector › INP › spans the processing over the entries of the interaction in the same frame | 0.37 ms |
| Passed | ViewCollector › INP › leaves out the interaction that started a soft navigation, also when its entry comes late | 0.33 ms |
| Passed | ViewCollector › INP › counts the processing of other events in the frame, as web-vitals does | 1.2 ms |
| Passed | ViewCollector › INP › starts the processing at the interaction at the earliest | 0.3 ms |
| Passed | ViewCollector › INP › leaves out the entries of the interaction that end in a different frame | 0.25 ms |
| Passed | ViewCollector › INP › keeps the entry details only for the interactions that can be INP | 2.6 ms |
| Passed | ViewCollector › INP › gives 8 ms after a restore when there were interactions but no entries | 0.41 ms |
| Passed | ViewCollector › CLS › reports a load only after FCP, and then includes the shifts from before FCP | 0.62 ms |
| Passed | ViewCollector › CLS › reports a restore and a soft navigation from the start, at 0 | 0.27 ms |
| Passed | ViewCollector › CLS › ignores shifts after recent input and shifts from before the view | 0.2 ms |
| Passed | ViewCollector › CLS › names the largest shift of the worst session window | 0.33 ms |
| Passed | ViewCollector › CLS › makes the selector of the largest shift at the time of the shift, while the node is in the document | 1.6 ms |
| Passed | ViewCollector › CLS › names the first source with an element node, as web-vitals does, also when a text node comes first | 0.23 ms |
| Passed | ViewCollector › CLS › names the first source when no source has an element node, as web-vitals does | 0.31 ms |
| Passed | ViewCollector › the time of each value › is the time of the occurrence that gave the value, also in a view that starts later | 0.47 ms |
| Passed | ViewCollector › the time of each value › is undefined for an INP estimate and for a CLS without shifts | 0.29 ms |
| Passed | ViewCollector › paint and network metrics › keeps the first FCP, the last LCP, and never a value below 0 | 0.31 ms |
| Passed | ViewCollector › paint and network metrics › leaves out the vitals that have no value | 0.2 ms |
| Passed | ViewCollector › rules of the entries › counts an event and a layout shift that start at the start of the view | 0.27 ms |
| Passed | ViewCollector › rules of the entries › gives 8 ms after a soft navigation when there were interactions but no entries | 0.23 ms |
| Passed | ViewCollector › rules of the entries › keeps no more than 16 entries of one interaction for the attribution | 0.28 ms |
| Passed | ViewCollector › 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 does | 0.28 ms |
| Passed | ViewCollector › rules of the entries › puts the entries whose render times are 8 ms apart into one frame | 0.19 ms |
| Passed | ViewCollector › rules of the entries › gives no interaction target when the target of the event is null or when no entry has a target | 0.28 ms |
| Passed | ViewCollector › rules of the entries › names the first source with an element node, also after a source without a node | 0.23 ms |
| Passed | ViewCollector › rules of the entries › gives no CLS target when the largest shift has no source | 0.2 ms |
| Passed | ViewCollector › rules of the entries › keeps an LCP that paints at the time at which the LCP became final, and ignores a later paint | 0.24 ms |
packages/lag/src/vitals/selector.test.ts7 passed
| Status | Test | Duration |
|---|---|---|
| Passed | describeNode › joins the parts from the root down with > | 3.3 ms |
| Passed | describeNode › stops at the first element with an ID | 0.53 ms |
| Passed | describeNode › keeps the selector at 100 characters or less, and gives the deepest part when no part fits | 0.59 ms |
| Passed | describeNode › names text nodes in upper case without the number sign | 0.31 ms |
| Passed | describeNode › gives an empty string for an empty value or an object that throws | 0.39 ms |
| Passed | describeNode › describes an element without a node name by its classes | 0.23 ms |
| Passed | describeNode › keeps a selector of exactly the maximum length, and stops before a longer one | 0.66 ms |
packages/lag/src/vitals/types.test.ts5 passed
| Status | Test | Duration |
|---|---|---|
| Passed | rateVital › rates INP as good up to 200 and as poor above 500, as web-vitals does | 3.6 ms |
| Passed | rateVital › rates CLS as good up to 0.1 and as poor above 0.25, as web-vitals does | 0.47 ms |
| Passed | rateVital › rates LCP as good up to 2500 and as poor above 4000, as web-vitals does | 0.31 ms |
| Passed | rateVital › rates FCP as good up to 1800 and as poor above 3000, as web-vitals does | 0.32 ms |
| Passed | rateVital › rates TTFB as good up to 800 and as poor above 1800, as web-vitals does | 0.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
| Status | Test | Duration |
|---|---|---|
| Passed | the 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 operates | 3.78 s |
| Passed | the back/forward cache with the peer hang watch › keeps a page with the library in the cache, and the page watches again after the restore | 4.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
| Status | Test | Duration |
|---|---|---|
| Passed | Monitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports | 80 ms |
| Passed | Monitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source | 2.02 s |
| Passed | Monitors of engine-specific APIs › the page source reads the visibility-state entries | 0.3 ms |
| Passed | Monitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events | 0.3 ms |
| Passed | Monitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page | 1.01 s |
| Passed | Monitors of engine-specific APIs › MemoryMonitor reads performance.memory | 51 ms |
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Facts of the engines › gives the entry types of the research | 1.3 ms |
| Passed | Facts of the engines › starts the listeners at window in the order of experiment E1 | 0.4 ms |
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag accuracy › reports approximately 0 on an idle page and the length of a block | 4.31 s |
packages/lag-integration-tests/src/drift-load.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load | 8.43 s |
| Passed | DriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load | 8.44 s |
packages/lag-integration-tests/src/hang-journal.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | hang journal in a browser › keeps the record of a hang that did not end | 7.02 s |
packages/lag-integration-tests/src/lag-monitors.test.ts13 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Integration › registers a monitor for each API that the browser has, and no other | 8.8 ms |
| Passed | Lag Monitor Integration › DriftLag measures a blocked main thread | 711 ms |
| Passed | Lag Monitor Integration › the worker measures main-thread blocking from outside the main thread | 1.31 s |
| Passed | Lag Monitor Integration › FrameTimingMonitor records frames | 0.6 ms |
| Passed | Lag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports | 654 ms |
| Passed | Lag Monitor Integration › PageViewVitals measures the load of the page and a real click | 808 ms |
| Passed | Lag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle | 1.51 s |
| Passed | Lag Monitor Integration › MemoryMonitor samples the heap through performance.memory | 0.5 ms |
| Passed | Lag Monitor Integration › ClockReliabilityChecker reports the clock resolution | 0.9 ms |
| Passed | Lag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure | 1.12 s |
| Passed | Lag Monitor Integration › emits a synthetic log to verify the Loki bridge | 0.4 ms |
| Passed | Lag Monitor Integration › stop() halts all reporting | 1.75 s |
| Passed | Lag Monitor Integration › flushes metrics to the OTLP endpoint | 8.41 s |
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier | 0.8 ms |
| Passed | LifecycleStateMachine in a browser › uses the time of the event for the transition | 0.7 ms |
| Passed | LifecycleStateMachine in a browser › removes every listener when it is disposed | 0.2 ms |
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the 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 | 12.47 s |
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | experiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held | 8.01 s |
| Passed | experiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang | 2.76 s |
packages/lag-integration-tests/src/soft-navigation.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | PageViewVitals 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 | 2.87 s |
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Stress Tests › light load profile completes and reports few events | 20.63 s |
| Passed | Lag Monitor Stress Tests › moderate load profile triggers measurable lag | 19.59 s |
| Passed | Lag Monitor Stress Tests › heavy load profile drives the system hard | 18.92 s |
| Passed | Lag Monitor Stress Tests › bursty load produces both small and huge events (bimodal) | 18.87 s |
| Passed | Lag Monitor Stress Tests › evolutionary load drifts upward over time | 19.04 s |
| Passed | Lag Monitor Stress Tests › kitchen sink profile exercises all generators | 18.63 s |
| Skipped | Lag Monitor Stress Tests › exports the heavy profile to Mimir | – |
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | PageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly | 508 ms |
| Passed | PageViewVitals agrees with web-vitals › CLS agrees exactly | 1.7 s |
| Skipped | PageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does | – |
| Passed | PageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases | 1.5 s |
packages/lag-integration-tests/src/worker-io.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit | 2.03 s |
| Passed | the input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit | 2.02 s |
| Passed | the 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 WebKit | 3.02 s |
| Passed | the 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 WebKit | 2.96 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation completes during the block | 2.29 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation completes during the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation completes during the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation completes during the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation completes during the block | 2.21 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation completes during the block | 2.21 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives during the block | 2.53 s |
packages/lag-integration-tests/src/worker.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Worker Lag Monitor Integration › receives heartbeats from a real Web Worker | 1.51 s |
| Passed | Worker Lag Monitor Integration › detects main thread blocking | 1.6 s |
| Passed | Worker Lag Monitor Integration › stops and restarts the worker's heartbeat loop | 1.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
| Status | Test | Duration |
|---|---|---|
| Passed | Monitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports | 76 ms |
| Passed | Monitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source | 2.03 s |
| Passed | Monitors of engine-specific APIs › the page source reads the visibility-state entries | 1.1 ms |
| Passed | Monitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events | 0.7 ms |
| Passed | Monitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page | 1 s |
| Passed | Monitors of engine-specific APIs › MemoryMonitor reads performance.memory | 51 ms |
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Facts of the engines › gives the entry types of the research | 2.7 ms |
| Passed | Facts of the engines › starts the listeners at window in the order of experiment E1 | 0.9 ms |
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag accuracy › reports approximately 0 on an idle page and the length of a block | 4.31 s |
packages/lag-integration-tests/src/drift-load.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load | 8.42 s |
| Passed | DriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load | 8.42 s |
packages/lag-integration-tests/src/hang-journal.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | hang journal in a browser › keeps the record of a hang that did not end | 7.01 s |
packages/lag-integration-tests/src/lag-monitors.test.ts13 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Integration › registers a monitor for each API that the browser has, and no other | 10 ms |
| Passed | Lag Monitor Integration › DriftLag measures a blocked main thread | 661 ms |
| Passed | Lag Monitor Integration › the worker measures main-thread blocking from outside the main thread | 1.32 s |
| Passed | Lag Monitor Integration › FrameTimingMonitor records frames | 0.8 ms |
| Passed | Lag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports | 663 ms |
| Passed | Lag Monitor Integration › PageViewVitals measures the load of the page and a real click | 752 ms |
| Passed | Lag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle | 1.62 s |
| Passed | Lag Monitor Integration › MemoryMonitor samples the heap through performance.memory | 0.4 ms |
| Passed | Lag Monitor Integration › ClockReliabilityChecker reports the clock resolution | 1.4 ms |
| Passed | Lag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure | 1.11 s |
| Passed | Lag Monitor Integration › emits a synthetic log to verify the Loki bridge | 0.3 ms |
| Passed | Lag Monitor Integration › stop() halts all reporting | 1.75 s |
| Passed | Lag Monitor Integration › flushes metrics to the OTLP endpoint | 8.88 s |
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier | 0.9 ms |
| Passed | LifecycleStateMachine in a browser › uses the time of the event for the transition | 0.6 ms |
| Passed | LifecycleStateMachine in a browser › removes every listener when it is disposed | 0.2 ms |
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the 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 | 12.97 s |
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | experiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held | 7.9 s |
| Passed | experiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang | 2.62 s |
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | PageViewVitals 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 | – |
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Stress Tests › light load profile completes and reports few events | 20.19 s |
| Passed | Lag Monitor Stress Tests › moderate load profile triggers measurable lag | 18.29 s |
| Passed | Lag Monitor Stress Tests › heavy load profile drives the system hard | 18.54 s |
| Passed | Lag Monitor Stress Tests › bursty load produces both small and huge events (bimodal) | 18.58 s |
| Passed | Lag Monitor Stress Tests › evolutionary load drifts upward over time | 18.42 s |
| Passed | Lag Monitor Stress Tests › kitchen sink profile exercises all generators | 19.06 s |
| Skipped | Lag Monitor Stress Tests › exports the heavy profile to Mimir | – |
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | PageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly | 583 ms |
| Passed | PageViewVitals agrees with web-vitals › CLS agrees exactly | 1.69 s |
| Skipped | PageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does | – |
| Passed | PageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases | 1.43 s |
packages/lag-integration-tests/src/worker-io.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit | 2.02 s |
| Passed | the input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit | 2.01 s |
| Passed | the 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 WebKit | 2.92 s |
| Passed | the 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 WebKit | 2.9 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation completes during the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation completes during the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation completes during the block | 2.21 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation completes during the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation completes during the block | 2.21 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation completes during the block | 2.23 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives during the block | 2.52 s |
packages/lag-integration-tests/src/worker.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Worker Lag Monitor Integration › receives heartbeats from a real Web Worker | 1.5 s |
| Passed | Worker Lag Monitor Integration › detects main thread blocking | 1.6 s |
| Passed | Worker Lag Monitor Integration › stops and restarts the worker's heartbeat loop | 1.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
| Status | Test | Duration |
|---|---|---|
| Skipped | Monitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports | – |
| Skipped | Monitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source | – |
| Skipped | Monitors of engine-specific APIs › the page source reads the visibility-state entries | – |
| Skipped | Monitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events | – |
| Passed | Monitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page | 1 s |
| Skipped | Monitors of engine-specific APIs › MemoryMonitor reads performance.memory | – |
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Facts of the engines › gives the entry types of the research | 2 ms |
| Passed | Facts of the engines › starts the listeners at window in the order of experiment E1 | 1 ms |
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag accuracy › reports approximately 0 on an idle page and the length of a block | 4.32 s |
packages/lag-integration-tests/src/drift-load.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load | 8.42 s |
| Passed | DriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load | 8.42 s |
packages/lag-integration-tests/src/hang-journal.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | hang journal in a browser › keeps the record of a hang that did not end | 7.02 s |
packages/lag-integration-tests/src/lag-monitors.test.ts11 passed, 2 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Integration › registers a monitor for each API that the browser has, and no other | 4 ms |
| Passed | Lag Monitor Integration › DriftLag measures a blocked main thread | 656 ms |
| Passed | Lag Monitor Integration › the worker measures main-thread blocking from outside the main thread | 1.31 s |
| Passed | Lag Monitor Integration › FrameTimingMonitor records frames | 1 ms |
| Skipped | Lag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports | – |
| Passed | Lag Monitor Integration › PageViewVitals measures the load of the page and a real click | 814 ms |
| Passed | Lag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle | 2.23 s |
| Skipped | Lag Monitor Integration › MemoryMonitor samples the heap through performance.memory | – |
| Passed | Lag Monitor Integration › ClockReliabilityChecker reports the clock resolution | 2 ms |
| Passed | Lag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure | 1.08 s |
| Passed | Lag Monitor Integration › emits a synthetic log to verify the Loki bridge | 13 ms |
| Passed | Lag Monitor Integration › stop() halts all reporting | 1.77 s |
| Passed | Lag Monitor Integration › flushes metrics to the OTLP endpoint | 9.24 s |
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier | 2 ms |
| Passed | LifecycleStateMachine in a browser › uses the time of the event for the transition | 1 ms |
| Passed | LifecycleStateMachine in a browser › removes every listener when it is disposed | 1 ms |
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the 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 | 10.57 s |
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | experiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held | 8.14 s |
| Passed | experiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang | 2.49 s |
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | PageViewVitals 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 | – |
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Stress Tests › light load profile completes and reports few events | 20.28 s |
| Passed | Lag Monitor Stress Tests › moderate load profile triggers measurable lag | 18.23 s |
| Passed | Lag Monitor Stress Tests › heavy load profile drives the system hard | 18.32 s |
| Passed | Lag Monitor Stress Tests › bursty load produces both small and huge events (bimodal) | 18.09 s |
| Passed | Lag Monitor Stress Tests › evolutionary load drifts upward over time | 17.93 s |
| Passed | Lag Monitor Stress Tests › kitchen sink profile exercises all generators | 17.61 s |
| Skipped | Lag Monitor Stress Tests › exports the heavy profile to Mimir | – |
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | PageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly | 518 ms |
| Skipped | PageViewVitals agrees with web-vitals › CLS agrees exactly | – |
| Passed | PageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does | 1 ms |
| Passed | PageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases | 1.64 s |
packages/lag-integration-tests/src/worker-io.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit | 2.05 s |
| Passed | the input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit | 2.04 s |
| Passed | the 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 WebKit | 3.03 s |
| Passed | the 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 WebKit | 2.91 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation completes during the block | 2.25 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation completes during the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation completes during the block | 2.23 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation completes during the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation waits for the end of the block | 2.24 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation waits for the end of the block | 2.25 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives after the block | 2.55 s |
packages/lag-integration-tests/src/worker.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Worker Lag Monitor Integration › receives heartbeats from a real Web Worker | 1.51 s |
| Passed | Worker Lag Monitor Integration › detects main thread blocking | 1.61 s |
| Passed | Worker Lag Monitor Integration › stops and restarts the worker's heartbeat loop | 1.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
| Status | Test | Duration |
|---|---|---|
| Skipped | Monitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports | – |
| Skipped | Monitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source | – |
| Skipped | Monitors of engine-specific APIs › the page source reads the visibility-state entries | – |
| Skipped | Monitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events | – |
| Skipped | Monitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page | – |
| Skipped | Monitors of engine-specific APIs › MemoryMonitor reads performance.memory | – |
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Facts of the engines › gives the entry types of the research | 4 ms |
| Passed | Facts of the engines › starts the listeners at window in the order of experiment E1 | 0 ms |
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag accuracy › reports approximately 0 on an idle page and the length of a block | 4.36 s |
packages/lag-integration-tests/src/drift-load.test.ts1 failed, 1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load | 8.47 s |
| Failed | DriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load | 8.5 s |
packages/lag-integration-tests/src/hang-journal.test.ts1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | hang journal in a browser › keeps the record of a hang that did not end | – |
packages/lag-integration-tests/src/lag-monitors.test.ts10 passed, 3 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Integration › registers a monitor for each API that the browser has, and no other | 11 ms |
| Passed | Lag Monitor Integration › DriftLag measures a blocked main thread | 831 ms |
| Passed | Lag Monitor Integration › the worker measures main-thread blocking from outside the main thread | 1.31 s |
| Passed | Lag Monitor Integration › FrameTimingMonitor records frames | 0 ms |
| Skipped | Lag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports | – |
| Skipped | Lag Monitor Integration › PageViewVitals measures the load of the page and a real click | – |
| Passed | Lag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle | 2.24 s |
| Skipped | Lag Monitor Integration › MemoryMonitor samples the heap through performance.memory | – |
| Passed | Lag Monitor Integration › ClockReliabilityChecker reports the clock resolution | 0 ms |
| Passed | Lag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure | 1.09 s |
| Passed | Lag Monitor Integration › emits a synthetic log to verify the Loki bridge | 1 ms |
| Passed | Lag Monitor Integration › stop() halts all reporting | 1.76 s |
| Passed | Lag Monitor Integration › flushes metrics to the OTLP endpoint | 8.87 s |
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier | 2 ms |
| Passed | LifecycleStateMachine in a browser › uses the time of the event for the transition | 1 ms |
| Passed | LifecycleStateMachine in a browser › removes every listener when it is disposed | 1 ms |
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | the 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 | – |
packages/lag-integration-tests/src/peer-tab.test.ts1 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | experiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held | – |
| Passed | experiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang | 9.05 s |
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | PageViewVitals 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 | – |
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Stress Tests › light load profile completes and reports few events | 20.24 s |
| Passed | Lag Monitor Stress Tests › moderate load profile triggers measurable lag | 18.82 s |
| Passed | Lag Monitor Stress Tests › heavy load profile drives the system hard | 18.47 s |
| Passed | Lag Monitor Stress Tests › bursty load produces both small and huge events (bimodal) | 18.89 s |
| Passed | Lag Monitor Stress Tests › evolutionary load drifts upward over time | 18.96 s |
| Passed | Lag Monitor Stress Tests › kitchen sink profile exercises all generators | 18.22 s |
| Skipped | Lag Monitor Stress Tests › exports the heavy profile to Mimir | – |
packages/lag-integration-tests/src/web-vitals-oracle.test.ts2 passed, 2 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | PageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly | 547 ms |
| Skipped | PageViewVitals agrees with web-vitals › CLS agrees exactly | – |
| Passed | PageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does | 0 ms |
| Skipped | PageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases | – |
packages/lag-integration-tests/src/worker-io.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit | 2.09 s |
| Passed | the input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit | 2.05 s |
| Passed | the 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 WebKit | 2.99 s |
| Passed | the 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 WebKit | 2.91 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation waits for the end of the block | 2.28 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation waits for the end of the block | 2.26 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation waits for the end of the block | 2.29 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation waits for the end of the block | 2.26 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation waits for the end of the block | 2.27 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation waits for the end of the block | 2.26 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives after the block | 2.54 s |
packages/lag-integration-tests/src/worker.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Worker Lag Monitor Integration › receives heartbeats from a real Web Worker | 1.55 s |
| Passed | Worker Lag Monitor Integration › detects main thread blocking | 1.61 s |
| Passed | Worker Lag Monitor Integration › stops and restarts the worker's heartbeat loop | 1.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
| Status | Test | Duration |
|---|---|---|
| Skipped | Monitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports | – |
| Skipped | Monitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source | – |
| Skipped | Monitors of engine-specific APIs › the page source reads the visibility-state entries | – |
| Skipped | Monitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events | – |
| Skipped | Monitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page | – |
| Skipped | Monitors of engine-specific APIs › MemoryMonitor reads performance.memory | – |
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Facts of the engines › gives the entry types of the research | 1 ms |
| Passed | Facts of the engines › starts the listeners at window in the order of experiment E1 | 0 ms |
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag accuracy › reports approximately 0 on an idle page and the length of a block | 4.34 s |
packages/lag-integration-tests/src/drift-load.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load | 8.44 s |
| Passed | DriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load | 8.42 s |
packages/lag-integration-tests/src/hang-journal.test.ts1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | hang journal in a browser › keeps the record of a hang that did not end | – |
packages/lag-integration-tests/src/lag-monitors.test.ts11 passed, 2 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Integration › registers a monitor for each API that the browser has, and no other | 7 ms |
| Passed | Lag Monitor Integration › DriftLag measures a blocked main thread | 748 ms |
| Passed | Lag Monitor Integration › the worker measures main-thread blocking from outside the main thread | 1.75 s |
| Passed | Lag Monitor Integration › FrameTimingMonitor records frames | 3 ms |
| Skipped | Lag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports | – |
| Passed | Lag Monitor Integration › PageViewVitals measures the load of the page and a real click | 1.36 s |
| Passed | Lag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle | 1.18 s |
| Skipped | Lag Monitor Integration › MemoryMonitor samples the heap through performance.memory | – |
| Passed | Lag Monitor Integration › ClockReliabilityChecker reports the clock resolution | 0 ms |
| Passed | Lag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure | 1.07 s |
| Passed | Lag Monitor Integration › emits a synthetic log to verify the Loki bridge | 1 ms |
| Passed | Lag Monitor Integration › stop() halts all reporting | 1.76 s |
| Passed | Lag Monitor Integration › flushes metrics to the OTLP endpoint | 8.87 s |
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier | 1 ms |
| Passed | LifecycleStateMachine in a browser › uses the time of the event for the transition | 1 ms |
| Passed | LifecycleStateMachine in a browser › removes every listener when it is disposed | 0 ms |
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the 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 | 17.62 s |
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | experiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held | 11.6 s |
| Passed | experiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang | 20.9 s |
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | PageViewVitals 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 | – |
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Stress Tests › light load profile completes and reports few events | 20.42 s |
| Passed | Lag Monitor Stress Tests › moderate load profile triggers measurable lag | 18.16 s |
| Passed | Lag Monitor Stress Tests › heavy load profile drives the system hard | 18.64 s |
| Passed | Lag Monitor Stress Tests › bursty load produces both small and huge events (bimodal) | 18.87 s |
| Passed | Lag Monitor Stress Tests › evolutionary load drifts upward over time | 18.81 s |
| Passed | Lag Monitor Stress Tests › kitchen sink profile exercises all generators | 18.76 s |
| Skipped | Lag Monitor Stress Tests › exports the heavy profile to Mimir | – |
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | PageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly | 527 ms |
| Skipped | PageViewVitals agrees with web-vitals › CLS agrees exactly | – |
| Passed | PageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does | 0 ms |
| Passed | PageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases | 1.47 s |
packages/lag-integration-tests/src/worker-io.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit | 2.16 s |
| Passed | the input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit | 2.06 s |
| Passed | the 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 WebKit | 2.99 s |
| Passed | the 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 WebKit | 2.91 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-sync-access: the operation waits for the end of the block | 2.25 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-writable: the operation waits for the end of the block | 2.24 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation waits for the end of the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation waits for the end of the block | 2.27 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation waits for the end of the block | 2.23 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation waits for the end of the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives after the block | 2.54 s |
packages/lag-integration-tests/src/worker.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Worker Lag Monitor Integration › receives heartbeats from a real Web Worker | 1.54 s |
| Passed | Worker Lag Monitor Integration › detects main thread blocking | 1.61 s |
| Passed | Worker Lag Monitor Integration › stops and restarts the worker's heartbeat loop | 1.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
| Status | Test | Duration |
|---|---|---|
| Skipped | Monitors of engine-specific APIs › LayoutShiftMonitor records each layout shift that the browser reports | – |
| Skipped | Monitors of engine-specific APIs › ComputePressureMonitor observes the real CPU pressure source | – |
| Skipped | Monitors of engine-specific APIs › the page source reads the visibility-state entries | – |
| Skipped | Monitors of engine-specific APIs › the browser has the Page Lifecycle freeze and resume events | – |
| Skipped | Monitors of engine-specific APIs › IdleAvailabilityMonitor sees the idle periods of an idle page | – |
| Skipped | Monitors of engine-specific APIs › MemoryMonitor reads performance.memory | – |
packages/lag-integration-tests/src/browser-facts.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Facts of the engines › gives the entry types of the research | 2 ms |
| Passed | Facts of the engines › starts the listeners at window in the order of experiment E1 | 1 ms |
packages/lag-integration-tests/src/drift-accuracy.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag accuracy › reports approximately 0 on an idle page and the length of a block | 4.31 s |
packages/lag-integration-tests/src/drift-load.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | DriftLag during a sustained load › reports equal message tasks of 20 ms as lag, and no lag after the load | 8.42 s |
| Passed | DriftLag during a sustained load › reports equal timer tasks of 30 ms as lag, and no lag after the load | 8.41 s |
packages/lag-integration-tests/src/hang-journal.test.ts1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | hang journal in a browser › keeps the record of a hang that did not end | – |
packages/lag-integration-tests/src/lag-monitors.test.ts11 passed, 2 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Integration › registers a monitor for each API that the browser has, and no other | 13 ms |
| Passed | Lag Monitor Integration › DriftLag measures a blocked main thread | 657 ms |
| Passed | Lag Monitor Integration › the worker measures main-thread blocking from outside the main thread | 1.3 s |
| Passed | Lag Monitor Integration › FrameTimingMonitor records frames | 1 ms |
| Skipped | Lag Monitor Integration › LongAnimationFrameMonitor records every long frame the browser reports | – |
| Passed | Lag Monitor Integration › PageViewVitals measures the load of the page and a real click | 998 ms |
| Passed | Lag Monitor Integration › MacrotaskLag, SchedulingFairness and idle monitors sample within one 5s cycle | 2.02 s |
| Skipped | Lag Monitor Integration › MemoryMonitor samples the heap through performance.memory | – |
| Passed | Lag Monitor Integration › ClockReliabilityChecker reports the clock resolution | 6 ms |
| Passed | Lag Monitor Integration › GCSignalDetector counts GC cycles under allocation pressure | 1.07 s |
| Passed | Lag Monitor Integration › emits a synthetic log to verify the Loki bridge | 1 ms |
| Passed | Lag Monitor Integration › stop() halts all reporting | 1.77 s |
| Passed | Lag Monitor Integration › flushes metrics to the OTLP endpoint | 9.22 s |
packages/lag-integration-tests/src/lifecycle.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LifecycleStateMachine in a browser › notifies its subscribers before a document listener that the page added earlier | 2 ms |
| Passed | LifecycleStateMachine in a browser › uses the time of the event for the transition | 2 ms |
| Passed | LifecycleStateMachine in a browser › removes every listener when it is disposed | 2 ms |
packages/lag-integration-tests/src/peer-hang-watch.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the 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 | 16.11 s |
packages/lag-integration-tests/src/peer-tab.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | experiment E7: another page of the origin watches a hang › sees the silence of the main thread, while the lock of the page stays held | 8.08 s |
| Passed | experiment E7: another page of the origin watches a hang › gets the lock of a page that closes during a hang | 5.6 s |
packages/lag-integration-tests/src/soft-navigation.test.ts1 skipped
| Status | Test | Duration |
|---|---|---|
| Skipped | PageViewVitals 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 | – |
packages/lag-integration-tests/src/stress.test.ts6 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | Lag Monitor Stress Tests › light load profile completes and reports few events | 21.25 s |
| Passed | Lag Monitor Stress Tests › moderate load profile triggers measurable lag | 18.84 s |
| Passed | Lag Monitor Stress Tests › heavy load profile drives the system hard | 19.3 s |
| Passed | Lag Monitor Stress Tests › bursty load produces both small and huge events (bimodal) | 17.75 s |
| Passed | Lag Monitor Stress Tests › evolutionary load drifts upward over time | 18.61 s |
| Passed | Lag Monitor Stress Tests › kitchen sink profile exercises all generators | 18.22 s |
| Skipped | Lag Monitor Stress Tests › exports the heavy profile to Mimir | – |
packages/lag-integration-tests/src/web-vitals-oracle.test.ts3 passed, 1 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | PageViewVitals agrees with web-vitals › FCP, LCP and TTFB agree exactly | 511 ms |
| Skipped | PageViewVitals agrees with web-vitals › CLS agrees exactly | – |
| Passed | PageViewVitals agrees with web-vitals › reports no CLS where the browser cannot measure it, as web-vitals does | 1 ms |
| Passed | PageViewVitals agrees with web-vitals › INP agrees exactly, and so do its attribution phases | 1.49 s |
packages/lag-integration-tests/src/worker-io.test.ts8 passed, 3 skipped
| Status | Test | Duration |
|---|---|---|
| Passed | the input and output of a worker during a main-thread block › an IndexedDB write of a worker completes during the block, except in WebKit | 2.01 s |
| Passed | the input and output of a worker during a main-thread block › a fetch with keepalive of a worker completes during the block, except in WebKit | 2.01 s |
| Passed | the 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 WebKit | 2.92 s |
| Passed | the 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 WebKit | 2.91 s |
| Skipped | the 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 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 output of a dedicated worker during a main-thread block (experiment E6) › opfs-lookup: the operation waits for the end of the block | – |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › cache-put: the operation waits for the end of the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › xhr: the operation waits for the end of the block | 2.22 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › sync-xhr: the operation waits for the end of the block | 2.23 s |
| Passed | the output of a dedicated worker during a main-thread block (experiment E6) › websocket: the message arrives after the block | 2.53 s |
packages/lag-integration-tests/src/worker.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Worker Lag Monitor Integration › receives heartbeats from a real Web Worker | 1.51 s |
| Passed | Worker Lag Monitor Integration › detects main thread blocking | 1.61 s |
| Passed | Worker Lag Monitor Integration › stops and restarts the worker's heartbeat loop | 1.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
| Status | Test | Duration |
|---|---|---|
| Passed | ComputePressureMonitor with a virtual CPU pressure source › records each state of the source, as ordinals 0 to 3 | 420 ms |
packages/lag-integration-tests/src/cdp/cpu-throttling.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | CPU throttling (CDP Emulation.setCPUThrottlingRate) › 4x throttling of the same work increases the drift and the worker lag | 8.74 s |
packages/lag-integration-tests/src/cdp/freeze.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | A frozen page (CDP Page.setWebLifecycleState) › the lifecycle state machine sees the freeze and the resume | 1.07 s |
| Passed | A frozen page (CDP Page.setWebLifecycleState) › timer monitors pause before the freeze, record no stall for it, and continue after the resume | 5.04 s |
packages/lag-integration-tests/src/cdp/visibility.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | A hidden page (a second page in front) › timer monitors pause while the page is hidden and continue when it is visible | 4.86 s |
packages/lag-integration-tests/src/cdp/vitals-checkpoint.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | The page-view vitals at the hidden checkpoint › record one value for each vital, and the events, when the page becomes hidden | 1.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
| Status | Test | Duration |
|---|---|---|
| Passed | A cross-origin-isolated page › is cross-origin isolated and has SharedArrayBuffer | 2.1 ms |
| Passed | A cross-origin-isolated page › the shared-memory liveness monitor reports a main-thread block | 1.29 s |
| Passed | A cross-origin-isolated page › the memory monitor uses measureUserAgentSpecificMemory() | 1.8 ms |
| Passed | A cross-origin-isolated page › performance.now() has a high resolution | 5.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
| Status | Test | Duration |
|---|---|---|
| Passed | A cross-origin-isolated page › is cross-origin isolated and has SharedArrayBuffer | 1.5 ms |
| Passed | A cross-origin-isolated page › the shared-memory liveness monitor reports a main-thread block | 1.26 s |
| Skipped | A cross-origin-isolated page › the memory monitor uses measureUserAgentSpecificMemory() | – |
| Passed | A cross-origin-isolated page › performance.now() has a high resolution | 3.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
| Status | Test | Duration |
|---|---|---|
| Passed | A cross-origin-isolated page › is cross-origin isolated and has SharedArrayBuffer | 4.4 ms |
| Passed | A cross-origin-isolated page › the shared-memory liveness monitor reports a main-thread block | 1.26 s |
| Skipped | A cross-origin-isolated page › the memory monitor uses measureUserAgentSpecificMemory() | – |
| Passed | A cross-origin-isolated page › performance.now() has a high resolution | 2.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
| Status | Test | Duration |
|---|---|---|
| Passed | The overhead of all monitors on an idle page › stays in the CPU and timer budgets | 1 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
| Status | Test | Duration |
|---|---|---|
| Passed | load: RNG › is reproducible given the same seed | 2.1 ms |
| Passed | load: RNG › produces different sequences for different seeds | 0.51 ms |
| Passed | load: RNG › int() respects bounds inclusively | 3.4 ms |
| Passed | load: RNG › range() respects bounds (half-open) | 3.1 ms |
| Passed | load: RNG › normal() produces values approximately centered at 0 | 1.9 ms |
| Passed | load: RNG › bool(p) approximates the requested probability | 1 ms |
| Passed | load: RNG › pick() selects from the array uniformly | 0.96 ms |
| Passed | load: Distributions › constant always returns the same value | 0.44 ms |
| Passed | load: Distributions › uniform stays in bounds | 24 ms |
| Passed | load: Distributions › normal clamps to [min, max] | 21 ms |
| Passed | load: Distributions › exponential is non-negative and skewed | 3.2 ms |
| Passed | load: Distributions › powerLaw produces a long tail | 2.5 ms |
| Passed | load: Distributions › bimodal produces two clusters | 0.52 ms |
| Passed | load: Distributions › evolutionary drifts as a random walk | 0.25 ms |
| Passed | load: Distributions › burst alternates between active and idle | 0.28 ms |
@lag/report: unit tests in node
Suite report-unit-node. 12 passed. Duration 15 ms.
packages/report/src/convert.test.ts12 passed
| Status | Test | Duration |
|---|---|---|
| Passed | relativePath › makes Windows and POSIX paths relative to the root, with forward slashes | 1.7 ms |
| Passed | relativePath › ignores case on the root, as Windows paths do | 0.21 ms |
| Passed | relativePath › keeps paths outside the root | 0.28 ms |
| Passed | relativePath › removes the checkout folder of another runner, thus the file names agree in each engine | 0.33 ms |
| Passed | relativePath › removes the part before the packages folder of a file from another machine | 0.32 ms |
| Passed | fromVitestJson › converts files, tests, statuses and timing | 1.3 ms |
| Passed | fromVitestJson › adds a failed test for a file that failed without a failed test, as Vitest's JSON reporter writes it | 0.72 ms |
| Passed | fromIstanbulSummary › separates the total from the files and sorts the files | 7.7 ms |
| Passed | fromStrykerReport › counts mutants and calculates the score from valid mutants only | 1.5 ms |
| Passed | fromStrykerReport › keeps the commit and the time of the Stryker run | 0.35 ms |
| Passed | fromStrykerReport › gives no score to a file without valid mutants, and puts it after the files with a score | 0.39 ms |
| Passed | run summaries › counts statuses across suites | 0.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
| Status | Test | Duration |
|---|---|---|
| Passed | pnpm new › refuses an existing folder, unless --force | 3.1 ms |
| Passed | pnpm new › refuses the name of a package in another folder, also with --force | 0.29 ms |
| Passed | pnpm new › adds the devDependencies that the types of each TypeScript config need, with the versions of the workspace | 1.7 ms |
| Passed | pnpm new › gives a dependency for each `types` entry of the config files | 3 ms |
| Passed | pnpm new › finds a version in the workspace for each devDependency of each config | 2.2 ms |
| Passed | pnpm new › takes the range with the highest version when two packages differ | 0.43 ms |
| Passed | pnpm new › makes the package.json and the tsconfig.json of an ESM and a CommonJS package | 0.7 ms |
| Passed | pnpm new › fails when no workspace package uses a necessary devDependency | 0.76 ms |
packages/scripts/src/readme-metrics.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | readme-metrics › makes one row for each metric of the catalog | 2.7 ms |
| Passed | readme-metrics › escapes the pipe character in a description | 0.22 ms |
| Passed | readme-metrics › replaces only the text between the markers | 0.93 ms |
| Passed | readme-metrics › finds the README in agreement with the catalog | 0.37 ms |
packages/scripts/src/results/model.test.ts16 passed
| Status | Test | Duration |
|---|---|---|
| Passed | suite names › names a suite after the package, the project and the environment | 5 ms |
| Passed | suite names › finds the kind of a suite from the project | 0.51 ms |
| Passed | suite names › shortens the package names | 0.3 ms |
| Passed | suite names › gives each project report a file name without spaces | 0.64 ms |
| Passed | results.jsonl › reads the valid records and leaves out the other lines | 0.63 ms |
| Passed | results.jsonl › gives each measurement the suite of its project and joins the same name | 0.64 ms |
| Passed | results.jsonl › keeps one budget for each name, calculates `pass` again and puts the failed ones first | 0.56 ms |
| Passed | the run index › makes a run ID that sorts by time and has the short commit | 0.66 ms |
| Passed | the run index › adds the run to the index, oldest first, and replaces a run with the same ID | 19 ms |
| Passed | the run index › gives the summary of the new run its budget counts, and keeps an older summary without them | 0.54 ms |
| Passed | the run index › starts again from an index that the site cannot read, and keeps at most maxRuns | 0.61 ms |
| Passed | the result of the collector › fails when a step gave an exit code that is not 0, also without a failed test | 0.38 ms |
| Passed | the result of the collector › fails when a test or a budget failed | 0.24 ms |
| Passed | the result of the collector › uses only the files that changed during the run, with a tolerance of 2 s | 0.28 ms |
| Passed | the origin of the mutation report › takes the commit and the time from the file of the Pages workflow | 0.29 ms |
| Passed | the origin of the mutation report › uses the time of the report file, and no commit, without a valid file | 0.36 ms |
packages/scripts/src/results/project-reporter.test.ts5 passed
| Status | Test | Duration |
|---|---|---|
| Passed | project reporter with Vitest › adds a failed test for a beforeAll hook that failed, and keeps its tests skipped | 1.6 ms |
| Passed | project reporter with Vitest › adds a failed test for a file that failed at its import | 0.27 ms |
| Passed | project reporter with Vitest › adds a failed test for an afterAll hook that failed, and keeps its tests passed | 0.4 ms |
| Passed | project reporter with Vitest › adds nothing to a file that passed, and the counts agree with the exit code of Vitest | 0.95 ms |
| Passed | project reporter › adds a failed test for a file that Vitest marks as failed without an error | 0.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
| Status | Test | Duration |
|---|---|---|
| Passed | routePathOf › gives the route of a URL path below the base | 5.5 ms |
| Passed | isPrerendering › is true only when the prerender sets the flag | 0.5 ms |
| Passed | mountApp › gives the root element when the page has no HTML from the build | 0.9 ms |
| Passed | mountApp › removes HTML from the build for a different route | 1 ms |
| Passed | mountApp › renders hidden after the saved HTML, and shows the app when nothing loads | 209 ms |
| Passed | mountApp › shows the app after the settle time, also when a live chart changes the DOM all the time | 252 ms |
| Passed | mountApp › shows the app after the time limit, also when an element still loads | 203 ms |
| Passed | mountApp › gives React an ID prefix, so the IDs differ from the IDs in the saved HTML | 24 ms |
packages/site/src/app/smoke.browser.test.tsx69 passed
| Status | Test | Duration |
|---|---|---|
| Passed | site routes › renders / without errors | 740 ms |
| Passed | site routes › renders /results without errors | 552 ms |
| Passed | site routes › renders /results/2026-10-06-f6e5d4c without errors | 305 ms |
| Passed | site routes › renders /results/2026-10-06-f6e5d4c/tests without errors | 288 ms |
| Passed | site routes › renders /results/2026-10-06-f6e5d4c/tests?status=failed&q=heartbeat without errors | 180 ms |
| Passed | site routes › renders /results/2026-10-06-f6e5d4c/coverage without errors | 254 ms |
| Passed | site routes › renders /results/2026-10-06-f6e5d4c/mutation without errors | 174 ms |
| Passed | site routes › renders /results/2026-10-06-f6e5d4c/budgets without errors | 155 ms |
| Passed | site routes › renders /results/2026-10-06-f6e5d4c/measurements without errors | 262 ms |
| Passed | site routes › renders /results/2026-10-06-f6e5d4c/measurements?group=browser without errors | 259 ms |
| Passed | site routes › renders /results/no-such-run without errors | 154 ms |
| Passed | site routes › renders /playground without errors | 456 ms |
| Passed | site routes › renders /no/such/page without errors | 154 ms |
| Passed | site routes › renders /docs/no-such-page without errors | 153 ms |
| Passed | site routes › renders /docs without errors | 454 ms |
| Passed | site routes › renders /docs/getting-started without errors | 457 ms |
| Passed | site routes › renders /docs/concepts/event-loop without errors | 963 ms |
| Passed | site routes › renders /docs/concepts/page-lifecycle without errors | 660 ms |
| Passed | site routes › renders /docs/concepts/page-views without errors | 483 ms |
| Passed | site routes › renders /docs/concepts/clocks-and-time without errors | 509 ms |
| Passed | site routes › renders /docs/concepts/measurement-validity without errors | 509 ms |
| Passed | site routes › renders /docs/concepts/statistics without errors | 449 ms |
| Passed | site routes › renders /docs/concepts/survivorship without errors | 491 ms |
| Passed | site routes › renders /docs/concepts/metrics-model without errors | 465 ms |
| Passed | site routes › renders /docs/monitors without errors | 427 ms |
| Passed | site routes › renders /docs/monitors/drift-lag without errors | 455 ms |
| Passed | site routes › renders /docs/monitors/macrotask-lag without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/scheduling-fairness without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/worker-lag without errors | 473 ms |
| Passed | site routes › renders /docs/monitors/peer-hang-watch without errors | 468 ms |
| Passed | site routes › renders /docs/monitors/shared-liveness without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/long-animation-frames without errors | 455 ms |
| Passed | site routes › renders /docs/monitors/event-timing without errors | 456 ms |
| Passed | site routes › renders /docs/monitors/layout-shift without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/page-view-vitals without errors | 460 ms |
| Passed | site routes › renders /docs/monitors/page-view-context without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/frame-timing without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/idle-availability without errors | 453 ms |
| Passed | site routes › renders /docs/monitors/memory without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/compute-pressure without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/gc-signal without errors | 453 ms |
| Passed | site routes › renders /docs/monitors/lifecycle without errors | 538 ms |
| Passed | site routes › renders /docs/monitors/timer-throttle without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/clock-reliability without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/clock-drift without errors | 454 ms |
| Passed | site routes › renders /docs/monitors/browser-reports without errors | 454 ms |
| Passed | site routes › renders /docs/architecture without errors | 649 ms |
| Passed | site routes › renders /docs/api without errors | 431 ms |
| Passed | site routes › renders /docs/operations/opentelemetry without errors | 454 ms |
| Passed | site routes › renders /docs/operations/grafana-stack without errors | 497 ms |
| Passed | site routes › renders /docs/operations/dashboards without errors | 457 ms |
| Passed | site routes › renders /docs/testing/strategy without errors | 460 ms |
| Passed | site routes › renders /docs/contributing/writing-style without errors | 453 ms |
| Passed | site routes › renders /docs/contributing/development without errors | 453 ms |
| Passed | site routes › renders /research without errors | 453 ms |
| Passed | site routes › renders /research/browser-support without errors | 459 ms |
| Passed | site routes › renders /research/clocks-and-timers without errors | 456 ms |
| Passed | site routes › renders /research/local-experiments without errors | 455 ms |
| Passed | site routes › renders /research/web-vitals-algorithms without errors | 455 ms |
| Passed | site routes › renders /research/rum-landscape without errors | 423 ms |
| Passed | site routes › renders /research/otel-browser-metrics without errors | 455 ms |
| Passed | site routes › renders /research/writing-standard without errors | 453 ms |
| Passed | site routes › renders /research/sources without errors | 455 ms |
| Passed | site routes › renders /thesis without errors | 455 ms |
| Passed | site routes › draws the measurement charts of almost equal values | 153 ms |
| Passed | site routes › shows the title of each content page as its h1 | 185 ms |
| Passed | site routes › shows the empty state without results | 52 ms |
| Passed | site routes › draws the boxes and the arrows of the architecture map | 263 ms |
| Passed | site routes › starts the monitors in the playground and stops them on unmount | 75 ms |
packages/site/src/playground/session.browser.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | browser session › records the real monitors and sees a blocked main thread | 1.55 s |
| Passed | browser session › records nothing more after it stops | 2.01 s |
| Passed | browser session › runs only the timer monitors for the home page | 505 ms |
packages/site/src/playground/timeline/Analysis.browser.test.tsx5 passed
| Status | Test | Duration |
|---|---|---|
| Passed | EpochPanel › draws the three signals around the blocks | 222 ms |
| Passed | EpochPanel › changes the time 0 to the end of the blocks | 50 ms |
| Passed | EpochPanel › tells what to do when there are no blocks, and keeps the place of the charts | 21 ms |
| Passed | InpScatterPanel › draws one dot for each interaction, with the INP thresholds | 35 ms |
| Passed | InpScatterPanel › tells that a browser without long animation frames puts all dots at 0 ms | 28 ms |
packages/site/src/playground/timeline/SessionTimeline.browser.test.tsx7 passed
| Status | Test | Duration |
|---|---|---|
| Passed | SessionTimeline › draws the tracks, and follows the present time | 130 ms |
| Passed | SessionTimeline › hides a track when its check box is cleared | 48 ms |
| Passed | SessionTimeline › zooms, pans and shows all with the keyboard, and stops following | 68 ms |
| Passed | SessionTimeline › goes to the next item with the keyboard, describes it and announces it | 91 ms |
| Passed | SessionTimeline › shows a tooltip for the item under the pointer | 53 ms |
| Passed | SessionTimeline › gives the items of the visible range as a table | 94 ms |
| Passed | SessionTimeline › keeps the frame rate of an empty timeline with thousands of items | 3.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
| Status | Test | Duration |
|---|---|---|
| Passed | normalizeBase › gives / for an empty value | 3.7 ms |
| Passed | normalizeBase › adds the slashes at the start and the end | 1.3 ms |
| Passed | normalizeBase › keeps a full URL | 0.43 ms |
packages/site/build/frontmatter.test.ts7 passed
| Status | Test | Duration |
|---|---|---|
| Passed | isFrontmatterRequest › accepts an .mdx ID with the frontmatter query | 2.5 ms |
| Passed | isFrontmatterRequest › rejects other IDs | 0.46 ms |
| Passed | stripQuery › removes the query | 0.33 ms |
| Passed | extractFrontmatter › reads the YAML block at the start of the file | 12 ms |
| Passed | extractFrontmatter › reads CRLF line endings and a byte order mark | 1.2 ms |
| Passed | extractFrontmatter › returns an empty object without frontmatter | 0.65 ms |
| Passed | extractFrontmatter › returns an empty object if the YAML is not a mapping | 1.4 ms |
packages/site/build/head-tags.test.ts10 passed
| Status | Test | Duration |
|---|---|---|
| Passed | head tags › gives an article its canonical URL, Open Graph, the Twitter card and the sitemap | 16 ms |
| Passed | head tags › gives the home page the full title, the type website and the site URL | 0.88 ms |
| Passed | head tags › uses the fallback description for a page without a description | 0.53 ms |
| Passed | head tags › tells search engines not to keep the page of a test run | 3.5 ms |
| Passed | head tags › gives the home page a WebSite and a SoftwareSourceCode in TypeScript under the MIT license | 8 ms |
| Passed | head tags › gives an article a TechArticle and a BreadcrumbList | 7.9 ms |
| Passed | head tags › gives a page of the app a WebPage | 0.6 ms |
| Passed | head tags › puts only the parent routes that exist into the breadcrumbs | 0.52 ms |
| Passed | head tags › escapes the JSON so that a text cannot close the script element | 9 ms |
| Passed | head tags › names the image files and the text alternatives | 0.75 ms |
packages/site/build/og-image.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | Open Graph images › gives an article its group, its title and its description | 8.2 ms |
| Passed | Open Graph images › gives the home page the language and the license of the library | 0.94 ms |
| Passed | Open Graph images › keeps each word with a hyphen on one line, and escapes the title | 1.7 ms |
| Passed | Open Graph images › gives the address of the site without the protocol | 0.27 ms |
| Passed | Open Graph images › escapes the text, uses the fonts of the site and tells the build when it is ready | 2.1 ms |
| Passed | lag chart › gives the same values for the same seed, and other values for another seed | 4 ms |
| Passed | lag chart › has a few long windows and many short windows, for each seed | 1.4 ms |
| Passed | lag chart › draws one bar for each window, red from 50 ms, the dashed line at 50 ms and the scale | 1.5 ms |
| Passed | lag chart › draws the site mark with its red frame | 2.1 ms |
| Passed | prerender switch › is on unless SITE_PRERENDER is 0, false, no or off | 0.6 ms |
| Passed | font preload › selects the Latin text font and the Latin code font of the bundle | 0.43 ms |
packages/site/build/rehype-export-toc.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | collectToc › collects the h2 and h3 headings that have an id, in order | 8.9 ms |
| Passed | createExportNode › makes an ESM export of the entries | 5.1 ms |
| Passed | rehypeExportToc › puts the export at the start of the tree | 1 ms |
packages/site/build/remark-mermaid.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | remarkMermaid › changes a mermaid fence into the Mermaid component, with its title and caption | 7.8 ms |
| Passed | remarkMermaid › changes fences inside other nodes, for example in a list | 0.74 ms |
| Passed | remarkMermaid › reads the key-value pairs of the meta string | 0.46 ms |
| Passed | remarkMermaid › makes MDX code that gives the chart to the component | 32 ms |
packages/site/build/site-url.test.ts6 passed
| Status | Test | Duration |
|---|---|---|
| Passed | site URL › uses SITE_URL, with a slash at the end and a host in lower case | 3.4 ms |
| Passed | site URL › uses the fallback when SITE_URL is not set or empty | 0.62 ms |
| Passed | site URL › refuses a value that is not an absolute http or https URL | 1.8 ms |
| Passed | site URL › gives the absolute URL of a route, as the links of the app give it | 0.78 ms |
| Passed | sitemap and robots.txt › lists each URL one time, with escapes | 1.8 ms |
| Passed | sitemap and robots.txt › lets all crawlers read the site and gives the sitemap | 1.2 ms |
packages/site/build/snapshot.test.ts10 passed
| Status | Test | Duration |
|---|---|---|
| Passed | color tokens › reads the colors of the light theme, and leaves out a color that two tokens have | 6.9 ms |
| Passed | color tokens › finds each color of styles/tokens.css one time, with the ink, the mark and the series colors | 15 ms |
| Passed | color tokens › replaces hex and rgb() colors of tokens, and nothing else | 0.75 ms |
| Passed | color tokens › works with no outside value, thus the prerender can start it in the browser | 0.37 ms |
| Passed | color tokens › makes CSS rules with no specificity for the SVG attributes with a token color | 0.81 ms |
| Passed | page HTML › puts the head tags after the title, and keeps the root element empty without a snapshot | 0.93 ms |
| Passed | page HTML › puts the snapshot into the root element, with the route, and the text stays as it is | 0.93 ms |
| Passed | page HTML › adds the style sheets of the page one time each, after the style sheet of the template | 2.6 ms |
| Passed | page HTML › adds the color rules before the style sheets, thus the other rules win | 1 ms |
| Passed | page HTML › refuses a template without an empty root element | 1.2 ms |
packages/site/build/social-card.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | social preview › shows the name, the claim, the facts and the chart at 1280 × 640 pixels | 5.4 ms |
| Passed | social preview › escapes the text | 0.7 ms |
packages/site/build/static-routes.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | static routes › gives the content pages the paths, titles and groups of the content registry, in path order | 63 ms |
| Passed | static routes › gives the views of each run, with a unique title, and ignores an unsafe run ID | 1.4 ms |
| Passed | static routes › gives the playground and the list of runs a title and a description | 4.2 ms |
| Passed | static routes › takes the home route from the title and the description of index.html | 4.2 ms |
| Passed | static routes › lists the home page first, then the content pages, the app pages and the runs | 8.8 ms |
| Passed | static routes › has the title of the home page in index.html | 1 ms |
| Passed | static routes › gives each page of the site a unique title and a description of a useful length | 64 ms |
| Passed | static routes › puts the title and the description of the route into the HTML, with escapes | 1.2 ms |
| Passed | static routes › gives the 404 page its title and noindex, and no description | 0.91 ms |
| Passed | static routes › writes a file for the path and a file for the path with a slash at the end | 0.41 ms |
| Passed | static routes › names the sections as the navigation does | 0.35 ms |
packages/site/src/architecture/graph.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | architecture graph › has a unique ID for each node | 2.2 ms |
| Passed | architecture graph › connects only nodes that exist | 6.8 ms |
| Passed | architecture graph › puts children in group nodes that exist | 0.59 ms |
| Passed | architecture graph › links each node to a page that exists | 1.7 ms |
packages/site/src/app/prerender-sessions.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | sessionsWithoutStart › gives the sessions of the factory, but they do not start the monitors | 13 ms |
| Passed | sessionsWithoutStart › gives the error of the factory | 4.7 ms |
packages/site/src/app/routes.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | routerBasename › removes the slash at the end of the base URL | 2.9 ms |
| Passed | routerBasename › uses the path of a full URL | 0.36 ms |
packages/site/src/content/content.test.ts53 passed
| Status | Test | Duration |
|---|---|---|
| Passed | site content › has valid frontmatter on every page | 8.9 ms |
| Passed | site content › has every required page | 17 ms |
| Passed | site content › gives each page in a section a different order | 0.65 ms |
| Passed | site content › compiles /docs with a component and a table of contents | 130 ms |
| Passed | site content › compiles /docs/getting-started with a component and a table of contents | 79 ms |
| Passed | site content › compiles /docs/concepts/event-loop with a component and a table of contents | 2.19 s |
| Passed | site content › compiles /docs/concepts/page-lifecycle with a component and a table of contents | 99 ms |
| Passed | site content › compiles /docs/concepts/page-views with a component and a table of contents | 75 ms |
| Passed | site content › compiles /docs/concepts/clocks-and-time with a component and a table of contents | 100 ms |
| Passed | site content › compiles /docs/concepts/measurement-validity with a component and a table of contents | 225 ms |
| Passed | site content › compiles /docs/concepts/statistics with a component and a table of contents | 178 ms |
| Passed | site content › compiles /docs/concepts/survivorship with a component and a table of contents | 168 ms |
| Passed | site content › compiles /docs/concepts/metrics-model with a component and a table of contents | 166 ms |
| Passed | site content › compiles /docs/monitors with a component and a table of contents | 145 ms |
| Passed | site content › compiles /docs/monitors/drift-lag with a component and a table of contents | 108 ms |
| Passed | site content › compiles /docs/monitors/macrotask-lag with a component and a table of contents | 38 ms |
| Passed | site content › compiles /docs/monitors/scheduling-fairness with a component and a table of contents | 37 ms |
| Passed | site content › compiles /docs/monitors/worker-lag with a component and a table of contents | 81 ms |
| Passed | site content › compiles /docs/monitors/peer-hang-watch with a component and a table of contents | 47 ms |
| Passed | site content › compiles /docs/monitors/shared-liveness with a component and a table of contents | 26 ms |
| Passed | site content › compiles /docs/monitors/long-animation-frames with a component and a table of contents | 29 ms |
| Passed | site content › compiles /docs/monitors/event-timing with a component and a table of contents | 32 ms |
| Passed | site content › compiles /docs/monitors/layout-shift with a component and a table of contents | 47 ms |
| Passed | site content › compiles /docs/monitors/page-view-vitals with a component and a table of contents | 84 ms |
| Passed | site content › compiles /docs/monitors/page-view-context with a component and a table of contents | 24 ms |
| Passed | site content › compiles /docs/monitors/frame-timing with a component and a table of contents | 26 ms |
| Passed | site content › compiles /docs/monitors/idle-availability with a component and a table of contents | 24 ms |
| Passed | site content › compiles /docs/monitors/memory with a component and a table of contents | 28 ms |
| Passed | site content › compiles /docs/monitors/compute-pressure with a component and a table of contents | 26 ms |
| Passed | site content › compiles /docs/monitors/gc-signal with a component and a table of contents | 24 ms |
| Passed | site content › compiles /docs/monitors/lifecycle with a component and a table of contents | 45 ms |
| Passed | site content › compiles /docs/monitors/timer-throttle with a component and a table of contents | 25 ms |
| Passed | site content › compiles /docs/monitors/clock-reliability with a component and a table of contents | 22 ms |
| Passed | site content › compiles /docs/monitors/clock-drift with a component and a table of contents | 29 ms |
| Passed | site content › compiles /docs/monitors/browser-reports with a component and a table of contents | 23 ms |
| Passed | site content › compiles /docs/architecture with a component and a table of contents | 30 ms |
| Passed | site content › compiles /docs/api with a component and a table of contents | 81 ms |
| Passed | site content › compiles /docs/operations/opentelemetry with a component and a table of contents | 45 ms |
| Passed | site content › compiles /docs/operations/grafana-stack with a component and a table of contents | 136 ms |
| Passed | site content › compiles /docs/operations/dashboards with a component and a table of contents | 181 ms |
| Passed | site content › compiles /docs/testing/strategy with a component and a table of contents | 112 ms |
| Passed | site content › compiles /docs/contributing/writing-style with a component and a table of contents | 22 ms |
| Passed | site content › compiles /docs/contributing/development with a component and a table of contents | 20 ms |
| Passed | site content › compiles /research with a component and a table of contents | 25 ms |
| Passed | site content › compiles /research/browser-support with a component and a table of contents | 110 ms |
| Passed | site content › compiles /research/clocks-and-timers with a component and a table of contents | 256 ms |
| Passed | site content › compiles /research/local-experiments with a component and a table of contents | 116 ms |
| Passed | site content › compiles /research/web-vitals-algorithms with a component and a table of contents | 92 ms |
| Passed | site content › compiles /research/rum-landscape with a component and a table of contents | 60 ms |
| Passed | site content › compiles /research/otel-browser-metrics with a component and a table of contents | 91 ms |
| Passed | site content › compiles /research/writing-standard with a component and a table of contents | 24 ms |
| Passed | site content › compiles /research/sources with a component and a table of contents | 77 ms |
| Passed | site content › compiles /thesis with a component and a table of contents | 100 ms |
packages/site/src/content/frontmatter.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | parsePageMeta › accepts valid frontmatter | 3.7 ms |
| Passed | parsePageMeta › keeps the status optional | 0.39 ms |
| Passed | parsePageMeta › uses safe values and marks the page as a draft for invalid fields | 1.5 ms |
| Passed | parsePageMeta › reports a missing frontmatter | 0.38 ms |
packages/site/src/content/registry.test.ts12 passed
| Status | Test | Duration |
|---|---|---|
| Passed | parseContentKey › splits a glob key into the section and the file | 3 ms |
| Passed | parseContentKey › rejects a file that is not in a section folder | 0.44 ms |
| Passed | slugOf and folderLabel › removes index from the path | 0.54 ms |
| Passed | slugOf and folderLabel › makes a label from a folder name | 0.26 ms |
| Passed | createContentRegistry › finds pages by section and slug | 0.71 ms |
| Passed | createContentRegistry › lists the sections | 0.41 ms |
| Passed | createContentRegistry › orders the sidebar by order, with each folder as one group | 0.34 ms |
| Passed | createContentRegistry › reads the pages in sidebar order | 0.35 ms |
| Passed | createContentRegistry › gives the previous and the next page | 0.48 ms |
| Passed | createContentRegistry › has no problems for valid entries | 0.35 ms |
| Passed | createContentRegistry › loads a page module only once | 2.6 ms |
| Passed | createContentRegistry › reports invalid frontmatter and duplicate paths | 2.2 ms |
packages/site/src/fixtures/sample-results.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | sample results › has two valid runs | 3.9 ms |
| Passed | sample results › covers Node and the three browser engines, with some failures | 1.7 ms |
| Passed | sample results › is the same each time | 0.37 ms |
packages/site/src/lib/lib.test.ts14 passed
| Status | Test | Duration |
|---|---|---|
| Passed | format › formats durations | 5.7 ms |
| Passed | format › rounds a duration of minutes to whole seconds before it divides them | 0.4 ms |
| Passed | format › shows 100% and 0% only for exactly 100 and 0 | 0.36 ms |
| Passed | format › formats percentages, bytes, units and counts | 5 ms |
| Passed | format › formats dates in UTC | 0.43 ms |
| Passed | stats › uses the nearest-rank percentile | 3.1 ms |
| Passed | stats › summarizes values | 0.47 ms |
| Passed | stats › makes an ECDF and limits its points | 5.7 ms |
| Passed | stats › bins values on a log(1 + x) scale | 4.2 ms |
| Passed | stats › gives one bin when the values differ but have the same log(1 + x) | 0.4 ms |
| Passed | stats › puts each value into a bin, also the maximum, and gives at least one bin | 0.41 ms |
| Passed | stats › keeps spikes when it reduces a series | 0.58 ms |
| Passed | memoizePromise › returns the same promise and tries again after a rejection | 7 ms |
| Passed | memoizePromise › keeps one entry for each key | 0.56 ms |
packages/site/src/playground/live-meter.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | LiveMeter › keeps histogram values with their time and attributes | 5.9 ms |
| Passed | LiveMeter › sums counter values | 0.59 ms |
| Passed | LiveMeter › keeps only the newest samples, but counts all of them | 1 ms |
| Passed | LiveMeter › shares one instrument for the same name | 0.8 ms |
packages/site/src/playground/ring-buffer.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | RingBuffer › keeps the newest items when it is full | 3.4 ms |
| Passed | RingBuffer › returns the newest items that pass a test | 0.58 ms |
| Passed | RingBuffer › can be cleared | 0.5 ms |
| Passed | RingBuffer › refuses a capacity that is not a positive integer | 0.66 ms |
packages/site/src/playground/session.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | PlaygroundSession › starts idle | 6.6 ms |
| Passed | PlaygroundSession › publishes snapshots two times each second while it runs | 8.8 ms |
| Passed | PlaygroundSession › drops values that are older than the window | 1 ms |
| Passed | PlaygroundSession › stops the handles, terminates the worker and leaves no timers | 1.2 ms |
| Passed | PlaygroundSession › starts again with a new meter | 1.4 ms |
| Passed | PlaygroundSession › reports a runtime that fails to start | 0.85 ms |
| Passed | PlaygroundSession › runs one load at a time and keeps a history | 2.1 ms |
| Passed | PlaygroundSession › has no timeline before the start, or without the names of the timeline | 0.87 ms |
| Passed | PlaygroundSession › makes the timeline from the meter, the recorder and the vitals | 3.2 ms |
| Passed | PlaygroundSession › shows each load on the timeline, and keeps the timeline after the stop | 3.3 ms |
| Passed | PlaygroundSession › stops a profile when the session stops | 3.1 ms |
packages/site/src/results/charts.test.ts7 passed
| Status | Test | Duration |
|---|---|---|
| Passed | barInset › keeps a bar at most 24 px thick | 4.7 ms |
| Passed | barInset › adds no inset when a band is already thin | 0.49 ms |
| Passed | symlogTicks › gives a 1-2-5 series up to the maximum | 3.2 ms |
| Passed | measurement charts › build the histogram and the ECDF of almost equal values | 9 ms |
| Passed | measurement charts › give the ticks short labels, not the precision of a very small domain | 2.7 ms |
| Passed | labels › formats a run date in UTC | 0.38 ms |
| Passed | labels › keeps the last two parts of a path | 0.82 ms |
packages/site/src/results/report-source.test.ts13 passed
| Status | Test | Duration |
|---|---|---|
| Passed | HttpReportSource › reads index.json below the base URL | 5.2 ms |
| Passed | HttpReportSource › adds the slash after a base URL without one | 0.49 ms |
| Passed | HttpReportSource › gives an empty index if there is no file | 0.48 ms |
| Passed | HttpReportSource › gives an empty index for the HTML page of a single-page app fallback | 0.64 ms |
| Passed | HttpReportSource › fails for a server error and for bad JSON | 1.9 ms |
| Passed | HttpReportSource › accepts a run without budget counts, and refuses budget counts that are not numbers | 2 ms |
| Passed | HttpReportSource › fails for an old schema version | 0.72 ms |
| Passed | HttpReportSource › reads a run file and checks it | 1.3 ms |
| Passed | HttpReportSource › refuses a run file outside the results folder | 0.82 ms |
| Passed | isSafeRelativePath › accepts a path in the folder and rejects other paths | 1.5 ms |
| Passed | MemoryReportSource › makes the index from the runs | 1.1 ms |
| Passed | MemoryReportSource › can be empty | 0.31 ms |
| Passed | cachedReportSource › loads each file once and tries again after a failure | 2.2 ms |
packages/site/src/results/run-pages.test.ts2 passed
| Status | Test | Duration |
|---|---|---|
| Passed | run pages › finds the view of a URL path, and the overview for the path of the run | 3.4 ms |
| Passed | run pages › gives each view a different title | 0.47 ms |
packages/site/src/theme/theme.test.ts11 passed
| Status | Test | Duration |
|---|---|---|
| Passed | theme preference › reads only light and dark; anything else is system | 3 ms |
| Passed | theme preference › cycles system, light, dark | 0.68 ms |
| Passed | theme preference › resolves the system preference | 2.3 ms |
| Passed | preference stores › keeps values in memory | 0.48 ms |
| Passed | preference stores › works with a storage that throws | 2.8 ms |
| Passed | preference stores › works when the storage itself cannot be read | 0.54 ms |
| Passed | preference stores › works without a storage | 5.5 ms |
| Passed | mixColor › puts a color with an opacity on a background, as an opaque color | 1.2 ms |
| Passed | mixColor › gives a color that is not a hex color without a change | 0.99 ms |
| Passed | contrast › calculates the relative luminance and the contrast ratio of WCAG 2 | 1.1 ms |
| Passed | contrast › selects the text color with the higher contrast on a fill | 0.47 ms |
packages/site/src/playground/timeline/docs-example.test.ts1 passed
| Status | Test | Duration |
|---|---|---|
| Passed | the simulated session of the documentation › agrees with the text of the statistics page | 7.5 ms |
packages/site/src/playground/timeline/epochs.test.ts13 passed
| Status | Test | Duration |
|---|---|---|
| Passed | blockEpisodes › joins a frame, a hang and a stall of the same block into one episode | 10 ms |
| Passed | blockEpisodes › ignores a frame that blocks less than the threshold, and a stall of a suspend | 4.8 ms |
| Passed | blockEpisodes › joins blocks that are less than the gap apart | 2.8 ms |
| Passed | tCritical95 › gives the critical values of the t distribution | 3.8 ms |
| Passed | binStat › gives the mean, and the interval only for 3 or more values | 0.54 ms |
| Passed | epochAverages › averages each signal in its bin | 9.4 ms |
| Passed | epochAverages › aligns at the end of each block | 4.1 ms |
| Passed | epochAverages › gives no value for the bins outside the recorded time | 1.4 ms |
| Passed | epochAverages › gives no blocking value in a browser without long animation frames | 1.1 ms |
| Passed | epochAverages › counts no epoch whose window is completely outside the recorded time | 0.41 ms |
| Passed | reportedLagIn › sums the lag of the windows that end in the bin | 0.18 ms |
| Passed | reportedLagIn › gives 0 ms in a long window, where the monitor reports nothing yet | 0.14 ms |
| Passed | reportedLagIn › gives no value where no window covers the bin | 0.15 ms |
packages/site/src/playground/timeline/inp-scatter.test.ts4 passed
| Status | Test | Duration |
|---|---|---|
| Passed | overlappingFrames › finds the frames whose time ranges overlap the interaction | 6.1 ms |
| Passed | overlappingFrames › does not count a frame that only touches the interaction | 4.1 ms |
| Passed | interactionScatter › gives each interaction the blocking time of the frames that overlap it | 1.3 ms |
| Passed | summarizeScatter › counts the slow interactions and the interactions with frames | 3.9 ms |
packages/site/src/playground/timeline/items.test.ts16 passed
| Status | Test | Duration |
|---|---|---|
| Passed | timelineItems › gives the items of the visible tracks, sorted by start | 6.5 ms |
| Passed | timelineItems › finds the items that overlap the visible range | 3.1 ms |
| Passed | adjacentItem › goes from the current item to the next and to the previous item | 0.71 ms |
| Passed | adjacentItem › starts from a time without a current item | 0.37 ms |
| Passed | hitTest › finds a long animation frame under the pointer | 0.7 ms |
| Passed | hitTest › finds the hang in the upper row and the stall in the lower row | 0.32 ms |
| Passed | hitTest › finds the interactions in the lower row, and the marks in the upper row of the vitals | 3.5 ms |
| Passed | hitTest › finds the nearest drift window, and the lifecycle period | 1.7 ms |
| Passed | hitTest › finds nothing outside the tracks | 0.92 ms |
| Passed | describeItem › describes a frame with its blocking time | 1.4 ms |
| Passed | describeItem › describes a span with its attributes, and an open span to now | 1.7 ms |
| Passed | describeItem › describes an interaction with its parts and its rating | 0.48 ms |
| Passed | describeItem › gives one sentence for the live region | 0.43 ms |
| Passed | describeItem › gives a key that stays the same for the same item | 0.31 ms |
| Passed | helpers › formats a score with more decimals when it is very small | 0.24 ms |
| Passed | helpers › finds the first item at or above a value | 0.21 ms |
packages/site/src/playground/timeline/model.test.ts13 passed
| Status | Test | Duration |
|---|---|---|
| Passed | buildTimelineModel › gives all times in seconds since the start of the session | 5.3 ms |
| Passed | buildTimelineModel › sorts the spans by name, and an open span ends at the present time | 1.6 ms |
| Passed | buildTimelineModel › shows a load that is active until the present time | 0.47 ms |
| Passed | buildTimelineModel › shows nothing that is more than 10 minutes before the session | 0.54 ms |
| Passed | buildTimelineModel › uses the time of the stop as the present time | 1 ms |
| Passed | placeLateWindows › moves a long window that the conditions recorded late to the gap that it fills | 1.4 ms |
| Passed | placeLateWindows › keeps a long window that follows its gap | 0.6 ms |
| Passed | placeLateWindows › keeps a long window without a gap of its length, and gives each gap to one window only | 0.6 ms |
| Passed | lifecycleSegments › starts with the state before the first transition, and merges a transition to the same state | 0.48 ms |
| Passed | lifecycleSegments › uses the current state without transitions, and gives nothing without a state | 0.45 ms |
| Passed | pressureSegments › makes the periods of each source from its changes | 0.41 ms |
| Passed | groupInteractions › joins the entries of one interaction, as INP does | 1.1 ms |
| Passed | rateDuration › uses the INP thresholds: at or below good is good, above poor is poor | 0.22 ms |
packages/site/src/playground/timeline/recorder.test.ts6 passed
| Status | Test | Duration |
|---|---|---|
| Passed | SessionRecorder › records events at the time of the occurrence, on the session clock | 9.2 ms |
| Passed | SessionRecorder › gives an event without a time (or with a time that is not finite) the time of the call | 0.8 ms |
| Passed | SessionRecorder › gives each span an identity, and keeps the trace of the parent | 3 ms |
| Passed | SessionRecorder › changes the attributes and the end of an open span only until it ends | 0.88 ms |
| Passed | SessionRecorder › keeps the entries of the probes | 7.8 ms |
| Passed | SessionRecorder › keeps only the newest items of each kind | 2.1 ms |
packages/site/src/playground/timeline/tracks.test.ts3 passed
| Status | Test | Duration |
|---|---|---|
| Passed | layoutTracks › places the visible tracks from top to bottom without gaps | 5.9 ms |
| Passed | layoutTracks › has each track once, in a fixed order | 0.63 ms |
| Passed | layoutTracks › finds the track at a height | 0.92 ms |
packages/site/src/playground/timeline/viewport.test.ts13 passed
| Status | Test | Duration |
|---|---|---|
| Passed | clampViewport › keeps a range in the bounds, with a small space after the present time | 9.1 ms |
| Passed | clampViewport › limits the length to the minimum and to all the data | 0.51 ms |
| Passed | clampViewport › starts a range that is longer than a short session at the start of the data | 0.35 ms |
| Passed | zoomViewport › keeps the anchor at the same place on the screen | 0.38 ms |
| Passed | zoomViewport › zooms out to all the data at most | 0.5 ms |
| Passed | panViewport › moves the range and stops at the bounds | 0.34 ms |
| Passed | followViewport › shows the present time near the right edge | 0.33 ms |
| Passed | followViewport › starts at the earliest data while the session is shorter than the range | 0.27 ms |
| Passed | fitViewport › shows all data | 0.46 ms |
| Passed | time and pixels › converts in both directions | 0.57 ms |
| Passed | ticks › uses steps of 1, 2 or 5 multiplied by a power of 10 | 0.55 ms |
| Passed | ticks › formats the ticks with the decimals of the step and a minus sign | 1.1 ms |
| Passed | ticks › puts a tick at each multiple of the step in the range | 3 ms |
packages/site/src/results/model/model.test.ts25 passed
| Status | Test | Duration |
|---|---|---|
| Passed | tests model › flattens every test with its suite and file | 5.5 ms |
| Passed | tests model › finds the failed and the slowest tests | 2.8 ms |
| Passed | tests model › filters by text, status and environment | 0.97 ms |
| Passed | tests model › groups the matching tests by suite and file | 3.4 ms |
| Passed | group status › shows a group with only skipped tests as skipped, and a group without tests as none, not as passed | 0.54 ms |
| Passed | group status › gives the counts as text | 0.51 ms |
| Passed | run summary status › fails a run with a failed budget, also when all tests passed | 0.72 ms |
| Passed | run summary status › passes a run whose tests and budgets passed, also from an index without budget counts | 1.9 ms |
| Passed | environment matrix › puts node first, then the engines | 0.38 ms |
| Passed | environment matrix › has one cell for each package and environment | 2.7 ms |
| Passed | durationBins › counts in 1-2-5 bins and trims the empty ends | 2.4 ms |
| Passed | coverage model › calculates percentages, and undefined for nothing to cover | 0.33 ms |
| Passed | coverage model › gives rows for packages and files | 0.89 ms |
| Passed | mutation model › sorts the files by score and sums the packages | 1.3 ms |
| Passed | mutation model › puts the files without a score last, and gives them no bar | 0.47 ms |
| Passed | mutation model › gives the commit and the time of each Stryker run, and its age in days | 0.49 ms |
| Passed | budgets model › puts the failed budgets first | 0.79 ms |
| Passed | measurements model › groups measurements by metric | 1.1 ms |
| Passed | measurements model › offers the measurement, the suite and each label as grouping keys | 2.6 ms |
| Passed | measurements model › groups each family by a label that the family has, with browser as the fallback | 1.2 ms |
| Passed | measurements model › joins the values of each group and summarizes them | 4.8 ms |
| Passed | measurements model › folds the smallest groups into Other past the limit | 0.98 ms |
| Passed | sortRows › sorts numbers and keeps missing values last in both directions | 4.8 ms |
| Passed | sortRows › changes the direction for the same column | 0.92 ms |
| Passed | run trend › orders the runs and makes one row per status | 0.78 ms |