blob: b6599a6ef7028696c0059446f3ea743f25e9cf7f [file] [log] [blame] [edit]
<!DOCTYPE html> <!-- webkit-test-runner [ ModelElementEnabled=true ModelProcessEnabled=true ModelElementImmersiveEnabled=true shouldAcceptImmersiveEnvironmentRequests=true ] -->
<meta charset="utf-8">
<title>&lt;model> immersive</title>
<script src="../../imported/w3c/web-platform-tests/resources/testdriver.js"></script>
<script src="../../resources/testdriver-vendor.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../resources/model-element-test-utils.js"></script>
<script src="../resources/model-utils.js"></script>
<body>
<script>
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
assert_true('requestImmersive' in model, 'requestImmersive should exist');
assert_equals(typeof model.requestImmersive, 'function', 'requestImmersive should be a function');
assert_true('immersiveEnabled' in document, 'document.immersiveEnabled should exist');
assert_true('immersiveElement' in document, 'document.immersiveElement should exist');
assert_true('exitImmersive' in document, 'document.exitImmersive should exist');
assert_equals(typeof document.exitImmersive, 'function', 'exitImmersive should be a function');
}, 'Immersive API exists on model and document');
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
await promise_rejects_js(t, TypeError,
model.requestImmersive(),
'Should reject without user activation'
);
assert_equals(document.immersiveElement, null, 'No immersive element without user gesture');
}, 'Model immersive request fails without user activation');
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
await model.requestImmersive();
assert_equals(document.immersiveElement, model, 'Document should reference immersive model');
}, 'Model enters immersive mode with user activation');
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
await model.requestImmersive();
assert_equals(document.immersiveElement, model, 'Model should be immersive');
await document.exitImmersive();
assert_equals(document.immersiveElement, null, 'No immersive element after exit');
}, 'Document.exitImmersive() exits immersive model');
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
await model.requestImmersive();
assert_equals(document.immersiveElement, model, 'Model is immersive after request');
if (window.testRunner)
testRunner.exitImmersive();
await t.step_wait(() => document.immersiveElement === null, "Waiting for immersive element to be null");
assert_equals(document.immersiveElement, null, 'No immersive element after exit');
}, 'WKWebview._exitImmersive() exits immersive model');
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
let modelChangeEvents = [];
let documentChangeEvents = [];
const modelHandler = () => { modelChangeEvents.push(document.immersiveElement); };
const documentHandler = () => { documentChangeEvents.push(document.immersiveElement); };
await test_driver.bless("immersive");
model.addEventListener('immersivechange', modelHandler);
document.addEventListener('immersivechange', documentHandler);
await model.requestImmersive();
await new Promise(resolve => setTimeout(resolve, 100));
model.removeEventListener('immersivechange', modelHandler);
document.removeEventListener('immersivechange', documentHandler);
assert_equals(modelChangeEvents.length, 1, 'Model should fire one immersivechange event');
assert_equals(modelChangeEvents[0], model, 'Model event should occur when model is immersive');
assert_equals(documentChangeEvents.length, 1, 'Document should fire one immersivechange event');
assert_equals(documentChangeEvents[0], model, 'Document event should reference model');
}, 'Immersivechange events fire when entering immersive');
promise_test(async t => {
const [model1, source1] = createModelAndSource(t, "../resources/cube.usdz");
const [model2, source2] = createModelAndSource(t, "../resources/heart.usdz");
await test_driver.bless("immersive");
await model1.requestImmersive();
assert_equals(document.immersiveElement, model1, 'Document should reference first model');
await test_driver.bless("immersive");
await model2.requestImmersive();
assert_equals(document.immersiveElement, model2, 'Document should reference second model');
}, 'Only one model can be immersive at a time');
promise_test(async t => {
const [model1, source1] = createModelAndSource(t, "../resources/cube.usdz");
const [model2, source2] = createModelAndSource(t, "../resources/heart.usdz");
await test_driver.bless("immersive");
await model1.requestImmersive();
assert_equals(document.immersiveElement, model1, 'Document should reference first model');
await test_driver.bless("immersive");
await model2.requestImmersive();
assert_equals(document.immersiveElement, model2, 'Document should reference second model');
await document.exitImmersive();
assert_equals(document.immersiveElement, null, 'Document immersive element should be null');
}, 'Exiting immersive model after an immersive update exits immersive mode');
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
await model.requestImmersive();
assert_equals(document.immersiveElement, model, 'Model should be immersive');
model.remove();
assert_equals(document.immersiveElement, null, 'No immersive element after removal');
}, 'Removing immersive model from DOM exits immersive mode');
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
let errorFired = false;
const errorHandler = () => { errorFired = true; };
model.addEventListener('immersiveerror', errorHandler);
await promise_rejects_js(t, TypeError,
model.requestImmersive(),
'Should reject without user activation'
);
await new Promise(resolve => setTimeout(resolve, 100));
model.removeEventListener('immersiveerror', errorHandler);
assert_true(errorFired, 'immersiveerror event should fire on failed request');
}, 'Immersiveerror event fires when request fails');
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
assert_false(model.matches(':immersive'), 'Should not match :immersive initially');
await test_driver.bless("immersive");
await model.requestImmersive();
assert_true(model.matches(':immersive'), 'Should match :immersive when immersive');
await document.exitImmersive();
assert_false(model.matches(':immersive'), 'Should not match :immersive after exit');
}, 'CSS :immersive pseudo-class matches correctly');
promise_test(async t => {
const [model, source] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
await model.requestImmersive();
assert_equals(model.complete, true, 'Model should be complete when immersive');
}, 'Model is complete once presented as immersive');
promise_test(async t => {
const [model1, source1] = createModelAndSource(t, "../resources/cube.usdz");
const [model2, source2] = createModelAndSource(t, "../resources/heart.usdz");
await test_driver.bless("immersive");
const promise1 = model1.requestImmersive();
const promise2 = promise_rejects_js(t, TypeError,
model2.requestImmersive(),
'Should reject without user activation'
);
await Promise.all([promise1, promise2]);
assert_equals(document.immersiveElement, model1, 'Model should be immersive after multiple requests');
}, 'Multiple concurrent requestImmersive calls are handled correctly');
</script>
</body>