From d840d2468acfecd15fbb30d6a5bff98ae023bce7 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sat, 3 Aug 2024 16:59:47 -0700 Subject: [PATCH 1/2] feat: add ability to specify `entryType` --- README.md | 15 ++++++++ config.schema.json | 8 +++++ src/measure.ts | 7 +++- ...rformance-measure-specific-entry-type.html | 19 ++++++++++ ...rformance-measure-specific-entry-type.json | 33 +++++++++++++++++ src/test/e2e_test.ts | 35 +++++++++++++++++++ src/types.ts | 1 + 7 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/test/data/performance-measure-specific-entry-type.html create mode 100644 src/test/data/performance-measure-specific-entry-type.json diff --git a/README.md b/README.md index 61eb287..c1d32f0 100644 --- a/README.md +++ b/README.md @@ -252,6 +252,21 @@ The following performance entry types are supported: Retrieve the `startTime` of a built-in paint measurement (e.g. `first-contentful-paint`). +If you have multiple entries with the same name (for example, a `mark` and `measure` both named `foo`), +then you can specify a particular `entryType` to narrow it down: + +```json +"benchmarks": [ + { + "measurement": { + "mode": "performance", + "entryName": "foo", + "entryType": "measure" + } + } +] +``` + #### Callback By default with local (non-URL) benchmarks, or when the `--measure` flag is set diff --git a/config.schema.json b/config.schema.json index 41a6619..7ef0b42 100644 --- a/config.schema.json +++ b/config.schema.json @@ -376,6 +376,14 @@ "entryName": { "type": "string" }, + "entryType": { + "enum": [ + "mark", + "measure", + "paint" + ], + "type": "string" + }, "mode": { "enum": [ "performance" diff --git a/src/measure.ts b/src/measure.ts index a9e2fca..d36e9bf 100644 --- a/src/measure.ts +++ b/src/measure.ts @@ -70,7 +70,12 @@ async function queryForPerformanceEntry( ): Promise { const escaped = escapeStringLiteral(measurement.entryName); const script = `return window.performance.getEntriesByName(\`${escaped}\`);`; - const entries = (await driver.executeScript(script)) as PerformanceEntry[]; + let entries = (await driver.executeScript(script)) as PerformanceEntry[]; + if (typeof measurement.entryType === 'string') { + entries = entries.filter( + (entry) => entry.entryType === measurement.entryType + ); + } if (entries.length === 0) { return undefined; } diff --git a/src/test/data/performance-measure-specific-entry-type.html b/src/test/data/performance-measure-specific-entry-type.html new file mode 100644 index 0000000..a485c67 --- /dev/null +++ b/src/test/data/performance-measure-specific-entry-type.html @@ -0,0 +1,19 @@ + + + + + performance measure test with specific entryType + + + + + diff --git a/src/test/data/performance-measure-specific-entry-type.json b/src/test/data/performance-measure-specific-entry-type.json new file mode 100644 index 0000000..a59cdfa --- /dev/null +++ b/src/test/data/performance-measure-specific-entry-type.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://raw.githubusercontent.com/Polymer/tachometer/master/config.schema.json", + "sampleSize": 10, + "timeout": 0, + "benchmarks": [ + { + "name": "20", + "url": "performance-measure-specific-entry-type.html?wait=20", + "measurement": { + "mode": "performance", + "entryName": "foo", + "entryType": "measure" + }, + "browser": { + "name": "chrome", + "headless": true + } + }, + { + "name": "60", + "url": "performance-measure-specific-entry-type.html?wait=60", + "measurement": { + "mode": "performance", + "entryName": "foo", + "entryType": "measure" + }, + "browser": { + "name": "chrome", + "headless": true + } + } + ] +} diff --git a/src/test/e2e_test.ts b/src/test/e2e_test.ts index 8cef2be..b6cdbca 100644 --- a/src/test/e2e_test.ts +++ b/src/test/e2e_test.ts @@ -226,6 +226,41 @@ suite('e2e', function () { }) ); + test( + 'performance entry with specific entryType', + hideOutput(async function () { + const delayA = 20; + const delayB = 60; + + // TODO(aomarks) This isn't actually testing each browser, since + // the browser is hard coded in the config file. Generate the JSON + // file dynamically instead. + const argv = [ + `--config=${path.join( + testData, + 'performance-measure-specific-entry-type.json' + )}`, + ]; + + const actual = await main(argv); + assert.isDefined(actual); + assert.lengthOf(actual!, 2); + const [a, b] = actual!; + const diffAB = a.differences[1]!; + const diffBA = b.differences[0]!; + + // We can't be very precise with expectations here, since + // setTimeout can be quite variable on a resource starved machine + // (e.g. some of our CI builds). + assert.isAtLeast(a.stats.mean, delayA); + assert.isAtLeast(b.stats.mean, delayB); + assert.isBelow(ciAverage(diffAB.absolute), 0); + assert.isAbove(ciAverage(diffBA.absolute), 0); + assert.isBelow(ciAverage(diffAB.relative), 0); + assert.isAbove(ciAverage(diffBA.relative), 0); + }) + ); + test( 'multiple measurements', hideOutput(async function () { diff --git a/src/types.ts b/src/types.ts index 6d3105e..8d49219 100644 --- a/src/types.ts +++ b/src/types.ts @@ -87,6 +87,7 @@ export interface CallbackMeasurement extends MeasurementBase { export interface PerformanceEntryMeasurement extends MeasurementBase { mode: 'performance'; entryName: string; + entryType?: 'mark' | 'measure' | 'paint'; } export interface ExpressionMeasurement extends MeasurementBase { From 3a53e5a7153c2ae66dcb9f3a9289374afa87e282 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sun, 4 Aug 2024 17:45:01 -0700 Subject: [PATCH 2/2] docs: update changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55d2a43..c1a5c40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). - +## Unreleased + +- Added the optional `entryType` option to specify the `entryType` of a [`PerformanceEntry`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry). ## [0.7.1] 2024-07-18