viewport_support.js (6795B)
1 // Simulates a small pinch-zoom to provide some page scale to make the visual 2 // viewport able to differ from the layout viewport. The amount of zoom is 3 // likely to vary between browsers so tests shouldn't rely on an exact scale 4 // factor. 5 // 6 // Simulates two fingers, 100px apart, pulling apart vertically to 200px of 7 // separation. 8 function pinchZoomIn() { 9 const viewport = window.visualViewport; 10 const center_x = Math.floor((viewport.width * viewport.scale) / 2); 11 const center_y = Math.floor((viewport.height * viewport.scale) / 2); 12 13 return new test_driver.Actions() 14 .setContext(window) 15 .addPointer("finger1", "touch") 16 .addPointer("finger2", "touch") 17 .pointerMove(center_x, center_y-50, {origin: "viewport", sourceName: "finger1"}) 18 .pointerMove(center_x, center_y+50, {origin: "viewport", sourceName: "finger2"}) 19 .pointerDown({sourceName: "finger1"}) 20 .pointerDown({sourceName: "finger2"}) 21 .pointerMove(center_x, center_y-100, {origin: "viewport", sourceName: "finger1"}) 22 .pointerMove(center_x, center_y+100, {origin: "viewport", sourceName: "finger2"}) 23 .pointerUp({sourceName: "finger1"}) 24 .pointerUp({sourceName: "finger2"}) 25 .send(); 26 } 27 28 // If scrollbars affect layout (i.e. what the CSS Overflow spec calls "classic 29 // scrollbars", as opposed to overlay scrollbars), return the scrollbar 30 // thickness in CSS pixels. Returns 0 otherwise. 31 function calculateScrollbarThickness() { 32 var container = document.createElement("div"); 33 container.style.width = "100px"; 34 container.style.height = "100px"; 35 container.style.position = "absolute"; 36 container.style.visibility = "hidden"; 37 container.style.overflow = "auto"; 38 39 document.body.appendChild(container); 40 41 var widthBefore = container.clientWidth; 42 var longContent = document.createElement("div"); 43 longContent.style.height = "1000px"; 44 container.appendChild(longContent); 45 46 var widthAfter = container.clientWidth; 47 48 container.remove(); 49 50 return widthBefore - widthAfter; 51 } 52 53 // Puts up a widget on screen instructing the user to pinch-zoom in to the 54 // given scale. The widget is sized such that the given scale is achieved. The 55 // widget is placed at (x, y) on the page. A button on the widget is used by 56 // the user to let the widget know that the user has finished. If a callback is 57 // provided, it will be called when the user dismisses the widget. 58 function showPinchWidget(scale, x, y, callback) { 59 var border = 10; 60 var width = window.innerWidth / scale - border; 61 var height = window.innerHeight / scale - border; 62 63 var box = document.createElement("div"); 64 box.style.width = width + "px"; 65 box.style.height = height + "px"; 66 67 // Adjust the x/y coordinates by the border width. We want the box to 68 // appear in a place such that if the user gets the window edges exactly on 69 // the half-point of the border they end up at x/y 70 box.style.left = x - border/2 + "px"; 71 box.style.top = y - border/2 + "px"; 72 73 box.style.position = "absolute"; 74 box.style.backgroundColor = "coral"; 75 box.style.border = border + "px solid blue"; 76 box.style.borderBottom = "0"; 77 box.style.overflow = "auto"; 78 79 var oldDocumentOverflow = document.documentElement.style.overflow; 80 81 var instructions = document.createElement("p"); 82 instructions.innerText = 83 "Pinch-zoom and align this box so that the left, right, and top " + 84 "window edges are over the border on each side. When done, click the " + 85 "'DONE' button above"; 86 instructions.style.textAlign = "center"; 87 instructions.style.fontSize = "medium"; 88 89 var button = document.createElement("button"); 90 button.innerText = "DONE"; 91 button.style.width = "50%"; 92 button.style.height = "20%"; 93 button.style.fontSize = "medium"; 94 button.style.marginLeft = "25%"; 95 button.addEventListener("click", function() { 96 box.remove(); 97 document.documentElement.style.overflow = oldDocumentOverflow; 98 if (callback) 99 callback(); 100 }); 101 102 box.appendChild(button); 103 box.appendChild(instructions); 104 105 document.documentElement.style.overflow = "hidden"; 106 107 document.body.appendChild(box); 108 } 109 110 // Ends a manual test. Must be called before any async tests are started. 111 function skipManualTest() { 112 test(function() { assert_true(false); }, "Manual Test Skipped"); 113 done(); 114 } 115 116 var stepInstructions = []; 117 var testNames = []; 118 var stepFunctions = []; 119 var steps; 120 var curStep = 0; 121 122 // Adds a manual test step to the test. A test will add a series of steps, 123 // along with instructions. Once all the tests steps are added, the test can 124 // be run by continually running the nextStep() function. All manual test steps 125 // must be added before calling nextStep. 126 // 127 // |func| A function to be executed at the given step. This function can include 128 // testharness assertions if |testName| is provided. If this is the last 129 // step, the |done()| function (used for manual testharness.js tests) 130 // will be called after |func| is executed. 131 // |testName| If provided, the |func| will be wrapped in a testharness.js 132 // async_test with this name. If null, |func| will be executed as a 133 // free function. 134 // |instructions| The text to display to the user. Note, these are shown after 135 // step is executed so these should be instructions to setup the 136 // checks in the next step. 137 function addManualTestStep(func, testName, instructions) { 138 stepFunctions.push(func); 139 testNames.push(testName); 140 stepInstructions.push(instructions); 141 } 142 143 // Runs the next step of the test. This must be called only after all test steps 144 // have been added using |addManualTestStep|. 145 // 146 // |callbackFunc| If provided, will be called with a single argument being the 147 // instruction string for the current step. Use this to update 148 // any necessary UI. 149 function nextStep(callbackFunc) { 150 if (curStep == 0) 151 _startManualTest(); 152 153 if (typeof(callbackFunc) === 'function') 154 callbackFunc(stepInstructions[curStep]); 155 156 steps[curStep](); 157 curStep++; 158 } 159 160 function _startManualTest() { 161 steps = []; 162 for (let i = 0; i < stepFunctions.length; ++i) { 163 var stepFunc = stepFunctions[i]; 164 var testName = testNames[i]; 165 if (testName) { 166 steps.push(async_test(testName).step_func(function() { 167 stepFunctions[i](); 168 this.done(); 169 if (i == stepFunctions.length - 1) 170 done(); 171 })); 172 } else { 173 steps.push(function() { 174 stepFunctions[i](); 175 if (i == stepFunctions.length - 1) 176 done(); 177 }); 178 } 179 } 180 }