chromium/content/test/data/gpu/webgpu-domain-unblocking.html

<script type="text/javascript">

function reportProgress(msg) {
  if (window.domAutomationController) {
    window.domAutomationController.send(msg);
  }
  console.log(msg);
}

// These must be "var" rather than "let" for the Telemetry harness to
// see them.
var gotDevice;
var deviceLost;
var proceed;

const later = (delay) =>
  new Promise(resolve => setTimeout(resolve, delay));

async function init() {
  reportProgress('LOADED');

  // This bakes in knowledge that GpuDataManagerImplPrivate blocks
  // WebGPU from fetching an adapter after two device losses on the
  // same domain.

  for (idx = 0; idx < 2; ++idx) {
    proceed = false;
    const adapter = await navigator.gpu.requestAdapter();
    if (!adapter) {
      reportProgress('FAILED');
      console.log('TEST FAILED - Could not get a GPUAdapter on iteration ' + idx);
      return null;
    }

    console.log('Iteration ' + idx + ': got adapter');

    let device;
    try {
      device = await adapter.requestDevice();
      gotDevice = true;
      deviceLost = false;
    } catch {
      reportProgress('FAILED');
      console.log('TEST FAILED - Could not get a GPUDevice on iteration ' + idx);
      return null;
    }

    console.log('Iteration ' + idx + ': got device');

    // The test runner forces the GPU process to crash. The second time,
    // this should result in the domain being blocked.
    console.log('Iteration ' + idx + ': Waiting for GPU crash to cause device loss');
    const lost = await device.lost;
    if (lost.reason !== 'unknown') {
      console.log('TEST FAILED - Expected device lost reason "unknown"');
      reportProgress('FAILED');
      return;
    }
    gotDevice = false;
    deviceLost = true;

    console.log('Iteration ' + idx + ': lost device');

    try {
      // First check that the previously acquired adapter can't get another device.
      // This should throw an exception.
      await adapter.requestDevice();
      reportProgress('FAILED');
      console.log('TEST FAILED - WebGPU device request should have failed on ' +
                  'stale GPUAdapter');
    } catch {
      console.log('Iteration ' + idx + ': Device request failed as expected');
    }

    // The second time, also check that we can't get another adapter.
    if (idx == 1) {
      const newAdapter = await navigator.gpu.requestAdapter();
      if (newAdapter !== null) {
        reportProgress('FAILED');
        console.log(
          'TEST FAILED - WebGPU adapter request should have been blocked');
      } else {
        console.log('Adapter request failed as expected');
        reportProgress('SUCCESS');
      }
    }

    // The harness will tell us when to proceed to the second iteration.
    while (!proceed) {
      await later(100);
    }
  }
}

init();
</script>