Commit f4c510e1 authored by Anna Offenwanger's avatar Anna Offenwanger Committed by Commit Bot

Move XR LayoutTests over to be WPTs

Moving as many of the WebXR LayoutTests as possible over to be
WebPlatformTests. All the tests that have been moved test some
aspect of the spec (https://immersive-web.github.io/webxr/) in
a platform agnostic way.

Bug: 863557, 844772
Change-Id: I203b4c59be0daa0ca624fb0281fc33035f1be8a1
Reviewed-on: https://chromium-review.googlesource.com/1171857Reviewed-by: default avatarBrandon Jones <bajones@chromium.org>
Reviewed-by: default avatarBrian Sheedy <bsheedy@chromium.org>
Commit-Queue: Anna Offenwanger <offenwanger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585064}
parent 1b4aedb2
......@@ -9,7 +9,11 @@ class ChromeXRTest {
}
simulateDeviceConnection(init_params) {
return Promise.resolve(this.mockVRService_.addDevice(init_params));
return Promise.resolve(this.mockVRService_.addRuntime(init_params));
}
simulateDeviceDisconnection(device) {
this.mockVRService_.removeRuntime(device);
}
simulateUserActivation(callback) {
......@@ -30,10 +34,12 @@ class ChromeXRTest {
}
// Mocking class definitions
// Mock service implements both the VRService and XRDevice mojo interfaces.
class MockVRService {
constructor() {
this.bindingSet_ = new mojo.BindingSet(device.mojom.VRService);
this.devices_ = [];
this.runtimes_ = [];
this.interceptor_ =
new MojoInterfaceInterceptor(device.mojom.VRService.name);
......@@ -43,31 +49,87 @@ class MockVRService {
}
// Test methods
addDevice(fakeDeviceInit) {
let device = new MockDevice(fakeDeviceInit, this);
this.devices_.push(device);
addRuntime(fakeDeviceInit) {
let runtime = new MockRuntime(fakeDeviceInit, this);
this.runtimes_.push(runtime);
if (this.client_) {
this.client_.onDeviceChanged();
}
return device;
return runtime;
}
removeRuntime(runtime) {
// We have no way of distinguishing between devices, so just clear the
// entire list for now.
// TODO(http://crbug.com/873409) We also have no way right now to disconnect
// devices.
this.runtimes_ = [];
}
// VRService implementation.
requestDevice() {
return Promise.resolve(
{device: this.devices_[0] ? this.devices_[0].getDevicePtr() : null});
if (this.runtimes_.length > 0) {
let devicePtr = new device.mojom.XRDevicePtr();
new mojo.Binding(
device.mojom.XRDevice, this, mojo.makeRequest(devicePtr));
return Promise.resolve({device: devicePtr});
} else {
return Promise.resolve({device: null});
}
}
setClient(client) {
this.client_ = client;
}
// XRDevice implementation.
requestSession(sessionOptions, was_activation) {
let requests = [];
// Request a session from all the runtimes.
for (let i = 0; i < this.runtimes_.length; i++) {
requests[i] = this.runtimes_[i].requestRuntimeSession(sessionOptions);
}
return Promise.all(requests).then((results) => {
// Find and return the first successful result.
for (let i = 0; i < results.length; i++) {
if (results[i].session) {
return results[i];
}
}
// If there were no successful results, returns a null session.
return {session: null};
});
}
supportsSession(sessionOptions) {
let requests = [];
// Check supports on all the runtimes.
for (let i = 0; i < this.runtimes_.length; i++) {
requests[i] = this.runtimes_[i].runtimeSupportsSession(sessionOptions);
}
return Promise.all(requests).then((results) => {
// Find and return the first successful result.
for (let i = 0; i < results.length; i++) {
if (results[i].supportsSession) {
return results[i];
}
}
// If there were no successful results, returns false.
return {supportsSession: false};
});
};
}
// Implements both XRDevice and VRMagicWindowProvider. Maintains a mock for
// XRPresentationProvider.
class MockDevice {
// Implements XRFrameDataProvider and XRPresentationProvider. Maintains a mock
// for XRPresentationProvider.
class MockRuntime {
constructor(fakeDeviceInit, service) {
this.sessionClient_ = new device.mojom.XRSessionClientPtr();
this.presentation_provider_ = new MockXRPresentationProvider();
......@@ -86,13 +148,6 @@ class MockDevice {
}
}
// Functions for setup.
getDevicePtr() {
let devicePtr = new device.mojom.XRDevicePtr();
new mojo.Binding(device.mojom.XRDevice, this, mojo.makeRequest(devicePtr));
return devicePtr;
}
// Test methods.
setXRPresentationFrameData(poseMatrix, views) {
if (poseMatrix == null) {
......@@ -273,9 +328,10 @@ class MockDevice {
// do not have any use for this data at present.
}
// XRDevice implementation.
requestSession(sessionOptions, was_activation) {
return this.supportsSession(sessionOptions).then((result) => {
// Utility function
requestRuntimeSession(sessionOptions) {
return this.runtimeSupportsSession(sessionOptions).then((result) => {
// The JavaScript bindings convert c_style_names to camelCase names.
let options = new device.mojom.XRPresentationTransportOptions();
options.transportMethod =
......@@ -320,7 +376,7 @@ class MockDevice {
});
}
supportsSession(options) {
runtimeSupportsSession(options) {
return Promise.resolve({
supportsSession:
!options.immersive || this.displayInfo_.capabilities.canPresent
......
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script>
xr_promise_test("navigator.xr.requestDevice returns a device", (t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive: true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => {
t.step(() => {
assert_true(device != null);
assert_true(device instanceof XRDevice);
});
});
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script>
promise_test( (t) => {
return promise_rejects(t, 'NotFoundError', navigator.xr.requestDevice());
}, "navigator.xr.requestDevice properly rejects when there are 0 devices");
</script>
</body>
......@@ -7,7 +7,7 @@
//
// --enable-blink-features=MojoJS,MojoJSTest
function xr_promise_test(func, name, properties) {
function xr_promise_test(name, func, properties) {
promise_test(async (t) => {
// Perform any required test setup:
......@@ -20,6 +20,74 @@ function xr_promise_test(func, name, properties) {
}, name, properties);
}
// A test function which runs through the common steps of requesting a session.
// Calls the passed in test function with the session, the controller for the
// device, and the test object.
// Requires a webglCanvas on the page.
function xr_session_promise_test(
name, func, fakeDeviceInit, sessionOptions, properties) {
let testDevice;
let testDeviceController;
let testSession;
const webglCanvas = document.getElementsByTagName('canvas')[0];
if (!webglCanvas) {
promise_test(async (t) => {
Promise.reject('xr_session_promise_test requires a canvas on the page!');
}, name, properties);
}
let gl = webglCanvas.getContext('webgl', {alpha: false, antialias: false});
xr_promise_test(
name,
(t) =>
XRTest.simulateDeviceConnection(fakeDeviceInit)
.then((controller) => {
testDeviceController = controller;
return navigator.xr.requestDevice();
})
.then((device) => {
testDevice = device;
return gl.setCompatibleXRDevice(device);
})
.then(() => new Promise((resolve, reject) => {
// Perform the session request in a user gesture.
XRTest.simulateUserActivation(() => {
testDevice.requestSession(sessionOptions)
.then((session) => {
testSession = session;
// Session must have a baseLayer or frame requests
// will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl);
resolve(func(session, testDeviceController, t));
})
.catch((err) => {
reject(
'Session with params ' +
JSON.stringify(sessionOptions) +
' was rejected on device ' +
JSON.stringify(fakeDeviceInit) +
' with error: ' + err);
});
});
}))
.then(() => {
// Cleanup system state.
testSession.end().catch(() => {});
XRTest.simulateDeviceDisconnection(testDevice);
}),
properties);
}
// A utility function to create an output context as required by non-immersive
// sessions.
// https://immersive-web.github.io/webxr/#xrsessioncreationoptions-interface
function getOutputContext() {
let outputCanvas = document.createElement('canvas');
document.body.appendChild(outputCanvas);
return outputCanvas.getContext('xrpresent');
}
// This functions calls a callback with each API object as specified
// by https://immersive-web.github.io/webxr/spec/latest/, allowing
// checks to be made on all ojects.
......@@ -59,8 +127,13 @@ let loadChromiumResources = Promise.resolve().then(() => {
let chain = Promise.resolve();
['/gen/layout_test_data/mojo/public/js/mojo_bindings.js',
'/gen/ui/gfx/geometry/mojo/geometry.mojom.js',
'/gen/mojo/public/mojom/base/time.mojom.js',
'/gen/gpu/ipc/common/mailbox_holder.mojom.js',
'/gen/gpu/ipc/common/sync_token.mojom.js',
'/gen/ui/display/mojo/display.mojom.js',
'/gen/ui/gfx/geometry/mojo/geometry.mojom.js',
'/gen/ui/gfx/mojo/gpu_fence_handle.mojom.js',
'/gen/ui/gfx/mojo/transform.mojom.js',
'/gen/device/vr/public/mojom/vr_service.mojom.js',
'/resources/chromium/webxr-test.js', '/resources/testdriver.js',
'/resources/testdriver-vendor.js',
......
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
xr_promise_test("webglCanvasContext can be created with an XRDevice",
(t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => {
webglCanvas = document.getElementById('webgl-canvas');
gl = webglCanvas.getContext('webgl', {compatibleXRDevice: device});
assert_equals(gl.getContextAttributes().compatibleXRDevice, device);
// Check that an offscreen context behaves no different.
let offscreenCanvas = document.createElement('canvas');
let offscreenGl = webglCanvas.getContext(
'webgl', {compatibleXRDevice: device});
assert_equals(
offscreenGl.getContextAttributes().compatibleXRDevice, device);
});
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
xr_promise_test(
"A lost webglCanvasContext should not be able to set device",
(t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => {
webglCanvas = document.getElementById('webgl-canvas');
gl = webglCanvas.getContext('webgl', {compatibleXRDevice: device});
gl.getExtension('WEBGL_lose_context').loseContext();
return promise_rejects(t, 'InvalidStateError',
gl.setCompatibleXRDevice(device));
});
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
xr_session_promise_test(
"Tests requestSession resolves when supported",
(session) => {
assert_not_equals(session, null);
}, { supportsImmersive:true }, { immersive: true });
</script>
</body>
\ No newline at end of file
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script>
xr_promise_test(
"Requesting immersive session outside of a user gesture rejects",
(t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => promise_rejects(
t, 'SecurityError', device.requestSession({ immersive: true })));
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script>
xr_promise_test(
"Requesting an immersive session when unsupported rejects",
(t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:false })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (magicWindowOnlyDevice) => new Promise((resolve) => {
XRTest.simulateUserActivation( () => {
resolve(promise_rejects(
t,
"NotSupportedError",
magicWindowOnlyDevice.requestSession({ immersive: true })
))
});
}));
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script>
xr_promise_test(
"Requesting non-immersive session outside of a user gesture succeeds",
(t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:false })
.then( (controller) => { return navigator.xr.requestDevice(); })
.then( (device) => device.requestSession({
immersive: false,
outputContext: getOutputContext()
}))
.then( (session) => { assert_not_equals(session, null); });
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script>
xr_promise_test(
"supportsSession resolves when immersive options supported",
() => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => device.supportsSession({ immersive: true }));
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script>
xr_promise_test(
"supportsSession rejects when options not supported",
(t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:false })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => {
return promise_rejects(
t,
"NotSupportedError",
device.supportsSession({ immersive: true })
);
});
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script>
xr_promise_test(
"supportsSession resolves when non-immersive options supported",
(t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => {
// Non-immersive sessions without a outputContext should not be supported.
promise_rejects(t, 'NotSupportedError', device.supportsSession());
// Non-immersive sessions with an outputContext should be supported.
return device.supportsSession({
outputContext: getOutputContext()
});
});
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
let immersiveTestName = "XRSession requestAnimationFrame callbacks can be "
+ "unregistered with cancelAnimationFrame for immersive sessions";
let nonImmersiveTestName = "XRSession requestAnimationFrame callbacks can be "
+ "unregistered with cancelAnimationFrame for non-immersive sessions";
let fakeDeviceInitParams = { supportsImmersive:true };
let immersiveSessionOptions = { immersive: true };
let nonImmersiveSessionOptions = { outputContext: getOutputContext() };
let testFunction = (session) => new Promise((resolve, reject) => {
// Schedule and immediately cancel animation frame
session.cancelAnimationFrame(session.requestAnimationFrame(
(time, vrFrame) => { reject("Cancelled frame callback was called"); }));
let counter = 0;
let handle;
function onFrame(time, vrFrame) {
// Cancel the second animation frame.
if (handle != 0) {
session.cancelAnimationFrame(handle);
handle = 0;
}
// Run a few more animation frames to be sure that the cancelled frame isn't
// going to call.
counter++;
if (counter >= 4) {
// Ok, we're done here.
resolve();
} else {
session.requestAnimationFrame(onFrame);
}
}
// Schedule two animation frame and cancel one during on animation frame.
session.requestAnimationFrame(onFrame);
handle = session.requestAnimationFrame(
(time, vrFrame) => { reject("Cancelled frame callback was called"); });
});
xr_session_promise_test(immersiveTestName, testFunction,
fakeDeviceInitParams, immersiveSessionOptions);
xr_session_promise_test(nonImmersiveTestName, testFunction,
fakeDeviceInitParams, nonImmersiveSessionOptions);
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
let immersiveTestName = "XRSession cancelAnimationFrame does not have unexpected "
+ "behavior when given invalid handles on immersive testSession";
let nonImmersiveTestName = "XRSession cancelAnimationFrame does not have unexpected "
+ "behavior when given invalid handles on non-immersive testSession";
let fakeDeviceInitParams = { supportsImmersive:true };
let immersiveSessionOptions = { immersive: true };
let nonImmersiveSessionOptions = { outputContext: getOutputContext() };
let testFunction = (testSession) => new Promise((resolve) => {
let counter = 0;
function onFrame(time, vrFrame) {
if(counter <= 10) {
testSession.requestAnimationFrame(onFrame);
} else {
resolve();
}
counter++;
}
let handle = testSession.requestAnimationFrame(onFrame);
testSession.cancelAnimationFrame(0);
testSession.cancelAnimationFrame(-1);
testSession.cancelAnimationFrame(handle + 1);
testSession.cancelAnimationFrame(handle - 1);
testSession.cancelAnimationFrame(0.5);
testSession.cancelAnimationFrame(null);
});
xr_session_promise_test(
immersiveTestName, testFunction, fakeDeviceInitParams, immersiveSessionOptions);
xr_session_promise_test(
nonImmersiveTestName, testFunction, fakeDeviceInitParams, nonImmersiveSessionOptions);
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
xr_promise_test("Requested session has device set",
(t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => new Promise((resolve) => {
XRTest.simulateUserActivation( () => {
resolve(device.requestSession({ immersive: true }).then( (session) => {
assert_true(session.immersive);
assert_equals(session.device, device);
}));
});
}));
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
const immersivetestName = "end event fires when immersive session ends";
const nonimmersiveTestName = "end event fires when non-immersive session ends";
let watcherDone = new Event("watcherdone");
const fakeDeviceInitParams = { supportsImmersive:true };
const immersiveSessionOptions = { immersive: true };
const nonImmersiveSessionOptions = { outputContext: getOutputContext() };
let testFunction = function(session, testDeviceController, t) {
let eventWatcher = new EventWatcher(t, session, ["end", "watcherdone"]);
let eventPromise = eventWatcher.wait_for(["end", "watcherdone"]);
function onSessionEnd(event) {
t.step( () => {
assert_equals(event.session, session);
session.dispatchEvent(watcherDone);
});
}
session.addEventListener("end", onSessionEnd, false);
session.end();
return eventPromise;
};
xr_session_promise_test(immersivetestName, testFunction,
fakeDeviceInitParams, immersiveSessionOptions);
xr_session_promise_test(nonimmersiveTestName, testFunction,
fakeDeviceInitParams, nonImmersiveSessionOptions);
</script>
</body>
\ No newline at end of file
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
const identityMatrix = new Float32Array([
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
]);
const rightFakeXRViewInit =
{eye:"right", projectionMatrix: identityMatrix, viewMatrix: identityMatrix};
const leftFakeXRViewInit =
{eye:"left", projectionMatrix: identityMatrix, viewMatrix: identityMatrix};
const immersiveFakeXRDeviceInit = { supportsImmersive:true };
const webglCanvas = document.getElementById('webgl-canvas');
let gl = webglCanvas.getContext('webgl', { alpha: false, antialias: false });
let testDevice;
let testDeviceController;
let testSession;
xr_promise_test(
(t) => XRTest.simulateDeviceConnection(immersiveFakeXRDeviceInit)
.then((controller) => {
testDeviceController = controller;
return navigator.xr.requestDevice();
})
.then((device) => {
testDevice = device;
return gl.setCompatibleXRDevice(device);
})
.then(() => new Promise((resolve, reject) => {
// Perform the session request in a user gesture.
XRTest.simulateUserActivation(() => {
testDevice.requestSession({ immersive: true })
.then((session) => {
testSession = session;
return session.requestFrameOfReference('eye-level');
})
.then((frameOfRef) => {
// Session must have a baseLayer or frame requests will be ignored.
testSession.baseLayer = new XRWebGLLayer(testSession, gl);
function onFrame(time, xrFrame) {
assert_true(xrFrame instanceof XRFrame);
assert_not_equals(xrFrame.views, null);
assert_equals(xrFrame.views.length, 2);
let devicePose = xrFrame.getDevicePose(frameOfRef);
assert_not_equals(devicePose, null);
for(let i = 0; i < identityMatrix.length; i++) {
assert_equals(devicePose.poseModelMatrix[i], identityMatrix[i]);
}
assert_not_equals(devicePose.getViewMatrix(xrFrame.views[0]), null);
assert_equals(devicePose.getViewMatrix(xrFrame.views[0]).length, 16);
assert_not_equals(devicePose.getViewMatrix(xrFrame.views[1]), null);
assert_equals(devicePose.getViewMatrix(xrFrame.views[1]).length, 16);
// Test does not complete until the returned promise resolves.
resolve();
}
testDeviceController.setXRPresentationFrameData(
identityMatrix,
[rightFakeXRViewInit, leftFakeXRViewInit]
);
testSession.requestAnimationFrame(onFrame);
}).catch((err) => {
reject("Session was rejected with error: "+err);
});
});
})
),
"RequestAnimationFrame resolves with good data"
);
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
xr_promise_test(
"Test prevention of multiple simultaneous immersive sessions",
(t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => new Promise((resolve) => {
XRTest.simulateUserActivation( () => {
resolve(device.requestSession({ immersive: true })
.then( (session) => new Promise((resolve) => {
XRTest.simulateUserActivation( () => {
// Requesting a second immersive session from a device that already
// has an active immersive session should fail. Immersive sessions
// should take up the users entire view, and therefore it should
// be impossible for a user to be engaged with more than one.
resolve(promise_rejects(
t,
"InvalidStateError",
device.requestSession({ immersive: true })
).then( () => {
// End the immersive session and try again. Now the immersive
// session creation should succeed.
return session.end().then( () => new Promise((resolve) => {
XRTest.simulateUserActivation( () => {
resolve(device.requestSession({ immersive: true }));
});
}));
}));
});
})));
});
}));
});
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
let immersiveTestName = "XRSession requestAnimationFrame calls the " +
"provided callback for an immersive session";
let nonImmersiveTestName = "XRSession requestAnimationFrame calls the " +
"provided callback a non-immersive session";
let fakeDeviceInitParams = { supportsImmersive:true };
let immersiveSessionOptions = { immersive: true };
let nonImmersiveSessionOptions = { outputContext: getOutputContext() };
let testFunction = (testSession) => new Promise((resolve) => {
function onFrame(time, xrFrame) {
assert_true(xrFrame instanceof XRFrame);
// Test does not complete until the returned promise resolves.
resolve();
}
testSession.requestAnimationFrame(onFrame);
});
xr_session_promise_test(immersiveTestName, testFunction,
fakeDeviceInitParams, immersiveSessionOptions);
xr_session_promise_test(nonImmersiveTestName, testFunction,
fakeDeviceInitParams, nonImmersiveSessionOptions);
</script>
</body>
\ No newline at end of file
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
const testName = "RequestAnimationFrame resolves with good data";
const identityMatrix = new Float32Array([
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
]);
const rightFakeXRViewInit = {
eye:"right",
projectionMatrix: identityMatrix,
viewMatrix: identityMatrix
};
const leftFakeXRViewInit = {
eye:"left",
projectionMatrix: identityMatrix,
viewMatrix: identityMatrix
};
const fakeDeviceInitOptions = { supportsImmersive:true };
const sessionOptions = { immersive:true };
let testSession;
let testFunction = function(session, testDeviceController) {
testSession = session;
return session.requestFrameOfReference('eye-level')
.then((frameOfRef) => new Promise((resolve) => {
function onFrame(time, xrFrame) {
assert_true(xrFrame instanceof XRFrame);
assert_not_equals(xrFrame.views, null);
assert_equals(xrFrame.views.length, 2);
let devicePose = xrFrame.getDevicePose(frameOfRef);
assert_not_equals(devicePose, null);
for(let i = 0; i < identityMatrix.length; i++) {
assert_equals(devicePose.poseModelMatrix[i], identityMatrix[i]);
}
assert_not_equals(devicePose.getViewMatrix(xrFrame.views[0]), null);
assert_equals(devicePose.getViewMatrix(xrFrame.views[0]).length, 16);
assert_not_equals(devicePose.getViewMatrix(xrFrame.views[1]), null);
assert_equals(devicePose.getViewMatrix(xrFrame.views[1]).length, 16);
// Test does not complete until the returned promise resolves.
resolve();
}
testDeviceController.setXRPresentationFrameData(
identityMatrix,
[rightFakeXRViewInit, leftFakeXRViewInit]
);
testSession.requestAnimationFrame(onFrame);
})
);
}
xr_session_promise_test(
testName, testFunction, fakeDeviceInitOptions, sessionOptions);
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
let immersiveTestName =
"XRFrame getDevicePose updates on the next frame for immersive sessions";
let nonImmersiveTestName =
"XRFrame getDevicePose updates on the next frame for non-immersive sessions";
let fakeDeviceInitParams = { supportsImmersive: true };
let immersiveSessionOptions = { immersive: true };
let nonImmersiveSessionOptions = { outputContext: getOutputContext() };
// Valid matrices for when we don't care about specific values
const validPoseMatrix = [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1];
const validProjectionMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 3, 2, -1, -1, 0, 0, -0.2, 0];
const validViewMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 4, 3, 2, 1];
let testFunction = function(session, fakeDeviceController, t) {
return session.requestFrameOfReference("eye-level")
.then((frameOfRef) => new Promise((resolve, reject) => {
let counter = 0;
function onFrame(time, vrFrame) {
session.requestAnimationFrame(onFrame);
if (counter == 0) {
t.step( () => {
// Expecting to not get a pose since none has been supplied
assert_equals(vrFrame.getDevicePose(frameOfRef), null);
fakeDeviceController.setXRPresentationFrameData(
validPoseMatrix, [{
eye:"left",
projectionMatrix: validProjectionMatrix,
viewMatrix: validViewMatrix
}, {
eye:"right",
projectionMatrix: validProjectionMatrix,
viewMatrix: validViewMatrix
}]);
// Check that pose does not update pose within the same frame.
assert_equals(vrFrame.getDevicePose(frameOfRef), null);
});
} else {
t.step( () => {
let pose = vrFrame.getDevicePose(frameOfRef);
assert_not_equals(pose, null);
let poseMatrix = pose.poseModelMatrix;
assert_not_equals(poseMatrix, null);
for(let i = 0; i < poseMatrix.length; i++) {
assert_equals(poseMatrix[i], validPoseMatrix[i]);
}
});
// Finished.
resolve();
}
counter++;
}
session.requestAnimationFrame(onFrame);
}));
};
xr_session_promise_test(immersiveTestName, testFunction,
fakeDeviceInitParams, immersiveSessionOptions);
xr_session_promise_test(nonImmersiveTestName, testFunction,
fakeDeviceInitParams, nonImmersiveSessionOptions);
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<canvas></canvas>
<script>
let immersiveTestName =
"Immersive XRSession requestFrameOfReference returns expected objects";
let nonImmersiveTestName =
"Non-immersive XRSession requestFrameOfReference returns expected objects";
let fakeDeviceInitParams = { supportsImmersive: true };
let immersiveSessionOptions = { immersive: true };
let nonImmersiveSessionOptions = { outputContext: getOutputContext() };
let testFunction = function(session, fakeDeviceController, t) {
return promise_rejects(t, new TypeError(), session.requestFrameOfReference("foo"))
.then(() => Promise.all([
session.requestFrameOfReference("head-model").then( (frameOfRef) => {
assert_true(frameOfRef instanceof XRCoordinateSystem,
"head-model frameOfRef is not correct type.");
assert_true(frameOfRef instanceof XRFrameOfReference,
"head-model frameOfRef is not correct type.");
}),
session.requestFrameOfReference("eye-level").then( (frameOfRef) => {
assert_true(frameOfRef instanceof XRCoordinateSystem,
"eye-level frameOfRef is not correct type.");
assert_true(frameOfRef instanceof XRFrameOfReference,
"eye-level frameOfRef is not correct type.");
}),
session.requestFrameOfReference("stage").then( (frameOfRef) => {
assert_true(frameOfRef instanceof XRCoordinateSystem,
"stage frameOfRef is not correct type.");
assert_true(frameOfRef instanceof XRFrameOfReference,
"stage frameOfRef is not correct type.");
})
]));
};
xr_session_promise_test(
immersiveTestName, testFunction, fakeDeviceInitParams, immersiveSessionOptions);
xr_session_promise_test(
nonImmersiveTestName, testFunction, fakeDeviceInitParams, nonImmersiveSessionOptions);
</script>
</body>
\ No newline at end of file
'use strict';
MockVRService.prototype.setListeningForActivate = function(client) {
for (let i = 0; i < this.devices_.length; i++) {
this.devices_[i].displayClient_ = client;
for (let i = 0; i < this.runtimes_.length; i++) {
this.runtimes_[i].displayClient_ = client;
}
};
MockVRService.prototype.getImmersiveVRDisplayInfo = function() {
return Promise.resolve(
{info: this.runtimes_[0] ? this.runtimes_[0].displayInfo_ : null});
};
MockDevice.prototype.setPose = function(pose) {
MockRuntime.prototype.setPose = function(pose) {
if (pose == null) {
this.pose_ = null;
} else {
......@@ -30,14 +34,10 @@ MockDevice.prototype.setPose = function(pose) {
}
};
MockDevice.prototype.forceActivate = function(reason) {
MockRuntime.prototype.forceActivate = function(reason) {
this.displayClient_.onActivate(reason);
};
MockDevice.prototype.getImmersiveVRDisplayInfo = function() {
return Promise.resolve({info: this.displayInfo_});
};
function vr_test(func, vrDisplays, name, properties) {
let chain = Promise.resolve();
let firstDeviceController;
......
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
let testName = "Test end fires when session ends";
let watcherDone = new Event("watcherdone");
let fakeDeviceInitParams = { supportsImmersive:true };
let requestSessionOptions = [
{ immersive: true },
{ outputContext: getOutputContext() }
];
let testFunction = function(session, t) {
let eventWatcher = new EventWatcher(t, session, ["end", "watcherdone"]);
let eventPromise = eventWatcher.wait_for(["end", "watcherdone"]);
function onSessionEnd(event) {
t.step( () => {
assert_equals(event.session, session);
session.dispatchEvent(watcherDone);
});
}
session.addEventListener("end", onSessionEnd, false);
session.end();
return eventPromise;
};
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionOptions, testName);
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
let testName = "XRSession requestAnimationFrame properly calls the provided "
+ "callback";
let fakeDeviceInitParams = { supportsImmersive:true };
let requestSessionOptions = [
{ immersive: true },
{ outputContext: getOutputContext() }
];
let testFunction = (session) => new Promise((resolve) => {
// Session must have a baseLayer or frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl);
function onFrame(time, xrFrame) {
assert_true(xrFrame instanceof XRFrame);
// Test does not complete until the returned promise resolves.
resolve();
}
session.requestAnimationFrame(onFrame);
});
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionOptions, testName);
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
let testName = "XRSession cancelAnimationFrame does not have unexpected "
+ "behavior when given invalid handles";
let fakeDeviceInitParams = { supportsImmersive:true };
let requestSessionOptions = [
{ immersive: true },
{ outputContext: getOutputContext() }
];
let testFunction = (session) => new Promise((resolve) => {
// Session must have a baseLayer or frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl);
let counter = 0;
function onFrame(time, vrFrame) {
// Intentionally session.requestAnimationFrame at the beginning, ensuring that
// there's an outstanding callback when the test completes. This is to make
// sure it doesn't cause any unexpected behavior like it did with
// crbug.com/679401
session.requestAnimationFrame(onFrame);
if (counter > 10) {
resolve();
}
counter++;
}
let handle = session.requestAnimationFrame(onFrame);
session.cancelAnimationFrame(0);
session.cancelAnimationFrame(-1);
session.cancelAnimationFrame(handle + 1);
session.cancelAnimationFrame(handle - 1);
session.cancelAnimationFrame(0.5);
session.cancelAnimationFrame(null);
});
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionOptions, testName);
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
let testName = "XRSession requestAnimationFrame callbacks can be unregistered "
+ "with cancelAnimationFrame";
let fakeDeviceInitParams = { supportsImmersive:true };
let requestSessionOptions = [
{ immersive: true },
{ outputContext: getOutputContext() }
];
let testFunction = (session) => new Promise((resolve, reject) => {
// Session must have a baseLayer or frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl);
function onFrameBad(time, vrFrame) {
reject("Unregistered callback was called");
}
let counter = 0;
let handle2 = 0;
function onFrameGood(time, vrFrame) {
counter++;
if (counter >= 4) {
resolve();
// Intentionally don't return immediately so that session.requestAnimationFrame
// gets called again to make sure it doesn't cause unexpected behavior
// like in crbug.com/679401
}
session.requestAnimationFrame(onFrameGood);
if (handle2 != 0) {
// The first time we enter this callback the callback associated with
// handle2 will have already been queued to execute immediately after
// this callback returns. Ensure that cancelAnimationFrame works even in that
// scenario.
session.cancelAnimationFrame(handle2);
handle2 = 0;
}
}
let handle = session.requestAnimationFrame(onFrameBad);
session.cancelAnimationFrame(handle);
session.requestAnimationFrame(onFrameGood);
handle2 = session.requestAnimationFrame(onFrameBad);
});
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionOptions, testName);
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
let testName = "XRFrame getDevicePose updates on the next frame";
let fakeDeviceInitParams = { supportsImmersive: true };
let requestSessionOptions = [
{ immersive: true },
{ outputContext: getOutputContext() }
];
let testFunction = function(session, t, fakeDeviceController) {
// Session must have a baseLayer or else frame requests will be ignored.
session.baseLayer = new XRWebGLLayer(session, gl);
return session.requestFrameOfReference("eye-level")
.then((frameOfRef) => new Promise((resolve, reject) => {
let counter = 0;
function onFrame(time, vrFrame) {
session.requestAnimationFrame(onFrame);
if (counter == 0) {
t.step( () => {
// Expecting to not get a pose since none has been supplied
assert_equals(vrFrame.getDevicePose(frameOfRef), null);
// Need to have a valid pose or input event's don't process.
fakeDeviceController.setXRPresentationFrameData(
VALID_POSE_MATRIX, [{
eye:"left",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: VALID_VIEW_MATRIX
}, {
eye:"right",
projectionMatrix: VALID_PROJECTION_MATRIX,
viewMatrix: VALID_VIEW_MATRIX
}]);
// Check that pose does not update pose within the same frame.
assert_equals(vrFrame.getDevicePose(frameOfRef), null);
});
} else {
t.step( () => {
// Check that pose was updated.
let pose = vrFrame.getDevicePose(frameOfRef);
assert_not_equals(pose, null);
let poseMatrix = pose.poseModelMatrix;
assert_not_equals(poseMatrix, null);
assert_matrices_approx_equal(poseMatrix, VALID_POSE_MATRIX);
});
// Finished.
resolve();
}
counter++;
}
session.requestAnimationFrame(onFrame);
}));
};
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionOptions, testName);
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script>
promise_test((t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive: true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => {
t.step(() => {
assert_true(device != null);
assert_true(device instanceof XRDevice);
});
});
}, "navigator.xr.requestDevice properly returns a single device");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script>
promise_test( (t) => {
return promise_rejects(t, 'NotFoundError', navigator.xr.requestDevice());
}, "navigator.xr.requestDevice properly rejects when there are 0 devices");
</script>
......@@ -4,9 +4,9 @@
* for interal tests. The main mocked objects are found in
* ../external/wpt/resources/chromium/webxr-test.js. */
MockDevice.prototype.base_getFrameData = MockDevice.prototype.getFrameData;
MockRuntime.prototype.base_getFrameData = MockRuntime.prototype.getFrameData;
MockDevice.prototype.getFrameData = function() {
MockRuntime.prototype.getFrameData = function() {
return this.base_getFrameData().then((result) => {
if (result.frameData && result.frameData.pose && this.input_sources_) {
let input_states = [];
......@@ -21,7 +21,7 @@ MockDevice.prototype.getFrameData = function() {
});
};
MockDevice.prototype.addInputSource = function(source) {
MockRuntime.prototype.addInputSource = function(source) {
if (!this.input_sources_) {
this.input_sources_ = [];
this.next_input_source_index_ = 1;
......@@ -32,7 +32,7 @@ MockDevice.prototype.addInputSource = function(source) {
this.input_sources_.push(source);
};
MockDevice.prototype.removeInputSource = function(source) {
MockRuntime.prototype.removeInputSource = function(source) {
if (!this.input_sources_)
return;
......@@ -44,11 +44,11 @@ MockDevice.prototype.removeInputSource = function(source) {
}
};
MockDevice.prototype.setHitTestResults = function(results) {
MockRuntime.prototype.setHitTestResults = function(results) {
this.hittest_results_ = results;
};
MockDevice.prototype.requestHitTest = function(ray) {
MockRuntime.prototype.requestHitTest = function(ray) {
var hit_results = this.hittest_results_;
if (!hit_results) {
var hit = new device.mojom.XRHitResult();
......@@ -58,13 +58,13 @@ MockDevice.prototype.requestHitTest = function(ray) {
return Promise.resolve(hit_results);
};
MockDevice.prototype.setResetPose = function(to) {
MockRuntime.prototype.setResetPose = function(to) {
if (this.pose_) {
this.pose_.poseReset = to;
}
};
MockDevice.prototype.setStageTransform = function(value) {
MockRuntime.prototype.setStageTransform = function(value) {
if (value) {
if (!this.displayInfo_.stageParameters) {
this.displayInfo_.stageParameters = {
......@@ -82,11 +82,11 @@ MockDevice.prototype.setStageTransform = function(value) {
this.sessionClient_.onChanged(this.displayInfo_);
};
MockDevice.prototype.getSubmitFrameCount = function() {
MockRuntime.prototype.getSubmitFrameCount = function() {
return this.presentation_provider_.submit_frame_count_;
};
MockDevice.prototype.getMissingFrameCount = function() {
MockRuntime.prototype.getMissingFrameCount = function() {
return this.presentation_provider_.missing_frame_count_;
};
......
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
promise_test( (t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => {
webglCanvas = document.getElementById('webgl-canvas');
gl = webglCanvas.getContext('webgl', {compatibleXRDevice: device});
assert_equals(gl.getContextAttributes().compatibleXRDevice, device);
// Check that an offscreen context behaves no different.
let offscreenCanvas = document.createElement('canvas');
let offscreenGl = webglCanvas.getContext('webgl', {compatibleXRDevice: device});
assert_equals(offscreenGl.getContextAttributes().compatibleXRDevice, device);
});
}, "A webglCanvasContext created with an XRDevice has that device set");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
promise_test( (t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => {
webglCanvas = document.getElementById('webgl-canvas');
gl = webglCanvas.getContext('webgl', {compatibleXRDevice: device});
gl.getExtension('WEBGL_lose_context').loseContext();
return promise_rejects(t, 'InvalidStateError',
gl.setCompatibleXRDevice(device));
});
}, "A lost webglCanvasContext should not be able to set device");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
promise_test( (t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => promise_rejects(
t, 'SecurityError', device.requestSession({ immersive: true })));
}, "request immersive session outside of a user gesture rejects");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
xr_session_promise_test( (session) => {
assert_not_equals(session, null);
}, { supportsImmersive:true }, [{ immersive: true }],
"requestSession for an immersive session with a user gesture resolves");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
promise_test( (t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:false })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (magicWindowOnlyDevice) => new Promise((resolve) => {
runWithUserGesture( () => {
resolve(promise_rejects(
t,
"NotSupportedError",
magicWindowOnlyDevice.requestSession({ immersive: true })
))
});
}));
}, "requesting an immersive session on an unsupported device rejects");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script>
promise_test( (t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:false })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (magicWindowOnlyDevice) => {
return promise_rejects(
t,
"NotSupportedError",
magicWindowOnlyDevice.supportsSession({ immersive: true })
);
});
}, "supportsSession rejects when immersive session is not supported on device");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script>
promise_test( () => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => device.supportsSession({ immersive: true }));
}, "supportsSession resolves when support immersive session is supported on device");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<script>
promise_test( (t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => {
// Non-immersive sessions without a outputContext should not be supported.
promise_rejects(t, 'NotSupportedError', device.supportsSession());
// Non-immersive sessions with an outputContext should be supported.
return device.supportsSession({
outputContext: getOutputContext()
});
});
}, "supportsSession properly identifies supported non-immersive sessions");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
promise_test( (t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => new Promise((resolve) => {
runWithUserGesture( () => {
resolve(device.requestSession({ immersive: true }).then( (session) => {
assert_true(session.immersive);
assert_equals(session.device, device);
assert_approx_equals(session.depthNear, 0.1, FLOAT_EPSILON);
assert_approx_equals(session.depthFar, 1000.0, FLOAT_EPSILON);
}));
});
}));
}, "supportsSession returns expected immersive session");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
promise_test( (t) => {
return XRTest.simulateDeviceConnection({ supportsImmersive:true })
.then( (controller) => { return navigator.xr.requestDevice() })
.then( (device) => new Promise((resolve) => {
runWithUserGesture( () => {
resolve(device.requestSession({ immersive: true })
.then( (session) => new Promise((resolve) => {
runWithUserGesture( () => {
// Requesting a second immersive session from a device that already
// has an active immersive session should fail. Immersive sessions
// should take up the users entire view, and therefore it should
// be impossible for a user to be engaged with more than one.
resolve(promise_rejects(
t,
"InvalidStateError",
device.requestSession({ immersive: true })
).then( () => {
// End the immersive session and try again. Now the immersive
// session creation should succeed.
return session.end().then( () => new Promise((resolve) => {
runWithUserGesture( () => {
resolve(device.requestSession({ immersive: true }));
});
}));
}));
});
})));
});
}));
}, "requestSession prevents creation of multiple simultaneous immersive sessions");
</script>
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>
<script>
let testName = "requestFrameOfReference returns the expected objects";
let fakeDeviceInitParams = { supportsImmersive:true };
let requestSessionOptions = [
{ outputContext: getOutputContext() },
{ immersive: true },
];
let testFunction = function(session, t) {
return promise_rejects(t, new TypeError(), session.requestFrameOfReference("foo"))
.then(() => Promise.all([
session.requestFrameOfReference("head-model").then( (frameOfRef) => {
assert_true(frameOfRef instanceof XRCoordinateSystem,
"head-model frameOfRef is not correct type.");
assert_true(frameOfRef instanceof XRFrameOfReference,
"head-model frameOfRef is not correct type.");
}),
session.requestFrameOfReference("eye-level").then( (frameOfRef) => {
assert_true(frameOfRef instanceof XRCoordinateSystem,
"eye-level frameOfRef is not correct type.");
assert_true(frameOfRef instanceof XRFrameOfReference,
"eye-level frameOfRef is not correct type.");
}),
session.requestFrameOfReference("stage").then( (frameOfRef) => {
assert_true(frameOfRef instanceof XRCoordinateSystem,
"stage frameOfRef is not correct type.");
assert_true(frameOfRef instanceof XRFrameOfReference,
"stage frameOfRef is not correct type.");
})
]));
};
xr_session_promise_test(
testFunction, fakeDeviceInitParams, requestSessionOptions, testName);
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment