mirror of
https://github.com/servo/servo.git
synced 2025-06-26 01:54:33 +01:00
553 lines
22 KiB
JavaScript
553 lines
22 KiB
JavaScript
'use strict';
|
|
|
|
// Run a set of tests for a given |sensorName|.
|
|
// |readingData| is an object with 3 keys, all of which are arrays of arrays:
|
|
// 1. "readings". Each value corresponds to one raw reading that will be
|
|
// processed by a sensor.
|
|
// 2. "expectedReadings". Each value corresponds to the processed value a
|
|
// sensor will make available to users (i.e. a capped or rounded value).
|
|
// Its length must match |readings|'.
|
|
// 3. "expectedRemappedReadings" (optional). Similar to |expectedReadings|, but
|
|
// used only by spatial sensors, whose reference frame can change the values
|
|
// returned by a sensor.
|
|
// Its length should match |readings|'.
|
|
// |verificationFunction| is called to verify that a given reading matches a
|
|
// value in |expectedReadings|.
|
|
// |featurePolicies| represents |sensorName|'s associated sensor feature name.
|
|
|
|
function runGenericSensorTests(sensorName,
|
|
readingData,
|
|
verificationFunction,
|
|
featurePolicies) {
|
|
const sensorType = self[sensorName];
|
|
|
|
function validateReadingFormat(data) {
|
|
return Array.isArray(data) && data.every(element => Array.isArray(element));
|
|
}
|
|
|
|
const { readings, expectedReadings, expectedRemappedReadings } = readingData;
|
|
if (!validateReadingFormat(readings)) {
|
|
throw new TypeError('readingData.readings must be an array of arrays.');
|
|
}
|
|
if (!validateReadingFormat(expectedReadings)) {
|
|
throw new TypeError('readingData.expectedReadings must be an array of ' +
|
|
'arrays.');
|
|
}
|
|
if (readings.length < expectedReadings.length) {
|
|
throw new TypeError('readingData.readings\' length must be bigger than ' +
|
|
'or equal to readingData.expectedReadings\' length.');
|
|
}
|
|
if (expectedRemappedReadings &&
|
|
!validateReadingFormat(expectedRemappedReadings)) {
|
|
throw new TypeError('readingData.expectedRemappedReadings must be an ' +
|
|
'array of arrays.');
|
|
}
|
|
if (expectedRemappedReadings &&
|
|
expectedReadings.length != expectedRemappedReadings.length) {
|
|
throw new TypeError('readingData.expectedReadings and ' +
|
|
'readingData.expectedRemappedReadings must have the same ' +
|
|
'length.');
|
|
}
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
sensorProvider.setGetSensorShouldFail(sensorName, true);
|
|
const sensor = new sensorType;
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
|
|
sensor.start();
|
|
|
|
const event = await sensorWatcher.wait_for("error");
|
|
|
|
assert_false(sensor.activated);
|
|
assert_equals(event.error.name, 'NotReadableError');
|
|
}, `${sensorName}: Test that onerror is sent when sensor is not supported.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
sensorProvider.setPermissionsDenied(sensorName, true);
|
|
const sensor = new sensorType;
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
|
|
sensor.start();
|
|
|
|
const event = await sensorWatcher.wait_for("error");
|
|
|
|
assert_false(sensor.activated);
|
|
assert_equals(event.error.name, 'NotAllowedError');
|
|
}, `${sensorName}: Test that onerror is sent when permissions are not\
|
|
granted.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType({frequency: 560});
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
|
|
sensor.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
mockSensor.setStartShouldFail(true);
|
|
|
|
const event = await sensorWatcher.wait_for("error");
|
|
|
|
assert_false(sensor.activated);
|
|
assert_equals(event.error.name, 'NotReadableError');
|
|
}, `${sensorName}: Test that onerror is send when start() call has failed.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType({frequency: 560});
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
|
|
sensor.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
|
|
await sensorWatcher.wait_for("activate");
|
|
|
|
assert_less_than_equal(mockSensor.getSamplingFrequency(), 60);
|
|
sensor.stop();
|
|
assert_false(sensor.activated);
|
|
}, `${sensorName}: Test that frequency is capped to allowed maximum.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const maxSupportedFrequency = 5;
|
|
sensorProvider.setMaximumSupportedFrequency(maxSupportedFrequency);
|
|
const sensor = new sensorType({frequency: 50});
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
|
|
sensor.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
|
|
await sensorWatcher.wait_for("activate");
|
|
|
|
assert_equals(mockSensor.getSamplingFrequency(), maxSupportedFrequency);
|
|
sensor.stop();
|
|
assert_false(sensor.activated);
|
|
}, `${sensorName}: Test that frequency is capped to the maximum supported\
|
|
frequency.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const minSupportedFrequency = 2;
|
|
sensorProvider.setMinimumSupportedFrequency(minSupportedFrequency);
|
|
const sensor = new sensorType({frequency: -1});
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
|
|
sensor.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
|
|
await sensorWatcher.wait_for("activate");
|
|
|
|
assert_equals(mockSensor.getSamplingFrequency(), minSupportedFrequency);
|
|
sensor.stop();
|
|
assert_false(sensor.activated);
|
|
}, `${sensorName}: Test that frequency is limited to the minimum supported\
|
|
frequency.`);
|
|
|
|
promise_test(async t => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const iframe = document.createElement('iframe');
|
|
iframe.allow = featurePolicies.join(' \'none\'; ') + ' \'none\';';
|
|
iframe.srcdoc = '<script>' +
|
|
' window.onmessage = message => {' +
|
|
' if (message.data === "LOADED") {' +
|
|
' try {' +
|
|
' new ' + sensorName + '();' +
|
|
' parent.postMessage("FAIL", "*");' +
|
|
' } catch (e) {' +
|
|
' parent.postMessage("PASS", "*");' +
|
|
' }' +
|
|
' }' +
|
|
' };' +
|
|
'<\/script>';
|
|
const iframeWatcher = new EventWatcher(t, iframe, "load");
|
|
document.body.appendChild(iframe);
|
|
await iframeWatcher.wait_for("load");
|
|
iframe.contentWindow.postMessage('LOADED', '*');
|
|
|
|
const windowWatcher = new EventWatcher(t, window, "message");
|
|
const message = await windowWatcher.wait_for("message");
|
|
assert_equals(message.data, 'PASS');
|
|
}, `${sensorName}: Test that sensor cannot be constructed within iframe\
|
|
disallowed to use feature policy.`);
|
|
|
|
promise_test(async t => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const iframe = document.createElement('iframe');
|
|
iframe.allow = featurePolicies.join(';') + ';';
|
|
iframe.srcdoc = '<script>' +
|
|
' window.onmessage = message => {' +
|
|
' if (message.data === "LOADED") {' +
|
|
' try {' +
|
|
' new ' + sensorName + '();' +
|
|
' parent.postMessage("PASS", "*");' +
|
|
' } catch (e) {' +
|
|
' parent.postMessage("FAIL", "*");' +
|
|
' }' +
|
|
' }' +
|
|
' };' +
|
|
'<\/script>';
|
|
const iframeWatcher = new EventWatcher(t, iframe, "load");
|
|
document.body.appendChild(iframe);
|
|
await iframeWatcher.wait_for("load");
|
|
iframe.contentWindow.postMessage('LOADED', '*');
|
|
|
|
const windowWatcher = new EventWatcher(t, window, "message");
|
|
const message = await windowWatcher.wait_for("message");
|
|
assert_equals(message.data, 'PASS');
|
|
}, `${sensorName}: Test that sensor can be constructed within an iframe\
|
|
allowed to use feature policy.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType();
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
|
|
sensor.start();
|
|
assert_false(sensor.hasReading);
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
mockSensor.setSensorReading(readings);
|
|
|
|
await sensorWatcher.wait_for("reading");
|
|
const expected = new RingBuffer(expectedReadings).next().value;
|
|
assert_true(verificationFunction(expected, sensor));
|
|
assert_true(sensor.hasReading);
|
|
|
|
sensor.stop();
|
|
assert_true(verificationFunction(expected, sensor, /*isNull=*/true));
|
|
assert_false(sensor.hasReading);
|
|
}, `${sensorName}: Test that 'onreading' is called and sensor reading is\
|
|
valid.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor1 = new sensorType();
|
|
const sensorWatcher1 = new EventWatcher(t, sensor1, ["reading", "error"]);
|
|
sensor1.start();
|
|
|
|
const sensor2 = new sensorType();
|
|
const sensorWatcher2 = new EventWatcher(t, sensor2, ["reading", "error"]);
|
|
sensor2.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
mockSensor.setSensorReading(readings);
|
|
|
|
await Promise.all([sensorWatcher1.wait_for("reading"),
|
|
sensorWatcher2.wait_for("reading")]);
|
|
const expected = new RingBuffer(expectedReadings).next().value;
|
|
// Reading values are correct for both sensors.
|
|
assert_true(verificationFunction(expected, sensor1));
|
|
assert_true(verificationFunction(expected, sensor2));
|
|
|
|
// After first sensor stops its reading values are null,
|
|
// reading values for the second sensor sensor remain.
|
|
sensor1.stop();
|
|
assert_true(verificationFunction(expected, sensor1, /*isNull=*/true));
|
|
assert_true(verificationFunction(expected, sensor2));
|
|
|
|
sensor2.stop();
|
|
assert_true(verificationFunction(expected, sensor2, /*isNull=*/true));
|
|
}, `${sensorName}: sensor reading is correct.`);
|
|
|
|
// Tests that readings maps to expectedReadings correctly. Due to threshold
|
|
// check and rounding some values might be discarded or changed.
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType();
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
|
|
sensor.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
await mockSensor.setSensorReading(readings);
|
|
|
|
for (let expectedReading of expectedReadings) {
|
|
await sensorWatcher.wait_for("reading");
|
|
assert_true(sensor.hasReading, "hasReading");
|
|
assert_true(verificationFunction(expectedReading, sensor),
|
|
"verification");
|
|
}
|
|
|
|
sensor.stop();
|
|
}, `${sensorName}: Test that readings are all mapped to expectedReadings\
|
|
correctly.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType();
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
|
|
sensor.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
mockSensor.setSensorReading(readings);
|
|
|
|
await sensorWatcher.wait_for("reading");
|
|
const cachedTimeStamp1 = sensor.timestamp;
|
|
|
|
await sensorWatcher.wait_for("reading");
|
|
const cachedTimeStamp2 = sensor.timestamp;
|
|
|
|
assert_greater_than(cachedTimeStamp2, cachedTimeStamp1);
|
|
sensor.stop();
|
|
}, `${sensorName}: sensor timestamp is updated when time passes.`);
|
|
|
|
sensor_test(async t => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType();
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
|
|
assert_false(sensor.activated);
|
|
sensor.start();
|
|
assert_false(sensor.activated);
|
|
|
|
await sensorWatcher.wait_for("activate");
|
|
assert_true(sensor.activated);
|
|
|
|
sensor.stop();
|
|
assert_false(sensor.activated);
|
|
}, `${sensorName}: Test that sensor can be successfully created and its\
|
|
states are correct.`);
|
|
|
|
sensor_test(async t => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType();
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
|
|
sensor.start();
|
|
sensor.start();
|
|
|
|
await sensorWatcher.wait_for("activate");
|
|
assert_true(sensor.activated);
|
|
sensor.stop();
|
|
}, `${sensorName}: no exception is thrown when calling start() on already\
|
|
started sensor.`);
|
|
|
|
sensor_test(async t => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType();
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
|
|
sensor.start();
|
|
|
|
await sensorWatcher.wait_for("activate");
|
|
sensor.stop();
|
|
sensor.stop();
|
|
assert_false(sensor.activated);
|
|
}, `${sensorName}: no exception is thrown when calling stop() on already\
|
|
stopped sensor.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType();
|
|
const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
|
|
sensor.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
mockSensor.setSensorReading(readings);
|
|
|
|
const expectedBuffer = new RingBuffer(expectedReadings);
|
|
await sensorWatcher.wait_for("reading");
|
|
const expected1 = expectedBuffer.next().value;
|
|
assert_true(sensor.hasReading);
|
|
assert_true(verificationFunction(expected1, sensor));
|
|
const timestamp = sensor.timestamp;
|
|
sensor.stop();
|
|
assert_false(sensor.hasReading);
|
|
|
|
sensor.start();
|
|
await sensorWatcher.wait_for("reading");
|
|
assert_true(sensor.hasReading);
|
|
// |readingData| may have a single reading/expectation value, and this
|
|
// is the second reading we are getting. For that case, make sure we
|
|
// also wrap around as if we had the same RingBuffer used in
|
|
// generic_sensor_mocks.js.
|
|
const expected2 = expectedBuffer.next().value;
|
|
assert_true(verificationFunction(expected2, sensor));
|
|
// Make sure that 'timestamp' is already initialized.
|
|
assert_greater_than(timestamp, 0);
|
|
// Check that the reading is updated.
|
|
assert_greater_than(sensor.timestamp, timestamp);
|
|
sensor.stop();
|
|
}, `${sensorName}: Test that fresh reading is fetched on start().`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor = new sensorType();
|
|
t.add_cleanup(() => {
|
|
sensor.stop();
|
|
});
|
|
const sensorWatcher = new EventWatcher(t, sensor, ['reading', 'error']);
|
|
sensor.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
mockSensor.setSensorReading(readings);
|
|
|
|
const expectedBuffer = new RingBuffer(expectedReadings);
|
|
await sensorWatcher.wait_for('reading');
|
|
const expected1 = expectedBuffer.next().value;
|
|
assert_true(verificationFunction(expected1, sensor));
|
|
assert_true(mockSensor.isReadingData());
|
|
const cachedTimestamp1 = sensor.timestamp;
|
|
|
|
const {minimize, restore} = window_state_context(t);
|
|
|
|
await minimize();
|
|
assert_true(document.hidden);
|
|
await t.step_wait(
|
|
() => !mockSensor.isReadingData(), 'readings must be suspended');
|
|
const cachedTimestamp2 = sensor.timestamp;
|
|
assert_equals(cachedTimestamp1, cachedTimestamp2);
|
|
|
|
await restore();
|
|
assert_false(document.hidden);
|
|
await t.step_wait(
|
|
() => mockSensor.isReadingData(), 'readings must be restored');
|
|
await sensorWatcher.wait_for('reading');
|
|
const expected2 = expectedBuffer.next().value;
|
|
assert_true(verificationFunction(expected2, sensor));
|
|
assert_greater_than(sensor.timestamp, cachedTimestamp2);
|
|
}, `${sensorName}: Losing visibility must cause readings to be suspended.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
|
|
const fastSensor = new sensorType({ frequency: 60 });
|
|
t.add_cleanup(() => { fastSensor.stop(); });
|
|
let eventWatcher = new EventWatcher(t, fastSensor, "activate");
|
|
fastSensor.start();
|
|
|
|
// Wait for |fastSensor| to be activated so that the call to
|
|
// getSamplingFrequency() below works.
|
|
await eventWatcher.wait_for("activate");
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
mockSensor.setSensorReading(readings);
|
|
|
|
// We need |fastSensorFrequency| because 60Hz might be higher than a sensor
|
|
// type's maximum allowed frequency.
|
|
const fastSensorFrequency = mockSensor.getSamplingFrequency();
|
|
const slowSensorFrequency = fastSensorFrequency * 0.25;
|
|
|
|
const slowSensor = new sensorType({ frequency: slowSensorFrequency });
|
|
t.add_cleanup(() => { slowSensor.stop(); });
|
|
eventWatcher = new EventWatcher(t, slowSensor, "activate");
|
|
slowSensor.start();
|
|
|
|
// Wait for |slowSensor| to be activated before we check if the mock
|
|
// platform sensor's sampling frequency has changed.
|
|
await eventWatcher.wait_for("activate");
|
|
assert_equals(mockSensor.getSamplingFrequency(), fastSensorFrequency);
|
|
|
|
// Now stop |fastSensor| and verify that the sampling frequency has dropped
|
|
// to the one |slowSensor| had requested.
|
|
fastSensor.stop();
|
|
return t.step_wait(() => {
|
|
return mockSensor.getSamplingFrequency() === slowSensorFrequency;
|
|
}, "Sampling frequency has dropped to slowSensor's requested frequency");
|
|
}, `${sensorName}: frequency hint works.`);
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
|
|
const sensor1 = new sensorType();
|
|
const sensor2 = new sensorType();
|
|
|
|
return new Promise((resolve, reject) => {
|
|
sensor1.addEventListener('reading', () => {
|
|
sensor2.addEventListener('activate', () => {
|
|
try {
|
|
assert_true(sensor1.activated);
|
|
assert_true(sensor1.hasReading);
|
|
assert_false(verificationFunction(null, sensor1, /*isNull=*/true));
|
|
assert_not_equals(sensor1.timestamp, null);
|
|
|
|
assert_true(sensor2.activated);
|
|
assert_false(verificationFunction(null, sensor2, /*isNull=*/true));
|
|
assert_not_equals(sensor2.timestamp, null);
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}, { once: true });
|
|
sensor2.addEventListener('reading', () => {
|
|
try {
|
|
assert_true(sensor2.activated);
|
|
assert_true(sensor2.hasReading);
|
|
assert_sensor_equals(sensor1, sensor2);
|
|
resolve();
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}, { once: true });
|
|
sensor2.start();
|
|
}, { once: true });
|
|
sensor1.start();
|
|
});
|
|
}, `${sensorName}: Readings delivered by shared platform sensor are\
|
|
immediately accessible to all sensors.`);
|
|
|
|
// Re-enable after https://github.com/w3c/sensors/issues/361 is fixed.
|
|
// test(() => {
|
|
// assert_throws_dom("NotSupportedError",
|
|
// () => { new sensorType({invalid: 1}) });
|
|
// assert_throws_dom("NotSupportedError",
|
|
// () => { new sensorType({frequency: 60, invalid: 1}) });
|
|
// if (!expectedRemappedReadings) {
|
|
// assert_throws_dom("NotSupportedError",
|
|
// () => { new sensorType({referenceFrame: "screen"}) });
|
|
// }
|
|
// }, `${sensorName}: throw 'NotSupportedError' for an unsupported sensor\
|
|
// option.`);
|
|
|
|
test(() => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const invalidFreqs = [
|
|
"invalid",
|
|
NaN,
|
|
Infinity,
|
|
-Infinity,
|
|
{}
|
|
];
|
|
invalidFreqs.map(freq => {
|
|
assert_throws_js(TypeError,
|
|
() => { new sensorType({frequency: freq}) },
|
|
`when freq is ${freq}`);
|
|
});
|
|
}, `${sensorName}: throw 'TypeError' if frequency is invalid.`);
|
|
|
|
if (!expectedRemappedReadings) {
|
|
// The sensorType does not represent a spatial sensor.
|
|
return;
|
|
}
|
|
|
|
sensor_test(async (t, sensorProvider) => {
|
|
assert_implements(sensorName in self, `${sensorName} is not supported.`);
|
|
const sensor1 = new sensorType({frequency: 60});
|
|
const sensor2 = new sensorType({frequency: 60, referenceFrame: "screen"});
|
|
const sensorWatcher1 = new EventWatcher(t, sensor1, ["reading", "error"]);
|
|
const sensorWatcher2 = new EventWatcher(t, sensor1, ["reading", "error"]);
|
|
|
|
sensor1.start();
|
|
sensor2.start();
|
|
|
|
const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
|
|
mockSensor.setSensorReading(readings);
|
|
|
|
await Promise.all([sensorWatcher1.wait_for("reading"),
|
|
sensorWatcher2.wait_for("reading")]);
|
|
|
|
const expected = new RingBuffer(expectedReadings).next().value;
|
|
const expectedRemapped =
|
|
new RingBuffer(expectedRemappedReadings).next().value;
|
|
assert_true(verificationFunction(expected, sensor1));
|
|
assert_true(verificationFunction(expectedRemapped, sensor2));
|
|
|
|
sensor1.stop();
|
|
assert_true(verificationFunction(expected, sensor1, /*isNull=*/true));
|
|
assert_true(verificationFunction(expectedRemapped, sensor2));
|
|
|
|
sensor2.stop();
|
|
assert_true(verificationFunction(expectedRemapped, sensor2,
|
|
/*isNull=*/true));
|
|
}, `${sensorName}: sensor reading is correct when options.referenceFrame\
|
|
is 'screen'.`);
|
|
}
|
|
|
|
function runGenericSensorInsecureContext(sensorName) {
|
|
test(() => {
|
|
assert_false(sensorName in window, `${sensorName} must not be exposed`);
|
|
}, `${sensorName} is not exposed in an insecure context.`);
|
|
}
|