tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }