usb.https.window.js (4746B)
1 // META: script=/resources/testdriver.js 2 // META: script=/resources/testdriver-vendor.js 3 // META: script=/resources/test-only-api.js 4 // META: script=/webusb/resources/fake-devices.js 5 // META: script=/webusb/resources/usb-helpers.js 6 'use strict'; 7 8 usb_test(() => { 9 return navigator.usb.requestDevice({ filters: [] }) 10 .then(device => { 11 assert_unreachable('requestDevice should reject without a user gesture'); 12 }) 13 .catch(error => { 14 assert_equals(error.code, DOMException.SECURITY_ERR); 15 }); 16 }, 'requestDevice rejects when called without a user gesture'); 17 18 usb_test(() => { 19 return callWithTrustedClick(() => navigator.usb.requestDevice({ filters: [] }) 20 .then(device => { 21 assert_unreachable('requestDevice should reject when no device selected'); 22 }) 23 .catch(error => { 24 assert_equals(error.code, DOMException.NOT_FOUND_ERR); 25 }) 26 ); 27 }, 'requestDevice rejects when no device is chosen'); 28 29 usb_test(() => { 30 return getFakeDevice().then(({ device, fakeDevice }) => { 31 navigator.usb.test.onrequestdevice = event => { 32 navigator.usb.test.onrequestdevice = undefined; 33 event.respondWith(fakeDevice); 34 }; 35 return callWithTrustedClick(() => { 36 return navigator.usb.requestDevice({ filters: [] }).then(chosenDevice => { 37 assert_equals(chosenDevice, device); 38 }); 39 }); 40 }); 41 }, 'requestDevice returns the device chosen by the user'); 42 43 usb_test(() => { 44 return getFakeDevice().then(({ device, fakeDevice }) => { 45 navigator.usb.test.onrequestdevice = event => { 46 navigator.usb.test.onrequestdevice = undefined; 47 event.respondWith(fakeDevice); 48 }; 49 return callWithTrustedClick(() => { 50 return navigator.usb.requestDevice({ filters: [] }).then(chosenDevice => { 51 assert_equals(chosenDevice, device); 52 return navigator.usb.getDevices().then(devices => { 53 assert_equals(devices.length, 1); 54 assert_equals(devices[0], chosenDevice); 55 }); 56 }); 57 }); 58 }); 59 }, 'getDevices returns the same object as requestDevice'); 60 61 usb_test(() => { 62 const expectedFilters = [ 63 { vendorId: 1234, classCode: 0xFF, serialNumber: "123ABC" }, 64 { vendorId: 5678, productId: 0xF00F }, 65 { vendorId: 9012, classCode: 0xFF, subclassCode: 0xEE, protocolCode: 0xDD }, 66 ]; 67 68 navigator.usb.test.onrequestdevice = event => { 69 navigator.usb.test.onrequestdevice = undefined; 70 71 assert_equals(event.filters.length, expectedFilters.length); 72 for (var i = 0; i < event.filters.length; ++i) { 73 assert_object_equals(event.filters[i], expectedFilters[i]); 74 } 75 76 assert_equals(event.exclusionFilters.length, expectedFilters.length); 77 for (var i = 0; i < event.exclusionFilters.length; ++i) { 78 assert_object_equals(event.exclusionFilters[i], expectedFilters[i]); 79 } 80 81 event.respondWith(null); 82 }; 83 84 const filters = expectedFilters; 85 const exclusionFilters = expectedFilters; 86 return callWithTrustedClick(() => { 87 return navigator.usb.requestDevice({ filters, exclusionFilters }) 88 .then(device => { 89 assert_unreached( 90 'requestDevice should reject because no device selected'); 91 }) 92 .catch(error => { 93 assert_equals(error.code, DOMException.NOT_FOUND_ERR); 94 }); 95 }); 96 }, 'filters are sent correctly'); 97 98 usb_test(async () => { 99 const badFilters = [ 100 { productId: 1234 }, // productId requires vendorId 101 { subclassCode: 5678 }, // subclassCode requires classCode 102 { protocolCode: 9012 }, // protocolCode requires subclassCode 103 ]; 104 const badFilterOptions = ['filters', 'exclusionFilters'].flatMap(key => { 105 return badFilters.map(filter => ({[key]: [filter]})); 106 }); 107 108 for (const badFilterOption of badFilterOptions) { 109 await callWithTrustedClick(async () => { 110 try { 111 await navigator.usb.requestDevice(badFilterOption); 112 assert_unreached( 113 'requestDevice should reject because of invalid filters'); 114 } catch (error) { 115 assert_equals(error.name, 'TypeError'); 116 } 117 }); 118 } 119 }, 'requestDevice rejects on invalid filters'); 120 121 usb_test(() => { 122 return getFakeDevice().then(({ device, fakeDevice }) => { 123 navigator.usb.test.onrequestdevice = event => { 124 event.respondWith(fakeDevice); 125 }; 126 return callWithTrustedClick(() => { 127 let first = navigator.usb.requestDevice({ filters: [] }); 128 let second = navigator.usb.requestDevice({ filters: [] }); 129 return Promise.all([ 130 first.then(chosenDevice => { 131 assert_equals(chosenDevice, device); 132 }), 133 second.then(chosenDevice => { 134 assert_equals(chosenDevice, device); 135 }) 136 ]); 137 }); 138 }); 139 }, 'multiple requestDevice calls are allowed per user activation');