usb-helpers.js (3568B)
1 'use strict'; 2 3 // These tests rely on the User Agent providing an implementation of the 4 // WebUSB Testing API (https://wicg.github.io/webusb/test/). 5 // 6 // In Chromium-based browsers this implementation is provided by a polyfill 7 // in order to reduce the amount of test-only code shipped to users. To enable 8 // these tests the browser must be run with these options: 9 // 10 // --enable-blink-features=MojoJS,MojoJSTest 11 12 (() => { 13 // Load scripts needed by the test API on context creation. 14 if (isChromiumBased) { 15 loadScript('/resources/chromium/webusb-child-test.js'); 16 } 17 })(); 18 19 function usb_test(func, name, properties) { 20 promise_test(async (t) => { 21 assert_implements(navigator.usb, 'missing navigator.usb'); 22 if (navigator.usb.test === undefined) { 23 // Try loading a polyfill for the WebUSB Testing API. 24 if (isChromiumBased) { 25 await loadScript('/resources/chromium/webusb-test.js'); 26 } 27 } 28 assert_implements(navigator.usb.test, 'missing navigator.usb.test after initialization'); 29 30 await navigator.usb.test.initialize(); 31 try { 32 await func(t); 33 } finally { 34 await navigator.usb.test.reset(); 35 } 36 }, name, properties); 37 } 38 39 // Returns a promise that is resolved when the next USBConnectionEvent of the 40 // given type is received. 41 function connectionEventPromise(eventType) { 42 return new Promise(resolve => { 43 let eventHandler = e => { 44 assert_true(e instanceof USBConnectionEvent); 45 navigator.usb.removeEventListener(eventType, eventHandler); 46 resolve(e.device); 47 }; 48 navigator.usb.addEventListener(eventType, eventHandler); 49 }); 50 } 51 52 // Creates a fake device and returns a promise that resolves once the 53 // 'connect' event is fired for the fake device. The promise is resolved with 54 // an object containing the fake USB device and the corresponding USBDevice. 55 function getFakeDevice() { 56 let promise = connectionEventPromise('connect'); 57 let fakeDevice = navigator.usb.test.addFakeDevice(fakeDeviceInit); 58 return promise.then(device => { 59 return { device: device, fakeDevice: fakeDevice }; 60 }); 61 } 62 63 // Disconnects the given device and returns a promise that is resolved when it 64 // is done. 65 function waitForDisconnect(fakeDevice) { 66 let promise = connectionEventPromise('disconnect'); 67 fakeDevice.disconnect(); 68 return promise; 69 } 70 71 function assertDeviceInfoEquals(usbDevice, deviceInit) { 72 for (var property in deviceInit) { 73 if (property == 'activeConfigurationValue') { 74 if (deviceInit.activeConfigurationValue == 0) { 75 assert_equals(usbDevice.configuration, null); 76 } else { 77 assert_equals(usbDevice.configuration.configurationValue, 78 deviceInit.activeConfigurationValue); 79 } 80 } else if (Array.isArray(deviceInit[property])) { 81 assert_equals(usbDevice[property].length, deviceInit[property].length); 82 for (var i = 0; i < usbDevice[property].length; ++i) 83 assertDeviceInfoEquals(usbDevice[property][i], deviceInit[property][i]); 84 } else { 85 assert_equals(usbDevice[property], deviceInit[property], property); 86 } 87 } 88 } 89 90 function callWithTrustedClick(callback) { 91 return new Promise(resolve => { 92 let button = document.createElement('button'); 93 button.textContent = 'click to continue test'; 94 button.style.display = 'block'; 95 button.style.fontSize = '20px'; 96 button.style.padding = '10px'; 97 button.onclick = () => { 98 resolve(callback()); 99 document.body.removeChild(button); 100 }; 101 document.body.appendChild(button); 102 test_driver.click(button); 103 }); 104 }