<!DOCTYPE html>
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
</head>
<body>
<script type="module">
import {MockMIDIService} from './resources/mock-midiservice.js';
const mock = new MockMIDIService();
function checkInputMap(inputs) {
let input;
for (const i of inputs.values()) {
input = i;
assert_equals(i.id, 'MockInputID-0');
assert_equals(i.manufacturer, 'MockInputManufacturer');
assert_equals(i.name, 'MockInputName');
assert_equals(i.version, 'MockInputVersion');
assert_equals(i.state, 'connected');
assert_equals(i.type, 'input');
}
let key;
for (const k of inputs.keys()) {
key = k;
assert_equals(k, 'MockInputID-0');
}
let entry;
for (const e of inputs.entries()) {
entry = e;
assert_equals(e[0], key);
assert_equals(e[1], input);
}
for (const e of inputs) {
assert_equals(e[0], key);
assert_equals(e[1], input);
}
assert_true(inputs.has('MockInputID-0'));
assert_false(inputs.has('MockOutputID-0'));
assert_equals(inputs.get('MockInputID-0'), input);
assert_equals(inputs.get('MockOutputID-0'), undefined);
inputs.forEach((i, k, m) => {
assert_equals(i, input);
assert_equals(k, key);
assert_equals(m, inputs);
});
}
function checkOutputMap(outputs) {
let output;
for (const o of outputs.values()) {
output = o;
assert_equals(o.id, 'MockOutputID-0');
assert_equals(o.manufacturer, 'MockOutputManufacturer');
assert_equals(o.name, 'MockOutputName');
assert_equals(o.version, 'MockOutputVersion');
assert_equals(o.state, 'connected');
assert_equals(o.type, 'output');
}
let key;
for (const k of outputs.keys()) {
key = k;
assert_equals(k, 'MockOutputID-0');
}
let entry;
for (const e of outputs.entries()) {
entry = e;
assert_equals(e[0], key);
assert_equals(e[1], output);
}
for (const e of outputs) {
assert_equals(e[0], key);
assert_equals(e[1], output);
}
assert_true(outputs.has('MockOutputID-0'));
assert_false(outputs.has('MockInputID-0'));
assert_equals(outputs.get('MockOutputID-0'), output);
assert_equals(outputs.get('MockInputID-0'), undefined);
outputs.forEach((o, k, m) => {
assert_equals(o, output);
assert_equals(k, key);
assert_equals(m, outputs);
});
}
promise_test(async t => {
await test_driver.set_permission({name: 'midi', sysex: true}, 'granted');
const access = await navigator.requestMIDIAccess();
// Validate the values of the attributes on the access.
assert_false(access.sysexEnabled);
assert_equals(access.inputs.size, 1);
assert_equals(access.outputs.size, 1);
checkInputMap(access.inputs);
checkOutputMap(access.outputs);
const output = access.outputs.values().next().value;
// Test sending of MIDI data with a Uint8Array.
const typedArrayData = new Uint8Array([0x90, 0x45, 0x7f]);
output.send(typedArrayData);
// Test sending of MIDI data with a regular Array.
output.send([0x90, 0x45, 0x7f]);
// Test sending of MIDI data with a regular Array giving an explicit timestamp.
output.send([0x90, 0x45, 0x7f], performance.now());
// Test sending of invalid MIDI data.
assert_throws_js(TypeError, () => output.send([0xfff, 0x45, 0x7f]));
// Test sending system exclusive messages. These should throw, since we don't have sysex access.
assert_throws_dom('InvalidAccessError', () => output.send([0xf0, 0x45, 0xf7]));
// Now test System Exclusive access without System Exclusive
// permission - our test mock should not allow this type of access.
await test_driver.set_permission({name: 'midi', sysex: true}, 'denied');
// Although not strictly necessary, also set the basic MIDI permission to
// 'granted' to test that it doesn't accidently grant the ability to use
// System Exclusive messages
await test_driver.set_permission({name: 'midi', sysex: false}, 'granted');
return promise_rejects_dom(t, 'SecurityError',
navigator.requestMIDIAccess({sysex: true}));
}, 'basic MIDI access is functional');
</script>
</body>
</html>