mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-23 17:58:59 +00:00
Tests: Import resize-observer/observe.html
WPT test
This commit is contained in:
parent
ad15edf2ff
commit
98c00f4b45
Notes:
github-actions[bot]
2025-09-08 16:41:08 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 98c00f4b45
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6117
Reviewed-by: https://github.com/tcl3
4 changed files with 1267 additions and 0 deletions
|
@ -0,0 +1,27 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 21 tests
|
||||||
|
|
||||||
|
10 Pass
|
||||||
|
11 Fail
|
||||||
|
Pass ResizeObserver implemented
|
||||||
|
Pass guard
|
||||||
|
Pass test0: simple observation
|
||||||
|
Pass test1: multiple observation on same element trigger only one
|
||||||
|
Pass test2: throw exception when observing non-element
|
||||||
|
Pass test3: disconnect stops all notifications
|
||||||
|
Pass test4: unobserve target stops notifications, unobserve non-observed does nothing
|
||||||
|
Fail test5: observe img
|
||||||
|
Pass test6: iframe notifications
|
||||||
|
Pass test7: callback.this
|
||||||
|
Fail test8: simple content-box observation
|
||||||
|
Fail test9: simple content-box observation but keep border-box size unchanged
|
||||||
|
Fail test10: simple border-box observation
|
||||||
|
Fail test11: simple observation with vertical writing mode
|
||||||
|
Fail test12: no observation is fired after the change of writing mode when box's specified size comes from logical size properties.
|
||||||
|
Fail test13: an observation is fired after the change of writing mode when box's specified size comes from physical size properties.
|
||||||
|
Fail test14: observe the same target but using a different box should override the previous one
|
||||||
|
Fail test15: an observation is fired with box dimensions 0 when element's display property is set to inline
|
||||||
|
Fail test16: observations fire once with 0x0 size for non-replaced inline elements
|
||||||
|
Fail test17: Box sizing snd Resize Observer notifications
|
||||||
|
Pass test18: an observation is fired when device-pixel-content-box is being observed
|
1007
Tests/LibWeb/Text/input/wpt-import/resize-observer/observe.html
Normal file
1007
Tests/LibWeb/Text/input/wpt-import/resize-observer/observe.html
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,38 @@
|
||||||
|
<!doctype html>
|
||||||
|
<head>
|
||||||
|
<script src="./resizeTestHelper.js"></script>
|
||||||
|
</head>
|
||||||
|
<p>iframe test</p>
|
||||||
|
<div id="itarget1" style="width:100px;height:100px;">t1</div>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
let t1 = document.querySelector('#itarget1');
|
||||||
|
function test0() {
|
||||||
|
let timeoutId = window.setTimeout( () => {
|
||||||
|
window.parent.postMessage('fail', '*');
|
||||||
|
}, ResizeTestHelper.TIMEOUT);
|
||||||
|
let ro = new ResizeObserver(function(entries) {
|
||||||
|
window.clearTimeout(timeoutId);
|
||||||
|
window.parent.postMessage('success', '*');
|
||||||
|
});
|
||||||
|
ro.observe(t1);
|
||||||
|
}
|
||||||
|
let testStarted = false;
|
||||||
|
window.addEventListener('message', function(ev) {
|
||||||
|
switch(ev.data) {
|
||||||
|
case 'startTest':
|
||||||
|
testStarted = true;
|
||||||
|
test0();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// How does parent know we've loaded problem is solved by
|
||||||
|
// broadcasting readyToTest message repeatedly until test starts.
|
||||||
|
function broadcastReady() {
|
||||||
|
if (!testStarted) {
|
||||||
|
window.parent.postMessage('readyToTest', '*');
|
||||||
|
window.requestAnimationFrame(broadcastReady);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.onload = broadcastReady;
|
||||||
|
</script>
|
|
@ -0,0 +1,195 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
ResizeTestHelper is a framework to test ResizeObserver
|
||||||
|
notifications. Use it to make assertions about ResizeObserverEntries.
|
||||||
|
This framework is needed because ResizeObservations are
|
||||||
|
delivered asynchronously inside the event loop.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- can queue multiple notification steps in a test
|
||||||
|
- handles timeouts
|
||||||
|
- returns Promise that is fulfilled when test completes.
|
||||||
|
Use to chain tests (since parallel async ResizeObserver tests
|
||||||
|
would conflict if reusing same DOM elements).
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
create ResizeTestHelper for every test.
|
||||||
|
Make assertions inside notify, timeout callbacks.
|
||||||
|
Start tests with helper.start()
|
||||||
|
Chain tests with Promises.
|
||||||
|
Counts animation frames, see startCountingRaf
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@param name: test name
|
||||||
|
@param steps:
|
||||||
|
{
|
||||||
|
setup: function(ResizeObserver) {
|
||||||
|
// called at the beginning of the test step
|
||||||
|
// your observe/resize code goes here
|
||||||
|
},
|
||||||
|
notify: function(entries, observer) {
|
||||||
|
// ResizeObserver callback.
|
||||||
|
// Make assertions here.
|
||||||
|
// Return true if next step should start on the next event loop.
|
||||||
|
},
|
||||||
|
timeout: function() {
|
||||||
|
// Define this if your test expects to time out, and the expected timeout
|
||||||
|
// value will be 100ms.
|
||||||
|
// If undefined, timeout is assert_unreached after 1000ms.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
function ResizeTestHelper(name, steps)
|
||||||
|
{
|
||||||
|
this._name = name;
|
||||||
|
this._steps = steps || [];
|
||||||
|
this._stepIdx = -1;
|
||||||
|
this._harnessTest = null;
|
||||||
|
this._observer = new ResizeObserver(this._handleNotification.bind(this));
|
||||||
|
this._timeoutBind = this._handleTimeout.bind(this);
|
||||||
|
this._nextStepBind = this._nextStep.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The default timeout value in ms.
|
||||||
|
// We expect TIMEOUT to be longer than we would ever have to wait for notify()
|
||||||
|
// to be fired. This is used for tests which are not expected to time out, so
|
||||||
|
// it can be large without slowing down the test.
|
||||||
|
ResizeTestHelper.TIMEOUT = 1000;
|
||||||
|
// A reasonable short timeout value in ms.
|
||||||
|
// We expect SHORT_TIMEOUT to be long enough that notify() would usually get a
|
||||||
|
// chance to fire before SHORT_TIMEOUT expires. This is used for tests which
|
||||||
|
// *are* expected to time out (with no callbacks fired), so we'd like to keep
|
||||||
|
// it relatively short to avoid slowing down the test.
|
||||||
|
ResizeTestHelper.SHORT_TIMEOUT = 100;
|
||||||
|
|
||||||
|
ResizeTestHelper.prototype = {
|
||||||
|
get _currentStep() {
|
||||||
|
return this._steps[this._stepIdx];
|
||||||
|
},
|
||||||
|
|
||||||
|
_nextStep: function() {
|
||||||
|
if (++this._stepIdx == this._steps.length)
|
||||||
|
return this._done();
|
||||||
|
// Use SHORT_TIMEOUT if this step expects timeout.
|
||||||
|
let timeoutValue = this._steps[this._stepIdx].timeout ?
|
||||||
|
ResizeTestHelper.SHORT_TIMEOUT :
|
||||||
|
ResizeTestHelper.TIMEOUT;
|
||||||
|
this._timeoutId = this._harnessTest.step_timeout(
|
||||||
|
this._timeoutBind, timeoutValue);
|
||||||
|
try {
|
||||||
|
this._steps[this._stepIdx].setup(this._observer);
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
this._harnessTest.step(() => {
|
||||||
|
assert_unreached("Caught a throw, possible syntax error");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_handleNotification: function(entries) {
|
||||||
|
if (this._timeoutId) {
|
||||||
|
window.clearTimeout(this._timeoutId);
|
||||||
|
delete this._timeoutId;
|
||||||
|
}
|
||||||
|
this._harnessTest.step(() => {
|
||||||
|
try {
|
||||||
|
let rafDelay = this._currentStep.notify(entries, this._observer);
|
||||||
|
if (rafDelay)
|
||||||
|
window.requestAnimationFrame(this._nextStepBind);
|
||||||
|
else
|
||||||
|
this._nextStep();
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
this._harnessTest.step(() => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
// Force to _done() the current test.
|
||||||
|
this._done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_handleTimeout: function() {
|
||||||
|
delete this._timeoutId;
|
||||||
|
this._harnessTest.step(() => {
|
||||||
|
if (this._currentStep.timeout) {
|
||||||
|
this._currentStep.timeout();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._harnessTest.step(() => {
|
||||||
|
assert_unreached("Timed out waiting for notification. (" + ResizeTestHelper.TIMEOUT + "ms)");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this._nextStep();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_done: function() {
|
||||||
|
this._observer.disconnect();
|
||||||
|
delete this._observer;
|
||||||
|
this._harnessTest.done();
|
||||||
|
if (this._rafCountRequest) {
|
||||||
|
window.cancelAnimationFrame(this._rafCountRequest);
|
||||||
|
delete this._rafCountRequest;
|
||||||
|
}
|
||||||
|
window.requestAnimationFrame(() => { this._resolvePromise(); });
|
||||||
|
},
|
||||||
|
|
||||||
|
start: function(cleanup) {
|
||||||
|
this._harnessTest = async_test(this._name);
|
||||||
|
|
||||||
|
if (cleanup) {
|
||||||
|
this._harnessTest.add_cleanup(cleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._harnessTest.step(() => {
|
||||||
|
assert_equals(this._stepIdx, -1, "start can only be called once");
|
||||||
|
this._nextStep();
|
||||||
|
});
|
||||||
|
return new Promise( (resolve, reject) => {
|
||||||
|
this._resolvePromise = resolve;
|
||||||
|
this._rejectPromise = reject;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
get rafCount() {
|
||||||
|
if (!this._rafCountRequest)
|
||||||
|
throw "rAF count is not active";
|
||||||
|
return this._rafCount;
|
||||||
|
},
|
||||||
|
|
||||||
|
get test() {
|
||||||
|
if (!this._harnessTest) {
|
||||||
|
throw "_harnessTest is not initialized";
|
||||||
|
}
|
||||||
|
return this._harnessTest;
|
||||||
|
},
|
||||||
|
|
||||||
|
_incrementRaf: function() {
|
||||||
|
if (this._rafCountRequest) {
|
||||||
|
this._rafCount++;
|
||||||
|
this._rafCountRequest = window.requestAnimationFrame(this._incrementRafBind);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
startCountingRaf: function() {
|
||||||
|
if (this._rafCountRequest)
|
||||||
|
window.cancelAnimationFrame(this._rafCountRequest);
|
||||||
|
if (!this._incrementRafBind)
|
||||||
|
this._incrementRafBind = this._incrementRaf.bind(this);
|
||||||
|
this._rafCount = 0;
|
||||||
|
this._rafCountRequest = window.requestAnimationFrame(this._incrementRafBind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAndAppendElement(tagName, parent) {
|
||||||
|
if (!parent) {
|
||||||
|
parent = document.body;
|
||||||
|
}
|
||||||
|
const element = document.createElement(tagName);
|
||||||
|
parent.appendChild(element);
|
||||||
|
return element;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue