summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/resize-observer/resources
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/resize-observer/resources
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/resize-observer/resources')
-rw-r--r--testing/web-platform/tests/resize-observer/resources/iframe.html38
-rw-r--r--testing/web-platform/tests/resize-observer/resources/image.pngbin0 -> 170 bytes
-rw-r--r--testing/web-platform/tests/resize-observer/resources/resizeTestHelper.js195
3 files changed, 233 insertions, 0 deletions
diff --git a/testing/web-platform/tests/resize-observer/resources/iframe.html b/testing/web-platform/tests/resize-observer/resources/iframe.html
new file mode 100644
index 0000000000..5c801e6368
--- /dev/null
+++ b/testing/web-platform/tests/resize-observer/resources/iframe.html
@@ -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>
diff --git a/testing/web-platform/tests/resize-observer/resources/image.png b/testing/web-platform/tests/resize-observer/resources/image.png
new file mode 100644
index 0000000000..51741584a0
--- /dev/null
+++ b/testing/web-platform/tests/resize-observer/resources/image.png
Binary files differ
diff --git a/testing/web-platform/tests/resize-observer/resources/resizeTestHelper.js b/testing/web-platform/tests/resize-observer/resources/resizeTestHelper.js
new file mode 100644
index 0000000000..284a780c25
--- /dev/null
+++ b/testing/web-platform/tests/resize-observer/resources/resizeTestHelper.js
@@ -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;
+}