blob: 4aab4c445ef0db21acc636a8b7dd45a1229731ab [file] [log] [blame]
<!DOCTYPE html>
<meta charset="utf-8">
<title>WebXR - interfaces exposed by origin trial</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/origin-trials-helper.js"></script>
<script>
let properties_to_check = {
'Navigator': ['xr']
};
// The WebXR APIs should not be present without the token.
test(t => {
OriginTrialsHelper.check_properties_missing_unless_runtime_flag(
this, properties_to_check, 'webXREnabled');
}, "WebXR's entrypoint properties are not available without a token.");
test(() => {
if (OriginTrialsHelper.is_runtime_flag_enabled('webXREnabled')) {
assert_in_array('xr-spatial-tracking', document.featurePolicy.features());
} else {
assert_equals(document.featurePolicy.features().indexOf("xr-spatial-tracking"), -1);
}
}, 'document.featurePolicy.features does not advertise xr-spatial-tracking without a token or flag.');
// Add the token, which was generated with the following command:
// tools/origin_trials/generate_token.py http://127.0.0.1:8000 WebXRDeviceM76 --expire-timestamp=2000000000
let token = "AkyVxpb70lHShWfDAoWZVaVN2iZ9BxVFtnErcD8gysTmnF+SNXlduVTCLBpcr1V2q/MFrjeqPb2BlFALolT1bAwAAABWeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiV2ViWFJEZXZpY2VNNzYiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0=";
OriginTrialsHelper.add_token(token);
// The WebXR APIs should be available now.
test(t => {
OriginTrialsHelper.check_properties_exist(this, properties_to_check);
}, "WebXR's entrypoint properties are available with origin trial token.");
test(() => {
assert_in_array('xr-spatial-tracking', document.featurePolicy.features());
}, 'document.featurePolicy.features advertises xr-spatial-tracking after token added.');
// Ensure Gamepad Extensions are NOT enabled by the WebXR origin trial token.
test(t => {
webvr_gamepad_properties = {
'Gamepad': ['pose', 'hand', 'displayId'],
};
OriginTrialsHelper.check_properties_missing_unless_runtime_flag(
this, webvr_gamepad_properties, 'webVREnabled');
}, "WebVR-specific Gamepad properties are not available with a WebXR token.");
test(t => {
webvr_gamepad_interfaces = [
'GamepadPose'
];
OriginTrialsHelper.check_interfaces_missing_unless_runtime_flag(
this, webvr_gamepad_interfaces, 'webVREnabled');
}, "WebVR-specific Gamepad interfaces are not available with a WebXR token.");
// Ensure that APIs that are not part of the core WebXR set are NOT enabled by
// the WebXR origin trial token.
test(t => {
let ar_properties = {
'XRSession': ['environmentBlendMode']
};
// TODO: Update AR support to use it's own runtime flag
OriginTrialsHelper.check_properties_missing_unless_runtime_flag(
this, ar_properties, 'webXRARModuleEnabled');
}, "AR properties are not available with a WebXR token.");
test(t => {
let hittest_properties = {
'XRSession': ['requestHitTest']
};
OriginTrialsHelper.check_properties_missing_unless_runtime_flag(
this, hittest_properties, 'webXRHitTestEnabled');
}, "Hit-test properties are not available with a WebXR token.");
test(t => {
let hittest_interfaces = [
'XRHitResult',
'XRRay'
];
OriginTrialsHelper.check_interfaces_missing_unless_runtime_flag(
this, hittest_interfaces, 'webXRHitTestEnabled');
}, "Hit-test interfaces are not available with a WebXR token.");
test(t => {
let planes_properties = {
'XRFrame': ['worldInformation'],
'XRSession': ['worldTrackingState', 'updateWorldTrackingState']
};
OriginTrialsHelper.check_properties_missing_unless_runtime_flag(
this, planes_properties, 'webXRPlaneDetectionEnabled');
}, "Plane properties are not available with a WebXR token.");
test(t => {
let planes_interfaces = [
'XRPlane',
'XRPlaneDetectionState',
'XRWorldInformation',
'XRWorldTrackingState'
];
OriginTrialsHelper.check_interfaces_missing_unless_runtime_flag(
this, planes_interfaces, 'webXRPlaneDetectionEnabled');
}, "Plane interfaces are not available with a WebXR token.");
// Ensure that AR sessions are not exposed as part of the WebXR origin trial.
// The webXREnabled check is effectively checking whether experimental features
// are enabled. This works as long as at least one AR feature is experimental.
promise_test(t => {
let promise = navigator.xr.supportsSession('immersive-ar');
if (OriginTrialsHelper.is_runtime_flag_enabled('webXREnabled')) {
return promise_rejects(t, "NotSupportedError", promise);
} else {
return promise_rejects(t, new TypeError(), promise);
}
}, "immersive-ar is not recognized by supportsSession() with a WebXR token.");
promise_test(t => {
let promise = navigator.xr.requestSession('immersive-ar');
if (OriginTrialsHelper.is_runtime_flag_enabled('webXREnabled')) {
return promise_rejects(t, "SecurityError", promise);
} else {
return promise_rejects(t, new TypeError(), promise);
}
}, "immersive-ar is not recognized by requestSession() with a WebXR token.");
// Verify the rejection reason matches that for other invalid enum values.
// It only makes sense to run these when the failure occurs.
if (!OriginTrialsHelper.is_runtime_flag_enabled('webXREnabled')) {
promise_test(t => {
return navigator.xr.supportsSession('invalid').then(function() {
assert_unreached("Promise should be rejected.")
}).catch(function(invalidReason) {
return navigator.xr.supportsSession('immersive-ar').then(function() {
assert_unreached("Promise should be rejected.")
}).catch(function(arReason) {
// Replace the enum value in the expected message. That is the only
// thing that should be different.
invalidReason.message = invalidReason.message.replace('invalid', 'immersive-ar');
assert_object_equals(invalidReason, arReason);
});
});
}, "supportsSession('immersive-ar') result matches result for other invalid values.");
promise_test(t => {
return navigator.xr.requestSession('invalid').then(function() {
assert_unreached("Promise should be rejected.")
}).catch(function(invalidReason) {
return navigator.xr.requestSession('immersive-ar').then(function() {
assert_unreached("Promise should be rejected.")
}).catch(function(arReason) {
// Replace the enum value in the expected message. That is the only
// thing that should be different.
invalidReason.message = invalidReason.message.replace('invalid', 'immersive-ar');
assert_object_equals(invalidReason, arReason);
});
});
}, "requestSession('immersive-ar') result matches result for other invalid values.");
}
</script>