зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1509598 [wpt PR 14215] - Move EventTiming tests to WPT, a=testonly
Automatic update from web-platform-tests Move EventTiming tests to WPT This CL moves the tests in http/tests/event-timing to external/wpt/event-timing. The slow image is change from php based to python based. The click is now handled by test driver. and setTimeout is replaced with step_timeout. Bug: 841224 Change-Id: I035c087550a2d9a67cda1aed88553c16967d04b6 Reviewed-on: https://chromium-review.googlesource.com/c/1349451 Commit-Queue: Nicolás Peña Moreno <npm@chromium.org> Reviewed-by: Timothy Dresser <tdresser@chromium.org> Cr-Commit-Position: refs/heads/master@{#610669} -- wpt-commits: 42061028f3951380908b400fb1b23a2d6e16bb22 wpt-pr: 14215
This commit is contained in:
Родитель
52d9898011
Коммит
fdf9e231c9
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<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/testdriver.js></script>
|
||||
<script src=/resources/testdriver-vendor.js></script>
|
||||
<script src=./resources/event-timing-support.js></script>
|
||||
<img src=./resources/slow-image.py>
|
||||
|
||||
<script>
|
||||
let clickTimeMin;
|
||||
let processingStartMin;
|
||||
let firstClickStart = 0;
|
||||
let firstClickEnd = 0;
|
||||
function clickDelay() {
|
||||
const onclickStart = performance.now();
|
||||
if (firstClickStart == 0)
|
||||
firstClickStart = onclickStart;
|
||||
while(performance.now() < onclickStart + 10) {}
|
||||
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);
|
||||
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,
|
||||
"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.processingEnd, firstClickEnd,
|
||||
"The processingEnd must be after onclick finishes.");
|
||||
|
||||
const entriesAfterOnload = entries.filter(
|
||||
e => e.startTime > onloadTime);
|
||||
assert_equals(entriesAfterOnload.length, 0,
|
||||
"Events after onload shouldn't be buffered.");
|
||||
}
|
||||
|
||||
/* Timeline:
|
||||
Begin Busy Loop
|
||||
Click 1 arrives
|
||||
End Busy Loop
|
||||
(Dispatch and Process Click 1 - buffered)
|
||||
Onload Event Fires
|
||||
Begin Busy Loop
|
||||
Click 2 arrives
|
||||
End Busy Loop
|
||||
(Dispatch and Process Click 2 - not buffered)
|
||||
*/
|
||||
async_test(function(t) {
|
||||
clickTimeMin = performance.now();
|
||||
clickAndBlockMain('button');
|
||||
processingStartMin = performance.now();
|
||||
on_event(window, 'load', e => {
|
||||
clickAndBlockMain('button').then(wait).then(
|
||||
t.step_func_done(validateEntries));
|
||||
});
|
||||
}, "Event Timing: click, onload.");
|
||||
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,90 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset=utf-8 />
|
||||
<title>Event Timing: entries should be observable by its own frame.</title>
|
||||
</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/testdriver.js></script>
|
||||
<script src=/resources/testdriver-vendor.js></script>
|
||||
<script src=./resources/event-timing-support.js></script>
|
||||
<img src=./resources/slow-image.py>
|
||||
<script>
|
||||
let clickTimeMin;
|
||||
let processingStartMin;
|
||||
|
||||
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."
|
||||
);
|
||||
const entry = entries[0];
|
||||
verifyClickEvent(entry, true);
|
||||
|
||||
assert_greater_than(entry.processingStart, processingStartMin,
|
||||
"The entry's processing start should be later than processingStartMin.");
|
||||
assert_greater_than(onloadTime, 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,
|
||||
"onload should occur later than the entry's start time.");
|
||||
}
|
||||
|
||||
function validateChildFrameEntries(childFrameData) {
|
||||
assert_equals(childFrameData.bufferedEntries.length, 1,
|
||||
"Event Timing of child frames should only capture child-frame event-timing entries."
|
||||
);
|
||||
const entry = entries[0];
|
||||
verifyClickEvent(entry);
|
||||
|
||||
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,
|
||||
"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,
|
||||
"Child frame's onload should be later than the entry's start time.");
|
||||
|
||||
assert_array_equals(childFrameData.observedEntries,
|
||||
childFrameData.bufferedEntries,
|
||||
"The child frame's observed entries should be buffered as well.");
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
clickTimeMin = performance.now();
|
||||
clickAndBlockMain('button');
|
||||
processingStartMin = performance.now();
|
||||
const childFrameEntriesPromise = new Promise((resolve, reject) => {
|
||||
window.addEventListener("message", (event) => {
|
||||
resolve(event.data);
|
||||
}, false);
|
||||
});
|
||||
on_event(window, 'load', e => {
|
||||
childFrameEntriesPromise.then((entries) => {
|
||||
t.step(() => {
|
||||
validateChildFrameEntries(entries);
|
||||
validateEntries();
|
||||
});
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
}, "Event Timing: entries should only be observable by its own frame.");
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,79 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=utf-8 />
|
||||
<title>Event Timing: entries should be observable by its own frame.
|
||||
</title>
|
||||
<script src=./resources/event-timing-support.js></script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Description:</h2>
|
||||
<p>
|
||||
<div>
|
||||
The goal of this manual test is to verify that observers that have
|
||||
registered "event" entry type can observe the long-latency input events,
|
||||
and verify the same behavior within iframe and in cross-frame scenario.
|
||||
</div>
|
||||
</p>
|
||||
<h2>Manual test steps:</h2>
|
||||
<p>
|
||||
<div>
|
||||
Step 1: Click the "make busy" button to make main-thread busy for 2 seconds.</span>
|
||||
</div>
|
||||
<div>
|
||||
Step 2: do several clicks on "click while busy" while busy to generate long-latency inputs.
|
||||
</div>
|
||||
<div>
|
||||
Step 3: observe in the "timeline" section that the long-latency clicks are captured by the observer.
|
||||
</div>
|
||||
<div>
|
||||
Step 4: do step 1 to step 3 for the iframe. Observe that the observers only observe input events within its frame.
|
||||
</div>
|
||||
</p>
|
||||
<div>
|
||||
<h2>Actions:</h2>
|
||||
<button id='busy_button' onclick='onMakeBusy()'>make busy</button>
|
||||
<button id='click_input_button' onclick='1'> click while busy </button>
|
||||
</div>
|
||||
<h2>iframe:</h2>
|
||||
<div>
|
||||
<iframe name='childframe' width="100%" height="30%" src=./resources/event-timing-observer-manual-childframe.html></iframe>
|
||||
</div>
|
||||
<h2>Timeline:</h2>
|
||||
<p id='timeline'></p>
|
||||
</body>
|
||||
<script>
|
||||
function log(message) {
|
||||
const timestamp = performance.now();
|
||||
const elem = document.createElement('div');
|
||||
elem.innerHTML = `${timestamp.toFixed(1)}: ${message}`;
|
||||
const timeline = document.getElementById('timeline');
|
||||
timeline.appendChild(elem);
|
||||
}
|
||||
|
||||
function onMakeBusy() {
|
||||
log("busy start");
|
||||
step_timeout(()=>{
|
||||
mainThreadBusy(2000);
|
||||
log("busy end");
|
||||
}, 0);
|
||||
}
|
||||
|
||||
document.body.onload = () => {
|
||||
new PerformanceObserver((entryList) => {
|
||||
entryList.getEntries().forEach(e => {
|
||||
log(`entry observed: ${JSON.stringify(e)}`);
|
||||
});
|
||||
}).observe({ entryTypes: ['event'] });
|
||||
log("observer registered");
|
||||
};
|
||||
|
||||
window.onmessage = (msg) => {
|
||||
log("received msg: " + msg.data);
|
||||
if (msg.data === 'CHILD_FRAME_IS_READY') {
|
||||
// TODO(crbug/831729): automate clicks on iframe when testdriver support
|
||||
// clicking in iframe.
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,91 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset=utf-8 />
|
||||
<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/testdriver.js></script>
|
||||
<script src=/resources/testdriver-vendor.js></script>
|
||||
<script src=./resources/event-timing-support.js></script>
|
||||
<img src=./resources/slow-image.py>
|
||||
|
||||
<script>
|
||||
let timeAfterFirstClick;
|
||||
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.");
|
||||
verifyClickEvent(entry, true);
|
||||
}
|
||||
|
||||
function verifyObserverEntries(observedEntries) {
|
||||
const entriesAfterFirstClick = observedEntries.filter(
|
||||
e => e.startTime > timeAfterFirstClick);
|
||||
assert_equals(entriesAfterFirstClick.length, 1,
|
||||
'There should be one event after timeAfterFirstClick.');
|
||||
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.");
|
||||
|
||||
const entriesBeforeFirstClick =
|
||||
observedEntries.filter(e => e.startTime < timeAfterFirstClick);
|
||||
assert_equals(entriesBeforeFirstClick.length, 1,
|
||||
'There should be one event before timeAfterFirstClick.'
|
||||
);
|
||||
const entry2 = entriesBeforeFirstClick[0];
|
||||
verifyClickEvent(entry2);
|
||||
assert_greater_than(entry2.processingStart, timeAfterFirstClick,
|
||||
"entry2's processing start should be later than timeAfterFirstClick.");
|
||||
assert_greater_than(timeAfterFirstClick, entry2.startTime,
|
||||
"timeAfterFirstClick should be later than entry2's start time.");
|
||||
}
|
||||
|
||||
/* Timeline:
|
||||
Observer starts
|
||||
Begin Busy Loop
|
||||
Click 1 arrives
|
||||
End Busy Loop
|
||||
(Dispatch and Process Click 1 (buffered, observed))
|
||||
Onload Event Fires
|
||||
Begin Busy Loop
|
||||
Click 2 arrives
|
||||
End Busy Loop
|
||||
(Dispatch and Process Click 2 (buffered, observed))
|
||||
observer callback start
|
||||
*/
|
||||
async_test(function(t) {
|
||||
const observerPromise = new Promise((resolve, reject) => {
|
||||
new PerformanceObserver(function(entryList) {
|
||||
observedEntries = observedEntries.concat(entryList.getEntries());
|
||||
if (observedEntries.length < 2) return;
|
||||
resolve(observedEntries);
|
||||
}).observe({ entryTypes: ['event'] });
|
||||
});
|
||||
clickAndBlockMain('button');
|
||||
timeAfterFirstClick = performance.now();
|
||||
on_event(window, 'load', function(e) {
|
||||
// After onload start and before registering observer.
|
||||
const bufferPromise = clickAndBlockMain('button').then(wait);
|
||||
Promise.all([observerPromise, bufferPromise]).then((results) => {
|
||||
t.step(verifyObserverEntries.bind(null, results[0]));
|
||||
t.step(verifyBuffer.bind(null, performance.getEntriesByName('click', 'event')));
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
}, "Event Timing: click, observer, onload, click.");
|
||||
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<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/testdriver.js></script>
|
||||
<script src=/resources/testdriver-vendor.js></script>
|
||||
<script src=./resources/event-timing-support.js></script>
|
||||
|
||||
<script>
|
||||
/* Timeline:
|
||||
Onload
|
||||
PerformanceObserver is registered
|
||||
Click 1
|
||||
Click 2
|
||||
PerformanceObserver should observe only one firstInput entry.
|
||||
(Dispatch and Process Click 2 - not buffered)
|
||||
*/
|
||||
async_test(function(t) {
|
||||
let numFirstInputObserved = 0;
|
||||
let numEventsObserved = 0;
|
||||
new PerformanceObserver(t.step_func((entryList, obs) => {
|
||||
const observedEntries = entryList.getEntries();
|
||||
numEventsObserved += observedEntries.filter(entry =>
|
||||
entry.entryType == 'event').length;
|
||||
numFirstInputObserved += observedEntries.filter(entry =>
|
||||
entry.entryType == 'firstInput').length;
|
||||
if (numEventsObserved >= 2) {
|
||||
assert_equals(performance.getEntriesByType('event').length, 0,
|
||||
"There should be no buffered event entries.");
|
||||
assert_equals(performance.getEntriesByType('firstInput').length, 0,
|
||||
"There should be no buffered firstInput entries.");
|
||||
// There should be 2 event entries and one firstInput entry.
|
||||
assert_equals(numEventsObserved, 2,
|
||||
"There should be 2 observed event entries.");
|
||||
assert_equals(numFirstInputObserved, 1,
|
||||
"There should be only 1 observed firstInput entry.");
|
||||
t.done();
|
||||
}
|
||||
})).observe({ entryTypes: ['event', 'firstInput'] });
|
||||
on_event(window, 'load', () => {
|
||||
clickAndBlockMain('button').then(wait).then(() => {
|
||||
clickAndBlockMain('button').then(wait);
|
||||
});
|
||||
});
|
||||
},
|
||||
"Event Timing: check firstInput after onload, observer, click, click."
|
||||
);
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset=utf-8 />
|
||||
<title>Event Timing: long-latency events after onload and before observer
|
||||
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/testdriver.js></script>
|
||||
<script src=/resources/testdriver-vendor.js></script>
|
||||
<script src=./resources/event-timing-support.js></script>
|
||||
<script>
|
||||
let callbackTime;
|
||||
let observerStart;
|
||||
let processingStartMin;
|
||||
|
||||
function verifyBufferAndObserverEntries(observedEntries) {
|
||||
// Verify buffer entries
|
||||
const bufferedEntries = performance.getEntriesByName('click', 'event');
|
||||
const bufferedEntriesBeforeObserver = bufferedEntries.filter(e => e.startTime <
|
||||
observerStart);
|
||||
assert_equals(bufferedEntries.length, 0,
|
||||
"Long latency events after onload should not be buffered."
|
||||
);
|
||||
|
||||
// Verify observer entries
|
||||
assert_equals(observedEntries.length, 1, "Long latency task after observer start should be observed.");
|
||||
const entry = observedEntries[0];
|
||||
verifyClickEvent(entry);
|
||||
assert_greater_than(entry.processingStart, processingStartMin,
|
||||
"The entry's processing start should be later than processingStartMin.");
|
||||
assert_greater_than(callbackTime, entry.processingStart,
|
||||
"The callback time should be later than the entry's processing start.");
|
||||
assert_greater_than(entry.startTime, observerStart,
|
||||
"The entry's start time should be later than observer start.");
|
||||
assert_greater_than(callbackTime, entry.startTime,
|
||||
"The callback time should be later than entry's start time.");
|
||||
}
|
||||
|
||||
function startObserver(t) {
|
||||
new PerformanceObserver(t.step_func_done((entryList, obs) => {
|
||||
callbackTime = performance.now();
|
||||
const observedEntries = entryList.getEntries();
|
||||
verifyBufferAndObserverEntries(observedEntries);
|
||||
})).observe({ entryTypes: ['event'] });
|
||||
observerStart = performance.now();
|
||||
}
|
||||
|
||||
/* Timeline:
|
||||
Onload Event fires
|
||||
Begin Busy Loop
|
||||
Click 1 arrives
|
||||
End Busy Loop
|
||||
(Dispatch and Process Click 1 (not buffered, not observed))
|
||||
Observer start
|
||||
Begin Busy Loop
|
||||
Click 2 arrives
|
||||
End Busy Loop
|
||||
(Dispatch and Process Click 2 (not buffered, observed))
|
||||
*/
|
||||
async_test(function(t) {
|
||||
on_event(window, 'load', () => {
|
||||
clickAndBlockMain('button').then(() => {
|
||||
startObserver(t);
|
||||
clickAndBlockMain('button').then(wait);
|
||||
processingStartMin = performance.now();
|
||||
});
|
||||
});
|
||||
},
|
||||
"Event Timing: onload, click, observer, click."
|
||||
);
|
||||
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<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/testdriver.js></script>
|
||||
<script src=/resources/testdriver-vendor.js></script>
|
||||
<script src=./resources/event-timing-support.js></script>
|
||||
|
||||
<script>
|
||||
/* Test:
|
||||
PerformanceObserver for firstInput is registered
|
||||
Click 1
|
||||
Click 2
|
||||
Wait
|
||||
Expected result:
|
||||
PerformanceObserver should observe one and only one entry.
|
||||
*/
|
||||
async_test(function(t) {
|
||||
let hasObservedFirstInput = false;
|
||||
new PerformanceObserver(t.step_func((entryList) => {
|
||||
assert_false(hasObservedFirstInput);
|
||||
hasObservedFirstInput = true;
|
||||
const observedEntries = entryList.getEntries();
|
||||
assert_equals(observedEntries.length, 1);
|
||||
assert_equals(observedEntries[0].entryType, 'firstInput');
|
||||
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);
|
||||
});
|
||||
});
|
||||
},
|
||||
"Event Timing: check firstInput for a PerformanceObserver observing only firstInput."
|
||||
);
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<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/testdriver.js></script>
|
||||
<script src=/resources/testdriver-vendor.js></script>
|
||||
<script src=./resources/event-timing-support.js></script>
|
||||
<img src=./resources/slow-image.py>
|
||||
|
||||
<script>
|
||||
function validateEntries() {
|
||||
const entriesByName = performance.getEntriesByName('click', 'event');
|
||||
const entriesByType = performance.getEntriesByType('event');
|
||||
const allEntries = performance.getEntries();
|
||||
assert_equals(entriesByName.length, 1, 'event-timing entry should be retrievable by getEntriesByName');
|
||||
const e = entriesByName[0];
|
||||
assert_true(entriesByType.includes(e), 'event-timing entry should be retrievable by getEntries');
|
||||
assert_true(allEntries.includes(e), 'event-timing entry should be retrievable by getEntriesByType');
|
||||
}
|
||||
|
||||
/* Timeline:
|
||||
Begin Busy Loop
|
||||
Click 1 arrives
|
||||
End Busy Loop
|
||||
(Dispatch and Process Click 1 - buffered)
|
||||
Onload Event Fires
|
||||
Validate entries
|
||||
*/
|
||||
async_test(function(t) {
|
||||
clickAndBlockMain('button').then(wait).then(t.step_func_done(validateEntries));
|
||||
}, "Event Timing: make sure event-timing entries are retrievable by existing perf APIs.");
|
||||
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset=utf-8 />
|
||||
<title>Event Timing only times certain types of trusted event.
|
||||
</title>
|
||||
<button id='button' onfocus='mainThreadBusy(100)'>Generate a 'click' event</button>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/resources/testdriver.js></script>
|
||||
<script src=/resources/testdriver-vendor.js></script>
|
||||
<script src=./resources/event-timing-support.js></script>
|
||||
<script>
|
||||
let trustedClickStart = 0;
|
||||
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
new PerformanceObserver(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
|
||||
trustedClickStart = performance.now();
|
||||
clickAndBlockMain('button').then(wait);
|
||||
}, "Event Timing only times certain types of trusted event.");
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCType html>
|
||||
<html>
|
||||
<script src=event-timing-support.js></script>
|
||||
<button id='button_child_frame' onclick='2'>Generate a 'click' event</button>
|
||||
<img src=slow-image.py>
|
||||
<script>
|
||||
const clickTimeMin = performance.now();
|
||||
clickAndBlockMain('button_child_frame');
|
||||
const processingStartMin = performance.now();
|
||||
const observerPromise = new Promise((resolve, reject) => {
|
||||
new PerformanceObserver((entryList) => {
|
||||
resolve(entryList.getEntries());
|
||||
}).observe({ entryTypes: ['event'] });
|
||||
});
|
||||
window.addEventListener('load', e => {
|
||||
observerPromise.then((observedEntries) => {
|
||||
const bufferedEntries = performance.getEntriesByType('event');
|
||||
const onloadTime = performance.timing.loadEventStart - performance.timeOrigin;
|
||||
top.postMessage({
|
||||
"bufferedEntries" : bufferedEntries,
|
||||
"observedEntries": observedEntries,
|
||||
"clickTimeMin": clickTimeMin,
|
||||
"processingStartMin" : processingStartMin,
|
||||
"onloadTime" : onloadTime,
|
||||
}, '*');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=utf-8 />
|
||||
</head>
|
||||
<script src=./event-timing-support.js></script>
|
||||
<script>
|
||||
function log(message) {
|
||||
const timestamp = performance.now();
|
||||
const elem = document.createElement('div');
|
||||
elem.innerHTML = `${timestamp.toFixed(1)}: ${message}`;
|
||||
const timeline = document.getElementById('timeline');
|
||||
timeline.appendChild(elem);
|
||||
}
|
||||
|
||||
function run() {
|
||||
new PerformanceObserver((entryList) => {
|
||||
entryList.getEntries().forEach(e => {
|
||||
log(`entry observed: ${JSON.stringify(e)}`);
|
||||
});
|
||||
}).observe({ entryTypes: ['event'] });
|
||||
log("observer registered");
|
||||
top.postMessage('CHILD_FRAME_IS_READY', "*");
|
||||
}
|
||||
|
||||
function onMakeBusy() {
|
||||
log("busy start");
|
||||
step_timeout(()=>{
|
||||
mainThreadBusy(2000);
|
||||
log("busy end");
|
||||
}, 0);
|
||||
}
|
||||
</script>
|
||||
<body onload='run()'>
|
||||
<h3>Actions:</h3>
|
||||
<p>
|
||||
<button id='busy_button' onclick='onMakeBusy()'>Make busy</button>
|
||||
<button id='click_input_button' onclick='1'> click while busy </button>
|
||||
</p>
|
||||
<h3>Timeline:</h3>
|
||||
<p id='timeline'></p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,58 @@
|
|||
function clickOnElement(id, resolve) {
|
||||
const element = document.getElementById(id);
|
||||
const clickHandler = () => {
|
||||
element.removeEventListener("click", clickHandler);
|
||||
resolve();
|
||||
};
|
||||
element.addEventListener("click", clickHandler);
|
||||
test_driver.click(element);
|
||||
}
|
||||
|
||||
function mainThreadBusy(duration) {
|
||||
const now = performance.now();
|
||||
while (performance.now() < now + duration);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
assert_true(entry.cancelable);
|
||||
assert_equals(entry.name, 'click');
|
||||
assert_equals(entry.entryType, 'event');
|
||||
assert_greater_than(entry.duration, 50,
|
||||
"The entry's duration should be greater than 50ms.");
|
||||
assert_greater_than(entry.processingStart, entry.startTime,
|
||||
"The entry's processingStart should be greater than startTime.");
|
||||
assert_greater_than_equal(entry.processingEnd, entry.processingStart,
|
||||
"The entry's processingEnd must be at least as large as processingStart.");
|
||||
assert_greater_than_equal(entry.duration, entry.processingEnd - entry.startTime,
|
||||
"The entry's duration must be at least as large as processingEnd - startTime.");
|
||||
if (is_first) {
|
||||
let firstInputs = performance.getEntriesByType('firstInput');
|
||||
assert_equals(firstInputs.length, 1, 'There should be a single firstInput entry');
|
||||
let firstInput = firstInputs[0];
|
||||
assert_equals(firstInput.name, entry.name);
|
||||
assert_equals(firstInput.entryType, 'firstInput');
|
||||
assert_equals(firstInput.startTime, entry.startTime);
|
||||
assert_equals(firstInput.duration, entry.duration);
|
||||
assert_equals(firstInput.processingStart, entry.processingStart);
|
||||
assert_equals(firstInput.processingEnd, entry.processingEnd);
|
||||
assert_equals(firstInput.cancelable, entry.cancelable);
|
||||
}
|
||||
}
|
||||
|
||||
function wait() {
|
||||
return new Promise((resolve, reject) => {
|
||||
step_timeout(() => {
|
||||
resolve();
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
function clickAndBlockMain(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
clickOnElement(id, resolve);
|
||||
mainThreadBusy(300);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import time
|
||||
|
||||
def main(request, response):
|
||||
# Sleep for 500ms to delay onload.
|
||||
time.sleep(0.5)
|
||||
response.headers.set("Cache-Control", "no-cache, must-revalidate");
|
||||
response.headers.set("Location", "data:image/gif;base64,R0lGODlhAQABAJAAAMjIyAAAACwAAAAAAQABAAACAgQBADs%3D");
|
Загрузка…
Ссылка в новой задаче