diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/compute-pressure | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/compute-pressure')
31 files changed, 1156 insertions, 0 deletions
diff --git a/testing/web-platform/tests/compute-pressure/README.md b/testing/web-platform/tests/compute-pressure/README.md new file mode 100644 index 0000000000..05bacb7f16 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/README.md @@ -0,0 +1,2 @@ +This directory contains (tentative) tests for the +[Compute Pressure](https://wicg.github.io/compute-pressure/) specification. diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_basic.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_basic.tentative.https.window.js new file mode 100644 index 0000000000..2f463e502b --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_basic.tentative.https.window.js @@ -0,0 +1,9 @@ +'use strict'; + +promise_test(async t => { + await new Promise((resolve, reject) => { + const observer = new PressureObserver(resolve, {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + observer.observe('cpu').catch(reject); + }); +}, 'An active PressureObserver calls its callback at least once'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_basic_async.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_basic_async.tentative.https.window.js new file mode 100644 index 0000000000..3a9a32dedc --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_basic_async.tentative.https.window.js @@ -0,0 +1,88 @@ +// META: timeout=long +// META: script=/resources/test-only-api.js +// META: script=resources/pressure-helpers.js + +'use strict'; + +pressure_test((t, mockPressureService) => { + const observer = new PressureObserver(() => { + assert_unreached('The observer callback should not be called'); + }); + + mockPressureService.setExpectedFailure( + new DOMException('', 'NotSupportedError')); + return promise_rejects_dom(t, 'NotSupportedError', observer.observe('cpu')); +}, 'Return NotSupportedError when calling observer()'); + +pressure_test(async (t, mockPressureService) => { + const changes = await new Promise(resolve => { + const observer = new PressureObserver(resolve); + observer.observe('cpu'); + mockPressureService.setPressureUpdate('critical'); + mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); + }); + assert_true(changes.length === 1); + assert_equals(changes[0].state, 'critical'); + assert_equals(changes[0].source, 'cpu'); + assert_equals(typeof changes[0].time, 'number'); +}, 'Basic functionality test'); + +pressure_test((t, mockPressureService) => { + const observer = new PressureObserver(() => { + assert_unreached('The observer callback should not be called'); + }); + + const promise = observer.observe('cpu'); + observer.unobserve('cpu'); + mockPressureService.setPressureUpdate('critical'); + mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); + + return promise_rejects_dom(t, 'NotSupportedError', promise); +}, 'Removing observer before observe() resolves works'); + +pressure_test(async (t, mockPressureService) => { + const callbackPromises = []; + const observePromises = []; + + for (let i = 0; i < 2; i++) { + callbackPromises.push(new Promise(resolve => { + const observer = new PressureObserver(resolve); + observePromises.push(observer.observe('cpu')); + })); + } + + await Promise.all(observePromises); + + mockPressureService.setPressureUpdate('critical'); + mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); + + return Promise.all(callbackPromises); +}, 'Calling observe() multiple times works'); + +pressure_test(async (t, mockPressureService) => { + const observer1_changes = []; + await new Promise(resolve => { + const observer1 = new PressureObserver(changes => { + observer1_changes.push(changes); + resolve(); + }); + t.add_cleanup(() => observer1.disconnect()); + observer1.observe('cpu'); + mockPressureService.setPressureUpdate('critical'); + mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); + }); + assert_true(observer1_changes.length === 1); + assert_equals(observer1_changes[0][0].state, 'critical'); + + const observer2_changes = []; + await new Promise(resolve => { + const observer2 = new PressureObserver(changes => { + observer2_changes.push(changes); + resolve(); + }); + t.add_cleanup(() => observer2.disconnect()); + observer2.observe('cpu'); + }); + assert_true(observer2_changes.length === 1); + assert_equals(observer2_changes[0][0].state, 'critical'); +}, 'Starting a new observer after an observer has started works'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_detached_iframe.tentative.https.html b/testing/web-platform/tests/compute-pressure/compute_pressure_detached_iframe.tentative.https.html new file mode 100644 index 0000000000..3b0a5504e5 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_detached_iframe.tentative.https.html @@ -0,0 +1,97 @@ +<!doctype html> +<meta charset="utf-8"> +<title>PressureObserver on DOMWindow of detached iframe</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> +'use strict'; + +test(() => { + const iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + const frame_window = iframe.contentWindow; + + iframe.remove(); + assert_equals(undefined, frame_window.PressureObserver); +}, 'PressureObserver constructor does not exist in detached iframes'); + +promise_test(async t => { + const iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + const frame_window = iframe.contentWindow; + + const observer = new frame_window.PressureObserver( + () => {}, + {sampleRate: 1}); + const iframe_DOMException = frame_window.DOMException; + + iframe.remove(); + + // Calling observe() from a detached iframe should fail but not crash. + await promise_rejects_dom(t, 'NotSupportedError', iframe_DOMException, + observer.observe('cpu')); +}, 'PressureObserver.observe() on detached frame rejects'); + +promise_test(async t => { + const iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + const frame_window = iframe.contentWindow; + + const observer = new frame_window.PressureObserver( + () => {}, + {sampleRate: 1}); + + await observer.observe('cpu'); + + iframe.remove(); + + // Calling disconnect() from a detached iframe should not crash. + observer.disconnect(); +}, 'PressureObserver.disconnect() on detached frame returns'); + +promise_test(async t => { + const iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + const frame_window = iframe.contentWindow; + + const observer = new frame_window.PressureObserver( + () => {}, + {sampleRate: 1}); + const iframe_DOMException = frame_window.DOMException; + + // await is intentionally not used here. We want to remove the iframe while + // the returned Promise settles. + const observe_promise = observer.observe('cpu'); + iframe.remove(); + + // Establish an observer and wait for changes in the main frame. This should + // keep the test running long enough to catch any crash from the observe() + // call in the removed iframe's PressureObserver. + const changes = await new Promise((resolve, reject) => { + const observer = new PressureObserver( + resolve, {sampleRate: 1}); + t.add_cleanup(() => observer.disconnect()); + observer.observe('cpu').catch(reject); + }); + assert_in_array(changes[0].state, ['nominal', 'fair', 'serious', 'critical'], + 'cpu pressure state'); +}, 'Detaching frame while PressureObserver.observe() settles'); + +promise_test(async t => { + const iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + const frame_window = iframe.contentWindow; + const observer = new frame_window.PressureObserver(() => { + assert_unreached('The observer callback should not be called'); + }, {sampleRate: 1}); + + await observer.observe('cpu'); + + iframe.remove(); + + return new Promise(resolve => t.step_timeout(resolve, 1000)); +}, 'PressureObserver on detached frame returns with no callback'); + +</script> +</body> diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_disconnect.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_disconnect.tentative.https.window.js new file mode 100644 index 0000000000..c9950f2dc8 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_disconnect.tentative.https.window.js @@ -0,0 +1,40 @@ +'use strict'; + +test(t => { + const observer = new PressureObserver(() => { + assert_unreached('The observer callback should not be called'); + }); + t.add_cleanup(() => observer.disconnect()); + observer.disconnect(); +}, 'Call disconnect() directly should not crash'); + +promise_test(async t => { + const observer1_changes = []; + const observer1 = new PressureObserver(change => { + observer1_changes.push(change); + }, {sampleRate: 1.0}); + t.add_cleanup(() => observer1.disconnect()); + // Ensure that observer1's schema gets registered before observer2 starts. + await observer1.observe('cpu'); + observer1.disconnect(); + + const observer2_changes = []; + await new Promise((resolve, reject) => { + const observer2 = new PressureObserver(change => { + observer2_changes.push(change); + resolve(); + }, {sampleRate: 1.0}); + t.add_cleanup(() => observer2.disconnect()); + observer2.observe('cpu').catch(reject); + }); + + assert_equals( + observer1_changes.length, 0, + 'disconnected observers should not receive callbacks'); + + assert_equals(observer2_changes.length, 1); + assert_equals(observer2_changes[0].length, 1); + assert_in_array( + observer2_changes[0][0].state, ['nominal', 'fair', 'serious', 'critical'], + 'cpu pressure state'); +}, 'Stopped PressureObserver do not receive changes'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_disconnect_idempotent.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_disconnect_idempotent.tentative.https.window.js new file mode 100644 index 0000000000..72021fd270 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_disconnect_idempotent.tentative.https.window.js @@ -0,0 +1,33 @@ +'use strict'; + +promise_test(async t => { + const observer1_changes = []; + const observer1 = new PressureObserver(changes => { + observer1_changes.push(changes); + }, {sampleRate: 1}); + t.add_cleanup(() => observer1.disconnect()); + // Ensure that observer1's schema gets registered before observer2 starts. + const promise = observer1.observe('cpu'); + observer1.disconnect(); + observer1.disconnect(); + await promise_rejects_dom(t, 'NotSupportedError', promise); + + const observer2_changes = []; + await new Promise((resolve, reject) => { + const observer2 = new PressureObserver(changes => { + observer2_changes.push(changes); + resolve(); + }, {sampleRate: 1}); + t.add_cleanup(() => observer2.disconnect()); + observer2.observe('cpu').catch(reject); + }); + + assert_equals( + observer1_changes.length, 0, + 'stopped observers should not receive callbacks'); + + assert_equals(observer2_changes.length, 1); + assert_in_array( + observer2_changes[0][0].state, ['nominal', 'fair', 'serious', 'critical'], + 'cpu pressure state'); +}, 'Stopped PressureObserver do not receive changes'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_disconnect_immediately.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_disconnect_immediately.tentative.https.window.js new file mode 100644 index 0000000000..1abe84d572 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_disconnect_immediately.tentative.https.window.js @@ -0,0 +1,63 @@ +'use strict'; + +promise_test(async t => { + const observer1_changes = []; + const observer1 = new PressureObserver(changes => { + observer1_changes.push(changes); + }, {sampleRate: 1.0}); + t.add_cleanup(() => observer1.disconnect()); + // Ensure that observer1's schema gets registered before observer2 starts. + const promise = observer1.observe('cpu'); + observer1.disconnect(); + await promise_rejects_dom(t, 'NotSupportedError', promise); + + const observer2_changes = []; + await new Promise((resolve, reject) => { + const observer2 = new PressureObserver(changes => { + observer2_changes.push(changes); + resolve(); + }, {sampleRate: 1.0}); + t.add_cleanup(() => observer2.disconnect()); + observer2.observe('cpu').catch(reject); + }); + + assert_equals( + observer1_changes.length, 0, + 'stopped observers should not receive callbacks'); + + assert_equals(observer2_changes.length, 1); + assert_equals(observer2_changes[0].length, 1); + assert_in_array( + observer2_changes[0][0].state, ['nominal', 'fair', 'serious', 'critical'], + 'cpu pressure state'); +}, 'Stopped PressureObserver do not receive changes'); + +promise_test(async t => { + const observer1_changes = []; + const observer1 = new PressureObserver(changes => { + observer1_changes.push(changes); + }, {sampleRate: 1}); + t.add_cleanup(() => observer1.disconnect()); + + const observer2_changes = []; + await new Promise(async resolve => { + const observer2 = new PressureObserver(changes => { + observer2_changes.push(changes); + resolve(); + }, {sampleRate: 1}); + t.add_cleanup(() => observer2.disconnect()); + const promise = observer1.observe('cpu'); + observer2.observe('cpu'); + observer1.disconnect(); + await promise_rejects_dom(t, 'NotSupportedError', promise); + }); + + assert_equals( + observer1_changes.length, 0, + 'stopped observers should not receive callbacks'); + + assert_equals(observer2_changes.length, 1); + assert_in_array( + observer2_changes[0][0].state, ['nominal', 'fair', 'serious', 'critical'], + 'cpu pressure state'); +}, 'Removing observer before observe() resolves does not affect other observers'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_duplicate_updates.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_duplicate_updates.tentative.https.window.js new file mode 100644 index 0000000000..3c312ca5b1 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_duplicate_updates.tentative.https.window.js @@ -0,0 +1,61 @@ +// META: script=/resources/test-only-api.js +// META: script=resources/pressure-helpers.js + +'use strict'; + +pressure_test(async (t, mockPressureService) => { + const pressureChanges = await new Promise(async resolve => { + const observer_changes = []; + let n = 0; + const observer = new PressureObserver(changes => { + observer_changes.push(changes); + if (++n === 2) + resolve(observer_changes); + }, {sampleRate: 5.0}); + observer.observe('cpu'); + const updatesDelivered = mockPressureService.updatesDelivered(); + mockPressureService.setPressureUpdate('critical'); + mockPressureService.startPlatformCollector(/*sampleRate*/ 5.0); + // Deliver 2 updates. + await t.step_wait( + () => mockPressureService.updatesDelivered() >= (updatesDelivered + 2), + 'Wait for more than one update to be delivered to the observer'); + mockPressureService.setPressureUpdate('nominal'); + // Deliver more updates, |resolve()| will be called when the new pressure + // state reaches PressureObserver and its callback is invoked + // for the second time. + }); + assert_equals(pressureChanges.length, 2); + assert_equals(pressureChanges[0][0].state, 'critical'); + assert_equals(pressureChanges[1][0].state, 'nominal'); +}, 'Changes that fail the "has change in data" test are discarded.'); + +pressure_test(async (t, mockPressureService) => { + const pressureChanges = await new Promise(async resolve => { + const observer_changes = []; + let n = 0; + const observer = new PressureObserver(changes => { + observer_changes.push(changes); + if (++n === 2) + resolve(observer_changes); + }, {sampleRate: 5.0}); + observer.observe('cpu'); + const updatesDelivered = mockPressureService.updatesDelivered(); + mockPressureService.setPressureUpdate('critical', ['thermal']); + mockPressureService.startPlatformCollector(/*sampleRate*/ 5.0); + + // Deliver 2 updates. + await t.step_wait( + () => mockPressureService.updatesDelivered() >= (updatesDelivered + 2), + 'Wait for more than one update to be delivered to the observer'); + mockPressureService.setPressureUpdate('critical', ['power-supply']); + // Deliver more updates, |resolve()| will be called when the new pressure + // state reaches PressureObserver and its callback is invoked + // for the second time. + }); + assert_equals(pressureChanges.length, 2); + assert_equals(pressureChanges[0][0].state, 'critical'); + assert_equals(pressureChanges[0][0].factors[0], 'thermal'); + assert_equals(pressureChanges[1][0].state, 'critical'); + assert_equals(pressureChanges[1][0].factors[0], 'power-supply'); +}, 'Factors that fail the "has change in data" test are discarded.'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_factors.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_factors.tentative.https.window.js new file mode 100644 index 0000000000..6d8d220888 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_factors.tentative.https.window.js @@ -0,0 +1,18 @@ +// META: script=/resources/test-only-api.js +// META: script=resources/pressure-helpers.js + +'use strict'; + +pressure_test(async (t, mockPressureService) => { + const changes = await new Promise(resolve => { + const observer = new PressureObserver(resolve, {sampleRate: 1.0}); + observer.observe('cpu'); + mockPressureService.setPressureUpdate('critical', ['thermal']); + mockPressureService.startPlatformCollector(/*sampleRate=*/ 1.0); + }); + assert_true(changes.length === 1); + assert_equals(changes[0].state, 'critical'); + assert_equals(changes[0].source, 'cpu'); + assert_equals(typeof changes[0].time, 'number'); + assert_equals(changes[0].factors[0], 'thermal'); +}, 'Basic factors functionality test'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_multiple.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_multiple.tentative.https.window.js new file mode 100644 index 0000000000..6015ae1f81 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_multiple.tentative.https.window.js @@ -0,0 +1,30 @@ +'use strict'; + +promise_test(async t => { + const changes1_promise = new Promise((resolve, reject) => { + const observer = new PressureObserver(resolve, {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + observer.observe('cpu').catch(reject); + }); + + const changes2_promise = new Promise((resolve, reject) => { + const observer = new PressureObserver(resolve, {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + observer.observe('cpu').catch(reject); + }); + + const changes3_promise = new Promise((resolve, reject) => { + const observer = new PressureObserver(resolve, {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + observer.observe('cpu').catch(reject); + }); + + const [changes1, changes2, changes3] = + await Promise.all([changes1_promise, changes2_promise, changes3_promise]); + + for (const changes of [changes1, changes2, changes3]) { + assert_in_array( + changes[0].state, ['nominal', 'fair', 'serious', 'critical'], + 'cpu pressure state'); + } +}, 'Three PressureObserver instances receive changes'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_multiple_across_iframes.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_multiple_across_iframes.tentative.https.window.js new file mode 100644 index 0000000000..838b9a17a0 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_multiple_across_iframes.tentative.https.window.js @@ -0,0 +1,40 @@ +'use strict'; + +promise_test(async t => { + const changes1_promise = new Promise((resolve, reject) => { + const observer = new PressureObserver(resolve, {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + observer.observe('cpu').catch(reject); + }); + + // iframe numbers are aligned with observer numbers. The first observer is + // in the main frame, so there is no iframe1. + const iframe2 = document.createElement('iframe'); + document.body.appendChild(iframe2); + + const changes2_promise = new Promise((resolve, reject) => { + const observer = + new iframe2.contentWindow.PressureObserver(resolve, {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + observer.observe('cpu').catch(reject); + }); + + const iframe3 = document.createElement('iframe'); + document.body.appendChild(iframe3); + + const changes3_promise = new Promise((resolve, reject) => { + const observer = + new iframe3.contentWindow.PressureObserver(resolve, {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + observer.observe('cpu').catch(reject); + }); + + const [changes1, changes2, changes3] = + await Promise.all([changes1_promise, changes2_promise, changes3_promise]); + + for (const changes of [changes1, changes2, changes3]) { + assert_in_array( + changes[0].state, ['nominal', 'fair', 'serious', 'critical'], + 'cpu pressure state'); + } +}, 'Three PressureObserver instances, in different iframes, receive changes'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_observe_idempotent.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_observe_idempotent.tentative.https.window.js new file mode 100644 index 0000000000..e60115fee8 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_observe_idempotent.tentative.https.window.js @@ -0,0 +1,16 @@ +'use strict'; + +promise_test(async t => { + const update = await new Promise((resolve, reject) => { + const observer = new PressureObserver(resolve, {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + observer.observe('cpu').catch(reject); + observer.observe('cpu').catch(reject); + observer.observe('cpu').catch(reject); + }); + + assert_equals(typeof update[0].state, 'string'); + assert_in_array( + update[0].state, ['nominal', 'fair', 'serious', 'critical'], + 'cpu pressure state'); +}, 'PressureObserver.observe() is idempotent'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_observe_unobserve_failure.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_observe_unobserve_failure.tentative.https.window.js new file mode 100644 index 0000000000..c32649da5c --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_observe_unobserve_failure.tentative.https.window.js @@ -0,0 +1,17 @@ +'use strict'; + +promise_test(async t => { + const observer = new PressureObserver( + t.unreached_func('oops should not end up here'), {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + await promise_rejects_js(t, TypeError, observer.observe('random')); +}, 'PressureObserver.observe() requires a valid source'); + +test(t => { + const observer = new PressureObserver( + t.unreached_func('oops should not end up here'), {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + assert_throws_js(TypeError, () => { + observer.unobserve('random'); + }); +}, 'PressureObserver.unobserve() requires a valid source'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_options.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_options.tentative.https.window.js new file mode 100644 index 0000000000..d142ecc088 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_options.tentative.https.window.js @@ -0,0 +1,23 @@ +'use strict'; + +test(t => { + assert_throws_js(RangeError, () => { + new PressureObserver(() => {}, {sampleRate: 0}); + }); +}, 'PressureObserver constructor requires a non-zero sampleRate'); + +test(t => { + assert_throws_js(RangeError, () => { + new PressureObserver(() => {}, {sampleRate: -2}); + }); +}, 'PressureObserver constructor requires a positive sampleRate'); + +test(t => { + const observer = new PressureObserver(() => {}, {sampleRate: 0.5}); + assert_equals(typeof observer, 'object'); +}, 'PressureObserver constructor doesnt throw error on positive sampleRate'); + +test(t => { + const observer = new PressureObserver(() => {}, {}); + assert_equals(typeof observer, 'object'); +}, 'PressureObserver constructor succeeds on empty sampleRate'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_privacy_test.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_privacy_test.tentative.https.window.js new file mode 100644 index 0000000000..3a4198f547 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_privacy_test.tentative.https.window.js @@ -0,0 +1,130 @@ +// META: timeout=long +// META: script=/common/get-host-info.sub.js +// META: script=/common/media.js +// META: script=/mediacapture-streams/permission-helper.js +// META: script=/picture-in-picture/resources/picture-in-picture-helpers.js +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js + +'use strict'; + +promise_test(async t => { + const video = await loadVideo(); + document.body.appendChild(video); + const pipWindow = await requestPictureInPictureWithTrustedClick(video); + assert_not_equals(pipWindow.width, 0); + assert_not_equals(pipWindow.height, 0); + + const iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + // Focus on the iframe to make the main frame lose focus, so that + // PressureObserver in the main frame can't receive PressureRecord + // by default. However, if the main frame is the initiator of active + // Picture-in-Picture session, PressureObserver in the main frame can + // receive PressureRecord. + iframe.contentWindow.focus(); + + await new Promise(resolve => { + const observer = new PressureObserver(resolve); + t.add_cleanup(async () => { + observer.disconnect(); + iframe.remove(); + if (document.pictureInPictureElement) { + await document.exitPictureInPicture(); + } + video.remove(); + }); + observer.observe('cpu'); + }); +}, 'Observer should receive PressureRecord if associated document is the initiator of active Picture-in-Picture session'); + +promise_test(async t => { + await setMediaPermission(); + const stream = + await navigator.mediaDevices.getUserMedia({video: true, audio: true}); + assert_true(stream.active); + + const iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + // Focus on the iframe to make the main frame lose focus, so that + // PressureObserver in the main frame can't receive PressureRecord + // by default. However, if the main frame's browsing context is capturing, + // PressureObserver in the main frame can receive PressureRecord. + iframe.contentWindow.focus(); + + await new Promise(resolve => { + const observer = new PressureObserver(resolve); + t.add_cleanup(async () => { + observer.disconnect(); + iframe.remove(); + stream.getTracks().forEach(track => track.stop()); + }); + observer.observe('cpu'); + }); +}, 'Observer should receive PressureRecord if browsing context is capturing'); + +promise_test(async t => { + const iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + // Focus on the iframe to make the main frame lose focus, so that + // PressureObserver in the main frame can't receive PressureRecord + // by default. + iframe.contentWindow.focus(); + + const observer = new PressureObserver(() => { + assert_unreached('The observer callback should not be called'); + }); + t.add_cleanup(() => { + observer.disconnect(); + iframe.remove(); + }); + + return new Promise(resolve => t.step_timeout(resolve, 2000)); +}, 'Observer should not receive PressureRecord when top-level browsing context does not have system focus'); + +promise_test(async t => { + const iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + // Focus on the main frame to make the iframe lose focus, so that + // PressureObserver in the iframe can't receive PressureRecord by default. + // However, if the iframe is same-origin with the main frame and the main + // frame has focus, PressureObserver in iframe can receive PressureRecord. + window.focus(); + + await new Promise(resolve => { + const observer = new iframe.contentWindow.PressureObserver(resolve); + t.add_cleanup(() => { + observer.disconnect(); + iframe.remove(); + }); + observer.observe('cpu'); + }); +}, 'Observer in iframe should receive PressureRecord when focused on same-origin main frame'); + +promise_test(async t => { + const iframe = document.createElement('iframe'); + iframe.src = get_host_info().HTTPS_REMOTE_ORIGIN + + '/compute-pressure/resources/support-iframe.html'; + iframe.allow = 'compute-pressure'; + const iframeLoadWatcher = new EventWatcher(t, iframe, 'load'); + document.body.appendChild(iframe); + await iframeLoadWatcher.wait_for('load'); + // Focus on the main frame to make the iframe lose focus, so that + // PressureObserver in the iframe can't receive PressureRecord by default. + // If the main frame has focus, but the iframe is cross-origin with the main + // frame, PressureObserver in the iframe still can't receive PressureRecord. + window.focus(); + + return new Promise((resolve, reject) => { + window.addEventListener('message', (e) => { + if (e.data.result === 'timeout') { + resolve(); + } else if (e.data.result === 'success') { + reject('Observer should not receive PressureRecord'); + } else { + reject('Got unexpected reply'); + } + }, {once: true}); + iframe.contentWindow.postMessage({command: 'start'}, '*'); + }); +}, 'Observer in iframe should not receive PressureRecord when focused on cross-origin main frame'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_supported_sources.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_supported_sources.tentative.https.window.js new file mode 100644 index 0000000000..2a69e731e7 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_supported_sources.tentative.https.window.js @@ -0,0 +1,19 @@ +'use strict'; + +test(() => { + // Compute Pressure should support at least "cpu" + const sources = PressureObserver.supportedSources; + assert_in_array('cpu', sources); +}, 'PressureObserver should support at least "cpu"'); + +test(() => { + // Compute Pressure should be frozen array + const sources = PressureObserver.supportedSources; + assert_equals(sources, PressureObserver.supportedSources); +}, 'PressureObserver must return always the same array'); + +test(() => { + // Compute Pressure should be frozen array + let sources = PressureObserver.supportedSources; + assert_equals(Object.isFrozen(), true); +}, 'PressureObserver must return a frozen array'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_take_records.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_take_records.tentative.https.window.js new file mode 100644 index 0000000000..d294a7e80f --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_take_records.tentative.https.window.js @@ -0,0 +1,29 @@ +// META: script=/resources/test-only-api.js +// META: script=resources/pressure-helpers.js + +'use strict'; + +test(t => { + const observer = new PressureObserver( + t.unreached_func('This callback should not have been called.'), + {sampleRate: 1.0}); + + const records = observer.takeRecords(); + assert_equals(records.length, 0, 'No record before observe'); +}, 'Calling takeRecords() before observe()'); + +promise_test(async t => { + let observer; + const changes = await new Promise(resolve => { + observer = new PressureObserver(resolve, {sampleRate: 1.0}); + t.add_cleanup(() => observer.disconnect()); + + observer.observe('cpu'); + }); + assert_in_array( + changes[0].state, ['nominal', 'fair', 'serious', 'critical'], + 'cpu presure state'); + + const records = observer.takeRecords(); + assert_equals(records.length, 0, 'No record available'); +}, 'takeRecords() returns empty record after callback invoke'); diff --git a/testing/web-platform/tests/compute-pressure/compute_pressure_timestamp.tentative.https.window.js b/testing/web-platform/tests/compute-pressure/compute_pressure_timestamp.tentative.https.window.js new file mode 100644 index 0000000000..b9b932e64f --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/compute_pressure_timestamp.tentative.https.window.js @@ -0,0 +1,77 @@ +// META: script=/resources/test-only-api.js +// META: script=resources/pressure-helpers.js + +'use strict'; + +pressure_test(async (t, mockPressureService) => { + const readings = ['nominal', 'fair', 'serious', 'critical']; + + const sampleRate = 4.0; + const pressureChanges = await new Promise(async resolve => { + const observerChanges = []; + const observer = new PressureObserver(changes => { + observerChanges.push(changes); + }, {sampleRate}); + observer.observe('cpu'); + + mockPressureService.startPlatformCollector(sampleRate * 2); + let i = 0; + // mockPressureService.updatesDelivered() does not necessarily match + // pressureChanges.length, as system load and browser optimizations can + // cause the actual timer used by mockPressureService to deliver readings + // to be a bit slower or faster than requested. + while (observerChanges.length < 4) { + mockPressureService.setPressureUpdate(readings[i++ % readings.length]); + await t.step_wait( + () => mockPressureService.updatesDelivered() >= i, + `At least ${i} readings have been delivered`); + } + observer.disconnect(); + resolve(observerChanges); + }); + + assert_equals(pressureChanges.length, 4); + assert_greater_than_equal( + pressureChanges[1][0].time - pressureChanges[0][0].time, + (1 / sampleRate * 1000)); + assert_greater_than_equal( + pressureChanges[2][0].time - pressureChanges[1][0].time, + (1 / sampleRate * 1000)); + assert_greater_than_equal( + pressureChanges[3][0].time - pressureChanges[2][0].time, + (1 / sampleRate * 1000)); +}, 'Faster collector: Timestamp difference between two changes should be higher or equal to the observer sample rate'); + +pressure_test(async (t, mockPressureService) => { + const pressureChanges = []; + const sampleRate = 1.0; + const observer = new PressureObserver(changes => { + pressureChanges.push(changes); + }, {sampleRate}); + + await new Promise(async resolve => { + observer.observe('cpu'); + mockPressureService.setPressureUpdate('critical'); + mockPressureService.startPlatformCollector(sampleRate); + await t.step_wait(() => pressureChanges.length == 1); + observer.disconnect(); + resolve(); + }); + + await new Promise(async resolve => { + observer.observe('cpu'); + mockPressureService.setPressureUpdate('serious'); + mockPressureService.startPlatformCollector(sampleRate * 4); + await t.step_wait(() => pressureChanges.length == 2); + observer.disconnect(); + resolve(); + }); + + assert_equals(pressureChanges.length, 2); + // When disconnect() is called, PressureRecord in [[LastRecordMap]] for cpu + // should be deleted. So the second PressureRecord is not discarded even + // though the time interval does not meet the requirement. + assert_less_than( + pressureChanges[1][0].time - pressureChanges[0][0].time, + (1 / sampleRate * 1000)); +}, 'disconnect() should update [[LastRecordMap]]'); diff --git a/testing/web-platform/tests/compute-pressure/idlharness.https.window.js b/testing/web-platform/tests/compute-pressure/idlharness.https.window.js new file mode 100644 index 0000000000..1cdfb59be0 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/idlharness.https.window.js @@ -0,0 +1,14 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// https://wicg.github.io/compute-pressure/ + +'use strict'; + +idl_test(['compute-pressure'], ['dom', 'html'], async idl_array => { + idl_array.add_objects({ + PressureObserver: ['observer'], + }); + + self.observer = new PressureObserver(() => {}, {sampleRate: 1.0}); +}); diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy-attribute-redirect-on-load.https.html b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy-attribute-redirect-on-load.https.html new file mode 100644 index 0000000000..ec5b464461 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy-attribute-redirect-on-load.https.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/permissions-policy/resources/permissions-policy.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> +"use strict"; + +const relative_path = + '/permissions-policy/resources/permissions-policy-compute-pressure.html'; +const base_src = '/permissions-policy/resources/redirect-on-load.html#'; +const same_origin_src = base_src + relative_path; +const cross_origin_src = + base_src + get_host_info().HTTPS_REMOTE_ORIGIN + relative_path; +const header = 'permissions policy allow="compute-pressure"'; + +async_test(t => { + test_feature_availability( + 'PressureObserver.observe()', + t, + same_origin_src, + expect_feature_available_default, + 'compute-pressure' + ); +}, `${header} allows same-origin navigation in an iframe.`); + +async_test(t => { + test_feature_availability( + 'PressureObserver.observe()', + t, + cross_origin_src, + expect_feature_unavailable_default, + 'compute-pressure' + ); +}, `${header} disallows cross-origin navigation in an iframe.`); + +</script> +</body> diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy-attribute.https.html b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy-attribute.https.html new file mode 100644 index 0000000000..d6dfcfc191 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy-attribute.https.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/permissions-policy/resources/permissions-policy.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> +"use strict"; + +const same_origin_src = + '/permissions-policy/resources/permissions-policy-compute-pressure.html'; +const cross_origin_src = get_host_info().HTTPS_REMOTE_ORIGIN + same_origin_src; +const feature_name = 'permissions policy "compute-pressure"'; +const attribute = 'allow="compute-pressure" attribute'; + +async_test(t => { + test_feature_availability( + 'PressureObserver.observe()', + t, + same_origin_src, + expect_feature_available_default, + 'compute-pressure' + ); +}, `${feature_name} can be enabled in same-origin iframe using ${attribute}`); + +async_test(t => { + test_feature_availability( + 'PressureObserver.observe()', + t, + cross_origin_src, + expect_feature_available_default, + 'compute-pressure' + ); +}, `${feature_name} can be enabled in cross-origin iframe using ${attribute}`); + +</script> +</body> diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy.https.html b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy.https.html new file mode 100644 index 0000000000..1651f72612 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy.https.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/permissions-policy/resources/permissions-policy.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> +"use strict"; + +const same_origin_src = + '/permissions-policy/resources/permissions-policy-compute-pressure.html'; +const cross_origin_src = get_host_info().HTTPS_REMOTE_ORIGIN + same_origin_src; +const header = 'permissions policy header "compute-pressure=*"'; +const attribute = 'allow="compute-pressure" attribute'; + +promise_test(async () => { + try { + const observer = new PressureObserver(() => {}); + await observer.observe("cpu"); + observer.disconnect(); + } catch (e) { + assert_unreached("expected promise to resolve."); + } +}, `${header} allows the top-level document.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + same_origin_src, + expect_feature_available_default + ); +}, `${header} allows same-origin iframes.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + cross_origin_src, + expect_feature_unavailable_default + ); +}, `${header} disallows cross-origin iframes.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + cross_origin_src, + expect_feature_available_default, + 'compute-pressure' + ); +}, `${header} allows cross-origin iframes with ${attribute}.`); + +</script> +</body> diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy.https.html.headers b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy.https.html.headers new file mode 100644 index 0000000000..76185cbb2d --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-by-permissions-policy.https.html.headers @@ -0,0 +1 @@ +Permissions-Policy: compute-pressure=* diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-on-self-origin-by-permissions-policy.https.html b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-on-self-origin-by-permissions-policy.https.html new file mode 100644 index 0000000000..98450b91a7 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-on-self-origin-by-permissions-policy.https.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/permissions-policy/resources/permissions-policy.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> +"use strict"; + +const same_origin_src = + '/permissions-policy/resources/permissions-policy-compute-pressure.html'; +const cross_origin_src = get_host_info().HTTPS_REMOTE_ORIGIN + same_origin_src; +const header = 'permissions policy header "compute-pressure=self"'; + +promise_test(async () => { + try { + const observer = new PressureObserver(() => {}); + await observer.observe("cpu"); + observer.disconnect(); + } catch (e) { + assert_unreached('expected promise to resolve.'); + } +}, `${header} allows the top-level document.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + same_origin_src, + expect_feature_available_default + ); +}, `${header} allows same-origin iframes.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + cross_origin_src, + expect_feature_unavailable_default + ); +}, `${header} disallows cross-origin iframes.`); + +</script> +</body> diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-on-self-origin-by-permissions-policy.https.html.headers b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-on-self-origin-by-permissions-policy.https.html.headers new file mode 100644 index 0000000000..6852f871bb --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-allowed-on-self-origin-by-permissions-policy.https.html.headers @@ -0,0 +1 @@ +Permissions-Policy: compute-pressure=self diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-default-permissions-policy.https.html b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-default-permissions-policy.https.html new file mode 100644 index 0000000000..5a7c77264e --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-default-permissions-policy.https.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/permissions-policy/resources/permissions-policy.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> +"use strict"; + +const same_origin_src = + '/permissions-policy/resources/permissions-policy-compute-pressure.html'; +const cross_origin_src = get_host_info().HTTPS_REMOTE_ORIGIN + same_origin_src; +const header = 'Default "compute-pressure" permissions policy'; + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + same_origin_src, + expect_feature_available_default + ); +}, `${header} allows same-origin iframes.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + cross_origin_src, + expect_feature_unavailable_default + ); +}, `${header} disallows cross-origin iframes.`); + +</script> +</body> diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-disabled-by-permissions-policy.https.html b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-disabled-by-permissions-policy.https.html new file mode 100644 index 0000000000..58b044247c --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-disabled-by-permissions-policy.https.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/permissions-policy/resources/permissions-policy.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> +"use strict"; + +const same_origin_src = + '/permissions-policy/resources/permissions-policy-compute-pressure.html'; +const cross_origin_src = get_host_info().HTTPS_REMOTE_ORIGIN + same_origin_src; +const header = 'permissions policy header "compute-pressure=()"'; +const attribute = 'allow="compute-pressure" attribute'; + +promise_test(async t => { + const observer = new PressureObserver( + t.unreached_func('oops should not end up here') + ); + await promise_rejects_dom(t, 'NotAllowedError', observer.observe("cpu")); +}, `${header} disallows the top-level document.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + same_origin_src, + expect_feature_unavailable_default + ); +}, `${header} disallows same-origin iframes.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + cross_origin_src, + expect_feature_unavailable_default + ); +}, `${header} disallows cross-origin iframes.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + same_origin_src, + expect_feature_unavailable_default, + 'compute-pressure' + ); +}, `${header} disallows same-origin iframes despite the ${attribute}.`); + +async_test(t => { + test_feature_availability( + 'ComputePressure.observe()', + t, + cross_origin_src, + expect_feature_unavailable_default, + 'compute-pressure' + ); +}, `${header} disallows cross-origin iframes despite the ${attribute}.`); + +</script> +</body> diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-disabled-by-permissions-policy.https.html.headers b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-disabled-by-permissions-policy.https.html.headers new file mode 100644 index 0000000000..2e9f2ecce0 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-disabled-by-permissions-policy.https.html.headers @@ -0,0 +1 @@ +Permissions-Policy: compute-pressure=() diff --git a/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-supported-by-permissions-policy.html b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-supported-by-permissions-policy.html new file mode 100644 index 0000000000..931fcb66b4 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/permissions-policy/compute-pressure-supported-by-permissions-policy.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<title>Test that compute-pressure is advertised in the feature list</title> +<link rel="help" href="https://w3c.github.io/webappsec-permissions-policy/#dom-permissions-policy-features"> +<link rel="help" href="https://wicg.github.io/compute-pressure/#policy-control"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +test(() => { + assert_in_array('compute-pressure', document.featurePolicy.features()); +}, 'document.featurePolicy.features should advertise compute-pressure.'); +</script> diff --git a/testing/web-platform/tests/compute-pressure/resources/pressure-helpers.js b/testing/web-platform/tests/compute-pressure/resources/pressure-helpers.js new file mode 100644 index 0000000000..5234cf2d78 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/resources/pressure-helpers.js @@ -0,0 +1,35 @@ +'use strict'; + +// These tests rely on the User Agent providing an implementation of +// platform compute pressure backends. +// +// In Chromium-based browsers this implementation is provided by a polyfill +// in order to reduce the amount of test-only code shipped to users. To enable +// these tests the browser must be run with these options: +// +// --enable-blink-features=MojoJS,MojoJSTest + +let mockPressureService = undefined; + +function pressure_test(func, name, properties) { + promise_test(async t => { + if (mockPressureService === undefined) { + if (isChromiumBased) { + const mocks = + await import('/resources/chromium/mock-pressure-service.js'); + mockPressureService = mocks.mockPressureService; + } + } + assert_implements( + mockPressureService, + 'missing mockPressureService after initialization'); + + mockPressureService.start(); + + t.add_cleanup(() => { + mockPressureService.reset(); + return mockPressureService.stop(); + }); + return func(t, mockPressureService); + }, name, properties); +} diff --git a/testing/web-platform/tests/compute-pressure/resources/support-iframe.html b/testing/web-platform/tests/compute-pressure/resources/support-iframe.html new file mode 100644 index 0000000000..57e18b77f6 --- /dev/null +++ b/testing/web-platform/tests/compute-pressure/resources/support-iframe.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<meta charset="utf-8"> +<title>compute pressure iframe tester</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +async function messageHandler(e) { + if (e.data.command === 'start') { + return new Promise((resolve, reject) => { + const observer = new PressureObserver(()=> { + resolve('success'); + }); + observer.observe('cpu'); + window.setTimeout(() => { reject('timeout'); }, 2000); + }); + } else { + return Promise.reject(`unknown command "${e.data.command}"`); + } +} + +window.onmessage = async (e) => { + let reply; + try { + reply = await messageHandler(e); + } catch (error) { + reply = error; + } + e.source.postMessage({ command: e.data.command, result: reply }, '*'); +} +</script> |