chromium/third_party/blink/web_tests/wpt_internal/webusb/usbDevice-iframe.https.html

<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/test-only-api.js"></script>
<script src="/webusb/resources/fake-devices.js"></script>
<script src="/webusb/resources/usb-helpers.js"></script>
<body>
<script>
'use strict';

async function getDetachedUsbDevice() {
  let iframe = document.createElement('iframe');
  iframe.src = '/webusb/resources/open-in-iframe.html';
  document.body.appendChild(iframe);

  await navigator.usb.test.attachToContext(iframe);

  navigator.usb.test.addFakeDevice(fakeDeviceInit);
  const devices = await iframe.contentWindow.navigator.usb.getDevices();

  assert_equals(devices.length, 1);
  document.body.removeChild(iframe);
  // Set iframe to null to ensure that the GC cleans up as much as possible.
  iframe = null;
  GCController.collect();
  return devices[0];
}

usb_test(() => {
  return navigator.usb.test.initialize().then(() => {
    return new Promise(async (resolve, reject) => {
      let iframe = document.createElement('iframe');
      iframe.src = '/webusb/resources/open-in-iframe.html';
      document.body.appendChild(iframe);
      await navigator.usb.test.attachToContext(iframe);

      window.onmessage = messageEvent => {
        if (messageEvent.data == 'Ready') {
          document.body.removeChild(iframe);
          GCController.collect();
          navigator.usb.test.addFakeDevice(fakeDeviceInit);
          resolve();
        } else {
          reject(messageEvent.data);
        }
      };

      iframe.contentWindow.postMessage('ConnectEvent', '*');
    });
  });
}, 'events are not delivered to detached frames');

usb_test(async (t) => {
  const device = await getDetachedUsbDevice();
  try {
    await device.forget();
    assert_unreached();
  } catch (e) {
    // Cannot use promise_rejects_dom() because |e| is thrown from a different
    // global.
    assert_equals(e.name, 'NotSupportedError');
  }
}, 'forget() rejects in a detached context');
</script>
</body>