chromium/third_party/blink/web_tests/wpt_internal/hid/hid_requestDevice.https.window.js

// META: script=/resources/test-only-api.js
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
// META: script=/webhid/resources/common.js
// META: script=resources/automation.js
'use strict';

const kTestVendorId = 0x1234;
const kTestProductId = 0xabcd;
const kTestUsage = 0x0001;

promise_test((t) => {
  return promise_rejects_dom(
      t, 'SecurityError', navigator.hid.requestDevice({filters: []}));
}, 'requestDevice() rejects without a user gesture');

promise_test(async (t) => {
  await trustedClick();
  return promise_rejects_js(
      t, TypeError, navigator.hid.requestDevice({filters: [{}]}));
}, 'requestDevice() rejects with an empty filter');

promise_test(async (t) => {
  await trustedClick();
  return promise_rejects_js(
    t,
    TypeError,
    navigator.hid.requestDevice({
      filters: [{ productId: kTestProductId }],
    })
  );
}, "requestDevice() rejects with a productId value only in a filter");

promise_test(async (t) => {
  await trustedClick();
  return promise_rejects_js(
    t,
    TypeError,
    navigator.hid.requestDevice({
      filters: [{ usage: kTestUsage }],
    })
  );
}, "requestDevice() rejects with an usage value only in a filter");

promise_test(async (t) => {
  await trustedClick();
  return promise_rejects_js(
    t,
    TypeError,
    navigator.hid.requestDevice({ filters: [], exclusionFilters: [] })
  );
}, "requestDevice() rejects with empty exclusion filters");

promise_test(async (t) => {
  await trustedClick();
  return promise_rejects_js(
    t,
    TypeError,
    navigator.hid.requestDevice({ filters: [], exclusionFilters: [{}] })
  );
}, "requestDevice() rejects with an empty exclusion filter");

promise_test(async (t) => {
  await trustedClick();
  return promise_rejects_js(
    t,
    TypeError,
    navigator.hid.requestDevice({
      filters: [],
      exclusionFilters: [{ productId: kTestProductId }],
    })
  );
}, "requestDevice() rejects with a productId value only in an exclusion filter");

promise_test(async (t) => {
  await trustedClick();
  return promise_rejects_js(
    t,
    TypeError,
    navigator.hid.requestDevice({
      filters: [],
      exclusionFilters: [{ usage: kTestUsage }],
    })
  );
}, "requestDevice() rejects with an usage value only in an exclusion filter");

promise_test(async (t) => {
  const {HidService} =
      await import('/gen/third_party/blink/public/mojom/hid/hid.mojom.m.js');
  let interceptor = new MojoInterfaceInterceptor(HidService.$interfaceName);
  interceptor.oninterfacerequest = e => e.handle.close();
  interceptor.start();

  await trustedClick();
  let devices = null;
  try {
    devices = await navigator.hid.requestDevice({filters: []});
  } finally {
    interceptor.stop();
  }
  assert_true(devices instanceof Array);
  assert_equals(devices.length, 0);
}, 'requestDevice() returns an empty array if Mojo service connection fails');

hid_test(async (t, fake) => {
  await trustedClick();
  let devices = await navigator.hid.requestDevice({filters: []});
  assert_true(devices instanceof Array);
  assert_equals(devices.length, 0);
}, 'requestDevice() returns an empty array if no device has been selected');

hid_test(async (t, fake) => {
  let guid = fake.addDevice(fake.makeDevice(kTestVendorId, kTestProductId));
  fake.setSelectedDevice(guid);

  await trustedClick();
  let devices = await navigator.hid.requestDevice({filters: []});
  assert_true(devices instanceof Array);
  assert_equals(devices.length, 1);
  assert_true(devices[0] instanceof HIDDevice);
}, 'requestDevice() returns the selected device');

hid_test(async (t, fake) => {
  let guid = fake.addDevice(fake.makeDevice(kTestVendorId, kTestProductId));
  fake.setSelectedDevice(guid);

  await trustedClick();
  let firstDevices = await navigator.hid.requestDevice({filters: []});
  assert_true(firstDevices instanceof Array);
  assert_equals(firstDevices.length, 1);
  assert_true(firstDevices[0] instanceof HIDDevice);
  let secondDevices = await navigator.hid.requestDevice({filters: []});
  assert_false(firstDevices === secondDevices);
  assert_true(secondDevices instanceof Array);
  assert_equals(secondDevices.length, 1);
  assert_true(secondDevices[0] instanceof HIDDevice);
  assert_true(firstDevices[0] === secondDevices[0]);
}, 'requestDevice() returns the same device object every time');

hid_test(async (t, fake) => {
  // Construct two HidDeviceInfo objects with the same physical device ID to
  // simulate a device with two HID interfaces.
  let device0 = fake.makeDevice(kTestVendorId, kTestProductId);
  let device1 = fake.makeDevice(kTestVendorId, kTestProductId);
  device1.physicalDeviceId = device0.physicalDeviceId;
  let key0 = fake.addDevice(device0);
  let key1 = fake.addDevice(device1);
  assert_equals(key0, key1);
  fake.setSelectedDevice(key0);

  await trustedClick();
  let devices = await navigator.hid.requestDevice({filters: []});
  assert_true(devices instanceof Array);
  assert_equals(2, devices.length);
  assert_true(devices[0] instanceof HIDDevice);
  assert_true(devices[1] instanceof HIDDevice);
  assert_false(devices[0] === devices[1]);
}, 'requestDevice() returns 2 HIDDevices for a device with 2 HID interfaces');

hid_test(async (t, fake) => {
  // Construct two HidDeviceInfo objects with empty physical device IDs.
  let device0 = fake.makeDevice(kTestVendorId, kTestProductId);
  let device1 = fake.makeDevice(kTestVendorId, kTestProductId);
  device0.physicalDeviceId = '';
  device1.physicalDeviceId = '';
  let key0 = fake.addDevice(device0);
  let key1 = fake.addDevice(device1);
  assert_not_equals('', key0);
  assert_not_equals(key1, key0);
  fake.setSelectedDevice(key0);

  await trustedClick();
  let devices = await navigator.hid.requestDevice({filters: []});
  assert_true(devices instanceof Array);
  assert_equals(1, devices.length);
  assert_true(devices[0] instanceof HIDDevice);
}, 'requestDevice() does not merge devices with empty physical device IDs');