diff options
Diffstat (limited to 'tests/wpt/tests/css/css-view-transitions')
10 files changed, 479 insertions, 6 deletions
diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/auto-name-on-descendant.html b/tests/wpt/tests/css/css-view-transitions/scoped/auto-name-on-descendant.html new file mode 100644 index 00000000000..01d570e8bfc --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/scoped/auto-name-on-descendant.html @@ -0,0 +1,110 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <!-- TODO update link --> + <link rel="help" href="https://www.w3.org/TR/css-view-transitions-2/"> + <title>Scoped element with name auto on descendant</title> +</head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + #container { + display: flex; + flex-direction: row; + position: relative; + /* Currently needed to force a stacking context in the absence of an + animation-name. + */ + will-change: opacity; + } + + .item { + background-color: teal; + color: white; + text-align: center; + line-height: 50px; + width: 50px; + height: 50px; + margin: 5px; + position: relative; + will-change: opacity; + view-transition-name: auto; + } + + #item1.active { + background-color: orange; + transform: scale(1.2); + } + + #item2.active { + background-color: salmon; + transform: scale(0.9); + } + + #item3.active { + background-color: hotpink; + transform: scale(0.8) translateX(-10px); + } + + ::view-transition-group(*) { + animation-duration: 2s; + } + + ::view-transition-old(*) { + animation-name: -ua-view-transition-fade-out; + } + + ::view-transition-new(*) { + animation-name: -ua-view-transition-fade-in; + } + +</style> +<body> + <div id="container"> + <div id="item1" class="item">A</div> + <div id="item2" class="item">B</div> + <div id="item3" class="item">C</div> + </div> +</body> +<script> + function assert_has_animations_with_name(name, count, message) { + const results = + document.getAnimations().filter(a => a.animationName == name); + assert_equals(results.length, count, message); + } + + promise_test(async t => { + const element = document.getElementById("container"); + const vt = element.startViewTransition(() => { + element.querySelectorAll('.item').forEach(el => { + el.classList.toggle('active'); + }); + }); + await vt.ready; + const results = + document.getAnimations().map((a) => { + return `${a.effect.target.id}${a.effect.pseudoElement}`; + }).sort(); + const expected = [ + 'container::view-transition-group(match-element)', + 'container::view-transition-group(match-element)', + 'container::view-transition-group(match-element)', + 'container::view-transition-new(match-element)', + 'container::view-transition-new(match-element)', + 'container::view-transition-new(match-element)', + 'container::view-transition-old(match-element)', + 'container::view-transition-old(match-element)', + 'container::view-transition-old(match-element)', + ]; + + assert_array_equals(results, expected, 'Matched pseudo-elements'); + + assert_has_animations_with_name('-ua-view-transition-fade-in', 3, + 'Fade in animation'); + assert_has_animations_with_name('-ua-view-transition-fade-out', 3, + 'Fade out animation'); + }, 'Scoped view transition with name auto on the scoped element'); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/auto-name.html b/tests/wpt/tests/css/css-view-transitions/scoped/auto-name.html new file mode 100644 index 00000000000..2d11985b398 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/scoped/auto-name.html @@ -0,0 +1,81 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <!-- TODO update link --> + <link rel="help" href="https://www.w3.org/TR/css-view-transitions-2/"> + <title>Scoped element with name auto</title> +</head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + #container { + display: flex; + flex-direction: row; + view-transition-name: auto; + position: relative; + } + + .item { + background-color: teal; + color: white; + text-align: center; + line-height: 50px; + width: 50px; + height: 50px; + margin: 5px; + display: inline-block; + } + + ::view-transition-group(*) { + animation-duration: 2s; + } + + ::view-transition-old(*) { + animation-name: -ua-view-transition-fade-out; + } + + ::view-transition-new(*) { + animation-name: -ua-view-transition-fade-in; + } +</style> +<body> + <div id="container"> + <div class="item">A</div> + <div class="item">B</div> + <div class="item">C</div> + </div> +</body> +<script> + function assert_has_animation_with_name(name, message) { + const results = + document.getAnimations().filter(a => a.animationName == name); + assert_equals(results.length, 1, message); + } + + promise_test(async t => { + const element = document.getElementById("container"); + const vt = element.startViewTransition(() => { + element.style.flexDirection = 'column'; + }); + await vt.ready; + const results = + document.getAnimations().map((a) => { + return `${a.effect.target.id}${a.effect.pseudoElement}`; + }).sort(); + const expected = [ + 'container::view-transition-group(match-element)', + 'container::view-transition-new(match-element)', + 'container::view-transition-old(match-element)', + ]; + + assert_array_equals(results, expected, 'Matched pseudo-elements'); + + assert_has_animation_with_name('-ua-view-transition-fade-in', + 'Fade in animation'); + assert_has_animation_with_name('-ua-view-transition-fade-out', + 'Fade out animation'); + }, 'Scoped view transition with name auto on the scoped element'); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/display-none-during-transition.html b/tests/wpt/tests/css/css-view-transitions/scoped/display-none-during-transition.html new file mode 100644 index 00000000000..f94d6f7fd76 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/scoped/display-none-during-transition.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <!-- TODO update link --> + <link rel="help" href="https://www.w3.org/TR/css-view-transitions-2/"> + <title>Display none during transition</title> +</head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + #target { + background-color: teal; + height: 100px; + width: 100px; + position: relative; + view-transition-name: target; + } + + .hidden { + display: none; + } + + ::view-transition-group(*) { + animation: unset; + } + + ::view-transition-old(target) { + animation: -ua-view-transition-fade-out 300s; + } + + ::view-transition-new(target) { + animation: -ua-view-transition-fade-in 300s; + } + +</style> +<body> + <div id="target")></div> +</body> +<script> + function animationsCanceledPromise() { + const animations = document.getAnimations(); + const promises = animations.map(a => a.finished); + return new Promise(async (resolve) => { + const values = await Promise.allSettled(promises); + values.forEach((result) => { + assert_equals(result.status, 'rejected'); + }); + resolve(); + }); + } + + promise_test(async t => { + const target = document.getElementById('target'); + const vt = target.startViewTransition(() => { + target.style.backgroundColor = 'orange'; + }); + await vt.ready; + const animations = document.getAnimations(); + assert_equals(animations.length, 2, + 'View transition has running animations'); + // wait for all animations to start running before hiding target. + await Promise.all([...animations.map(a => a.ready)]); + target.classList.toggle('hidden'); + // Verify that the finished promise is rejected for each of the started + // animations. + await animationsCanceledPromise(); + // Verify finished promise is resolved even though the transition did not + // run to completion. + return vt.finished; + }, 'Display none during a view transition skips the transition.'); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/document-element-start-view-transition.html b/tests/wpt/tests/css/css-view-transitions/scoped/document-element-start-view-transition.html new file mode 100644 index 00000000000..42f87f93a07 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/scoped/document-element-start-view-transition.html @@ -0,0 +1,91 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <!-- TODO update link --> + <link rel="help" href="https://www.w3.org/TR/css-view-transitions-2/"> + <title>startViewTransition on document.documentElement</title> + <link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/"> +</head> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> + :root { + view-transition-name: none; + } + #target { + width: 100px; + height: 100px; + background: blue; + contain: paint; + view-transition-name: target; + } + #target.update-1 { + height: 150px; + } + #target.update-2 { + height: 200px; + } +</style> + +<body> + <div id="target"></div> +</body> +<script> + function run_view_transtiion_test(scope1, scope2, message) { + promise_test(async t => { + let rejected_promise_tally = 0; + const target = document.getElementById("target"); + assert_implements(document.startViewTransition, + "Missing document.startViewTransition"); + + const verifyAbortedTransition = (promise) => { + return promise.then( + () => { assert_not_reached('transition aborted') }, + (reason) => { + assert_true(reason instanceof DOMException); + assert_equals(reason.code, DOMException.ABORT_ERR); + rejected_promise_tally++; + }); + }; + + const vt1 = scope1.startViewTransition(() => { + target.className = 'update-1'; + }); + const vt2 = scope2.startViewTransition(() => { + assert_equals(target.className, 'update-1'); + target.className = 'update-2'; + }); + + await verifyAbortedTransition(vt1.ready); + await vt2.ready; + + assert_equals(rejected_promise_tally, 1, + 'first transition is skipped'); + const sizeTransformAnimations = document.getAnimations().filter(a => { + return 'height' in a.effect.getKeyframes()[0]; + }); + assert_equals(sizeTransformAnimations.length, 1); + const startingHeight = + sizeTransformAnimations[0].effect.getKeyframes()[0].height; + + assert_equals(startingHeight, '150px', + 'Height change applied before capture'); + }, message); + } + + run_view_transtiion_test( + document, document.documentElement, + 'Synchronously starting a view transition on document.documentElement ' + + 'skips the previously active document view transition.'); + + run_view_transtiion_test( + document.documentElement, document, + 'Synchronously starting a view transition on document skips the ' + + 'previously active view transition on document.documentElement.'); + +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe-ref.html b/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe-ref.html new file mode 100644 index 00000000000..188cefecd3d --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe-ref.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<title>View transitions: use snapshot containing block for static position in iframe (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/#snapshot-containing-block-concept/"> + +<style> +#inner { + width: 400px; + height: 200px; +} +</style> +<iframe id="inner" srcdoc=" + <style> + body { + height: 200vh; + background: limegreen; + overflow: hidden; + } + </style> + <body></body> +"></iframe> + +<script> +onload = () => { + inner.contentWindow.scrollTo(0, 100); +}; +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe.html b/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe.html new file mode 100644 index 00000000000..1903b9cacbd --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<title>View transitions: use snapshot containing block for static position in iframe</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/#snapshot-containing-block-concept/"> +<link rel="match" href="snapshot-containing-block-static-iframe-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<script src="/common/rendering-utils.js"></script> + +<style> +#inner { + width: 400px; + height: 200px; +} +</style> +<iframe id="inner" srcdoc=" + <style> + body { + height: 200vh; + overflow: hidden; + } + ::view-transition { + position: static; + display: block; + width: 100%; + height: 100%; + background: limegreen; + } + ::view-transition-group(*), + ::view-transition-image-pair(*), + ::view-transition-old(*), + ::view-transition-new(*) { + animation-play-state: paused; + } + + </style> + <body></body> +"></iframe> +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +async function runTest() { + // Start the view transition at a scroll offset so that the snapshot + // containing block differs from the initial containing block. + inner.contentWindow.scrollTo(0, 100); + await waitForAtLeastOneFrame(); + + const contentDocument = inner.contentDocument; + let vt = inner.contentDocument.startViewTransition(); + await vt.ready; + takeScreenshot(); +} + +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-name-stacking-context-dynamic.html b/tests/wpt/tests/css/css-view-transitions/view-transition-name-stacking-context-dynamic.html new file mode 100644 index 00000000000..1a908e6f659 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-name-stacking-context-dynamic.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<meta charset="utf-8"> +<title>CSS will-change: 'will-change: view-transition-name' creates a stacking context dynamically</title> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1962862"> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/#named-and-transitioning"> +<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html"> +<style> +div { width: 100px; height: 100px } +#wc { background: red; position: relative; } +#child { position: absolute; top: 0; left: 0; z-index: -1; background: green } +</style> +<p>Test passes if there is a filled green square.</p> +<div id="wc"> + <div id="child"></div> +</div> +<script> +window.addEventListener("TestRendered", function() { + wc.style.viewTransitionName = "something"; + document.documentElement.removeAttribute("class"); +}); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html index f1940c39869..d5c0abd652c 100644 --- a/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html @@ -3,6 +3,15 @@ <link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> + +<style> +::view-transition-group(*), +::view-transition-image-pair(*), +::view-transition-old(*), +::view-transition-new(*) { + animation-play-state: paused; +} +</style> <script> test(() => { diff --git a/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition-before-ready.html b/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition-before-ready.html index 3c4ba37b26b..09e6e6cc1c9 100644 --- a/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition-before-ready.html +++ b/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition-before-ready.html @@ -37,9 +37,11 @@ promise_test(async t => { // Wait until the popup window is loaded to make sure the document we start // the view transitions is the right one. - await new Promise(resolve => { - popup_win.addEventListener('load', resolve, { once: true }); - }); + if (!popup_win.document || popup_win.document.readyState != 'complete') { + await new Promise(resolve => { + popup_win.addEventListener('load', resolve, { once: true }); + }); + } if (popup_win.document.visibilityState == "hidden") { await new Promise((resolve) => { diff --git a/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition.html b/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition.html index 8d61a3e3c53..966f23c0fdf 100644 --- a/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition.html +++ b/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition.html @@ -37,9 +37,11 @@ promise_test(async t => { // Wait until the popup window is loaded to make sure the document we update // below is the right one. - await new Promise(resolve => { - popupWin.addEventListener('load', resolve, { once: true }); - }); + if (!popupWin.document || popupWin.document.readyState != 'complete') { + await new Promise(resolve => { + popupWin.addEventListener('load', resolve, { once: true }); + }); + } let popupDoc = popupWin.document; popupDoc.documentElement.innerHTML = ` |