summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/orientation-event
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/orientation-event
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/orientation-event')
-rw-r--r--testing/web-platform/tests/orientation-event/META.yml4
-rw-r--r--testing/web-platform/tests/orientation-event/README.md8
-rw-r--r--testing/web-platform/tests/orientation-event/device-orientation-events-of-detached-documents.https.html48
-rw-r--r--testing/web-platform/tests/orientation-event/device-orientation-events-unavailable-on-insecure-origins.html61
-rw-r--r--testing/web-platform/tests/orientation-event/idlharness.https.window.js19
-rw-r--r--testing/web-platform/tests/orientation-event/motion/add-during-dispatch.https.html36
-rw-r--r--testing/web-platform/tests/orientation-event/motion/add-listener-from-callback.https.html53
-rw-r--r--testing/web-platform/tests/orientation-event/motion/create-event.https.html41
-rw-r--r--testing/web-platform/tests/orientation-event/motion/free-fall-manual.https.html48
-rw-r--r--testing/web-platform/tests/orientation-event/motion/multiple-event-listeners.https.html30
-rw-r--r--testing/web-platform/tests/orientation-event/motion/null-values.https.html53
-rw-r--r--testing/web-platform/tests/orientation-event/motion/optional-event-properties.https.html257
-rw-r--r--testing/web-platform/tests/orientation-event/motion/page-visibility.https.html52
-rw-r--r--testing/web-platform/tests/orientation-event/motion/requestPermission.https.window.js48
-rw-r--r--testing/web-platform/tests/orientation-event/motion/screen-upmost-manual.https.html51
-rw-r--r--testing/web-platform/tests/orientation-event/motion/screen-upright-manual.https.html50
-rw-r--r--testing/web-platform/tests/orientation-event/motion/t025-manual.https.html38
-rw-r--r--testing/web-platform/tests/orientation-event/motion/t028-manual.https.html36
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/absolute-fallback.https.html23
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/add-listener-from-callback.https.html59
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/basic-operation-absolute.https.html34
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/basic-operation.https.html34
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/create-event.https.html40
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/horizontal-surface-manual.https.html34
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/multiple-event-listeners.https.html27
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/no-synchronous-events.https.html24
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/null-values.https.html27
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/optional-event-properties.https.html73
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/page-visibility.https.html50
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/requestPermission.https.window.js48
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/t006-manual.https.html30
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/t009-manual.https.html30
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/t010-manual.https.html30
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/t012-manual.https.html41
-rw-r--r--testing/web-platform/tests/orientation-event/orientation/updates.https.html37
-rw-r--r--testing/web-platform/tests/orientation-event/resources/orientation-event-helpers.js274
36 files changed, 1848 insertions, 0 deletions
diff --git a/testing/web-platform/tests/orientation-event/META.yml b/testing/web-platform/tests/orientation-event/META.yml
new file mode 100644
index 0000000000..88014849d0
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/META.yml
@@ -0,0 +1,4 @@
+spec: https://w3c.github.io/deviceorientation/
+suggested_reviewers:
+ - reillyeon
+ - timvolodine
diff --git a/testing/web-platform/tests/orientation-event/README.md b/testing/web-platform/tests/orientation-event/README.md
new file mode 100644
index 0000000000..14ea2f5117
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/README.md
@@ -0,0 +1,8 @@
+The `resources/orientation-event-helpers.js` tests depend on the implementation of
+the `GenericSensorTest` interface which is defined in [README.md](../generic-sensor/README.md).
+
+The Chromium implementation of the `GenericSensorTest` interface is located in
+[generic_sensor_mocks.js](../resources/chromium/generic_sensor_mocks.js).
+
+Other browser vendors should provide their own implementations of
+the `GenericSensorTest` interface.
diff --git a/testing/web-platform/tests/orientation-event/device-orientation-events-of-detached-documents.https.html b/testing/web-platform/tests/orientation-event/device-orientation-events-of-detached-documents.https.html
new file mode 100644
index 0000000000..f05be6d0d2
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/device-orientation-events-of-detached-documents.https.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Device sensor event listeners for `window` of detached documents.</title>
+</head>
+<body>
+<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>
+<script src="resources/orientation-event-helpers.js"></script>
+<script>
+
+promise_test(async t => {
+ const childFrame = document.createElement('iframe');
+ childFrame.src = "/common/blank.html";
+ document.body.append(childFrame);
+
+ const childLoadWatcher = new EventWatcher(t, childFrame, ["load"]);
+ await childLoadWatcher.wait_for("load");
+
+ const contentWindow = childFrame.contentWindow;
+ const contentDocument = childFrame.contentDocument;
+
+ await test_driver.set_permission({ name: 'accelerometer' }, 'granted', contentWindow);
+ await test_driver.set_permission({ name: 'gyroscope' }, 'granted', contentWindow);
+ await test_driver.set_permission({ name: 'magnetometer' }, 'granted', contentWindow);
+
+ assert_equals(await contentWindow.DeviceOrientationEvent.requestPermission(),
+ 'granted');
+ assert_equals(await contentWindow.DeviceMotionEvent.requestPermission(),
+ 'granted');
+
+ document.body.remove(childFrame);
+
+ assert_not_equals(contentWindow, null);
+ assert_not_equals(contentDocument, null);
+ assert_equals(contentDocument.defaultView, null);
+
+ contentWindow.addEventListener("devicemotion", () => {});
+ contentWindow.addEventListener("deviceorientation", () => {});
+ contentWindow.addEventListener("deviceorientationabsolute", () => {});
+
+}, 'Adding an event listener on the window of a detached document does not crash.');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/orientation-event/device-orientation-events-unavailable-on-insecure-origins.html b/testing/web-platform/tests/orientation-event/device-orientation-events-unavailable-on-insecure-origins.html
new file mode 100644
index 0000000000..6d2eee402f
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/device-orientation-events-unavailable-on-insecure-origins.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<title>Device Sensor Events not exposed to insecure origins</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/orientation-event-helpers.js"></script>
+<script>
+
+if (window.location.origin != get_host_info().HTTP_ORIGIN) {
+ window.location = get_host_info().HTTP_ORIGIN + window.location.pathname;
+ promise_test(_ => new Promise(_ => {}), "Stall tests on the wrong host.");
+} else {
+ test(() => {
+ assert_false('DeviceMotionEvent' in window);
+ assert_false('DeviceOrientationEvent' in window);
+ assert_false('DeviceOrientationAbsoluteEvent' in window);
+ assert_false('DeviceMotionEventAcceleration' in window);
+ assert_false('DeviceMotionEventRotationRate' in window);
+ assert_false('ondevicemotion' in window);
+ assert_false('ondeviceorientation' in window);
+ assert_false('ondeviceorientationabsolute' in window);
+ }, 'Event interfaces and event handlers are not exposed on `window`.');
+
+ promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'devicemotion');
+ await helper.initializeSensors();
+ const motionData = generateMotionData(1, 2, 3,
+ 4, 5, 6,
+ 7, 8, 9);
+ await helper.setData(motionData);
+
+ window.ondevicemotion = t.unreached_func("devicemotion event should not be fired.");
+
+ await new Promise(r => t.step_timeout(r, 1000));
+ }, 'addEventListener() for `devicemotion` does not crash but the handler never fires.');
+
+ promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.initializeSensors();
+ const orientationData = generateOrientationData(1.1, 2.2, 3.3, false);
+ await helper.setData(orientationData);
+
+ window.ondeviceorientation = t.unreached_func("deviceorientation event should not be fired.");
+
+ await new Promise(r => t.step_timeout(r, 1000));
+ }, 'addEventListener() for `deviceorientation` does not crash but the handler never fires.');
+
+ promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientationabsolute');
+ await helper.initializeSensors();
+ const orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
+ await helper.setData(orientationData);
+
+ window.ondeviceorientationabsolute = t.unreached_func("deviceorientationabsolute event should not be fired.");
+
+ await new Promise(r => t.step_timeout(r, 1000));
+ }, 'addEventListener() for `deviceorientationabsolute` does not crash but the handler never fires.');
+}
+</script>
diff --git a/testing/web-platform/tests/orientation-event/idlharness.https.window.js b/testing/web-platform/tests/orientation-event/idlharness.https.window.js
new file mode 100644
index 0000000000..ba816bb87c
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/idlharness.https.window.js
@@ -0,0 +1,19 @@
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+// META: timeout=long
+
+// https://w3c.github.io/deviceorientation/spec-source-orientation.html
+
+'use strict';
+
+idl_test(
+ ['orientation-event'],
+ ['html', 'dom'],
+ idl_array => {
+ idl_array.add_objects({
+ Window: ['window'],
+ DeviceOrientationEvent: ['new DeviceOrientationEvent("foo")'],
+ DeviceMotionEvent: ['new DeviceMotionEvent("foo")'],
+ });
+ }
+);
diff --git a/testing/web-platform/tests/orientation-event/motion/add-during-dispatch.https.html b/testing/web-platform/tests/orientation-event/motion/add-during-dispatch.https.html
new file mode 100644
index 0000000000..262715ce55
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/add-during-dispatch.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'devicemotion');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const motionData = generateMotionData(1, 2, 3,
+ 4, 5, 6,
+ 7, 8, 9);
+ await helper.setData(motionData);
+
+ return new Promise((resolve, reject) => {
+ let result = reject;
+ window.addEventListener('devicemotion', event1 => {
+ // Now we are in event dispatch.
+ assertEventEquals(event1, getExpectedMotionEvent(motionData));
+
+ window.addEventListener('devicemotion', event2 => {
+ // Not called until the outer function returns.
+ assertEventEquals(event2, getExpectedMotionEvent(motionData));
+ result();
+ }, {once: true});
+
+ result = resolve;
+ }, {once: true});
+ });
+}, 'Test no fire listeners added during event dispatch.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/motion/add-listener-from-callback.https.html b/testing/web-platform/tests/orientation-event/motion/add-listener-from-callback.https.html
new file mode 100644
index 0000000000..1f8cca86b2
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/add-listener-from-callback.https.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'devicemotion');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const motionData = generateMotionData(1.1, 2.1, 3.1,
+ 1.2, 2.2, 3.2,
+ 1.3, 2.3, 3.3);
+
+ let firstListener = null;
+ let secondListener = null;
+ let firstEventCount = 0;
+ let firstPromise = new Promise(resolve => {
+ firstListener = (event) => {
+ assert_true(event instanceof DeviceMotionEvent, 'event is DeviceMotionEvent');
+ assert_equals(event.type, 'devicemotion', 'event.type is devicemotion');
+ assert_true(event.target instanceof Window, 'event is fired on the window object');
+ assertEventEquals(event, getExpectedMotionEvent(motionData));
+ window.removeEventListener('devicemotion', firstListener);
+ if (++firstEventCount == 1) {
+ window.addEventListener('devicemotion', secondListener);
+ }
+ resolve(event);
+ };
+ });
+
+ let secondEventCount = 0;
+ let secondPromise = new Promise(resolve => {
+ secondListener = (event) => {
+ assertEventEquals(event, getExpectedMotionEvent(motionData));
+ window.removeEventListener('devicemotion', secondListener);
+ ++secondEventCount;
+ resolve(event);
+ };
+ });
+
+ await helper.setData(motionData);
+ window.addEventListener('devicemotion', firstListener);
+ await firstPromise;
+ await secondPromise;
+ assert_equals(firstEventCount, 1, "Too many events fired for the first listener");
+ assert_equals(secondEventCount, 1, "Too many events fired for the second listener");
+}, 'Tests that adding a new devicemotion event listener from a callback works as expected.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/motion/create-event.https.html b/testing/web-platform/tests/orientation-event/motion/create-event.https.html
new file mode 100644
index 0000000000..e8a2c469b1
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/create-event.https.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+test(test => {
+ const event = document.createEvent('DeviceMotionEvent');
+ const newEvent = new CustomEvent("devicemotion", {
+ bubbles: false, cancelable: false,
+ acceleration: {x:1.5,y:2.5,z:3.5},
+ accelerationIncludingGravity: {x:4.5,y:5.5,z:6.5},
+ rotationRate: {alpha:7.5,beta:8.5,gamma:9.5},
+ interval: 0.5
+ });
+
+ assert_equals(typeof event, 'object');
+ assert_equals(Object.getPrototypeOf(event), DeviceMotionEvent.prototype);
+
+ assert_true('type' in event);
+ assert_true('bubbles' in event);
+ assert_true('cancelable' in event);
+ assert_true('acceleration' in event);
+ assert_true('accelerationIncludingGravity' in event);
+ assert_true('rotationRate' in event);
+ assert_true('interval' in event);
+
+ assert_equals(typeof newEvent.type, 'string');
+ assert_equals(newEvent.type, "devicemotion");
+ assert_equals(typeof newEvent.bubbles, 'boolean');
+ assert_false(event.bubbles);
+ assert_false(newEvent.bubbles);
+ assert_equals(typeof newEvent.cancelable, 'boolean');
+ assert_false(event.cancelable);
+ assert_false(newEvent.cancelable);
+ assert_equals(typeof event.acceleration, 'object');
+ assert_equals(typeof event.accelerationIncludingGravity, 'object');
+ assert_equals(typeof event.rotationRate, 'object');
+ assert_equals(typeof event.interval, 'number');
+}, 'Tests that document.createEvent() works with DeviceMotionEvent.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/motion/free-fall-manual.https.html b/testing/web-platform/tests/orientation-event/motion/free-fall-manual.https.html
new file mode 100644
index 0000000000..c71f61fa69
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/free-fall-manual.https.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>DeviceMotionEvent: A device in free-fall, with the screen horizontal and upmost</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author' title='Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-14 -->
+ </head>
+ <body>
+ <p>Free fall the device to run the test, with the screen horizontal and upmost.</p>
+ <div id="log"></div>
+ <script>
+ var t = async_test();
+ var run = false;
+
+ /*
+ * A device in free-fall, with the screen horizontal and upmost,
+ * has an accelerationIncludingGravity of zero and
+ * the following value for acceleration:
+ * {
+ * x: 0,
+ * y: 0,
+ * z: -9.81
+ * };
+ */
+ window.addEventListener("devicemotion", function(e) {
+ if (!run) {
+ run = true;
+ t.step(function() {
+ var gvt = e.accelerationIncludingGravity;
+ var acc = e.acceleration;
+
+ assert_approx_equals(gvt.x, 0, 1);
+ assert_approx_equals(gvt.y, 0, 1);
+ assert_approx_equals(gvt.z, 0, 1);
+
+ assert_approx_equals(acc.x, 0, 1);
+ assert_approx_equals(acc.y, 0, 1);
+ assert_approx_equals(acc.z, -9.81, 1.5);
+ });
+ t.done();
+ }
+ }, false);
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/motion/multiple-event-listeners.https.html b/testing/web-platform/tests/orientation-event/motion/multiple-event-listeners.https.html
new file mode 100644
index 0000000000..f94c9d136e
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/multiple-event-listeners.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'devicemotion');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const motionData1 = generateMotionData(1, 2, 3,
+ 4, 5, 6,
+ 7, 8, 9);
+ await helper.setData(motionData1);
+ await Promise.all([
+ waitForEvent(getExpectedMotionEvent(motionData1)),
+ waitForEvent(getExpectedMotionEvent(motionData1))
+ ]);
+
+ const motionData2 = generateMotionData(11, 12, 13,
+ 14, 15, 16,
+ 17, 18, 19);
+ await helper.setData(motionData2);
+ await waitForEvent(getExpectedMotionEvent(motionData2));
+}, 'Tests using multiple event handlers for the Device Motion API.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/motion/null-values.https.html b/testing/web-platform/tests/orientation-event/motion/null-values.https.html
new file mode 100644
index 0000000000..f875afcd64
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/null-values.https.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'devicemotion');
+ await helper.grantSensorsPermissions();
+
+ const motionData1 = generateMotionData(1, 2, 3,
+ null, null, null,
+ null, null, null);
+
+ const motionData2 = generateMotionData(null, null, null,
+ 1, 2, 3,
+ null, null, null);
+
+ const motionData3 = generateMotionData(null, null, null,
+ null, null, null,
+ 1, 2, 3);
+
+ const motionData4 = generateMotionData(null, null, null,
+ null, null, null,
+ null, null, null);
+
+ await helper.initializeSensors({disabledSensors: ['accelerometer','gyroscope']});
+ await helper.setData(motionData1);
+ await waitForEvent(getExpectedMotionEvent(motionData1));
+ // If test needs to change virtual sensor state from connected to not
+ // connected or vise versa, reset needs to be called. It removes created
+ // virtual sensors and creating them with different connection state is then
+ // possible.
+ await helper.reset();
+
+ await helper.initializeSensors({disabledSensors: ['linear-acceleration','gyroscope']});
+ await helper.setData(motionData2);
+ await waitForEvent(getExpectedMotionEvent(motionData2));
+ await helper.reset();
+
+ await helper.initializeSensors({disabledSensors: ['accelerometer','linear-acceleration']});
+ await helper.setData(motionData3);
+ await waitForEvent(getExpectedMotionEvent(motionData3));
+ await helper.reset();
+
+ await helper.initializeSensors({disabledSensors: ['accelerometer','linear-acceleration','gyroscope']});
+ await helper.setData(motionData4);
+ await waitForEvent(getExpectedMotionEvent(motionData4));
+}, 'Tests using null values for some or all of the event properties.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/motion/optional-event-properties.https.html b/testing/web-platform/tests/orientation-event/motion/optional-event-properties.https.html
new file mode 100644
index 0000000000..0a73721cb9
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/optional-event-properties.https.html
@@ -0,0 +1,257 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+function ObjectThrowingException() {};
+ObjectThrowingException.prototype.valueOf = () => { throw new Error('valueOf threw exception'); }
+ObjectThrowingException.prototype.__defineGetter__("x", () => { throw new Error('x getter exception'); });
+ObjectThrowingException.prototype.__defineGetter__("alpha", () => { throw new Error('alpha getter exception'); });
+const objectThrowingException = new ObjectThrowingException();
+
+test(test => {
+ event = document.createEvent('DeviceMotionEvent');
+ assert_equals(event.type, "");
+ assert_equals(event.acceleration, null);
+ assert_equals(event.accelerationIncludingGravity, null);
+ assert_equals(event.rotationRate, null);
+ assert_equals(event.interval, 0);
+}, 'Tests creating a DeviceMotionEvent.');
+
+test(test => {
+ event = new DeviceMotionEvent('foo', {acceleration: {x: 0, y: 1, z: 2},
+ accelerationIncludingGravity: {x: 3, y: 4, z: 5},
+ rotationRate: {alpha: 6, beta: 7, gamma: 8},
+ interval: 9});
+ assert_equals(event.type, "foo");
+ assert_equals(event.acceleration.x, 0);
+ assert_equals(event.acceleration.y, 1);
+ assert_equals(event.acceleration.z, 2);
+ assert_equals(event.accelerationIncludingGravity.x, 3);
+ assert_equals(event.accelerationIncludingGravity.y, 4);
+ assert_equals(event.accelerationIncludingGravity.z, 5);
+ assert_equals(event.rotationRate.alpha, 6);
+ assert_equals(event.rotationRate.beta, 7);
+ assert_equals(event.rotationRate.gamma, 8);
+ assert_equals(event.interval, 9);
+}, 'Tests no missing value.');
+
+test(test => {
+ try {
+ event = new DeviceMotionEvent('', {acceleration: objectThrowingException,
+ accelerationIncludingGravity: {x: 3, z: 5},
+ rotationRate: {gamma: 8, beta: 7},
+ interval: 9});
+ assert_unreached("Invalid acceleration, must throw an Error exception");
+ } catch (e) {
+ assert_equals(e.name, "Error");
+ assert_equals(e.message, "x getter exception");
+ }
+}, 'Tests invalid acceleration.');
+
+test(test => {
+ try {
+ event = new DeviceMotionEvent('', {acceleration: {x: 0, y: 1, z: 2},
+ accelerationIncludingGravity: objectThrowingException,
+ rotationRate: {gamma: 8, beta: 7},
+ interval: 9});
+ assert_unreached("Invalid acelerationIncludingGravity, must throw an Error exception");
+ } catch (e) {
+ assert_equals(e.name, "Error");
+ assert_equals(e.message, "x getter exception");
+ }
+}, 'Tests invalid acelerationIncludingGravity.');
+
+test(test => {
+ try {
+ event = new DeviceMotionEvent('', {acceleration: {x: 0, y: 1, z: 2},
+ accelerationIncludingGravity: {x: 3, z: 5},
+ rotationRate: objectThrowingException,
+ interval: 9});
+ assert_unreached("Invalid rotationRate, must throw an Error exception");
+ } catch (e) {
+ assert_equals(e.name, "Error");
+ assert_equals(e.message, "alpha getter exception");
+ }
+}, 'Tests invalid rotationRate.');
+
+test(test => {
+ try {
+ event = new DeviceMotionEvent('', {acceleration: {x: objectThrowingException, y: 1, z: 2},
+ accelerationIncludingGravity: {x: 3, y: 4, z: 5},
+ rotationRate: {alpha: 6, beta: 7, gamma: 8},
+ interval: 9});
+ assert_unreached("Invalid acceleration.x, must throw an Error exception");
+ } catch (e) {
+ assert_equals(e.name, "Error");
+ assert_equals(e.message, "valueOf threw exception");
+ }
+}, 'Tests invalid acceleration.x.');
+
+test(test => {
+ try {
+ event = new DeviceMotionEvent('', {acceleration: {x: 0, y: 1, z: 2},
+ accelerationIncludingGravity: {x: 3, y: objectThrowingException, z: 5},
+ rotationRate: {alpha: 6, beta: 7, gamma: 8},
+ interval: 9});
+ assert_unreached("Invalid accelerationIncludingGravity.y, must throw an Error exception");
+ } catch (e) {
+ assert_equals(e.name, "Error");
+ assert_equals(e.message, "valueOf threw exception");
+ }
+}, 'Tests invalid accelerationIncludingGravity.y.');
+
+test(test => {
+ try {
+ event = new DeviceMotionEvent('', {acceleration: {x: 0, y: 1, z: 2},
+ accelerationIncludingGravity: {x: 3, y: 4, z: 5},
+ rotationRate: {alpha: 6, beta: 7, gamma: objectThrowingException},
+ interval: 9});
+ assert_unreached("Invalid rotationRate.gamma, must throw an Error exception");
+ } catch (e) {
+ assert_equals(e.name, "Error");
+ assert_equals(e.message, "valueOf threw exception");
+ }
+}, 'Tests invalid rotationRate.gamma.');
+
+test(test => {
+ event = new DeviceMotionEvent('', {acceleration: {y: 1, x: 0},
+ accelerationIncludingGravity: {x: 3, z: 5},
+ rotationRate: {gamma: 8, beta: 7},
+ interval: 9});
+ assert_equals(event.acceleration.x, 0);
+ assert_equals(event.acceleration.y, 1);
+ assert_equals(event.acceleration.z, null);
+ assert_equals(event.accelerationIncludingGravity.x, 3);
+ assert_equals(event.accelerationIncludingGravity.y, null);
+ assert_equals(event.accelerationIncludingGravity.z, 5);
+ assert_equals(event.rotationRate.alpha, null);
+ assert_equals(event.rotationRate.beta, 7);
+ assert_equals(event.rotationRate.gamma, 8);
+ assert_equals(event.interval, 9);
+}, 'Tests missing fields should be null.');
+
+test(test => {
+ event = new DeviceMotionEvent('');
+ assert_equals(event.acceleration, null);
+ assert_equals(event.accelerationIncludingGravity, null);
+ assert_equals(event.rotationRate, null);
+ assert_equals(event.interval, 0);
+}, 'Tests DeviceMotionEvent default constructor.');
+
+test(test => {
+ event = new DeviceMotionEvent('', {acceleration: [],
+ accelerationIncludingGravity: [],
+ rotationRate: [],
+ interval: []});
+ assert_equals(event.acceleration.x, null);
+ assert_equals(event.acceleration.y, null);
+ assert_equals(event.acceleration.z, null);
+ assert_equals(event.accelerationIncludingGravity.x, null);
+ assert_equals(event.accelerationIncludingGravity.y, null);
+ assert_equals(event.accelerationIncludingGravity.z, null);
+ assert_equals(event.rotationRate.alpha, null);
+ assert_equals(event.rotationRate.beta, null);
+ assert_equals(event.rotationRate.gamma, null);
+ assert_equals(event.interval, 0);
+}, 'Tests all values are empty array.');
+
+test(test => {
+ event = new DeviceMotionEvent('', {acceleration: [],
+ accelerationIncludingGravity: undefined,
+ rotationRate: undefined,
+ interval: undefined});
+ assert_equals(event.acceleration.x, null);
+ assert_equals(event.acceleration.y, null);
+ assert_equals(event.acceleration.z, null);
+ assert_equals(event.accelerationIncludingGravity, null);
+ assert_equals(event.rotationRate, null);
+ assert_equals(event.interval, 0);
+}, 'Tests some values are empty array and some values are undefined.');
+
+test(test => {
+ event = new DeviceMotionEvent('', {acceleration: null,
+ accelerationIncludingGravity: null,
+ rotationRate: null,
+ interval: null});
+ assert_equals(event.acceleration.x, null);
+ assert_equals(event.acceleration.y, null);
+ assert_equals(event.acceleration.z, null);
+ assert_equals(event.accelerationIncludingGravity.x, null);
+ assert_equals(event.accelerationIncludingGravity.y, null);
+ assert_equals(event.accelerationIncludingGravity.z, null);
+ assert_equals(event.rotationRate.alpha, null);
+ assert_equals(event.rotationRate.beta, null);
+ assert_equals(event.rotationRate.gamma, null);
+ assert_equals(event.interval, 0);
+}, "Tests all values are null.");
+
+test(test => {
+ event = new DeviceMotionEvent('', {acceleration: {x: null, y: null, z: null},
+ accelerationIncludingGravity: {x: null, y: null, z: null},
+ rotationRate: {alpha: null, beta: null, gamma: null},
+ interval: null});
+ assert_equals(event.acceleration.x, null);
+ assert_equals(event.acceleration.y, null);
+ assert_equals(event.acceleration.z, null);
+ assert_equals(event.accelerationIncludingGravity.x, null);
+ assert_equals(event.accelerationIncludingGravity.y, null);
+ assert_equals(event.accelerationIncludingGravity.z, null);
+ assert_equals(event.rotationRate.alpha, null);
+ assert_equals(event.rotationRate.beta, null);
+ assert_equals(event.rotationRate.gamma, null);
+ assert_equals(event.interval, 0);
+}, 'Tests all fields are null.');
+
+test(test => {
+ event = new DeviceMotionEvent('', {acceleration: {x: null, y: null, z: 1},
+ accelerationIncludingGravity: {x: null, y: null, z: 2},
+ rotationRate: {alpha: null, beta: null, gamma: 3},
+ interval: null});
+ assert_equals(event.acceleration.x, null);
+ assert_equals(event.acceleration.y, null);
+ assert_equals(event.acceleration.z, 1);
+ assert_equals(event.accelerationIncludingGravity.x, null);
+ assert_equals(event.accelerationIncludingGravity.y, null);
+ assert_equals(event.accelerationIncludingGravity.z, 2);
+ assert_equals(event.rotationRate.alpha, null);
+ assert_equals(event.rotationRate.beta, null);
+ assert_equals(event.rotationRate.gamma, 3);
+ assert_equals(event.interval, 0);
+}, 'Tests some fields are null.');
+
+test(test => {
+ event = new DeviceMotionEvent('', {acceleration: {x: undefined, y: undefined, z: undefined},
+ accelerationIncludingGravity: {x: undefined, y: undefined, z: undefined},
+ rotationRate: {alpha: undefined, beta: undefined, gamma: undefined},
+ interval: undefined});
+ assert_equals(event.acceleration.x, null);
+ assert_equals(event.acceleration.y, null);
+ assert_equals(event.acceleration.z, null);
+ assert_equals(event.accelerationIncludingGravity.x, null);
+ assert_equals(event.accelerationIncludingGravity.y, null);
+ assert_equals(event.accelerationIncludingGravity.z, null);
+ assert_equals(event.rotationRate.alpha, null);
+ assert_equals(event.rotationRate.beta, null);
+ assert_equals(event.rotationRate.gamma, null);
+ assert_equals(event.interval, 0);
+}, 'Tests all fields are undefined.');
+
+test(test => {
+ event = new DeviceMotionEvent('', {acceleration: {x: undefined, y: undefined, z: 1},
+ accelerationIncludingGravity: {x: undefined, y: undefined, z: 2},
+ rotationRate: {alpha: undefined, beta: undefined, gamma: 3},
+ interval: undefined});
+ assert_equals(event.acceleration.x, null);
+ assert_equals(event.acceleration.y, null);
+ assert_equals(event.acceleration.z, 1);
+ assert_equals(event.accelerationIncludingGravity.x, null);
+ assert_equals(event.accelerationIncludingGravity.y, null);
+ assert_equals(event.accelerationIncludingGravity.z, 2);
+ assert_equals(event.rotationRate.alpha, null);
+ assert_equals(event.rotationRate.beta, null);
+ assert_equals(event.rotationRate.gamma, 3);
+ assert_equals(event.interval, 0);
+}, 'Tests some fields are undefined.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/motion/page-visibility.https.html b/testing/web-platform/tests/orientation-event/motion/page-visibility.https.html
new file mode 100644
index 0000000000..2925af9331
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/page-visibility.https.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<body>
+<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>
+<script src="/page-visibility/resources/window_state_context.js"></script>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'devicemotion');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const motionData = generateMotionData(0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0);
+
+ await helper.setData(motionData);
+ const event = getExpectedMotionEvent(motionData);
+ await waitForEvent(event);
+
+ const {minimize, restore} = window_state_context(t);
+ await minimize();
+ assert_true(document.hidden);
+
+ let hiddenEventPromise = new Promise((resolve, reject) => {
+ window.addEventListener(
+ 'devicemotion',
+ event => {
+ if (document.hidden) {
+ reject();
+ } else {
+ resolve();
+ }
+ },
+ { once: true });
+ });
+
+ // devicemotion events fire every 16ms when active, so we sleep for a while
+ // here to make sure we're not actually getting any events.
+ await new Promise(resolve => { t.step_timeout(resolve, 100); });
+ await restore();
+ assert_false(document.hidden);
+ return Promise.all([hiddenEventPromise, waitForEvent(event)]);
+}, 'Tests to check that devicemotion events are not fired when the page is not visible.');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/orientation-event/motion/requestPermission.https.window.js b/testing/web-platform/tests/orientation-event/motion/requestPermission.https.window.js
new file mode 100644
index 0000000000..2c96d26d10
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/requestPermission.https.window.js
@@ -0,0 +1,48 @@
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+
+'use strict';
+
+// The Device Orientation spec does not fully integrate with the Permissions
+// spec and does not list the permissions that are expected for
+// requestPermission() to work. The list below was based on the permission
+// tokens corresponding to the sensors used to implement support for motion
+// events. They also match the feature policy tokens required by both Blink and
+// WebKit.
+const permissionDescriptorNames = ['accelerometer', 'gyroscope'];
+
+promise_test(async (t) => {
+ await Promise.all(permissionDescriptorNames.map(
+ name => test_driver.set_permission({name}, 'granted')));
+
+ const permission = await DeviceMotionEvent.requestPermission();
+ assert_equals(permission, 'granted');
+}, 'requestPermission() returns "granted" for granted permissions without user activation');
+
+promise_test(async (t) => {
+ await Promise.all(permissionDescriptorNames.map(
+ name => test_driver.set_permission({name}, 'granted')));
+
+ return test_driver.bless('enable user activation', async () => {
+ const permission = await DeviceMotionEvent.requestPermission();
+ assert_equals(permission, 'granted');
+ });
+}, 'requestPermission() returns "granted" for granted permissions with user activation');
+
+promise_test(async (t) => {
+ await Promise.all(permissionDescriptorNames.map(
+ name => test_driver.set_permission({name}, 'denied')));
+
+ const permission = await DeviceMotionEvent.requestPermission();
+ assert_equals(permission, 'denied');
+}, 'requestPermission() returns "denied" for denied permissions without user activation');
+
+promise_test(async (t) => {
+ await Promise.all(permissionDescriptorNames.map(
+ name => test_driver.set_permission({name}, 'denied')));
+
+ return test_driver.bless('enable user activation', async () => {
+ const permission = await DeviceMotionEvent.requestPermission();
+ assert_equals(permission, 'denied');
+ });
+}, 'requestPermission() returns "denied" for denied permissions with user activation');
diff --git a/testing/web-platform/tests/orientation-event/motion/screen-upmost-manual.https.html b/testing/web-platform/tests/orientation-event/motion/screen-upmost-manual.https.html
new file mode 100644
index 0000000000..560c3e3a1f
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/screen-upmost-manual.https.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>DeviceMotionEvent: A device lying flat on a horizontal surface with the screen upmost</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author' title='Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-14 -->
+ </head>
+ <body>
+ <p>Put the device on a horizontal surface with the screen upmost.</p>
+ <div id="log"></div>
+ <script>
+ var t = async_test();
+ var run = false;
+
+ /*
+ * A device lying flat on a horizontal surface with the screen upmost
+ * has an acceleration of zero and the following value for
+ * accelerationIncludingGravity:
+ * {
+ * x: 0,
+ * y: 0,
+ * z: 9.81
+ * };
+ */
+ window.addEventListener("devicemotion", function(e) {
+ if (!run) {
+ run = true;
+ t.step(function() {
+ var gvt = e.accelerationIncludingGravity;
+ var acc = e.acceleration;
+ var rot = e.rotationRate;
+
+ assert_approx_equals(gvt.x, 0, 1);
+ assert_approx_equals(gvt.y, 0, 1);
+ assert_approx_equals(gvt.z, 9.81, 1.5);
+
+ assert_approx_equals(acc.x, 0, 1);
+ assert_approx_equals(acc.y, 0, 1);
+ assert_approx_equals(acc.z, 0, 1);
+
+ assert_equals(rot, null);
+ });
+ t.done();
+ }
+ }, false);
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/motion/screen-upright-manual.https.html b/testing/web-platform/tests/orientation-event/motion/screen-upright-manual.https.html
new file mode 100644
index 0000000000..8a1b6d27da
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/screen-upright-manual.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>DeviceMotionEvent: A device with the screen upright</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author' title='Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-14 -->
+ </head>
+ <body>
+ <p>Put the device with the screen upright.</p>
+ <div id="log"></div>
+ <script>
+ var t = async_test();
+ var run = false;
+
+ /*
+ * A device with the screen upright has an acceleration of zero
+ * and the following value for accelerationIncludingGravity:
+ * {
+ * x: 0,
+ * y: -9.81,
+ * z: 0
+ * };
+ */
+ window.addEventListener("devicemotion", function(e) {
+ if (!run) {
+ run = true;
+ t.step(function() {
+ var gvt = e.accelerationIncludingGravity;
+ var acc = e.acceleration;
+ var rot = e.rotationRate;
+
+ assert_approx_equals(gvt.x, 0, 1);
+ assert_approx_equals(gvt.y, -9.81, 1.5);
+ assert_approx_equals(gvt.z, 0, 1);
+
+ assert_approx_equals(acc.x, 0, 1);
+ assert_approx_equals(acc.y, 0, 1);
+ assert_approx_equals(acc.z, 0, 1);
+
+ assert_equals(rot, null);
+ });
+ t.done();
+ }
+ }, false);
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/motion/t025-manual.https.html b/testing/web-platform/tests/orientation-event/motion/t025-manual.https.html
new file mode 100644
index 0000000000..9489855fcd
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/t025-manual.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Implementations that are unable to provide acceleration data without the effect of gravity may instead supply the acceleration including the effect of gravity</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-14 -->
+ </head>
+ <body>
+ <p>Move the device to run the test.</p>
+ <div id="log"></div>
+ <script>
+ var t1 = async_test("Implementation is unable to provide 'acceleration' property");
+ var t2 = async_test("Implementation is able to provide 'acceleration IncludingGravity' property");
+ var run = false;
+ window.ondevicemotion = function(e) {
+ if (!run) {
+ run = true;
+ t1.step(function() {
+ assert_equals(e.acceleration, null);
+ });
+ t1.done();
+ t2.step(function() {
+ var eaccgvt = e.accelerationIncludingGravity;
+ assert_equals(typeof eaccgvt, "object");
+ assert_not_equals(eaccgvt.x, 0);
+ assert_not_equals(eaccgvt.y, 0);
+ assert_not_equals(eaccgvt.z, 0);
+ });
+ t2.done();
+ }
+ };
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/motion/t028-manual.https.html b/testing/web-platform/tests/orientation-event/motion/t028-manual.https.html
new file mode 100644
index 0000000000..669c4e47e0
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/motion/t028-manual.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>The interval property must be expressed in milliseconds. It must be a constant, to simplify filtering of the data by the Web application</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-14 -->
+ </head>
+ <body>
+ <p>Move the device to run the test.</p>
+ <div id="log"></div>
+ <script>
+ var t = async_test("The interval property must be different to zero and must be a constant");
+ var inter1 = 0;
+ var inter2 = 0;
+ var run = false;
+ window.addEventListener("devicemotion", function(e) {
+ if (!run) {
+ run = true;
+ t.step(function() {
+ if (inter1 == 0) {
+ inter2 = e.interval;
+ }
+ inter1 = e.interval;
+ assert_not_equals(inter1, 0);
+ assert_not_equals(inter1, inter2);
+ });
+ t.done();
+ }
+ }, false);
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/orientation/absolute-fallback.https.html b/testing/web-platform/tests/orientation-event/orientation/absolute-fallback.https.html
new file mode 100644
index 0000000000..27a430728e
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/absolute-fallback.https.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+
+ // Make the relative orientation sensor unavailable and set mock data for
+ // the absolute one.
+ await helper.initializeSensors({enabledSensors: ['absolute-orientation'], disabledSensors: ['relative-orientation']});
+ const orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
+
+ // Check sensor values when fallback is activated.
+ await helper.setData(orientationData);
+ await waitForEvent(getExpectedOrientationEvent(orientationData));
+}, 'Tests that deviceorientation falls back to using absolute orientation data if relative is unavailable.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/orientation/add-listener-from-callback.https.html b/testing/web-platform/tests/orientation-event/orientation/add-listener-from-callback.https.html
new file mode 100644
index 0000000000..7f664ab400
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/add-listener-from-callback.https.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const orientationData1 = generateOrientationData(1.1, 2.2, 3.3, false);
+ const orientationData2 = generateOrientationData(11.1, 22.2, 33.3, false);
+
+ let firstListener = null;
+ let secondListener = null;
+ let firstEventCount = 0;
+ let firstPromise = new Promise(resolve => {
+ firstListener = async (event) => {
+ assert_true(event instanceof DeviceOrientationEvent, 'event is DeviceOrientationEvent');
+ assert_equals(event.type, 'deviceorientation', 'event.type is devicemotion');
+ assert_true(event.target instanceof Window, 'event is fired on the window object');
+ assertEventEquals(event, getExpectedOrientationEvent(orientationData1));
+ window.removeEventListener('deviceorientation', firstListener);
+ // Some implementations (e.g. Chromium) work without the call below
+ // because they disconnect from the virtual sensor in the
+ // removeEventListener() call above before connecting again, and in this
+ // case the same orientation data is still considered a significant
+ // change. This is an implementation detail though, so we explicitly pass
+ // different data here.
+ await helper.setData(orientationData2);
+ if (++firstEventCount == 1) {
+ window.addEventListener('deviceorientation', secondListener);
+ }
+ resolve(event);
+ };
+ });
+
+ let secondEventCount = 0;
+ let secondPromise = new Promise(resolve => {
+ secondListener = (event) => {
+ assertEventEquals(event, getExpectedOrientationEvent(orientationData2));
+ window.removeEventListener('deviceorientation', secondListener);
+ ++secondEventCount;
+ resolve(event);
+ };
+ });
+
+ await helper.setData(orientationData1);
+ window.addEventListener('deviceorientation', firstListener);
+ await firstPromise;
+ await secondPromise;
+ assert_equals(firstEventCount, 1, "Too many events fired for the first listener");
+ assert_equals(secondEventCount, 1, "Too many events fired for the second listener");
+}, 'Tests that adding a new deviceorientation event listener from a callback works as expected.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/orientation/basic-operation-absolute.https.html b/testing/web-platform/tests/orientation-event/orientation/basic-operation-absolute.https.html
new file mode 100644
index 0000000000..bebd69b952
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/basic-operation-absolute.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientationabsolute');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
+ await helper.setData(orientationData);
+ await waitForEvent(getExpectedAbsoluteOrientationEvent(orientationData));
+}, 'Tests basic operation of deviceorientationabsolute event using mock data.');
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientationabsolute');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors({disabledSensors: ['absolute-orientation']});
+
+ const orientationData = generateOrientationData(null, null, null, true);
+ const watcher = new EventWatcher(t, window, ['deviceorientationabsolute']);
+
+ const event = await watcher.wait_for('deviceorientationabsolute');
+ assert_equals(event.type, 'deviceorientationabsolute', 'type is set to \"deviceorientationabsolute\"');
+ assert_true(event instanceof DeviceOrientationEvent, 'event is DeviceOrientationEvent');
+
+ assertEventEquals(event, getExpectedAbsoluteOrientationEvent(orientationData));
+}, 'If UA can never provide absolute information, the event should be fired as a null event.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/orientation/basic-operation.https.html b/testing/web-platform/tests/orientation-event/orientation/basic-operation.https.html
new file mode 100644
index 0000000000..c4d26e3744
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/basic-operation.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const orientationData = generateOrientationData(1.1, 2.2, 3.3, false);
+ await helper.setData(orientationData);
+ await waitForEvent(getExpectedOrientationEvent(orientationData));
+}, 'Tests basic operation of deviceorientation event using mock data.');
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors({disabledSensors: ['relative-orientation']});
+
+ const orientationData = generateOrientationData(null, null, null, false);
+ const watcher = new EventWatcher(t, window, ['deviceorientation']);
+
+ const event = await watcher.wait_for('deviceorientation');
+ assert_equals(event.type, 'deviceorientation', 'type is set to \"deviceorientation\"');
+ assert_true(event instanceof DeviceOrientationEvent, 'event is DeviceOrientationEvent');
+
+ assertEventEquals(event, getExpectedOrientationEvent(orientationData));
+}, 'If UA can never provide orientation information, the event should be fired as a null event.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/orientation/create-event.https.html b/testing/web-platform/tests/orientation-event/orientation/create-event.https.html
new file mode 100644
index 0000000000..a21f95655e
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/create-event.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+test(test => {
+ const event = document.createEvent('DeviceOrientationEvent');
+ const newEvent = new CustomEvent("deviceorientation", {
+ bubbles: false, cancelable: false,
+ alpha: 1.0,
+ beta: 2.0,
+ gama: 3.0,
+ absolute: false
+ });
+
+ assert_equals(typeof event, 'object');
+ assert_equals(Object.getPrototypeOf(event), DeviceOrientationEvent.prototype);
+
+ assert_true('type' in event);
+ assert_true('bubbles' in event);
+ assert_true('cancelable' in event);
+ assert_true('alpha' in event);
+ assert_true('beta' in event);
+ assert_true('gamma' in event);
+ assert_true('absolute' in event);
+
+ assert_equals(typeof event.type, 'string');
+ assert_equals(typeof event.bubbles, 'boolean');
+ assert_equals(typeof event.cancelable, 'boolean');
+ assert_equals(typeof event.alpha, 'object');
+ assert_equals(typeof event.beta, 'object');
+ assert_equals(typeof event.gamma, 'object');
+ assert_equals(typeof event.absolute, 'boolean');
+
+ assert_equals(newEvent.type, "deviceorientation");
+ assert_false(newEvent.bubbles);
+ assert_false(newEvent.cancelable);
+}, 'Tests that document.createEvent() works with DeviceOrientationEvent.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/orientation/horizontal-surface-manual.https.html b/testing/web-platform/tests/orientation-event/orientation/horizontal-surface-manual.https.html
new file mode 100644
index 0000000000..0b7302e704
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/horizontal-surface-manual.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>DeviceOrientationEvent: A device lying flat on a horizontal surface</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author' title='Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-12 -->
+ </head>
+ <body>
+ <p>Put the device on a horizontal surface to run the test.</p>
+ <div id="log"></div>
+ <script>
+ var gamma, beta;
+ var run = false;
+ window.addEventListener("deviceorientation", function(e) {
+ if (!run) {
+ run = true;
+ gamma = e.gamma; // Gamma : angle par rapport a x
+ beta = e.beta; // Beta : angle par rapport a y
+ }
+ }, false);
+
+ test(function() {
+ assert_approx_equals(gamma, 0, 2);
+ }, "X angle");
+
+ test(function() {
+ assert_approx_equals(beta, 0, 2);
+ }, "Y angle");
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/orientation/multiple-event-listeners.https.html b/testing/web-platform/tests/orientation-event/orientation/multiple-event-listeners.https.html
new file mode 100644
index 0000000000..a32f9f3a1f
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/multiple-event-listeners.https.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const orientationData1 = generateOrientationData(1, 2, 3, false);
+ await helper.setData(orientationData1);
+
+ await Promise.all([
+ waitForEvent(getExpectedOrientationEvent(orientationData1)),
+ waitForEvent(getExpectedOrientationEvent(orientationData1))
+ ]);
+
+ const orientationData2 = generateOrientationData(11, 12, 13, false);
+ await helper.setData(orientationData2);
+ await waitForEvent(getExpectedOrientationEvent(orientationData2));
+}, 'Tests using multiple event handlers for the Device Orientation API.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/orientation/no-synchronous-events.https.html b/testing/web-platform/tests/orientation-event/orientation/no-synchronous-events.https.html
new file mode 100644
index 0000000000..97dccfbc31
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/no-synchronous-events.https.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const orientationData = generateOrientationData(1.1, 2.2, 3.3, false);
+ await helper.setData(orientationData);
+
+ return new Promise((resolve, reject) => {
+ let result = reject;
+ window.addEventListener('deviceorientation', event => result());
+ result = resolve;
+ });
+}, 'Tests that events are never fired synchronously from a call to window.addEventListener().');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/orientation/null-values.https.html b/testing/web-platform/tests/orientation-event/orientation/null-values.https.html
new file mode 100644
index 0000000000..c54d73da50
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/null-values.https.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors({disabledSensors: ['absolute-orientation', 'relative-orientation']});
+
+ const orientationData1 = generateOrientationData(1.1, 2.2, 3.3, false);
+ // Currently it is not possible to set individual values to null because the
+ // parsing algorithms used by
+ // https://w3c.github.io/sensors/#update-virtual-sensor-reading-command
+ // always expect numbers.
+ const orientationData2 = generateOrientationData(null, null, null, false);
+
+ // An example how setting relative-orientation sensor as disabled will output
+ // null values. Even if we try to set non null values to sensor.
+ await helper.setData(orientationData1);
+ await waitForEvent(getExpectedOrientationEvent(orientationData2));
+}, 'Tests using null values for some of the event properties.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/orientation/optional-event-properties.https.html b/testing/web-platform/tests/orientation-event/orientation/optional-event-properties.https.html
new file mode 100644
index 0000000000..150ce5ca1d
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/optional-event-properties.https.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+test(test => {
+ event = document.createEvent('DeviceOrientationEvent');
+ assert_equals(event.type, "");
+ assert_equals(event.alpha, null);
+ assert_equals(event.beta, null);
+ assert_equals(event.gamma, null);
+ assert_false(event.absolute);
+}, 'Tests creating a DeviceOrientationEvent.');
+
+test(test => {
+ event = new DeviceOrientationEvent('foo', {alpha: 0, beta: 1, gamma: 2, absolute: false});
+ assert_equals(event.type, "foo");
+ assert_equals(event.alpha, 0);
+ assert_equals(event.beta, 1);
+ assert_equals(event.gamma, 2);
+ assert_false(event.absolute);
+}, 'Tests no missing value (absolute field is false).');
+
+test(test => {
+ event = new DeviceOrientationEvent('', {alpha: 0, beta: 1, gamma: 2, absolute: true});
+ assert_equals(event.alpha, 0);
+ assert_equals(event.beta, 1);
+ assert_equals(event.gamma, 2);
+ assert_true(event.absolute);
+}, 'Tests no missing value (absolute field is true).');
+
+test(test => {
+ event = new DeviceOrientationEvent('');
+ assert_equals(event.alpha, null);
+ assert_equals(event.beta, null);
+ assert_equals(event.gamma, null);
+ assert_false(event.absolute);
+}, 'Tests DeviceOrientationEvent default constructor.');
+
+test(test => {
+ event = new DeviceOrientationEvent('', {alpha: [], beta: [], gamma: [], absolute: []});
+ assert_equals(event.alpha, 0);
+ assert_equals(event.beta, 0);
+ assert_equals(event.gamma, 0);
+ assert_true(event.absolute);
+}, 'Tests all values are empty array.');
+
+test(test => {
+ event = new DeviceOrientationEvent('', {alpha: undefined, beta: undefined, gamma: undefined, absolute: undefined});
+ assert_equals(event.alpha, null);
+ assert_equals(event.beta, null);
+ assert_equals(event.gamma, null);
+ assert_false(event.absolute);
+}, 'Tests all values are undefined.');
+
+test(test => {
+ event = new DeviceOrientationEvent('', {alpha: '', beta: '', gamma: '', absolute: ''});
+ assert_equals(event.alpha, 0);
+ assert_equals(event.beta, 0);
+ assert_equals(event.gamma, 0);
+ assert_false(event.absolute);
+}, 'Tests all values are empty string.');
+
+
+test(test => {
+ event = new DeviceOrientationEvent('', {alpha: null, beta: null, gamma: null, absolute: null});
+ assert_equals(event.alpha, null);
+ assert_equals(event.beta, null);
+ assert_equals(event.gamma, null);
+ assert_false(event.absolute);
+}, 'Tests all values are null.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/orientation/page-visibility.https.html b/testing/web-platform/tests/orientation-event/orientation/page-visibility.https.html
new file mode 100644
index 0000000000..bcb4beeb8e
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/page-visibility.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<body>
+<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>
+<script src="/page-visibility/resources/window_state_context.js"></script>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const orientationData = generateOrientationData(1, 2, 3, false);
+
+ await helper.setData(orientationData);
+ const event = getExpectedOrientationEvent(orientationData);
+ await waitForEvent(event);
+
+ const {minimize, restore} = window_state_context(t);
+ await minimize();
+ assert_true(document.hidden);
+
+ let hiddenEventPromise = new Promise((resolve, reject) => {
+ window.addEventListener(
+ 'deviceorientation',
+ event => {
+ if (document.hidden) {
+ reject();
+ } else {
+ resolve();
+ }
+ },
+ { once: true });
+ });
+
+ // Sleep for a while to make sure no deviceorientation events are fired
+ // while the page is hidden.
+ await new Promise(resolve => { t.step_timeout(resolve, 100); });
+ await restore();
+ assert_false(document.hidden);
+ return Promise.all([hiddenEventPromise, waitForEvent(event)]);
+}, 'Tests to check that deviceorientation events are not fired when the page is not visible.');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/orientation-event/orientation/requestPermission.https.window.js b/testing/web-platform/tests/orientation-event/orientation/requestPermission.https.window.js
new file mode 100644
index 0000000000..4a39a238d0
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/requestPermission.https.window.js
@@ -0,0 +1,48 @@
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+
+'use strict';
+
+// The Device Orientation spec does not fully integrate with the Permissions
+// spec and does not list the permissions that are expected for
+// requestPermission() to work. The list below was based on the permissions
+// listed in https://w3c.github.io/orientation-sensor/#model for the low-level
+// sensors that power absolute and relative orientation sensors.
+const permissionDescriptorNames =
+ ['accelerometer', 'gyroscope', 'magnetometer'];
+
+promise_test(async (t) => {
+ await Promise.all(permissionDescriptorNames.map(
+ name => test_driver.set_permission({name}, 'granted')));
+
+ const permission = await DeviceOrientationEvent.requestPermission();
+ assert_equals(permission, 'granted');
+}, 'requestPermission() returns "granted" for granted permissions without user activation');
+
+promise_test(async (t) => {
+ await Promise.all(permissionDescriptorNames.map(
+ name => test_driver.set_permission({name}, 'granted')));
+
+ return test_driver.bless('enable user activation', async () => {
+ const permission = await DeviceOrientationEvent.requestPermission();
+ assert_equals(permission, 'granted');
+ });
+}, 'requestPermission() returns "granted" for granted permissions with user activation');
+
+promise_test(async (t) => {
+ await Promise.all(permissionDescriptorNames.map(
+ name => test_driver.set_permission({name}, 'denied')));
+
+ const permission = await DeviceOrientationEvent.requestPermission();
+ assert_equals(permission, 'denied');
+}, 'requestPermission() returns "denied" for denied permissions without user activation');
+
+promise_test(async (t) => {
+ await Promise.all(permissionDescriptorNames.map(
+ name => test_driver.set_permission({name}, 'denied')));
+
+ return test_driver.bless('enable user activation', async () => {
+ const permission = await DeviceOrientationEvent.requestPermission();
+ assert_equals(permission, 'denied');
+ });
+}, 'requestPermission() returns "denied" for denied permissions with user activation');
diff --git a/testing/web-platform/tests/orientation-event/orientation/t006-manual.https.html b/testing/web-platform/tests/orientation-event/orientation/t006-manual.https.html
new file mode 100644
index 0000000000..e41f4634e8
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/t006-manual.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Rotate the device frame around its z axis</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-12 -->
+ </head>
+ <body>
+ <p>Rotate the device frame around its z axis to run the test.</p>
+ <div id="log"></div>
+ <script>
+ var t1 = async_test("Alpha is in [0, 360)");
+ var run = false;
+ window.addEventListener("deviceorientation", function(e) {
+ if (!run && e.alpha !== null) {
+ run = true;
+ t1.step(function() {
+ assert_greater_than_equal(e.alpha, 0);
+ assert_less_than(e.alpha, 360);
+ });
+ t1.done();
+ }
+ }, false);
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/orientation/t009-manual.https.html b/testing/web-platform/tests/orientation-event/orientation/t009-manual.https.html
new file mode 100644
index 0000000000..d00f7e71b0
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/t009-manual.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Rotate the device frame around its x axis</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-12 -->
+ </head>
+ <body>
+ <p>Rotate the device frame around its x axis to run the test.</p>
+ <div id="log"></div>
+ <script>
+ var t1 = async_test("Beta is in [-180, 180)");
+ var run = false;
+ window.addEventListener("deviceorientation", function(e) {
+ if (!run && e.beta !== null) {
+ run = true;
+ t1.step(function() {
+ assert_greater_than_equal(e.beta, -180);
+ assert_less_than(e.beta, 180);
+ });
+ t1.done();
+ }
+ }, false);
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/orientation/t010-manual.https.html b/testing/web-platform/tests/orientation-event/orientation/t010-manual.https.html
new file mode 100644
index 0000000000..9a6e00e1f7
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/t010-manual.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Rotate the device frame around its y axis</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-12 -->
+ </head>
+ <body>
+ <p>Rotate the device frame around its y axis to run the test.</p>
+ <div id="log"></div>
+ <script>
+ var t1 = async_test("Gamma is in [-90, 90)");
+ var run = false;
+ window.addEventListener("deviceorientation", function(e) {
+ if (!run && e.gamma !== null) {
+ run = true;
+ t1.step(function() {
+ assert_greater_than_equal(e.gamma, -90);
+ assert_less_than(e.gamma, 90);
+ });
+ t1.done();
+ }
+ }, false);
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/orientation/t012-manual.https.html b/testing/web-platform/tests/orientation-event/orientation/t012-manual.https.html
new file mode 100644
index 0000000000..e5ac1c98b4
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/t012-manual.https.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Implementations that are unable to provide all three angles must set the values of the unknown angles to null</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="Mosquito FP7">
+ <link rel="reviewer author" title="Zhiqiang Zhang" href="mailto:zhiqiang.zhang@intel.com"> <!-- 2013-10-12 -->
+ </head>
+ <body>
+ <p>Precondition: implementation is unable to provide all three angles</p>
+ <p>Rotate the device to run the test.</p>
+ <div id="log"></div>
+ <script>
+ var t1 = async_test("Alpha, Beta and Gamma are null. absolute is false.");
+ var run = false;
+ window.addEventListener("deviceorientation", function(e) {
+ if (!run) {
+ run = true;
+ t1.step(function() {
+ assert_equals(e.alpha, null, "alpha is set to null");
+ assert_equals(e.beta, null, "beta is set to null");
+ assert_equals(e.gamma, null, "gamma is set to null");
+ assert_false(e.absolute, "absolute is set to false");
+ });
+ t1.done();
+ }
+ }, false);
+
+ test(function() {
+ var evt = new DeviceOrientationEvent("foo");
+ assert_equals(evt.alpha, null, "alpha is set to null");
+ assert_equals(evt.beta, null, "beta is set to null");
+ assert_equals(evt.gamma, null, "gamma is set to null");
+ assert_false(evt.absolute, "absolute is set to false");
+ }, "User created event is initialized properly");
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/orientation-event/orientation/updates.https.html b/testing/web-platform/tests/orientation-event/orientation/updates.https.html
new file mode 100644
index 0000000000..fe1811535b
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/orientation/updates.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<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>
+<script src="../resources/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const orientationData1 = generateOrientationData(1.1, 2.2, 3.3, false);
+ await helper.setData(orientationData1);
+ await waitForEvent(getExpectedOrientationEvent(orientationData1));
+
+ const orientationData2 = generateOrientationData(11.1, 22.2, 33.3, false);
+ await helper.setData(orientationData2);
+ await waitForEvent(getExpectedOrientationEvent(orientationData2));
+}, 'Tests that updates to the relative orientation causes new events to fire.');
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientationabsolute');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const orientationData1 = generateOrientationData(1.1, 2.2, 3.3, true);
+ await helper.setData(orientationData1);
+ await waitForEvent(getExpectedAbsoluteOrientationEvent(orientationData1));
+
+ const orientationData2 = generateOrientationData(11.1, 22.2, 33.3, true);
+ await helper.setData(orientationData2);
+ await waitForEvent(getExpectedAbsoluteOrientationEvent(orientationData2));
+}, 'Tests that updates to the absolute orientation causes new events to fire.');
+</script>
diff --git a/testing/web-platform/tests/orientation-event/resources/orientation-event-helpers.js b/testing/web-platform/tests/orientation-event/resources/orientation-event-helpers.js
new file mode 100644
index 0000000000..01e91c62ae
--- /dev/null
+++ b/testing/web-platform/tests/orientation-event/resources/orientation-event-helpers.js
@@ -0,0 +1,274 @@
+'use strict';
+
+// @class SensorTestHelper
+//
+// SensorTestHelper is a helper utilities for orientation event tests.
+//
+// Usage example with device orientation:
+// const helper = new SensorTestHelper(t, 'deviceorientation');
+// await helper.grantSensorsPermissions();
+// await helper.initializeSensors();
+// const generatedData = generateOrientationData(1, 2, 3, false);
+// await helper.setData(generatedData);
+// await waitForEvent(getExpectedOrientationEvent(generatedData));
+class SensorTestHelper {
+ #eventName;
+ #sensorsEnabledByDefault;
+ #enabledSensors;
+ #disabledSensors;
+ #testObject;
+
+ // @param {object} t - A testharness.js subtest instance.
+ // @param {string} eventName - A name of event. Accepted values are
+ // devicemotion, deviceorientation or
+ // deviceorientationabsolute.
+ constructor(t, eventName) {
+ this.#eventName = eventName;
+ this.#testObject = t;
+ this.#testObject.add_cleanup(() => this.reset());
+
+ switch (this.#eventName) {
+ case 'devicemotion':
+ this.#sensorsEnabledByDefault =
+ new Set(['accelerometer', 'gyroscope', 'linear-acceleration']);
+ break;
+ case 'deviceorientation':
+ this.#sensorsEnabledByDefault = new Set(['relative-orientation']);
+ break;
+ case 'deviceorientationabsolute':
+ this.#sensorsEnabledByDefault = new Set(['absolute-orientation']);
+ break;
+ default:
+ throw new Error(`Invalid event name ${this.#eventName}`);
+ }
+ }
+
+ // Creates virtual sensors that will be used in tests.
+ //
+ // This function must be called before event listeners are added or calls
+ // to setData() or waitForEvent() are made.
+ //
+ // The |options| parameter is an object that accepts the following entries:
+ // - enabledSensors: A list of virtual sensor names that will be created
+ // instead of the default ones for a given event type.
+ // - disabledSensors: A list of virtual sensor names that will be created
+ // in a disabled state, so that creating a sensor of
+ // a given type is guaranteed to fail.
+ // An Error is thrown if the same name is passed to both options.
+ //
+ // A default list of virtual sensors based on the |eventName| parameter passed
+ // to the constructor is used if |options| is not specified.
+ //
+ // Usage examples
+ // Use default sensors for the given event type:
+ // await helper.initializeSensors()
+ // Enable specific sensors:
+ // await helper.initializeSensors({
+ // enabledSensors: ['accelerometer', 'gyroscope']
+ // })
+ // Disable some sensors, make some report as not available:
+ // await helper.initializeSensors({
+ // disabledSensors: ['gyroscope']
+ // })
+ // Enable some sensors, make some report as not available:
+ // await helper.initializeSensors({
+ // enabledSensors: ['accelerometer'],
+ // disabledSensors: ['gyroscope']
+ // })
+ async initializeSensors(options = {}) {
+ this.#disabledSensors = new Set(options.disabledSensors || []);
+ // Check that a sensor name is not in both |options.enabledSensors| and
+ // |options.disabledSensors|.
+ for (const sensor of (options.enabledSensors || [])) {
+ if (this.#disabledSensors.has(sensor)) {
+ throw new Error(`${sensor} can be defined only as enabledSensors or disabledSensors`);
+ }
+ }
+
+ this.#enabledSensors = new Set(options.enabledSensors || this.#sensorsEnabledByDefault);
+ // Remove sensors from enabledSensors that are in disabledSensors
+ for (const sensor of this.#disabledSensors) {
+ this.#enabledSensors.delete(sensor);
+ }
+
+ const createVirtualSensorPromises = [];
+ for (const sensor of this.#enabledSensors) {
+ createVirtualSensorPromises.push(
+ test_driver.create_virtual_sensor(sensor));
+ }
+ for (const sensor of this.#disabledSensors) {
+ createVirtualSensorPromises.push(
+ test_driver.create_virtual_sensor(sensor, {connected: false}));
+ }
+ await Promise.all(createVirtualSensorPromises);
+ }
+
+ // Updates virtual sensor with given data.
+ // @param {object} data - Generated data by generateMotionData or
+ // generateOrientationData which is passed to
+ // test_driver.update_virtual_sensor().
+ async setData(data) {
+ // WebDriver expects numbers for all values in the readings it receives. We
+ // convert null to zero here, but any other numeric value would work, as it
+ // is the presence of one or more sensors in initializeSensors()'
+ // options.disabledSensors that cause null to be reported in one or more
+ // event attributes.
+ const nullToZero = x => (x === null ? 0 : x);
+ if (this.#eventName === 'devicemotion') {
+ const degToRad = Math.PI / 180;
+ await Promise.all([
+ test_driver.update_virtual_sensor('accelerometer', {
+ 'x': nullToZero(data.accelerationIncludingGravityX),
+ 'y': nullToZero(data.accelerationIncludingGravityY),
+ 'z': nullToZero(data.accelerationIncludingGravityZ),
+ }),
+ test_driver.update_virtual_sensor('linear-acceleration', {
+ 'x': nullToZero(data.accelerationX),
+ 'y': nullToZero(data.accelerationY),
+ 'z': nullToZero(data.accelerationZ),
+ }),
+ test_driver.update_virtual_sensor('gyroscope', {
+ 'x': nullToZero(data.rotationRateAlpha) * degToRad,
+ 'y': nullToZero(data.rotationRateBeta) * degToRad,
+ 'z': nullToZero(data.rotationRateGamma) * degToRad,
+ }),
+ ]);
+ } else {
+ const sensorType =
+ data.absolute ? 'absolute-orientation' : 'relative-orientation';
+ await test_driver.update_virtual_sensor(sensorType, {
+ alpha: nullToZero(data.alpha),
+ beta: nullToZero(data.beta),
+ gamma: nullToZero(data.gamma),
+ });
+ }
+ }
+
+ // Grants permissions to sensors. Depending on |eventName|, requests
+ // permission to use either the DeviceMotionEvent or the
+ // DeviceOrientationEvent API.
+ async grantSensorsPermissions() {
+ // Required by all event types.
+ await test_driver.set_permission({name: 'accelerometer'}, 'granted');
+ await test_driver.set_permission({name: 'gyroscope'}, 'granted');
+ if (this.#eventName == 'deviceorientationabsolute') {
+ await test_driver.set_permission({name: 'magnetometer'}, 'granted');
+ }
+
+ const interfaceName = this.#eventName == 'devicemotion' ?
+ DeviceMotionEvent :
+ DeviceOrientationEvent;
+ await test_driver.bless('enable user activation', async () => {
+ const permission = await interfaceName.requestPermission();
+ assert_equals(permission, 'granted');
+ });
+ }
+
+ // Resets SensorTestHelper to default state. Removes all created virtual
+ // sensors.
+ async reset() {
+ const createdVirtualSensors =
+ new Set([...this.#enabledSensors, ...this.#disabledSensors]);
+
+ const sensorRemovalPromises = [];
+ for (const sensor of createdVirtualSensors) {
+ sensorRemovalPromises.push(test_driver.remove_virtual_sensor(sensor));
+ }
+ await Promise.all(sensorRemovalPromises);
+ }
+}
+
+function generateMotionData(
+ accelerationX, accelerationY, accelerationZ, accelerationIncludingGravityX,
+ accelerationIncludingGravityY, accelerationIncludingGravityZ,
+ rotationRateAlpha, rotationRateBeta, rotationRateGamma, interval = 16) {
+ const motionData = {
+ accelerationX: accelerationX,
+ accelerationY: accelerationY,
+ accelerationZ: accelerationZ,
+ accelerationIncludingGravityX: accelerationIncludingGravityX,
+ accelerationIncludingGravityY: accelerationIncludingGravityY,
+ accelerationIncludingGravityZ: accelerationIncludingGravityZ,
+ rotationRateAlpha: rotationRateAlpha,
+ rotationRateBeta: rotationRateBeta,
+ rotationRateGamma: rotationRateGamma,
+ interval: interval
+ };
+ return motionData;
+}
+
+function generateOrientationData(alpha, beta, gamma, absolute) {
+ const orientationData =
+ {alpha: alpha, beta: beta, gamma: gamma, absolute: absolute};
+ return orientationData;
+}
+
+function assertEventEquals(actualEvent, expectedEvent) {
+ // If two doubles differ by less than this amount, we can consider them
+ // to be effectively equal.
+ const EPSILON = 1e-8;
+
+ for (let key1 of Object.keys(Object.getPrototypeOf(expectedEvent))) {
+ if (typeof expectedEvent[key1] === 'object' &&
+ expectedEvent[key1] !== null) {
+ assertEventEquals(actualEvent[key1], expectedEvent[key1]);
+ } else if (typeof expectedEvent[key1] === 'number') {
+ assert_approx_equals(
+ actualEvent[key1], expectedEvent[key1], EPSILON, key1);
+ } else {
+ assert_equals(actualEvent[key1], expectedEvent[key1], key1);
+ }
+ }
+}
+
+function getExpectedOrientationEvent(expectedOrientationData) {
+ return new DeviceOrientationEvent('deviceorientation', {
+ alpha: expectedOrientationData.alpha,
+ beta: expectedOrientationData.beta,
+ gamma: expectedOrientationData.gamma,
+ absolute: expectedOrientationData.absolute,
+ });
+}
+
+function getExpectedAbsoluteOrientationEvent(expectedOrientationData) {
+ return new DeviceOrientationEvent('deviceorientationabsolute', {
+ alpha: expectedOrientationData.alpha,
+ beta: expectedOrientationData.beta,
+ gamma: expectedOrientationData.gamma,
+ absolute: expectedOrientationData.absolute,
+ });
+}
+
+function getExpectedMotionEvent(expectedMotionData) {
+ return new DeviceMotionEvent('devicemotion', {
+ acceleration: {
+ x: expectedMotionData.accelerationX,
+ y: expectedMotionData.accelerationY,
+ z: expectedMotionData.accelerationZ,
+ },
+ accelerationIncludingGravity: {
+ x: expectedMotionData.accelerationIncludingGravityX,
+ y: expectedMotionData.accelerationIncludingGravityY,
+ z: expectedMotionData.accelerationIncludingGravityZ,
+ },
+ rotationRate: {
+ alpha: expectedMotionData.rotationRateAlpha,
+ beta: expectedMotionData.rotationRateBeta,
+ gamma: expectedMotionData.rotationRateGamma,
+ },
+ interval: expectedMotionData.interval,
+ });
+}
+
+function waitForEvent(expected_event) {
+ return new Promise((resolve, reject) => {
+ window.addEventListener(expected_event.type, (event) => {
+ try {
+ assertEventEquals(event, expected_event);
+ resolve();
+ } catch (e) {
+ reject(e);
+ }
+ }, {once: true});
+ });
+}