run_in_parallel.html (3621B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <!-- TODO update link --> 7 <link rel="help" href="https://www.w3.org/TR/css-view-transitions-2/"> 8 <title>Scope view transitions run in parallel</title> 9 </head> 10 <script src="/resources/testharness.js"></script> 11 <script src="/resources/testharnessreport.js"></script> 12 <style type="text/css"> 13 .block { 14 background-color: blue; 15 position: relative; 16 height: 100px; 17 width: 100px; 18 margin: 50px; 19 } 20 21 #target1 { 22 view-transition-name: a; 23 } 24 25 #target2 { 26 view-transition-name: b; 27 } 28 29 ::view-transition-group(*), 30 ::view-transition-image-pair(*), 31 ::view-transition-old(*) { 32 animation: unset; 33 } 34 35 ::view-transition-old(*) { 36 opacity: 0; 37 } 38 39 @keyframes stylize { 40 from { 41 opacity: 0.5; 42 } 43 to { 44 opacity: 1.0; 45 } 46 } 47 ::view-transition-new(*) { 48 animation: stylize 1s paused; 49 } 50 51 </style> 52 <body> 53 <div id="target1" class="block"></div> 54 <div id="target2" class="block"></div> 55 </body> 56 <script type="text/javascript"> 57 58 async function run_parallel_scoped_view_transition_test( 59 transition_update_callback, 60 message) { 61 promise_test(async t => { 62 const vt1 = target1.startViewTransition(() => {}); 63 const vt2 = target2.startViewTransition(() => {}); 64 await Promise.all([vt1.ready, vt2.ready]); 65 66 let list = document.getAnimations().map(a => { 67 return `${a.effect.pseudoElement}:${a.animationName}`; 68 }); 69 let expected = [ 70 '::view-transition-new(a):stylize', 71 '::view-transition-new(b):stylize' 72 ]; 73 assert_array_equals(list, expected, 'Before callback'); 74 assert_equals( 75 getComputedStyle(target1, "::view-transition-new(a)") 76 .getPropertyValue("opacity"), 77 "0.5"); 78 assert_equals( 79 getComputedStyle(target2, "::view-transition-new(b)") 80 .getPropertyValue("opacity"), 81 "0.5"); 82 83 transition_update_callback(vt1); 84 await vt1.finished.then( 85 () => {}, 86 () => { 87 // The only case where the finished promise should not be resolved is 88 // when the DOM update callback returns a rejected promise. 89 assert_unreached('Finished promise should have been resolved'); 90 }); 91 92 list = document.getAnimations().map(a => { 93 return `${a.effect.pseudoElement}:${a.animationName}`; 94 }); 95 assert_array_equals(list, [`::view-transition-new(b):stylize`], 96 'After callback'); 97 assert_equals( 98 getComputedStyle(target2, "::view-transition-new(b)") 99 .getPropertyValue("opacity"), 100 "0.5"); 101 }, message); 102 } 103 104 run_parallel_scoped_view_transition_test( 105 (vt) => { 106 vt.skipTransition(); 107 }, 108 'Concurrent transition keeps running after transition skipped'); 109 110 run_parallel_scoped_view_transition_test( 111 () => { 112 document.getAnimations().filter(a => { 113 return a.effect.target.id == 'target1'; 114 }).forEach(a => { 115 a.finish(); 116 }); 117 }, 'Concurrent transition keeps running after transition finished'); 118 119 run_parallel_scoped_view_transition_test( 120 () => { 121 document.getAnimations().filter(a => { 122 return a.effect.target.id == 'target1'; 123 }).forEach(a => { 124 a.cancel(); 125 }); 126 }, 'Concurrent transition keeps running after transition canceled'); 127 </script> 128 </html>