mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Report performance based timestamps relative to ESO time origin
This commit is contained in:
parent
8963e62a5e
commit
7488136a51
Notes:
github-actions[bot]
2025-01-27 13:54:36 +00:00
Author: https://github.com/tcl3
Commit: 7488136a51
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3341
12 changed files with 248 additions and 28 deletions
|
@ -24,9 +24,7 @@ GC_DEFINE_ALLOCATOR(Performance);
|
||||||
|
|
||||||
Performance::Performance(JS::Realm& realm)
|
Performance::Performance(JS::Realm& realm)
|
||||||
: DOM::EventTarget(realm)
|
: DOM::EventTarget(realm)
|
||||||
, m_timer(Core::TimerType::Precise)
|
|
||||||
{
|
{
|
||||||
m_timer.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Performance::~Performance() = default;
|
Performance::~Performance() = default;
|
||||||
|
@ -68,8 +66,8 @@ GC::Ptr<NavigationTiming::PerformanceNavigation> Performance::navigation()
|
||||||
// https://w3c.github.io/hr-time/#timeorigin-attribute
|
// https://w3c.github.io/hr-time/#timeorigin-attribute
|
||||||
double Performance::time_origin() const
|
double Performance::time_origin() const
|
||||||
{
|
{
|
||||||
// FIXME: The timeOrigin attribute MUST return the number of milliseconds in the duration returned by get time origin timestamp for the relevant global object of this.
|
// The timeOrigin attribute MUST return the number of milliseconds in the duration returned by get time origin timestamp for the relevant global object of this.
|
||||||
return static_cast<double>(m_timer.origin_time().nanoseconds()) / 1e6;
|
return get_time_origin_timestamp(HTML::relevant_principal_global_object(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/hr-time/#now-method
|
// https://w3c.github.io/hr-time/#now-method
|
||||||
|
|
|
@ -51,8 +51,6 @@ private:
|
||||||
|
|
||||||
GC::Ptr<NavigationTiming::PerformanceNavigation> m_navigation;
|
GC::Ptr<NavigationTiming::PerformanceNavigation> m_navigation;
|
||||||
GC::Ptr<NavigationTiming::PerformanceTiming> m_timing;
|
GC::Ptr<NavigationTiming::PerformanceTiming> m_timing;
|
||||||
|
|
||||||
Core::ElapsedTimer m_timer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,23 +11,15 @@
|
||||||
|
|
||||||
namespace Web::HighResolutionTime {
|
namespace Web::HighResolutionTime {
|
||||||
|
|
||||||
// https://w3c.github.io/hr-time/#dfn-get-time-origin-timestamp
|
// https://w3c.github.io/hr-time/#dfn-estimated-monotonic-time-of-the-unix-epoch
|
||||||
DOMHighResTimeStamp get_time_origin_timestamp(JS::Object const& global)
|
DOMHighResTimeStamp estimated_monotonic_time_of_the_unix_epoch()
|
||||||
{
|
{
|
||||||
(void)global;
|
|
||||||
|
|
||||||
// To get time origin timestamp, given a global object global, run the following steps, which return a duration:
|
|
||||||
// FIXME: 1. Let timeOrigin be global's relevant settings object's time origin.
|
|
||||||
auto time_origin = 0;
|
|
||||||
|
|
||||||
// Each group of environment settings objects that could possibly communicate in any way
|
// Each group of environment settings objects that could possibly communicate in any way
|
||||||
// has an estimated monotonic time of the Unix epoch, a moment on the monotonic clock,
|
// has an estimated monotonic time of the Unix epoch, a moment on the monotonic clock,
|
||||||
// whose value is initialized by the following steps:
|
// whose value is initialized by the following steps:
|
||||||
|
|
||||||
// !. Let wall time be the wall clock's unsafe current time.
|
// 1. Let wall time be the wall clock's unsafe current time.
|
||||||
struct timeval tv;
|
auto wall_time = wall_clock_unsafe_current_time();
|
||||||
gettimeofday(&tv, nullptr);
|
|
||||||
auto wall_time = tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
|
|
||||||
|
|
||||||
// 2. Let monotonic time be the monotonic clock's unsafe current time.
|
// 2. Let monotonic time be the monotonic clock's unsafe current time.
|
||||||
auto monotonic_time = unsafe_shared_current_time();
|
auto monotonic_time = unsafe_shared_current_time();
|
||||||
|
@ -37,9 +29,18 @@ DOMHighResTimeStamp get_time_origin_timestamp(JS::Object const& global)
|
||||||
|
|
||||||
// 4. Initialize the estimated monotonic time of the Unix epoch to the result of calling coarsen time with epoch time
|
// 4. Initialize the estimated monotonic time of the Unix epoch to the result of calling coarsen time with epoch time
|
||||||
auto estimated_monotonic_time = coarsen_time(epoch_time);
|
auto estimated_monotonic_time = coarsen_time(epoch_time);
|
||||||
|
return estimated_monotonic_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/hr-time/#dfn-get-time-origin-timestamp
|
||||||
|
DOMHighResTimeStamp get_time_origin_timestamp(JS::Object const& global)
|
||||||
|
{
|
||||||
|
// To get time origin timestamp, given a global object global, run the following steps, which return a duration:
|
||||||
|
// 1. Let timeOrigin be global's relevant settings object's time origin.
|
||||||
|
auto time_origin = HTML::relevant_principal_settings_object(global).time_origin();
|
||||||
|
|
||||||
// 2. Return the duration from the estimated monotonic time of the Unix epoch to timeOrigin.
|
// 2. Return the duration from the estimated monotonic time of the Unix epoch to timeOrigin.
|
||||||
return estimated_monotonic_time - time_origin;
|
return time_origin - estimated_monotonic_time_of_the_unix_epoch();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/hr-time/#dfn-coarsen-time
|
// https://w3c.github.io/hr-time/#dfn-coarsen-time
|
||||||
|
@ -75,8 +76,9 @@ DOMHighResTimeStamp relative_high_resolution_time(DOMHighResTimeStamp time, JS::
|
||||||
// https://w3c.github.io/hr-time/#dfn-relative-high-resolution-coarse-time
|
// https://w3c.github.io/hr-time/#dfn-relative-high-resolution-coarse-time
|
||||||
DOMHighResTimeStamp relative_high_resolution_coarsen_time(DOMHighResTimeStamp coarsen_time, JS::Object const& global)
|
DOMHighResTimeStamp relative_high_resolution_coarsen_time(DOMHighResTimeStamp coarsen_time, JS::Object const& global)
|
||||||
{
|
{
|
||||||
// The relative high resolution coarse time given a DOMHighResTimeStamp coarseTime and a global object global, is the difference between coarseTime and the result of calling get time origin timestamp with global.
|
// The relative high resolution coarse time given a moment from the monotonic clock coarseTime and a global object global, is the duration from global's relevant settings object's time origin to coarseTime.
|
||||||
return coarsen_time - get_time_origin_timestamp(global);
|
auto time_origin = HTML::relevant_principal_settings_object(global).time_origin();
|
||||||
|
return coarsen_time - time_origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/hr-time/#dfn-coarsened-shared-current-time
|
// https://w3c.github.io/hr-time/#dfn-coarsened-shared-current-time
|
||||||
|
@ -86,6 +88,12 @@ DOMHighResTimeStamp coarsened_shared_current_time(bool cross_origin_isolated_cap
|
||||||
return coarsen_time(unsafe_shared_current_time(), cross_origin_isolated_capability);
|
return coarsen_time(unsafe_shared_current_time(), cross_origin_isolated_capability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://w3c.github.io/hr-time/#wall-clock-unsafe-current-time
|
||||||
|
DOMHighResTimeStamp wall_clock_unsafe_current_time()
|
||||||
|
{
|
||||||
|
return UnixDateTime::now().nanoseconds_since_epoch() / 1.0e6;
|
||||||
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/hr-time/#dfn-unsafe-shared-current-time
|
// https://w3c.github.io/hr-time/#dfn-unsafe-shared-current-time
|
||||||
DOMHighResTimeStamp unsafe_shared_current_time()
|
DOMHighResTimeStamp unsafe_shared_current_time()
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,12 +12,14 @@
|
||||||
|
|
||||||
namespace Web::HighResolutionTime {
|
namespace Web::HighResolutionTime {
|
||||||
|
|
||||||
|
DOMHighResTimeStamp estimated_monotonic_time_of_the_unix_epoch();
|
||||||
DOMHighResTimeStamp get_time_origin_timestamp(JS::Object const&);
|
DOMHighResTimeStamp get_time_origin_timestamp(JS::Object const&);
|
||||||
DOMHighResTimeStamp coarsen_time(DOMHighResTimeStamp timestamp, bool cross_origin_isolated_capability = false);
|
DOMHighResTimeStamp coarsen_time(DOMHighResTimeStamp timestamp, bool cross_origin_isolated_capability = false);
|
||||||
DOMHighResTimeStamp current_high_resolution_time(JS::Object const&);
|
DOMHighResTimeStamp current_high_resolution_time(JS::Object const&);
|
||||||
DOMHighResTimeStamp relative_high_resolution_time(DOMHighResTimeStamp, JS::Object const&);
|
DOMHighResTimeStamp relative_high_resolution_time(DOMHighResTimeStamp, JS::Object const&);
|
||||||
DOMHighResTimeStamp relative_high_resolution_coarsen_time(DOMHighResTimeStamp, JS::Object const&);
|
DOMHighResTimeStamp relative_high_resolution_coarsen_time(DOMHighResTimeStamp, JS::Object const&);
|
||||||
DOMHighResTimeStamp coarsened_shared_current_time(bool cross_origin_isolated_capability = false);
|
DOMHighResTimeStamp coarsened_shared_current_time(bool cross_origin_isolated_capability = false);
|
||||||
|
DOMHighResTimeStamp wall_clock_unsafe_current_time();
|
||||||
DOMHighResTimeStamp unsafe_shared_current_time();
|
DOMHighResTimeStamp unsafe_shared_current_time();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <LibWeb/Bindings/PerformanceMarkPrototype.h>
|
#include <LibWeb/Bindings/PerformanceMarkPrototype.h>
|
||||||
#include <LibWeb/HTML/StructuredSerialize.h>
|
#include <LibWeb/HTML/StructuredSerialize.h>
|
||||||
#include <LibWeb/HTML/Window.h>
|
#include <LibWeb/HTML/Window.h>
|
||||||
|
#include <LibWeb/HighResolutionTime/Performance.h>
|
||||||
#include <LibWeb/HighResolutionTime/TimeOrigin.h>
|
#include <LibWeb/HighResolutionTime/TimeOrigin.h>
|
||||||
#include <LibWeb/NavigationTiming/EntryNames.h>
|
#include <LibWeb/NavigationTiming/EntryNames.h>
|
||||||
#include <LibWeb/PerformanceTimeline/EntryTypes.h>
|
#include <LibWeb/PerformanceTimeline/EntryTypes.h>
|
||||||
|
@ -68,8 +69,7 @@ WebIDL::ExceptionOr<GC::Ref<PerformanceMark>> PerformanceMark::construct_impl(JS
|
||||||
}
|
}
|
||||||
// 2. Otherwise, set it to the value that would be returned by the Performance object's now() method.
|
// 2. Otherwise, set it to the value that would be returned by the Performance object's now() method.
|
||||||
else {
|
else {
|
||||||
// FIXME: Performance#now doesn't currently use TimeOrigin's functions, update this and Performance#now to match Performance#now's specification.
|
start_time = HighResolutionTime::current_high_resolution_time(current_principal_global_object);
|
||||||
start_time = HighResolutionTime::unsafe_shared_current_time();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Set entry's duration attribute to 0.
|
// 6. Set entry's duration attribute to 0.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 3 tests
|
||||||
|
|
||||||
|
3 Pass
|
||||||
|
Pass Window timeOrigin is close to Date.now() when there is no system clock adjustment.
|
||||||
|
Pass Window and worker timeOrigins are close when created one after another.
|
||||||
|
Pass Window and worker timeOrigins differ when worker is created after a delay.
|
|
@ -0,0 +1,27 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 22 tests
|
||||||
|
|
||||||
|
22 Pass
|
||||||
|
Pass Entry 0 is properly created
|
||||||
|
Pass Entry 1 is properly created
|
||||||
|
Pass Entry 0 has the proper name
|
||||||
|
Pass Entry 0 startTime is approximately correct (up to 20ms difference allowed)
|
||||||
|
Pass Entry 0 has the proper entryType
|
||||||
|
Pass Entry 0 duration == 0
|
||||||
|
Pass getEntriesByName("mark", "mark")[0] returns an object containing a "mark" mark
|
||||||
|
Pass The mark returned by getEntriesByName("mark", "mark")[0] matches the mark returned by getEntriesByName("mark")[0]
|
||||||
|
Pass getEntries()[0] returns an object containing a "mark" mark
|
||||||
|
Pass The mark returned by getEntries()[0] matches the mark returned by getEntriesByName("mark")[0]
|
||||||
|
Pass getEntriesByType("mark")[0] returns an object containing a "mark" mark
|
||||||
|
Pass The mark returned by getEntriesByType("mark")[0] matches the mark returned by getEntriesByName("mark")[0]
|
||||||
|
Pass Entry 1 has the proper name
|
||||||
|
Pass Entry 1 startTime is approximately correct (up to 20ms difference allowed)
|
||||||
|
Pass Entry 1 has the proper entryType
|
||||||
|
Pass Entry 1 duration == 0
|
||||||
|
Pass getEntriesByName("mark", "mark")[1] returns an object containing a "mark" mark
|
||||||
|
Pass The mark returned by getEntriesByName("mark", "mark")[1] matches the mark returned by getEntriesByName("mark")[1]
|
||||||
|
Pass getEntries()[1] returns an object containing a "mark" mark
|
||||||
|
Pass The mark returned by getEntries()[1] matches the mark returned by getEntriesByName("mark")[1]
|
||||||
|
Pass getEntriesByType("mark")[1] returns an object containing a "mark" mark
|
||||||
|
Pass The mark returned by getEntriesByType("mark")[1] matches the mark returned by getEntriesByName("mark")[1]
|
|
@ -2,13 +2,13 @@ Harness status: OK
|
||||||
|
|
||||||
Found 8 tests
|
Found 8 tests
|
||||||
|
|
||||||
7 Pass
|
6 Pass
|
||||||
1 Fail
|
2 Fail
|
||||||
Pass Measure of navigationStart to now should be positive value.
|
Pass Measure of navigationStart to now should be positive value.
|
||||||
Pass Measure of navigationStart to loadEventEnd should be positive value.
|
Pass Measure of navigationStart to loadEventEnd should be positive value.
|
||||||
Pass Measure of current mark to navigationStart should be negative value.
|
Pass Measure of current mark to navigationStart should be negative value.
|
||||||
Fail loadTime plus loadEventEnd to a mark "a" should equal to navigationStart to "a".
|
Fail loadTime plus loadEventEnd to a mark "a" should equal to navigationStart to "a".
|
||||||
Pass Second measure of current mark to navigationStart should be negative value.
|
Pass Second measure of current mark to navigationStart should be negative value.
|
||||||
Pass Measures of loadTime should have same duration.
|
Pass Measures of loadTime should have same duration.
|
||||||
Pass Measure from domComplete event to most recent mark "a" should have longer duration.
|
Fail Measure from domComplete event to most recent mark "a" should have longer duration.
|
||||||
Pass Measure from most recent mark to navigationStart should have longer duration.
|
Pass Measure from most recent mark to navigationStart should have longer duration.
|
|
@ -11,11 +11,12 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let timestamp = performance.now();
|
let monotonicTime = performance.now();
|
||||||
let date = Date.now();
|
let date = Date.now();
|
||||||
|
let relativeDate = date - performance.timeOrigin;
|
||||||
let allowedDifference = 300;
|
let allowedDifference = 300;
|
||||||
|
|
||||||
if (timestamp <= date - allowedDifference || timestamp >= date + allowedDifference) {
|
if (Math.abs(monotonicTime - relativeDate) >= allowedDifference) {
|
||||||
println('performance.now() should be close to Date.now(), but was ' + (timestamp - date));
|
println('performance.now() should be close to Date.now(), but was ' + (timestamp - date));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
45
Tests/LibWeb/Text/input/wpt-import/hr-time/timeOrigin.html
Normal file
45
Tests/LibWeb/Text/input/wpt-import/hr-time/timeOrigin.html
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="../resources/testharness.js"></script>
|
||||||
|
<script src="../resources/testharnessreport.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
const windowOrigin = performance.timeOrigin;
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
// Use a 30ms cushion when comparing with Date() to account for inaccuracy.
|
||||||
|
const startTime = Date.now();
|
||||||
|
assert_greater_than_equal(startTime + 30, windowOrigin, 'Date.now() should be at least as large as the window timeOrigin.');
|
||||||
|
const startNow = performance.now();
|
||||||
|
assert_less_than_equal(startTime, windowOrigin + startNow + 30, 'Date.now() should be close to window timeOrigin.');
|
||||||
|
}, 'Window timeOrigin is close to Date.now() when there is no system clock adjustment.');
|
||||||
|
|
||||||
|
const workerScript = 'postMessage({timeOrigin: performance.timeOrigin})';
|
||||||
|
const blob = new Blob([workerScript]);
|
||||||
|
|
||||||
|
async_test(function(t) {
|
||||||
|
const beforeWorkerCreation = performance.now();
|
||||||
|
const worker = new Worker(URL.createObjectURL(blob));
|
||||||
|
worker.addEventListener('message', t.step_func_done(function(event) {
|
||||||
|
const workerOrigin = event.data.timeOrigin;
|
||||||
|
assert_greater_than_equal(workerOrigin, windowOrigin + beforeWorkerCreation, 'Worker timeOrigin should be greater than the window timeOrigin.');
|
||||||
|
const afterWorkerCreation = performance.now();
|
||||||
|
assert_less_than_equal(workerOrigin - windowOrigin, afterWorkerCreation, 'Window and worker timeOrigins should be close.');
|
||||||
|
}));
|
||||||
|
}, 'Window and worker timeOrigins are close when created one after another.');
|
||||||
|
|
||||||
|
async_test(function(t) {
|
||||||
|
this.step_timeout(function() {
|
||||||
|
const workerCreation = performance.now();
|
||||||
|
const worker = new Worker(URL.createObjectURL(blob));
|
||||||
|
worker.addEventListener('message', t.step_func_done(function(event) {
|
||||||
|
const workerOrigin = event.data.timeOrigin;
|
||||||
|
assert_greater_than_equal(workerOrigin - windowOrigin, 200, 'We waited 200ms to spawn the second worker, so its timeOrigin should be greater than that of the window.');
|
||||||
|
}));
|
||||||
|
}, 200);
|
||||||
|
}, 'Window and worker timeOrigins differ when worker is created after a delay.');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
Tests/LibWeb/Text/input/wpt-import/user-timing/mark.any.html
Normal file
15
Tests/LibWeb/Text/input/wpt-import/user-timing/mark.any.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
self.GLOBAL = {
|
||||||
|
isWindow: function() { return true; },
|
||||||
|
isWorker: function() { return false; },
|
||||||
|
isShadowRealm: function() { return false; },
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="../resources/testharness.js"></script>
|
||||||
|
<script src="../resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<div id=log></div>
|
||||||
|
<script src="../user-timing/mark.any.js"></script>
|
118
Tests/LibWeb/Text/input/wpt-import/user-timing/mark.any.js
Normal file
118
Tests/LibWeb/Text/input/wpt-import/user-timing/mark.any.js
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
// test data
|
||||||
|
var testThreshold = 20;
|
||||||
|
|
||||||
|
var expectedTimes = new Array();
|
||||||
|
|
||||||
|
function match_entries(entries, index)
|
||||||
|
{
|
||||||
|
var entry = entries[index];
|
||||||
|
var match = self.performance.getEntriesByName("mark")[index];
|
||||||
|
assert_equals(entry.name, match.name, "entry.name");
|
||||||
|
assert_equals(entry.startTime, match.startTime, "entry.startTime");
|
||||||
|
assert_equals(entry.entryType, match.entryType, "entry.entryType");
|
||||||
|
assert_equals(entry.duration, match.duration, "entry.duration");
|
||||||
|
}
|
||||||
|
|
||||||
|
function filter_entries_by_type(entryList, entryType)
|
||||||
|
{
|
||||||
|
var testEntries = new Array();
|
||||||
|
|
||||||
|
// filter entryList
|
||||||
|
for (var i in entryList)
|
||||||
|
{
|
||||||
|
if (entryList[i].entryType == entryType)
|
||||||
|
{
|
||||||
|
testEntries.push(entryList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return testEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
// create first mark
|
||||||
|
self.performance.mark("mark");
|
||||||
|
|
||||||
|
expectedTimes[0] = self.performance.now();
|
||||||
|
|
||||||
|
const entries = self.performance.getEntriesByName("mark");
|
||||||
|
assert_equals(entries.length, 1);
|
||||||
|
}, "Entry 0 is properly created");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
// create second, duplicate mark
|
||||||
|
self.performance.mark("mark");
|
||||||
|
|
||||||
|
expectedTimes[1] = self.performance.now();
|
||||||
|
|
||||||
|
const entries = self.performance.getEntriesByName("mark");
|
||||||
|
assert_equals(entries.length, 2);
|
||||||
|
|
||||||
|
}, "Entry 1 is properly created");
|
||||||
|
|
||||||
|
function test_mark(index) {
|
||||||
|
test(function () {
|
||||||
|
const entries = self.performance.getEntriesByName("mark");
|
||||||
|
assert_equals(entries[index].name, "mark", "Entry has the proper name");
|
||||||
|
}, "Entry " + index + " has the proper name");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
const entries = self.performance.getEntriesByName("mark");
|
||||||
|
assert_approx_equals(entries[index].startTime, expectedTimes[index], testThreshold);
|
||||||
|
}, "Entry " + index + " startTime is approximately correct (up to " + testThreshold +
|
||||||
|
"ms difference allowed)");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
const entries = self.performance.getEntriesByName("mark");
|
||||||
|
assert_equals(entries[index].entryType, "mark");
|
||||||
|
}, "Entry " + index + " has the proper entryType");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
const entries = self.performance.getEntriesByName("mark");
|
||||||
|
assert_equals(entries[index].duration, 0);
|
||||||
|
}, "Entry " + index + " duration == 0");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
const entries = self.performance.getEntriesByName("mark", "mark");
|
||||||
|
assert_equals(entries[index].name, "mark");
|
||||||
|
}, "getEntriesByName(\"mark\", \"mark\")[" + index + "] returns an " +
|
||||||
|
"object containing a \"mark\" mark");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
const entries = self.performance.getEntriesByName("mark", "mark");
|
||||||
|
match_entries(entries, index);
|
||||||
|
}, "The mark returned by getEntriesByName(\"mark\", \"mark\")[" + index
|
||||||
|
+ "] matches the mark returned by " +
|
||||||
|
"getEntriesByName(\"mark\")[" + index + "]");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
const entries = filter_entries_by_type(self.performance.getEntries(), "mark");
|
||||||
|
assert_equals(entries[index].name, "mark");
|
||||||
|
}, "getEntries()[" + index + "] returns an " +
|
||||||
|
"object containing a \"mark\" mark");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
const entries = filter_entries_by_type(self.performance.getEntries(), "mark");
|
||||||
|
match_entries(entries, index);
|
||||||
|
}, "The mark returned by getEntries()[" + index
|
||||||
|
+ "] matches the mark returned by " +
|
||||||
|
"getEntriesByName(\"mark\")[" + index + "]");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
const entries = self.performance.getEntriesByType("mark");
|
||||||
|
assert_equals(entries[index].name, "mark");
|
||||||
|
}, "getEntriesByType(\"mark\")[" + index + "] returns an " +
|
||||||
|
"object containing a \"mark\" mark");
|
||||||
|
|
||||||
|
test(function () {
|
||||||
|
const entries = self.performance.getEntriesByType("mark");
|
||||||
|
match_entries(entries, index);
|
||||||
|
}, "The mark returned by getEntriesByType(\"mark\")[" + index
|
||||||
|
+ "] matches the mark returned by " +
|
||||||
|
"getEntriesByName(\"mark\")[" + index + "]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < expectedTimes.length; i++) {
|
||||||
|
test_mark(i);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue