summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js')
-rw-r--r--testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js186
1 files changed, 186 insertions, 0 deletions
diff --git a/testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js b/testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
new file mode 100644
index 0000000000..1d1a012380
--- /dev/null
+++ b/testing/web-platform/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
@@ -0,0 +1,186 @@
+function send_message_to_iframe(iframe, message, reply) {
+ if (reply === undefined) {
+ reply = 'success';
+ }
+
+ return new Promise((resolve, reject) => {
+ window.addEventListener('message', (e) => {
+ if (e.data.command !== message.command) {
+ reject(`Expected reply with command '${message.command}', got '${e.data.command}' instead`);
+ return;
+ }
+ if (e.data.result === reply) {
+ resolve();
+ } else {
+ reject(`Got unexpected reply '${e.data.result}' to command '${message.command}', expected '${reply}'`);
+ }
+ }, { once: true });
+ iframe.contentWindow.postMessage(message, '*');
+ });
+}
+
+function run_generic_sensor_iframe_tests(sensorName) {
+ const sensorType = self[sensorName];
+ const featurePolicies = get_feature_policies_for_sensor(sensorName);
+
+ sensor_test(async t => {
+ assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ const iframe = document.createElement('iframe');
+ iframe.allow = featurePolicies.join(';') + ';';
+ iframe.src = 'https://{{domains[www1]}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
+
+ // Create sensor inside cross-origin nested browsing context.
+ const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
+ document.body.appendChild(iframe);
+ t.add_cleanup(async () => {
+ await send_message_to_iframe(iframe, { command: 'reset_sensor_backend' });
+ iframe.parentNode.removeChild(iframe);
+ });
+ await iframeLoadWatcher.wait_for('load');
+ await send_message_to_iframe(iframe, {command: 'create_sensor',
+ type: sensorName});
+
+ // Focus on the main frame and test that sensor receives readings.
+ window.focus();
+ const sensor = new sensorType();
+ const sensorWatcher = new EventWatcher(t, sensor, ['reading', 'error']);
+ sensor.start();
+
+ await sensorWatcher.wait_for('reading');
+ const cachedTimeStamp = sensor.timestamp;
+
+ // Focus on the cross-origin frame and verify that sensor reading updates in
+ // the top level browsing context are suspended.
+ iframe.contentWindow.focus();
+ await send_message_to_iframe(iframe, {command: 'start_sensor'});
+
+ // Focus on the main frame, verify that sensor reading updates are resumed.
+ window.focus();
+ await sensorWatcher.wait_for('reading');
+ assert_greater_than(sensor.timestamp, cachedTimeStamp);
+ sensor.stop();
+
+ // Verify that sensor in cross-origin frame is suspended.
+ await send_message_to_iframe(iframe, {command: 'is_sensor_suspended'}, true);
+ }, `${sensorName}: sensor is suspended and resumed when focus traverses from\
+ to cross-origin frame`);
+
+ sensor_test(async t => {
+ assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ const iframe = document.createElement('iframe');
+ iframe.allow = featurePolicies.join(';') + ';';
+ iframe.src = 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
+
+ // Create sensor inside same-origin nested browsing context.
+ const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
+ document.body.appendChild(iframe);
+ t.add_cleanup(async () => {
+ await send_message_to_iframe(iframe, { command: 'reset_sensor_backend' });
+ iframe.parentNode.removeChild(iframe);
+ });
+ await iframeLoadWatcher.wait_for('load');
+ await send_message_to_iframe(iframe, {command: 'create_sensor',
+ type: sensorName});
+
+ // Focus on main frame and test that sensor receives readings.
+ window.focus();
+ const sensor = new sensorType({
+ // generic_sensor_mocks.js uses a default frequency of 5Hz for sensors.
+ // We deliberately use a higher frequency here to make it easier to spot
+ // spurious, unexpected 'reading' events caused by the main frame's
+ // sensor not stopping early enough.
+ // TODO(rakuco): Create a constant with the 5Hz default frequency instead
+ // of using magic numbers.
+ frequency: 15
+ });
+ const sensorWatcher = new EventWatcher(t, sensor, ['reading', 'error']);
+ sensor.start();
+ await sensorWatcher.wait_for('reading');
+ let cachedTimeStamp = sensor.timestamp;
+
+ // Stop sensor in main frame, so that sensorWatcher would not receive
+ // readings while sensor in iframe is started. Sensors that are active and
+ // belong to the same-origin context are not suspended automatically when
+ // focus changes to another same-origin iframe, so if we do not explicitly
+ // stop them we may receive extra 'reading' events that cause the test to
+ // fail (see e.g. https://crbug.com/857520).
+ sensor.stop();
+
+ iframe.contentWindow.focus();
+ await send_message_to_iframe(iframe, {command: 'start_sensor'});
+
+ // Start sensor on main frame, verify that readings are updated.
+ window.focus();
+ sensor.start();
+ await sensorWatcher.wait_for('reading');
+ assert_greater_than(sensor.timestamp, cachedTimeStamp);
+ cachedTimeStamp = sensor.timestamp;
+ sensor.stop();
+
+ // Verify that sensor in nested browsing context is not suspended.
+ await send_message_to_iframe(iframe, {command: 'is_sensor_suspended'}, false);
+
+ // Verify that sensor in top level browsing context is receiving readings.
+ iframe.contentWindow.focus();
+ sensor.start();
+ await sensorWatcher.wait_for('reading');
+ assert_greater_than(sensor.timestamp, cachedTimeStamp);
+ sensor.stop();
+ }, `${sensorName}: sensor is not suspended when focus traverses from\
+ to same-origin frame`);
+
+ sensor_test(async t => {
+ assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ const iframe = document.createElement('iframe');
+ iframe.allow = featurePolicies.join(';') + ';';
+ iframe.src = 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
+
+ // Create sensor in the iframe (we do not care whether this is a
+ // cross-origin nested context in this test).
+ const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
+ document.body.appendChild(iframe);
+ await iframeLoadWatcher.wait_for('load');
+ await send_message_to_iframe(iframe, {command: 'create_sensor',
+ type: sensorName});
+ iframe.contentWindow.focus();
+ await send_message_to_iframe(iframe, {command: 'start_sensor'});
+
+ // Remove iframe from main document and change focus. When focus changes,
+ // we need to determine whether a sensor must have its execution suspended
+ // or resumed (section 4.2.3, "Focused Area" of the Generic Sensor API
+ // spec). In Blink, this involves querying a frame, which might no longer
+ // exist at the time of the check.
+ // Note that we cannot send the "reset_sensor_backend" command because the
+ // iframe is discarded with the removeChild call.
+ iframe.parentNode.removeChild(iframe);
+ window.focus();
+ }, `${sensorName}: losing a document's frame with an active sensor does not crash`);
+
+ sensor_test(async t => {
+ assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ const iframe = document.createElement('iframe');
+ iframe.allow = featurePolicies.join(';') + ';';
+ iframe.src = 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
+
+ // Create sensor in the iframe (we do not care whether this is a
+ // cross-origin nested context in this test).
+ const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
+ document.body.appendChild(iframe);
+ await iframeLoadWatcher.wait_for('load');
+
+ // The purpose of this message is to initialize the mock backend in the
+ // iframe. We are not going to use the sensor created there.
+ await send_message_to_iframe(iframe, {command: 'create_sensor',
+ type: sensorName});
+
+ const iframeSensor = new iframe.contentWindow[sensorName]();
+ assert_not_equals(iframeSensor, null);
+
+ // Remove iframe from main document. |iframeSensor| no longer has a
+ // non-null browsing context. Calling start() should probably throw an
+ // error when called from a non-fully active document, but that depends on
+ // https://github.com/w3c/sensors/issues/415
+ iframe.parentNode.removeChild(iframe);
+ iframeSensor.start();
+ }, `${sensorName}: calling start() in a non-fully active document does not crash`);
+}