OLD | NEW |
(Empty) | |
| 1 <!-- |
| 2 |
| 3 /* |
| 4 ** Copyright (c) 2013 The Khronos Group Inc. |
| 5 ** |
| 6 ** Permission is hereby granted, free of charge, to any person obtaining a |
| 7 ** copy of this software and/or associated documentation files (the |
| 8 ** "Materials"), to deal in the Materials without restriction, including |
| 9 ** without limitation the rights to use, copy, modify, merge, publish, |
| 10 ** distribute, sublicense, and/or sell copies of the Materials, and to |
| 11 ** permit persons to whom the Materials are furnished to do so, subject to |
| 12 ** the following conditions: |
| 13 ** |
| 14 ** The above copyright notice and this permission notice shall be included |
| 15 ** in all copies or substantial portions of the Materials. |
| 16 ** |
| 17 ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 18 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 19 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 20 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| 21 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| 22 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| 23 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. |
| 24 */ |
| 25 |
| 26 --> |
| 27 |
| 28 <!DOCTYPE html> |
| 29 <html> |
| 30 <head> |
| 31 <meta charset="utf-8"> |
| 32 <title>WebGL ANGLE_instanced_arrays Conformance Tests</title> |
| 33 <link rel="stylesheet" href="../../resources/js-test-style.css"/> |
| 34 <script src="../../resources/desktop-gl-constants.js" type="text/javascript"></s
cript> |
| 35 <script src="../../resources/js-test-pre.js"></script> |
| 36 <script src="../resources/webgl-test.js"></script> |
| 37 <script src="../resources/webgl-test-utils.js"></script> |
| 38 </head> |
| 39 <body> |
| 40 <div id="description"></div> |
| 41 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> |
| 42 <div id="console"></div> |
| 43 <!-- Shaders for testing instanced draws --> |
| 44 <script id="outputVertexShader" type="x-shader/x-vertex"> |
| 45 attribute vec4 aPosition; |
| 46 attribute vec2 aOffset; |
| 47 attribute vec4 aColor; |
| 48 varying vec4 vColor; |
| 49 void main() { |
| 50 vColor = aColor; |
| 51 gl_Position = aPosition + vec4(aOffset, 0.0, 0.0); |
| 52 } |
| 53 </script> |
| 54 |
| 55 <script id="outputFragmentShader" type="x-shader/x-fragment"> |
| 56 precision mediump float; |
| 57 varying vec4 vColor; |
| 58 void main() { |
| 59 gl_FragColor = vColor; |
| 60 } |
| 61 </script> |
| 62 |
| 63 <script> |
| 64 "use strict"; |
| 65 description("This test verifies the functionality of the ANGLE_instanced_arrays
extension, if it is available."); |
| 66 |
| 67 debug(""); |
| 68 |
| 69 var wtu = WebGLTestUtils; |
| 70 var canvas = document.getElementById("canvas"); |
| 71 var gl = wtu.create3DContext(canvas); |
| 72 var ext = null; |
| 73 |
| 74 var positionLoc = 0; |
| 75 var offsetLoc = 2; |
| 76 var colorLoc = 3; |
| 77 var program; |
| 78 |
| 79 if (!gl) { |
| 80 testFailed("WebGL context does not exist"); |
| 81 } else { |
| 82 testPassed("WebGL context exists"); |
| 83 |
| 84 runDivisorTestDisabled(); |
| 85 |
| 86 // Query the extension and store globally so shouldBe can access it |
| 87 ext = wtu.getExtensionWithKnownPrefixes(gl, "ANGLE_instanced_arrays"); |
| 88 if (!ext) { |
| 89 testPassed("No ANGLE_instanced_arrays support -- this is legal"); |
| 90 |
| 91 runSupportedTest(false); |
| 92 } else { |
| 93 testPassed("Successfully enabled ANGLE_instanced_arrays extension"); |
| 94 |
| 95 runSupportedTest(true); |
| 96 |
| 97 runDivisorTestEnabled(); |
| 98 runUniqueObjectTest(); |
| 99 |
| 100 setupCanvas(); |
| 101 runOutputTests(); |
| 102 runANGLECorruptionTest(); |
| 103 } |
| 104 } |
| 105 |
| 106 function runSupportedTest(extensionEnabled) { |
| 107 var supported = gl.getSupportedExtensions(); |
| 108 if (supported.indexOf("ANGLE_instanced_arrays") >= 0) { |
| 109 if (extensionEnabled) { |
| 110 testPassed("ANGLE_instanced_arrays listed as supported and getExtens
ion succeeded"); |
| 111 } else { |
| 112 testFailed("ANGLE_instanced_arrays listed as supported but getExtens
ion failed"); |
| 113 } |
| 114 } else { |
| 115 if (extensionEnabled) { |
| 116 testFailed("ANGLE_instanced_arrays not listed as supported but getEx
tension succeeded"); |
| 117 } else { |
| 118 testPassed("ANGLE_instanced_arrays not listed as supported and getEx
tension failed -- this is legal"); |
| 119 } |
| 120 } |
| 121 } |
| 122 |
| 123 function runDivisorTestDisabled() { |
| 124 debug("Testing VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE with extension disabled"); |
| 125 |
| 126 var VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE; |
| 127 |
| 128 gl.getVertexAttrib(0, VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE); |
| 129 glErrorShouldBe(gl, gl.INVALID_ENUM, "VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE shou
ld not be queryable if extension is disabled"); |
| 130 } |
| 131 |
| 132 function runDivisorTestEnabled() { |
| 133 debug("Testing VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE with extension enabled"); |
| 134 |
| 135 shouldBe("ext.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE", "0x88FE"); |
| 136 |
| 137 var max_vertex_attribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); |
| 138 |
| 139 for (var i = 0; i < max_vertex_attribs; ++i) { |
| 140 var queried_value = gl.getVertexAttrib(i, ext.VERTEX_ATTRIB_ARRAY_DIVISO
R_ANGLE); |
| 141 if(queried_value == 0){ |
| 142 testPassed("Vertex attribute " + i + " must has a default divisor of
0"); |
| 143 } |
| 144 else{ |
| 145 testFailed("Default divisor of vertex attribute " + i + " should be:
0, returned value was: " + queried_value); |
| 146 } |
| 147 } |
| 148 |
| 149 ext.vertexAttribDivisorANGLE(max_vertex_attribs, 2); |
| 150 glErrorShouldBe(gl, gl.INVALID_VALUE, "vertexAttribDivisorANGLE index set gr
eater than or equal to MAX_VERTEX_ATTRIBS should be an invalid value"); |
| 151 |
| 152 ext.vertexAttribDivisorANGLE(max_vertex_attribs-1, 2); |
| 153 glErrorShouldBe(gl, gl.NO_ERROR, "vertexAttribDivisorANGLE index set less th
an MAX_VERTEX_ATTRIBS should succeed"); |
| 154 |
| 155 var queried_value = gl.getVertexAttrib(max_vertex_attribs-1, ext.VERTEX_ATTR
IB_ARRAY_DIVISOR_ANGLE); |
| 156 if(queried_value == 2){ |
| 157 testPassed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE matches expec
ation"); |
| 158 } |
| 159 else{ |
| 160 testFailed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE should be: 2,
returned value was: " + queried_value); |
| 161 } |
| 162 } |
| 163 |
| 164 function setupCanvas() { |
| 165 canvas.width = 50; canvas.height = 50; |
| 166 gl.viewport(0, 0, canvas.width, canvas.height); |
| 167 gl.clearColor(0, 0, 0, 0); |
| 168 |
| 169 program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"
], ['aPosition', 'aOffset', 'aColor'], [positionLoc, offsetLoc, colorLoc]); |
| 170 } |
| 171 |
| 172 function runOutputTests() { |
| 173 var e = 2; // Amount of variance to allow in result pixels - may need to be
tweaked higher |
| 174 var instanceCount = 4; |
| 175 |
| 176 debug("Testing various draws for valid built-in function behavior"); |
| 177 |
| 178 var offsets = new Float32Array([ |
| 179 -1.0, 1.0, |
| 180 1.0, 1.0, |
| 181 -1.0, -1.0, |
| 182 1.0, -1.0, |
| 183 ]); |
| 184 var offsetBuffer = gl.createBuffer(); |
| 185 gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); |
| 186 gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW); |
| 187 gl.enableVertexAttribArray(offsetLoc); |
| 188 gl.vertexAttribPointer(offsetLoc, 2, gl.FLOAT, false, 0, 0); |
| 189 ext.vertexAttribDivisorANGLE(offsetLoc, 1); |
| 190 |
| 191 var colors = new Float32Array([ |
| 192 1.0, 0.0, 0.0, 1.0, // Red |
| 193 0.0, 1.0, 0.0, 1.0, // Green |
| 194 0.0, 0.0, 1.0, 1.0, // Blue |
| 195 1.0, 1.0, 0.0, 1.0, // Yellow |
| 196 ]); |
| 197 var colorBuffer = gl.createBuffer(); |
| 198 gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); |
| 199 gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); |
| 200 gl.enableVertexAttribArray(colorLoc); |
| 201 gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0); |
| 202 ext.vertexAttribDivisorANGLE(colorLoc, 1); |
| 203 |
| 204 // Draw 1: Draw Non-indexed instances |
| 205 debug("Testing drawArraysInstancedANGLE"); |
| 206 gl.clear(gl.COLOR_BUFFER_BIT); |
| 207 wtu.setupUnitQuad(gl, 0); |
| 208 |
| 209 // Test drawArraysInstancedANGLE error conditions |
| 210 ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount); |
| 211 wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2,
[255, 0, 0, 255]); |
| 212 wtu.checkCanvasRect(gl, canvas.width/2, canvas.height/2, canvas.width/2, can
vas.height/2, [0, 255, 0, 255]); |
| 213 wtu.checkCanvasRect(gl, 0, 0, canvas.width/2, canvas.height/2, [0, 0, 255, 2
55]); |
| 214 wtu.checkCanvasRect(gl, canvas.width/2, 0, canvas.width/2, canvas.height/2,
[255, 255, 0, 255]); |
| 215 |
| 216 ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, -1); |
| 217 glErrorShouldBe(gl, gl.INVALID_VALUE, "drawArraysInstancedANGLE cannot have
a primcount less than 0"); |
| 218 |
| 219 ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, -1, instanceCount); |
| 220 glErrorShouldBe(gl, gl.INVALID_VALUE, "drawArraysInstancedANGLE cannot have
a count less than 0"); |
| 221 |
| 222 ext.vertexAttribDivisorANGLE(positionLoc, 1); |
| 223 ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount); |
| 224 glErrorShouldBe(gl, gl.INVALID_OPERATION, "There must be at least one vertex
attribute with a divisor of zero when calling drawArraysInstancedANGLE"); |
| 225 ext.vertexAttribDivisorANGLE(positionLoc, 0); |
| 226 |
| 227 ext.drawArraysInstancedANGLE(gl.POINTS, 0, 6, instanceCount); |
| 228 glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE with POINTS shoul
d succeed"); |
| 229 ext.drawArraysInstancedANGLE(gl.LINES, 0, 6, instanceCount); |
| 230 glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE with LINES should
succeed"); |
| 231 ext.drawArraysInstancedANGLE(gl.LINE_LIST, 0, 6, instanceCount); |
| 232 glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE with LINE_LIST sh
ould return succeed"); |
| 233 ext.drawArraysInstancedANGLE(gl.TRIANGLE_LIST, 0, 6, instanceCount); |
| 234 glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE with TRIANGLE_LIS
T should succeed"); |
| 235 |
| 236 ext.drawArraysInstancedANGLE(desktopGL['QUAD_STRIP'], 0, 6, instanceCount); |
| 237 glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstancedANGLE with QUAD_STR
IP should return INVALID_ENUM"); |
| 238 ext.drawArraysInstancedANGLE(desktopGL['QUADS'], 0, 6, instanceCount); |
| 239 glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstancedANGLE with QUADS sh
ould return INVALID_ENUM"); |
| 240 ext.drawArraysInstancedANGLE(desktopGL['POLYGON'], 0, 6, instanceCount); |
| 241 glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstancedANGLE with POLYGON
should return INVALID_ENUM"); |
| 242 |
| 243 // Draw 2: Draw indexed instances |
| 244 debug("Testing drawElementsInstancedANGLE"); |
| 245 gl.clear(gl.COLOR_BUFFER_BIT); |
| 246 wtu.setupIndexedQuad(gl, 1, 0); |
| 247 ext.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instan
ceCount); |
| 248 wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2,
[255, 0, 0, 255]); |
| 249 wtu.checkCanvasRect(gl, canvas.width/2, canvas.height/2, canvas.width/2, can
vas.height/2, [0, 255, 0, 255]); |
| 250 wtu.checkCanvasRect(gl, 0, 0, canvas.width/2, canvas.height/2, [0, 0, 255, 2
55]); |
| 251 wtu.checkCanvasRect(gl, canvas.width/2, 0, canvas.width/2, canvas.height/2,
[255, 255, 0, 255]); |
| 252 |
| 253 // Test drawElementsInstancedANGLE error conditions |
| 254 ext.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, -1); |
| 255 glErrorShouldBe(gl, gl.INVALID_VALUE, "drawElementsInstancedANGLE cannot hav
e a primcount less than 0"); |
| 256 |
| 257 ext.drawElementsInstancedANGLE(gl.TRIANGLES, -1, gl.UNSIGNED_SHORT, 0, insta
nceCount); |
| 258 glErrorShouldBe(gl, gl.INVALID_VALUE, "drawElementsInstancedANGLE cannot hav
e a count less than 0"); |
| 259 |
| 260 ext.vertexAttribDivisorANGLE(positionLoc, 1); |
| 261 ext.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instan
ceCount); |
| 262 glErrorShouldBe(gl, gl.INVALID_OPERATION, "There must be at least one vertex
attribute with a divisor of zero when calling drawElementsInstancedANGLE"); |
| 263 ext.vertexAttribDivisorANGLE(positionLoc, 0); |
| 264 |
| 265 ext.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, instanc
eCount); |
| 266 glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with UNSIGNED_B
YTE should succeed"); |
| 267 |
| 268 ext.drawElementsInstancedANGLE(gl.POINTS, 6, gl.UNSIGNED_SHORT, 0, instanceC
ount); |
| 269 glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with POINTS sho
uld succeed"); |
| 270 ext.drawElementsInstancedANGLE(gl.LINES, 6, gl.UNSIGNED_SHORT, 0, instanceCo
unt); |
| 271 glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with LINES shou
ld succeed"); |
| 272 ext.drawElementsInstancedANGLE(gl.LINE_LIST, 6, gl.UNSIGNED_SHORT, 0, instan
ceCount); |
| 273 glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with LINE_LIST
should return succeed"); |
| 274 ext.drawElementsInstancedANGLE(gl.TRIANGLE_LIST, 6, gl.UNSIGNED_SHORT, 0, in
stanceCount); |
| 275 glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with TRIANGLE_L
IST should succeed"); |
| 276 |
| 277 ext.drawElementsInstancedANGLE(desktopGL['QUAD_STRIP'], 6, gl.UNSIGNED_SHORT
, 0, instanceCount); |
| 278 glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with QUAD_S
TRIP should return INVALID_ENUM"); |
| 279 ext.drawElementsInstancedANGLE(desktopGL['QUADS'], 6, gl.UNSIGNED_SHORT, 0,
instanceCount); |
| 280 glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with QUADS
should return INVALID_ENUM"); |
| 281 ext.drawElementsInstancedANGLE(desktopGL['POLYGON'], 6, gl.UNSIGNED_SHORT, 0
, instanceCount); |
| 282 glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with POLYGO
N should return INVALID_ENUM"); |
| 283 } |
| 284 |
| 285 function runUniqueObjectTest() |
| 286 { |
| 287 debug("Testing that getExtension() returns the same object each time"); |
| 288 gl.getExtension("ANGLE_instanced_arrays").myProperty = 2; |
| 289 gc(); |
| 290 shouldBe('gl.getExtension("ANGLE_instanced_arrays").myProperty', '2'); |
| 291 } |
| 292 |
| 293 function runANGLECorruptionTest() |
| 294 { |
| 295 debug("") |
| 296 debug("Testing to ensure that rendering isn't corrupt due to an ANGLE bug"); |
| 297 // See: https://code.google.com/p/angleproject/issues/detail?id=467 |
| 298 |
| 299 var tolerance = 2; // Amount of variance to allow in result pixels - may nee
d to be tweaked higher |
| 300 var instanceCount = 10; // Must be higher than 6 |
| 301 var iteration = 0; |
| 302 var totalIterations = 10; |
| 303 |
| 304 var offsets = new Float32Array([ |
| 305 0.0, 0.0, |
| 306 0.2, 0.0, |
| 307 0.4, 0.0, |
| 308 0.6, 0.0, |
| 309 0.8, 0.0, |
| 310 1.0, 0.0, |
| 311 1.2, 0.0, |
| 312 1.4, 0.0, |
| 313 1.6, 0.0, |
| 314 1.8, 0.0, |
| 315 ]); |
| 316 var offsetBuffer = gl.createBuffer(); |
| 317 gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); |
| 318 gl.bufferData(gl.ARRAY_BUFFER, offsets.byteLength * 2, gl.STATIC_DRAW); |
| 319 gl.bufferSubData(gl.ARRAY_BUFFER, 0, offsets); |
| 320 gl.enableVertexAttribArray(offsetLoc); |
| 321 gl.vertexAttribPointer(offsetLoc, 2, gl.FLOAT, false, 0, 0); |
| 322 ext.vertexAttribDivisorANGLE(offsetLoc, 1); |
| 323 |
| 324 var colors = new Float32Array([ |
| 325 1.0, 0.0, 0.0, 1.0, |
| 326 1.0, 1.0, 0.0, 1.0, |
| 327 0.0, 1.0, 0.0, 1.0, |
| 328 0.0, 1.0, 1.0, 1.0, |
| 329 0.0, 0.0, 1.0, 1.0, |
| 330 1.0, 0.0, 1.0, 1.0, |
| 331 1.0, 0.0, 0.0, 1.0, |
| 332 1.0, 1.0, 0.0, 1.0, |
| 333 0.0, 1.0, 0.0, 1.0, |
| 334 0.0, 1.0, 1.0, 1.0, |
| 335 ]); |
| 336 var colorBuffer = gl.createBuffer(); |
| 337 gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); |
| 338 gl.bufferData(gl.ARRAY_BUFFER, colors.byteLength * 2, gl.STATIC_DRAW); |
| 339 gl.bufferSubData(gl.ARRAY_BUFFER, 0, colors); |
| 340 gl.enableVertexAttribArray(colorLoc); |
| 341 gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0); |
| 342 ext.vertexAttribDivisorANGLE(colorLoc, 1); |
| 343 |
| 344 gl.clear(gl.COLOR_BUFFER_BIT); |
| 345 wtu.setupUnitQuad(gl, 0); |
| 346 |
| 347 function cycleAndTest() { |
| 348 // Update the instanced data buffers outside the accessed range. |
| 349 // This, plus rendering more instances than vertices, triggers the bug. |
| 350 var nullData = new Float32Array(offsets.length); |
| 351 gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); |
| 352 gl.bufferSubData(gl.ARRAY_BUFFER, offsets.byteLength, nullData); |
| 353 |
| 354 nullData = new Float32Array(colors.length); |
| 355 gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); |
| 356 gl.bufferSubData(gl.ARRAY_BUFFER, colors.byteLength, nullData); |
| 357 |
| 358 ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount); |
| 359 |
| 360 // Make sure each color was drawn correctly |
| 361 var i; |
| 362 var passed = true; |
| 363 for (i = 0; i < instanceCount; ++i) { |
| 364 var w = canvas.width / instanceCount; |
| 365 var x = w * i; |
| 366 var color = [colors[(i*4)] * 255, colors[(i*4)+1] * 255, colors[(i*
4)+2] * 255, 255] |
| 367 |
| 368 wtu.checkCanvasRectColor( |
| 369 gl, x, 0, w, canvas.height, color, tolerance, |
| 370 function() {}, |
| 371 function() { |
| 372 passed = false; |
| 373 }, debug); |
| 374 } |
| 375 |
| 376 if (passed) { |
| 377 testPassed("Passed test " + iteration + " of " + totalIterations); |
| 378 if (iteration < totalIterations) { |
| 379 ++iteration; |
| 380 setTimeout(cycleAndTest, 100); |
| 381 } else { |
| 382 finishTest(); |
| 383 } |
| 384 } else { |
| 385 testFailed("Failed test " + iteration + " of " + totalIterations); |
| 386 finishTest(); |
| 387 } |
| 388 } |
| 389 |
| 390 cycleAndTest(); |
| 391 } |
| 392 |
| 393 var successfullyParsed = true; |
| 394 </script> |
| 395 <script src="../../resources/js-test-post.js"></script> |
| 396 |
| 397 </body> |
| 398 </html> |
OLD | NEW |