blob: 1ee6f936ba5e0942a0b13a819070d00fd20ef15d [file] [edit]
<!DOCTYPE html> <!-- webkit-test-runner [ ModelElementEnabled=true ModelProcessEnabled=true ModelElementImmersiveEnabled=true shouldAcceptImmersiveEnvironmentRequests=true ] -->
<meta charset="utf-8">
<title>&lt;model> immersive state consistency</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>
<body>
<script>
promise_test(async t => {
const [model1, source1] = createModelAndSource(t, "../resources/cube.usdz");
const [model2, source2] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
const promise1 = model1.requestImmersive();
await test_driver.bless("immersive");
const promise2 = model2.requestImmersive();
await promise_rejects_dom(t, "AbortError", promise1,
'First request should be superseded by second');
await promise2;
assert_equals(document.immersiveElement, model2,
'document.immersiveElement should match successful request');
}, 'Second request during first request completes correctly');
promise_test(async t => {
const [model1, source1] = createModelAndSource(t, "../resources/cube.usdz");
const [model2, source2] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
await model1.requestImmersive();
const exitPromise = document.exitImmersive();
await test_driver.bless("immersive");
const requestPromise = model2.requestImmersive();
await t.step_wait(() => document.immersiveElement === null, 'Waiting for immersive exit');
await t.step_wait(() => document.immersiveElement === model2, 'Waiting for new model to be immersive');
}, 'Immersive request during immersive exit should first wait for exit and then proceeds');
promise_test(async t => {
const [model1, source1] = createModelAndSource(t, "../resources/cube.usdz");
const [model2, source2] = createModelAndSource(t, "../resources/cube.usdz");
const [model3, source3] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
await model1.requestImmersive();
assert_equals(document.immersiveElement, model1);
await document.exitImmersive();
assert_equals(document.immersiveElement, null);
await test_driver.bless("immersive");
await model2.requestImmersive();
assert_equals(document.immersiveElement, model2);
await document.exitImmersive();
assert_equals(document.immersiveElement, null);
await test_driver.bless("immersive");
await model3.requestImmersive();
assert_equals(document.immersiveElement, model3);
}, 'Rapid request/exit cycles maintain consistent state');
promise_test(async t => {
const promises = [];
const models = [];
// Create 5 models and start 5 concurrent requests
for (let i = 0; i < 5; i++) {
const [model, source] = createModelAndSource(t, "../resources/teapot.usdz");
models.push(model);
await test_driver.bless("immersive", () => {
promises.push(model.requestImmersive());
});
}
const results = await Promise.allSettled(promises);
const succeeded = results.filter(r => r.status === 'fulfilled');
const failed = results.filter(r => r.status === 'rejected');
assert_equals(succeeded.length, 1, 'Exactly one request should succeed');
assert_equals(failed.length, 4, 'Four requests should be rejected');
for (const result of failed) {
assert_equals(result.reason.name, 'AbortError', 'Failed requests should reject with AbortError');
assert_true(result.reason.message.includes('superseded'), 'Failed requests should indicate they were superseded');
}
assert_equals(document.immersiveElement, models[4], 'Last request should be the one fulfilled');
}, 'Multiple concurrent requests - exactly one succeeds');
promise_test(async t => {
const [model1, source1] = createModelAndSource(t, "../resources/cube.usdz");
const [model2, source2] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
const promise1 = model1.requestImmersive();
model1.remove();
await promise_rejects_dom(t, "AbortError", promise1);
assert_equals(document.immersiveElement, null, 'No immersive element after aborted request');
await test_driver.bless("immersive");
await model2.requestImmersive();
assert_equals(document.immersiveElement, model2, 'State should be clean for new request');
}, 'State remains clean after request aborted by element removal');
promise_test(async t => {
const [model1, source1] = createModelAndSource(t, "../resources/cube.usdz");
const [model2, source2] = createModelAndSource(t, "../resources/cube.usdz");
await test_driver.bless("immersive");
await model1.requestImmersive();
const exitPromise = document.exitImmersive();
await test_driver.bless("immersive");
const requestPromise = model2.requestImmersive();
model2.remove();
await exitPromise;
await promise_rejects_dom(t, "AbortError", requestPromise);
assert_equals(document.immersiveElement, null, 'State should be clean after removal during exit');
}, 'Element removed while waiting for exit to complete');
</script>
</body>