[UserTiming] Move UserTiming L3 tests to WPT
In preparation for shipping, move tests to WPT. Remove the Virtual Test
Suite.
Bug: 758385
Change-Id: Idc864521d35fce9e4ee4c44f2b3d32130fc88053
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1550692
Commit-Queue: Nicolás Peña Moreno <npm@chromium.org>
Reviewed-by: Liquan (Max) Gu <maxlg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#647406}
diff --git a/user-timing/mark-errors.html b/user-timing/mark-errors.html
new file mode 100644
index 0000000..c182a39
--- /dev/null
+++ b/user-timing/mark-errors.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>UserTimingL3: errors are thrown when mark() is called incorrectly.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<h1>UserTimingL3: Mark</h1>
+<script>
+ test(function() {
+ assert_throws(new TypeError(), function() { self.performance.mark("mark1", 123); }, "Number passed as a dict argument should cause type-error.")
+ }, "Number should be rejected as the mark-options.")
+
+ test(function() {
+ assert_throws(new TypeError(), function() { self.performance.mark("mark1", NaN); }, "NaN passed as a dict argument should cause type-error.")
+ }, "NaN should be rejected as the mark-options.")
+
+ test(function() {
+ assert_throws(new TypeError(), function() { self.performance.mark("mark1", Infinity); }, "Infinity passed as a dict argument should cause type-error.")
+ }, "Infinity should be rejected as the mark-options.")
+
+ test(function() {
+ assert_throws(new TypeError(), function() { self.performance.mark("mark1", "string"); }, "String passed as a dict argument should cause type-error.")
+ }, "String should be rejected as the mark-options.")
+</script>
diff --git a/user-timing/mark-l3.html b/user-timing/mark-l3.html
new file mode 100644
index 0000000..429768d
--- /dev/null
+++ b/user-timing/mark-l3.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>User Timing L3: mark</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/user-timing-helpers.js"></script>
+<script>
+ async_test(function (t) {
+ let mark_entries = [];
+ const expected_entries =
+ [{ entryType: "mark", name: "mark1", detail: null},
+ { entryType: "mark", name: "mark2", detail: null},
+ { entryType: "mark", name: "mark3", detail: null},
+ { entryType: "mark", name: "mark4", detail: null},
+ { entryType: "mark", name: "mark5", detail: null},
+ { entryType: "mark", name: "mark6", detail: {}},
+ { entryType: "mark", name: "mark7", detail: {info: 'abc'}},
+ { entryType: "mark", name: "mark8", detail: null, startTime: 234.56},
+ { entryType: "mark", name: "mark9", detail: {count: 3}, startTime: 345.67}];
+ const observer = new PerformanceObserver(
+ t.step_func(function (entryList, obs) {
+ mark_entries =
+ mark_entries.concat(entryList.getEntries());
+ if (mark_entries.length >= expected_entries.length) {
+ checkEntries(mark_entries, expected_entries);
+ observer.disconnect();
+ t.done();
+ }
+ })
+ );
+ self.performance.clearMarks();
+ observer.observe({entryTypes: ["mark"]});
+ const returned_entries = [];
+ returned_entries.push(self.performance.mark("mark1"));
+ returned_entries.push(self.performance.mark("mark2", undefined));
+ returned_entries.push(self.performance.mark("mark3", null));
+ returned_entries.push(self.performance.mark("mark4", {}));
+ returned_entries.push(self.performance.mark("mark5", {detail: null}));
+ returned_entries.push(self.performance.mark("mark6", {detail: {}}));
+ returned_entries.push(self.performance.mark("mark7", {detail: {info: 'abc'}}));
+ returned_entries.push(self.performance.mark("mark8", {startTime: 234.56}));
+ returned_entries.push(self.performance.mark("mark9", {detail: {count: 3}, startTime: 345.67}));
+ checkEntries(returned_entries, expected_entries);
+ }, "mark entries' detail and startTime are customizable.");
+</script>
diff --git a/user-timing/mark-measure-return-objects.html b/user-timing/mark-measure-return-objects.html
new file mode 100644
index 0000000..d2d8cc3
--- /dev/null
+++ b/user-timing/mark-measure-return-objects.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>UserTiming L3: mark/measure methods return objects.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p>Custom User Timing: L3 API returns a mark/measure object</p>
+<div id="log"></div>
+<script>
+ async_test(function (t) {
+ self.performance.clearMeasures();
+ const measure = self.performance.measure("measure1");
+ assert_true(measure instanceof PerformanceMeasure);
+ t.done();
+ }, "L3: performance.measure(name) should return an entry.");
+
+ async_test(function (t) {
+ self.performance.clearMeasures();
+ const measure = self.performance.measure("measure2",
+ { startTime: 12, endTime:23 });
+ assert_true(measure instanceof PerformanceMeasure);
+ t.done();
+ }, "L3: performance.measure(name, param1) should return an entry.");
+
+ async_test(function (t) {
+ self.performance.clearMeasures();
+ self.performance.mark("1");
+ self.performance.mark("2");
+ const measure = self.performance.measure("measure3", "1", "2");
+ assert_true(measure instanceof PerformanceMeasure);
+ t.done();
+ }, "L3: performance.measure(name, param1, param2) should return an entry.");
+
+ async_test(function (t) {
+ self.performance.clearMarks();
+ const mark = self.performance.mark("mark1");
+ assert_true(mark instanceof PerformanceMark);
+ t.done();
+ }, "L3: performance.mark(name) should return an entry.");
+
+ async_test(function (t) {
+ self.performance.clearMarks();
+ const mark = self.performance.mark("mark2", { startTime: 34 });
+ assert_true(mark instanceof PerformanceMark);
+ t.done();
+ }, "L3: performance.mark(name, param) should return an entry.");
+</script>
diff --git a/user-timing/measure-l3.html b/user-timing/measure-l3.html
new file mode 100644
index 0000000..0e8dacf
--- /dev/null
+++ b/user-timing/measure-l3.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>UserTiming L3: Measure basic usage</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ function endTime(entry) {
+ return entry.startTime + entry.duration;
+ }
+
+ test(function() {
+ performance.clearMarks();
+ performance.clearMeasures();
+ const markEntry = performance.mark("mark", {startTime: 123});
+ const measureEntry = performance.measure("A", undefined, "mark");
+ assert_equals(measureEntry.startTime, 0);
+ assert_equals(endTime(measureEntry), markEntry.startTime);
+ }, "When the end mark is given and the start is unprovided, the end time of the measure entry should be the end mark's time, the start time should be 0.");
+
+ test(function() {
+ performance.clearMarks();
+ performance.clearMeasures();
+ const markEntry = performance.mark("mark", {startTime: 123});
+ const endMin = performance.now();
+ const measureEntry = performance.measure("A", "mark", undefined);
+ const endMax = performance.now();
+ assert_equals(measureEntry.startTime, markEntry.startTime);
+ assert_greater_than_equal(endTime(measureEntry), endMin);
+ assert_greater_than_equal(endMax, endTime(measureEntry));
+ }, "When the start mark is given and the end is unprovided, the start time of the measure entry should be the start mark's time, the end should be now.");
+
+ test(function() {
+ performance.clearMarks();
+ performance.clearMeasures();
+ const markEntry = performance.mark("mark", {startTime: 123});
+ const measureEntry = performance.measure("A", "mark", "mark");
+ assert_equals(endTime(measureEntry), markEntry.startTime);
+ assert_equals(measureEntry.startTime, markEntry.startTime);
+ }, "When start and end mark are both given, the start time and end time of the measure entry should be the the marks' time, repectively");
+</script>
diff --git a/user-timing/measure-with-dict.html b/user-timing/measure-with-dict.html
new file mode 100644
index 0000000..83990a6
--- /dev/null
+++ b/user-timing/measure-with-dict.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>User Timing L3: measure is customizable</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/user-timing-helpers.js"></script>
+<script>
+ async_test(function (t) {
+ let measureEntries = [];
+ const timeStamp1 = 784.4;
+ const timeStamp2 = 1234.5;
+ const timeStamp3 = 66.6;
+ const timeStamp4 = 5566;
+ const expectedEntries =
+ [{ entryType: "measure", name: "measure1", detail: null, startTime: 0 },
+ { entryType: "measure", name: "measure2", detail: null, startTime: 0 },
+ { entryType: "measure", name: "measure3", detail: null, startTime: 0 },
+ { entryType: "measure", name: "measure5", detail: null },
+ { entryType: "measure", name: "measure7", detail: null, startTime: 0 },
+ { entryType: "measure", name: "measure11", detail: null, startTime: timeStamp1 },
+ { entryType: "measure", name: "measure13", detail: null, startTime: timeStamp1, duration: timeStamp2 - timeStamp1 },
+ { entryType: "measure", name: "measure14", detail: null, startTime: 0 },
+ { entryType: "measure", name: "measure15", detail: null, startTime: 0 },
+ { entryType: "measure", name: "measure16", detail: null, startTime: 0 },
+ { entryType: "measure", name: "measure17", detail: null, startTime: timeStamp1 },
+ { entryType: "measure", name: "measure18", detail: null, startTime: timeStamp3 },
+ { entryType: "measure", name: "measure19", detail: null, startTime: 0 },
+ { entryType: "measure", name: "measure20", detail: null, startTime: 0 },
+ { entryType: "measure", name: "measure21", detail: null, startTime: timeStamp3, duration: timeStamp1 - timeStamp3 },
+ { entryType: "measure", name: "measure22", detail: null, startTime: timeStamp1, duration: timeStamp2 - timeStamp1 },
+ { entryType: "measure", name: "measure23", detail: null, startTime: timeStamp1 },
+ { entryType: "measure", name: "measure24", detail: {}, startTime: 0 },
+ { entryType: "measure", name: "measure25", detail: { customInfo: 159 }, startTime: timeStamp3, duration: timeStamp2 - timeStamp3 }];
+ const observer = new PerformanceObserver(
+ t.step_func(function (entryList, obs) {
+ measureEntries =
+ measureEntries.concat(entryList.getEntries());
+ if (measureEntries.length >= expectedEntries.length) {
+ checkEntries(measureEntries, expectedEntries);
+ observer.disconnect();
+ t.done();
+ }
+ })
+ );
+ self.performance.clearMarks();
+ self.performance.clearMeasures();
+ observer.observe({ entryTypes: ["measure"] });
+ self.performance.mark("mark1", { detail: { randomInfo: 3 }, startTime: timeStamp1 });
+ self.performance.mark("mark2", { startTime: timeStamp2 });
+
+ const returnedEntries = [];
+ returnedEntries.push(self.performance.measure("measure1"));
+ returnedEntries.push(self.performance.measure("measure2", undefined));
+ returnedEntries.push(self.performance.measure("measure3", null));
+ returnedEntries.push(self.performance.measure("measure5", 'mark1'));
+ returnedEntries.push(
+ self.performance.measure("measure7", null, 'mark1'));
+ returnedEntries.push(
+ self.performance.measure("measure11", 'mark1', undefined));
+ returnedEntries.push(
+ self.performance.measure("measure13", 'mark1', 'mark2'));
+ returnedEntries.push(
+ self.performance.measure("measure14", {}));
+ returnedEntries.push(
+ self.performance.measure("measure15", { startTime: null }));
+ returnedEntries.push(
+ self.performance.measure("measure16", { startTime: undefined }));
+ returnedEntries.push(
+ self.performance.measure("measure17", { startTime: 'mark1' }));
+ returnedEntries.push(
+ self.performance.measure("measure18", { startTime: timeStamp3 }));
+ returnedEntries.push(
+ self.performance.measure("measure19", { endTime: undefined }));
+ returnedEntries.push(
+ self.performance.measure("measure20", { endTime: 'mark1' }));
+ returnedEntries.push(
+ self.performance.measure("measure21", { startTime: timeStamp3, endTime: 'mark1' }));
+ returnedEntries.push(
+ self.performance.measure("measure22", { startTime: timeStamp1, endTime: timeStamp2, detail: undefined }));
+ returnedEntries.push(
+ self.performance.measure("measure23", { startTime: 'mark1', endTime: undefined, detail: null }));
+ returnedEntries.push(
+ self.performance.measure("measure24", { startTime: null, endTime: timeStamp1, detail: {} }));
+ returnedEntries.push(
+ self.performance.measure("measure25", { startTime: timeStamp3, endTime: 'mark2', detail: { customInfo: 159 }}));
+ checkEntries(returnedEntries, expectedEntries);
+ }, "measure entries' detail and start/end are customizable");
+
+ async_test(function (t) {
+ assert_throws("SyntaxError", function() {
+ self.performance.measure("wrongUsage1", {}, 12);
+ });
+ t.done();
+ }, "measure should throw exception when passing option object and end at the same time");
+</script>
diff --git a/user-timing/resources/user-timing-helper.js b/user-timing/resources/user-timing-helper.js
new file mode 100644
index 0000000..8d43768
--- /dev/null
+++ b/user-timing/resources/user-timing-helper.js
@@ -0,0 +1,30 @@
+// Compares a list of performance entries to a predefined one.
+// actualEntries is an array of performance entries from the user agent,
+// and expectedEntries is an array of performance entries minted by the test.
+// The comparison doesn't assert the order of the entries.
+function checkEntries(actualEntries, expectedEntries) {
+ assert_equals(actualEntries.length, expectedEntries.length,
+ `The length of actual and expected entries should match.
+ actual: ${JSON.stringify(actualEntries)},
+ expected: ${JSON.stringify(expectedEntries)}`);
+ const actualEntrySet = new Set(actualEntries.map(ae=>ae.name));
+ assert_equals(actualEntrySet.size, actualEntries.length, `Actual entry names are not unique: ${JSON.stringify(actualEntries)}`);
+ const expectedEntrySet = new Set(expectedEntries.map(ee=>ee.name));
+ assert_equals(expectedEntrySet.size, expectedEntries.length, `Expected entry names are not unique: ${JSON.stringify(expectedEntries)}`);
+ actualEntries.forEach(ae=>{
+ const expectedEntry = expectedEntries.find(e=>e.name === ae.name);
+ assert_true(!!expectedEntry, `Entry name '${ae.name}' was not found.`);
+ checkEntry(ae, expectedEntry);
+ });
+}
+
+function checkEntry(entry, {name, entryType, startTime, detail, duration}) {
+ assert_equals(entry.name, name);
+ assert_equals(entry.entryType, entryType);
+ if (startTime !== undefined)
+ assert_equals(entry.startTime, startTime);
+ if (detail !== undefined)
+ assert_equals(JSON.stringify(entry.detail), JSON.stringify(detail));
+ if (duration !== undefined)
+ assert_equals(entry.duration, duration);
+}