| <!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> |