export const description = `Tests for GPUDevice.onuncapturederror / addEventListener('uncapturederror')`;import { makeTestGroup } from '../../../common/framework/test_group.js';import { raceWithRejectOnTimeout } from '../../../common/util/util.js';import { kGeneratableErrorScopeFilters } from '../../capability_info.js';import { ErrorTest } from '../../error_test.js';export const g = makeTestGroup(ErrorTest);g.test('iff_uncaptured').desc(`{validation, out-of-memory} error should fire uncapturederror iff not captured by a scope.`).params(u =>u.combine('useOnuncapturederror', [false, true]).combine('errorType', kGeneratableErrorScopeFilters)).fn(async t => {const { useOnuncapturederror, errorType } = t.params;const uncapturedErrorEvent = await t.expectUncapturedError(() => {t.generateError(errorType);}, useOnuncapturederror);t.expect(t.isInstanceOfError(errorType, uncapturedErrorEvent.error));});g.test('only_original_device_is_event_target').desc(`Original GPUDevice objects are EventTargets and have onuncapturederror, butdeserialized GPUDevices do not.`).unimplemented();g.test('uncapturederror_from_non_originating_thread').desc(`Uncaptured errors on any thread should always propagate to the original GPUDevice object(since deserialized ones don't have EventTarget/onuncapturederror).`).unimplemented();g.test('onuncapturederror_order_wrt_addEventListener').desc(`Test that onuncapturederror and addEventListener work in the correct order.The spec says setting onuncapturederror adds a listener via addEventListener thatcalls the callback. Changing onuncapturederror changes the callback to the existinglistener. Setting onuncapturederror to null removes the listener.`).fn(async t => {const callOrder: string[] = [];const makeListener = (id: string) => {let resolve: () => void;return {getPromise() {return new Promise<void>(r => {resolve = r;});},listener: (e: Event) => {e.preventDefault();t.debug(`listener ${id} called`);callOrder.push(id);resolve();},};};const listenerA = makeListener('a');const listenerB = makeListener('b');const callbackC = makeListener('c');const callbackD = makeListener('d');const callbackE = makeListener('e');try {t.debug('test they are called in the order added');{const promises = [listenerA.getPromise(), listenerB.getPromise(), callbackC.getPromise()];t.device.addEventListener('uncapturederror', listenerA.listener);t.device.onuncapturederror = callbackC.listener;t.device.addEventListener('uncapturederror', listenerB.listener);t.generateError('validation');await raceWithRejectOnTimeout(Promise.all(promises), 500, 'timeout1');const order = callOrder.join(',');t.expect(order === 'a,c,b', `'${order}' === 'a,c,b'`);callOrder.length = 0;}t.debug('test changing onuncapturederror does not change the order');{const promises = [listenerA.getPromise(), listenerB.getPromise(), callbackD.getPromise()];t.device.onuncapturederror = callbackD.listener;t.generateError('validation');await raceWithRejectOnTimeout(Promise.all(promises), 500, 'timeout2');const order = callOrder.join(',');t.expect(order === 'a,d,b', `'${order}' === 'a,d,b'`);callOrder.length = 0;}t.debug('test clearing onuncapturederror then setting it does change the order');{const promises = [listenerA.getPromise(), listenerB.getPromise(), callbackE.getPromise()];t.device.onuncapturederror = null;t.device.onuncapturederror = callbackE.listener;t.generateError('validation');await raceWithRejectOnTimeout(Promise.all(promises), 500, 'timeout3');const order = callOrder.join(',');t.expect(order === 'a,b,e', `'${order}' === 'a,b,e'`);callOrder.length = 0;}} finally {t.device.onuncapturederror = null;t.device.removeEventListener('uncapturederror', listenerA.listener);t.device.removeEventListener('uncapturederror', listenerB.listener);}});