testcommon.js (4728B)
1 'use strict'; 2 3 // Builds a generic structure that looks like: 4 // 5 // <div class="scroller"> // 100x100 viewport 6 // <div class="contents"></div> // 500x500 7 // </div> 8 // 9 // The |scrollerOverrides| and |contentOverrides| parameters are maps which 10 // are applied to the scroller and contents style after basic setup. 11 // 12 // Appends the outer 'scroller' element to the document body, and returns it. 13 function setupScrollTimelineTest( 14 scrollerOverrides = new Map(), contentOverrides = new Map()) { 15 let scroller = document.createElement('div'); 16 scroller.style.width = '100px'; 17 scroller.style.height = '100px'; 18 // Hide the scrollbars, but maintain the ability to scroll. This setting 19 // ensures that variability in scrollbar sizing does not contribute to test 20 // failures or flakes. 21 scroller.style.overflow = 'hidden'; 22 for (const [key, value] of scrollerOverrides) { 23 scroller.style[key] = value; 24 } 25 26 let contents = document.createElement('div'); 27 contents.style.width = '500px'; 28 contents.style.height = '500px'; 29 for (const [key, value] of contentOverrides) { 30 contents.style[key] = value; 31 } 32 33 scroller.appendChild(contents); 34 document.body.appendChild(scroller); 35 return scroller; 36 } 37 38 // Helper method to calculate the current time, implementing only step 5 of 39 // https://wicg.github.io/scroll-animations/#current-time-algorithm 40 function calculateCurrentTime( 41 currentScrollOffset, startScrollOffset, endScrollOffset) { 42 return ((currentScrollOffset - startScrollOffset) / 43 (endScrollOffset - startScrollOffset)) * 44 100; 45 } 46 47 function createScroller(test) { 48 var scroller = createDiv(test); 49 scroller.innerHTML = "<div class='contents'></div>"; 50 scroller.classList.add('scroller'); 51 // Trigger layout run. 52 scroller.scrollTop; 53 return scroller; 54 } 55 56 function createScrollerWithStartAndEnd(test, orientationClass = 'vertical') { 57 var scroller = createDiv(test); 58 scroller.innerHTML = 59 `<div class='contents'> 60 <div id='start'></div> 61 <div id='end'></div> 62 </div>`; 63 scroller.classList.add('scroller'); 64 scroller.classList.add(orientationClass); 65 66 return scroller; 67 } 68 69 function createScrollTimeline(test, options) { 70 options = options || { 71 source: createScroller(test) 72 } 73 return new ScrollTimeline(options); 74 } 75 76 function createScrollLinkedAnimation(test, timeline) { 77 return createScrollLinkedAnimationWithTiming(test, /* duration in ms*/ 1000, timeline); 78 } 79 80 function createScrollLinkedAnimationWithTiming(test, timing, timeline) { 81 if (timeline === undefined) 82 timeline = createScrollTimeline(test); 83 const KEYFRAMES = { opacity: [0, 1] }; 84 return new Animation( 85 new KeyframeEffect(createDiv(test), KEYFRAMES, timing), timeline); 86 } 87 88 function createViewTimeline(t) { 89 const parent = document.querySelector('.scroller'); 90 const elem = document.createElement('div'); 91 elem.id = 'target'; 92 t.add_cleanup(() => { 93 elem.remove(); 94 }); 95 parent.appendChild(elem); 96 return new ViewTimeline({ subject: elem }); 97 } 98 99 function createAnimation(t) { 100 const elem = createDiv(t); 101 const animation = elem.animate({ opacity: [1, 0] }, 1000); 102 return animation; 103 } 104 105 function assert_approx_equals_or_null(actual, expected, tolerance, name) { 106 if (actual === null || expected === null){ 107 assert_equals(actual, expected, name); 108 } 109 else { 110 assert_approx_equals(actual, expected, tolerance, name); 111 } 112 } 113 114 function assert_percents_approx_equal(actual, expected, maxScroll, 115 description) { 116 // Base the tolerance on being out by up to half a pixel. 117 const tolerance = 0.5 / maxScroll * 100; 118 assert_equals(actual.unit, "percent", `'actual' unit type must be ` + 119 `'percent' for "${description}"`); 120 assert_true(actual instanceof CSSUnitValue, `'actual' must be of type ` + 121 `CSSNumberish for "${description}"`); 122 if (expected instanceof CSSUnitValue){ 123 // Verify that when the expected in a CSSUnitValue, it is the correct unit 124 // type 125 assert_equals(expected.unit, "percent", `'expected' unit type must be ` + 126 `'percent' for "${description}"`); 127 assert_approx_equals(actual.value, expected.value, tolerance, 128 `values do not match for "${description}"`); 129 } else if (typeof expected, "number"){ 130 assert_approx_equals(actual.value, expected, tolerance, 131 `values do not match for "${description}"`); 132 } 133 } 134 135 function assert_percents_equal(actual, expected, description) { 136 // Rough estimate of the default size of the scrollable area based on 137 // sizes in setupScrollTimelineTest. 138 const defaultScrollRange = 400; 139 return assert_percents_approx_equal(actual, expected, defaultScrollRange, 140 description); 141 }