let manualTestDevice = null; navigator.usb.addEventListener('disconnect', (e) => { if (e.device === manualTestDevice) { manualTestDevice = null; } }) async function getDeviceForManualTest() { if (manualTestDevice) { return manualTestDevice; } const button = document.createElement('button'); button.textContent = 'Click to select a device'; button.style.display = 'block'; button.style.fontSize = '20px'; button.style.padding = '10px'; await new Promise((resolve) => { button.onclick = () => { document.body.removeChild(button); resolve(); }; document.body.appendChild(button); }); manualTestDevice = await navigator.usb.requestDevice({filters: []}); assert_true(manualTestDevice instanceof USBDevice); return manualTestDevice; } function manual_usb_test(func, name, properties) { promise_test(async (test) => { await func(test, await getDeviceForManualTest()); }, name, properties); } function manual_usb_serial_test(func, name, properties) { promise_test(async (test) => { const device = await getDeviceForManualTest(); await device.open(); test.add_cleanup(async () => { if (device.opened) { await device.close(); } }); await device.selectConfiguration(1); let controlInterface = undefined; for (const iface of device.configuration.interfaces) { const alternate = iface.alternates[0]; if (alternate.interfaceClass == 2 && alternate.interfaceSubclass == 2 && alternate.interfaceProtocol == 0) { controlInterface = iface; break; } } assert_not_equals(controlInterface, undefined, 'No control interface found.'); let dataInterface = undefined; for (const iface of device.configuration.interfaces) { const alternate = iface.alternates[0]; if (alternate.interfaceClass == 10 && alternate.interfaceSubclass == 0 && alternate.interfaceProtocol == 0) { dataInterface = iface; break; } } assert_not_equals(dataInterface, undefined, 'No data interface found.'); await device.claimInterface(controlInterface.interfaceNumber); await device.claimInterface(dataInterface.interfaceNumber); let inEndpoint = undefined; for (const endpoint of dataInterface.alternate.endpoints) { if (endpoint.type == 'bulk' && endpoint.direction == 'in') { inEndpoint = endpoint; break; } } assert_not_equals(inEndpoint, undefined, 'No IN endpoint found.'); let outEndpoint = undefined; for (const endpoint of dataInterface.alternate.endpoints) { if (endpoint.type == 'bulk' && endpoint.direction == 'out') { outEndpoint = endpoint; break; } } assert_not_equals(outEndpoint, undefined, 'No OUT endpoint found.'); // Execute a SET_CONTROL_LINE_STATE command to let the device know the // host is ready to transmit and receive data. await device.controlTransferOut({ requestType: 'class', recipient: 'interface', request: 0x22, value: 0x01, index: controlInterface.interfaceNumber, }); await func(test, device, inEndpoint, outEndpoint); }, name, properties); }