Commit 7cfae578 authored by Nicolas Pena's avatar Nicolas Pena Committed by Commit Bot

Prepare to move EventTiming tests to WPT

This CL does most of the changes needed to move EventTiming tests to WPT. The CL
attempts to make the tests less flaky by ensuring the event handlers themselves
take a long time to execute.

Bug: 908187, 907948, 907949
Change-Id: Iced25d635cb05c9903a209d43988ba4e71681195
Reviewed-on: https://chromium-review.googlesource.com/c/1351600Reviewed-by: default avatarTimothy Dresser <tdresser@chromium.org>
Commit-Queue: Nicolás Peña Moreno <npm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611099}
parent 6c181a47
......@@ -3,47 +3,47 @@
<meta charset=utf-8 />
<title>Event Timing: buffer long-latency events before onload</title>
<button id='button' onclick='clickDelay()'>Generate a 'click' event</button>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<script src=./resources/event-timing-support.js></script>
<img src=./resources/slow-image.php>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=resources/event-timing-support.js></script>
<img src=resources/slow-image.php>
<script>
let clickTimeMin;
let processingStartMin;
let onloadStart;
let firstClickStart = 0;
let firstClickEnd = 0;
function clickDelay() {
const onclickStart = performance.now();
if (firstClickStart == 0)
if (firstClickStart === 0)
firstClickStart = onclickStart;
while(performance.now() < onclickStart + 10) {}
if (firstClickEnd == 0)
while(performance.now() < onclickStart + 60) {}
if (firstClickEnd === 0)
firstClickEnd = performance.now();
}
function validateEntries() {
const entries = performance.getEntriesByName('click', 'event');
const onloadTime = performance.timing.loadEventStart - performance.timeOrigin;
const entriesBeforeOnload = entries.filter(
e => e.startTime < onloadTime);
e => e.startTime < onloadStart);
assert_equals(entriesBeforeOnload.length, 1,
"Long latency events before onload should be buffered.");
const entry = entriesBeforeOnload[0];
verifyClickEvent(entry, true);
assert_greater_than(entry.processingStart, processingStartMin,
"The entry should be processed later than processingStartMin.");
assert_greater_than(entry.startTime, clickTimeMin,
assert_greater_than_equal(entry.startTime, clickTimeMin,
"The entry's start time should be later than clickTimeMin.");
assert_greater_than_equal(firstClickStart, entry.processingStart,
"The processingStart must be before the onclick starts.")
assert_greater_than_equal(entry.processingStart, processingStartMin,
"The entry should be processed later than processingStartMin.");
assert_less_than_equal(entry.processingStart, firstClickStart,
"The processingStart must be before firstClickStart.")
assert_greater_than_equal(entry.processingEnd, firstClickEnd,
"The processingEnd must be after onclick finishes.");
"The processingEnd must be after firstClickEnd.");
const entriesAfterOnload = entries.filter(
e => e.startTime > onloadTime);
e => e.startTime >= onloadStart);
assert_equals(entriesAfterOnload.length, 0,
"Events after onload shouldn't be buffered.");
}
......@@ -62,8 +62,11 @@
async_test(function(t) {
clickTimeMin = performance.now();
clickAndBlockMain('button');
// Event handlers will be dispatched asynchronously, so this will be called
// before processing begins.
processingStartMin = performance.now();
on_event(window, 'load', e => {
onloadStart = performance.now();
clickAndBlockMain('button').then(wait).then(
t.step_func_done(validateEntries));
});
......
......@@ -7,22 +7,19 @@
</head>
<body>
<button id='button' onclick='1'>Generate a 'click' event</button>
</body>
<div>
<iframe src=./resources/event-timing-crossiframe-childframe.html></iframe>
</div>
<script src=../../../resources/testharness.js></script>
<script src=../../../resources/testharnessreport.js></script>
<script src=./resources/event-timing-support.js></script>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=resources/event-timing-support.js></script>
<img src=./resources/slow-image.php>
<iframe src=resources/event-timing-crossiframe-childframe.html></iframe>
<script>
let clickTimeMin;
let processingStartMin;
let onloadStart;
function validateEntries() {
const entries = performance.getEntriesByName('click', 'event');
const onloadTime = performance.timing.loadEventStart - performance.timeOrigin;
assert_equals(entries.length, 1,
"Observer of main frames should only capture main-frame event-timing entries."
......@@ -32,11 +29,11 @@
assert_greater_than(entry.processingStart, processingStartMin,
"The entry's processing start should be later than processingStartMin.");
assert_greater_than(onloadTime, entry.processingStart,
assert_greater_than(onloadStart, entry.processingStart,
"onload should occur later than the entry's procesisng start.");
assert_greater_than(entry.startTime, clickTimeMin,
"The entry's start time should be later than clickTimeMin.");
assert_greater_than(onloadTime, entry.startTime,
assert_greater_than(onloadStart, entry.startTime,
"onload should occur later than the entry's start time.");
}
......@@ -49,13 +46,13 @@
assert_greater_than(entry.processingStart, childFrameData.processingStartMin,
"The entry's processing start should be later than the child frame's processingStartMin.");
assert_greater_than(childFrameData.onloadTime, entry.processingStart,
assert_greater_than(childFrameData.onloadStart, entry.processingStart,
"Child frame's onload should occur later than the entry's processing \
start.");
assert_greater_than(entry.startTime, childFrameData.clickTimeMin,
"The entry's start time should be later than the child frame's \
clickTimeMin.");
assert_greater_than(childFrameData.onloadTime, entry.startTime,
assert_greater_than(childFrameData.onloadStart, entry.startTime,
"Child frame's onload should be later than the entry's start time.");
assert_array_equals(childFrameData.observedEntries,
......@@ -73,6 +70,7 @@
}, false);
});
on_event(window, 'load', e => {
onloadStart = performance.now();
childFrameEntriesPromise.then((entries) => {
t.step(() => {
validateChildFrameEntries(entries);
......@@ -84,5 +82,5 @@
}, "Event Timing: entries should only be observable by its own frame.");
</script>
</body>
</html>
......@@ -4,25 +4,28 @@
<title>Event Timing: Performance observers can observe long-latency events
</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=../../../resources/testharness.js></script>
<script src=../../../resources/testharnessreport.js></script>
<script src=./resources/event-timing-support.js></script>
<img src=./resources/slow-image.php>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=resources/event-timing-support.js></script>
<img src=resources/slow-image.php>
<script>
let timeBeforeFirstClick;
let timeAfterFirstClick;
let timeAfterSecondClick;
let onloadStart;
let observedEntries = [];
function verifyBuffer(bufferedEntries) {
const loadStart =
performance.timing.loadEventStart - performance.timeOrigin;
assert_equals(bufferedEntries.length, 1,
"Only events before onload should be buffered.");
const entry = bufferedEntries[0];
assert_greater_than(loadStart, entry.startTime,
"onload should be later than entry's start time.");
assert_greater_than(entry.processingStart, timeAfterFirstClick,
"The entry's processing start should be later than timeAfterFirstClick.");
assert_greater_than(onloadStart, entry.startTime,
"Onload should be later than entry's start time.");
assert_greater_than(entry.processingStart, timeBeforeFirstClick,
"The entry's processing start should be after timeBeforeFirstClick");
assert_less_than(entry.processingStart, timeAfterFirstClick,
"The entry's processing start should be before timeAfterFirstClick.");
verifyClickEvent(entry, true);
}
......@@ -34,9 +37,11 @@
const entry1 = entriesAfterFirstClick[0];
verifyClickEvent(entry1);
assert_greater_than(entry1.processingStart, timeAfterFirstClick,
"entry1's processing start should be later than timeAfterFirstClick.");
assert_greater_than(entry1.startTime, timeAfterFirstClick,
"entry1's start time should be later than timeAfterFirstClick.");
"entry1's processing start should be after timeAfterFirstClick");
assert_less_than(entry1.processingStart, timeAfterSecondClick,
"entry1's processing start should be before timeAfterSecondClick.");
assert_greater_than(entry1.startTime, onloadStart,
"entry1's start time should be later than onloadStart.");
const entriesBeforeFirstClick =
observedEntries.filter(e => e.startTime < timeAfterFirstClick);
......@@ -45,8 +50,10 @@
);
const entry2 = entriesBeforeFirstClick[0];
verifyClickEvent(entry2);
assert_greater_than(entry2.processingStart, timeAfterFirstClick,
"entry2's processing start should be later than timeAfterFirstClick.");
assert_greater_than(entry2.processingStart, timeBeforeFirstClick,
"entry2's processing start should be after timeBeforeFirstClick");
assert_less_than(entry2.processingStart, timeAfterFirstClick,
"entry2's processing start should be berfore timeAfterFirstClick.");
assert_greater_than(timeAfterFirstClick, entry2.startTime,
"timeAfterFirstClick should be later than entry2's start time.");
}
......@@ -72,12 +79,16 @@
resolve(observedEntries);
}).observe({ entryTypes: ['event'] });
});
clickAndBlockMain('button');
timeAfterFirstClick = performance.now();
timeBeforeFirstClick = performance.now();
clickAndBlockMain('button').then( () => {
timeAfterFirstClick = performance.now();
});
on_event(window, 'load', function(e) {
onloadStart = performance.now();
// After onload start and before registering observer.
const bufferPromise = clickAndBlockMain('button').then(wait);
Promise.all([observerPromise, bufferPromise]).then((results) => {
timeAfterSecondClick = performance.now();
t.step(verifyObserverEntries.bind(null, results[0]));
t.step(verifyBuffer.bind(null, performance.getEntriesByName('click', 'event')));
t.done();
......
......@@ -3,9 +3,9 @@
<meta charset=utf-8 />
<title>Event Timing: buffer long-latency events before onload</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<script src=./resources/event-timing-support.js></script>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=resources/event-timing-support.js></script>
<script>
/* Timeline:
......
......@@ -5,9 +5,9 @@
registration are lost
</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=../../../resources/testharness.js></script>
<script src=../../../resources/testharnessreport.js></script>
<script src=./resources/event-timing-support.js></script>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=resources/event-timing-support.js></script>
<script>
let callbackTime;
let observerStart;
......
......@@ -3,9 +3,9 @@
<meta charset=utf-8 />
<title>Event Timing: only observe the first input</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<script src=./resources/event-timing-support.js></script>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=resources/event-timing-support.js></script>
<script>
/* Test:
......@@ -27,19 +27,20 @@
assert_equals(observedEntries[0].name, 'click');
})).observe({ entryTypes: ['firstInput'] });
on_event(window, 'load', () => {
clickAndBlockMain('button').then(wait).then(() => {
clickAndBlockMain('button').then(wait);
// After some wait, the PerformanceObserver should have processed both clicks.
// One and only one firstInput entry should have been dispatched, so
// |hasObservedFirstInput| should be true.
t.step_timeout( () => {
assert_true(hasObservedFirstInput);
t.done();
}, 100);
clickAndBlockMain('button').then(() => {
clickAndBlockMain('button').then(wait).then( () => {
// After some wait, the PerformanceObserver should have processed both clicks.
// One and only one firstInput entry should have been dispatched, so
// |hasObservedFirstInput| should be true.
t.step_timeout( () => {
assert_true(hasObservedFirstInput);
t.done();
}, 10);
});
});
});
},
"Event Timing: check firstInput for a PerformanceObserver observing only firstInput."
);
</script>
</html>
\ No newline at end of file
</html>
......@@ -3,10 +3,10 @@
<meta charset=utf-8>
<title>Event Timing: make sure event-timing entries are retrievable by existing perf APIs.</title>
<button id='button' onclick='1'>Generate a 'click' event</button>
<script src=../../../resources/testharness.js></script>
<script src=../../../resources/testharnessreport.js></script>
<script src=./resources/event-timing-support.js></script>
<img src=./resources/slow-image.php>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=resources/event-timing-support.js></script>
<img src=resources/slow-image.php>
<script>
function validateEntries() {
......
......@@ -3,63 +3,52 @@
<meta charset=utf-8 />
<title>Event Timing only times certain types of trusted event.
</title>
<button id='button' onclick='mainThreadBusy(100)'
onfocus='mainThreadBusy(100)'>Generate a 'click' event</button>
<script src=../../../resources/testharness.js></script>
<script src=../../../resources/testharnessreport.js></script>
<script src=./resources/event-timing-support.js></script>
<button id='button' onclick='mainThreadBusy(60)'
onfocus='mainThreadBusy(60)'>Generate a 'click' event</button>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=resources/event-timing-support.js></script>
<script>
let trustedClickStart = 0;
let trustedClickStart;
function trustedClickAndBlockMain(id) {
return new Promise((resolve, reject) => {
trustedClickStart = performance.now();
clickOnElement(id);
mainThreadBusy(100);
resolve();
clickOnElement(id, resolve);
});
}
function untrustedClickAndBlockMain(id) {
return new Promise((resolve, reject) => {
const target = document.getElementById(id);
target.dispatchEvent(new MouseEvent('click'));
// Block mainthread in the callback, as dispatchEvent() is an sync call.
resolve();
});
const target = document.getElementById(id);
// Block mainthread in the callback, as dispatchEvent() is a sync call.
target.dispatchEvent(new MouseEvent('click'));
}
function trustedFocusAndBlockMain(id) {
return new Promise((resolve, reject) => {
const target = document.getElementById(id);
trustedFocusStart = performance.now();
target.focus();
// Block mainthread in the callback, as focus() is an sync call.
resolve();
});
const target = document.getElementById(id);
trustedFocusStart = performance.now();
// Block mainthread in the callback, as focus() is a sync call.
target.focus();
}
async_test(function(t) {
new PerformanceObserver(entryList => {
new PerformanceObserver(t.step_func_done(entryList => {
const observerCallbackTime = performance.now();
const entries = entryList.getEntries();
t.step(()=>{
assert_equals(entries.length, 1,
"Observe more than one entries: " +
JSON.stringify(entries) + ".");
assert_equals(entries[0].name, 'click',
"The observed entry should be a click");
assert_greater_than(observerCallbackTime, entries[0].startTime,
"assert(untrustedClickStart > entries[0].startTime) failed");
assert_greater_than(entries[0].startTime, trustedClickStart,
"assert(entries[0].startTime > trustedClickStart) failed");
});
t.done();
}).observe({ entryTypes: ['event'] });
// untrusted event of a type event timing cares about
untrustedClickAndBlockMain('button').then(wait);
// trusted event of a type event timing doesn't cares about
trustedFocusAndBlockMain('button').then(wait);
// trusted event of a type event timing cares about
assert_equals(entries.length, 1,
"Should only observe one entry: " +
JSON.stringify(entries) + ".");
assert_equals(entries[0].name, 'click',
"The observed entry should be a click");
assert_less_than(entries[0].startTime, observerCallbackTime,
"The startTime should be before observerCallbackTime");
assert_greater_than(entries[0].startTime, trustedClickStart,
"The startTime should be after trustedClickStart");
})).observe({ entryTypes: ['event'] });
// Untrusted event of a type event timing cares about.
untrustedClickAndBlockMain('button');
// Trusted event of a type event timing doesn't cares about.
trustedFocusAndBlockMain('button');
// Trusted event of a type event timing cares about.
trustedClickAndBlockMain('button').then(wait);
}, "Event Timing only times certain types of trusted event.");
</script>
......
......@@ -14,14 +14,14 @@
});
window.addEventListener('load', e => {
observerPromise.then((observedEntries) => {
const onloadStart = performance.now();
const bufferedEntries = performance.getEntriesByType('event');
const onloadTime = performance.timing.loadEventStart - performance.timeOrigin;
top.postMessage({
"bufferedEntries" : bufferedEntries,
"observedEntries": observedEntries,
"clickTimeMin": clickTimeMin,
"processingStartMin" : processingStartMin,
"onloadTime" : onloadTime,
"onloadStart" : onloadStart,
}, '*');
});
});
......
// Clicks on the element with the given ID. It adds an event handler to the element
// which ensures that the events have a long duration and reported by EventTiming
// where appropriate.
function clickOnElement(id, callback) {
const element = document.getElementById(id);
const rect = element.getBoundingClientRect();
......@@ -12,6 +15,7 @@ function clickOnElement(id, callback) {
]
}];
var clickHandler = () => {
mainThreadBusy(60);
if (callback)
callback();
element.removeEventListener("click", clickHandler);
......@@ -29,7 +33,7 @@ function mainThreadBusy(duration) {
while (performance.now() < now + duration);
}
// This method should receive an entry of type 'event'. |is_false| is true only
// This method should receive an entry of type 'event'. |is_first| is true only
// when the event also happens to correspond to the first event. In this case,
// the timings of the 'firstInput' entry should be equal to those of this entry.
function verifyClickEvent(entry, is_first=false) {
......@@ -69,6 +73,5 @@ function wait() {
function clickAndBlockMain(id) {
return new Promise((resolve, reject) => {
clickOnElement(id, resolve);
mainThreadBusy(300);
});
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment