Bug 1760642 [wpt PR 33286] - Unify wpt test drawing-images-to-the-canvas, a=testonly
authorYi Xu <yiyix@chromium.org>
Thu, 24 Mar 2022 12:21:55 +0000
changeset 687331 12b1423d447f562d686fd42a7a8595e1392b17e3
parent 687330 35ee4a724a64ce6850d17881df64b8afd2c1281f
child 687332 203717c0cfe2339cee58e4bb0d58018d1493ae93
push id2831
push userffxbld-merge
push dateMon, 25 Apr 2022 15:51:01 +0000
treeherdermozilla-release@bad8853d0c21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1760642, 33286, 1275750, 3536424, 984188
milestone100.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1760642 [wpt PR 33286] - Unify wpt test drawing-images-to-the-canvas, a=testonly Automatic update from web-platform-tests Unify wpt test drawing-images-to-the-canvas Unify wpt test drawing-images-to-the-canvas for both HTMLCanvas and OffscreenCanvas. Bug: 1275750 Change-Id: I5eee4f187ad09214222e985d3b001168fdcc8871 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3536424 Reviewed-by: Juanmi Huertas <juanmihd@chromium.org> Commit-Queue: Yi Xu <yiyix@chromium.org> Cr-Commit-Position: refs/heads/main@{#984188} -- wpt-commits: f917fa0fbbbdb64ea38382e2f69d5168ac4fc40c wpt-pr: 33286
testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.paragraph.html
testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.html
testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.worker.js
testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.html
testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.worker.js
testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.html
testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.worker.js
testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.html
testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.worker.js
testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.html
testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.worker.js
testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.worker.js
testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py
testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
testing/web-platform/tests/html/canvas/tools/yaml/element/drawing-images-to-the-canvas.yaml
testing/web-platform/tests/html/canvas/tools/yaml/offscreen/drawing-images-to-the-canvas.yaml
--- a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
@@ -5,26 +5,25 @@
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
 <h1>2d.drawImage.wrongtype</h1>
 <p class="desc">Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError</p>
 
-<p class="notes">Defined in "Web IDL" (draft)
+
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 
 <ul id="d"></ul>
 <script>
 var t = async_test("Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError");
 _addTest(function(canvas, ctx) {
 
 assert_throws_js(TypeError, function() { ctx.drawImage(undefined, 0, 0); });
 assert_throws_js(TypeError, function() { ctx.drawImage(0, 0, 0); });
 assert_throws_js(TypeError, function() { ctx.drawImage("", 0, 0); });
-assert_throws_js(TypeError, function() { ctx.drawImage(document.createElement('p'), 0, 0); });
 
 
 });
 </script>
 
copy from testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
copy to testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.paragraph.html
--- a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.paragraph.html
@@ -1,30 +1,27 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: 2d.drawImage.wrongtype</title>
+<title>Canvas test: 2d.drawImage.wrongtype.paragraph</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>2d.drawImage.wrongtype</h1>
+<h1>2d.drawImage.wrongtype.paragraph</h1>
 <p class="desc">Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError</p>
 
 <p class="notes">Defined in "Web IDL" (draft)
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 
 <ul id="d"></ul>
 <script>
 var t = async_test("Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError");
 _addTest(function(canvas, ctx) {
 
-assert_throws_js(TypeError, function() { ctx.drawImage(undefined, 0, 0); });
-assert_throws_js(TypeError, function() { ctx.drawImage(0, 0, 0); });
-assert_throws_js(TypeError, function() { ctx.drawImage("", 0, 0); });
 assert_throws_js(TypeError, function() { ctx.drawImage(document.createElement('p'), 0, 0); });
 
 
 });
 </script>
 
--- a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.html
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.html
@@ -33,12 +33,11 @@ var promise = new Promise(function(resol
     };
 });
 promise.then(function(response) {
     createImageBitmap(response).then(bitmap => {
         ctx.drawImage(bitmap, 0, 0);
         _assertPixelApprox(canvas, 50,25, 2,253,0,255, "50,25", "2,253,0,255", 2);
     }, t_fail);
 }).then(t_pass, t_fail);
-t.done();
 
 });
 </script>
--- a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.worker.js
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.worker.js
@@ -29,12 +29,11 @@ var promise = new Promise(function(resol
     };
 });
 promise.then(function(response) {
     createImageBitmap(response).then(bitmap => {
         ctx.drawImage(bitmap, 0, 0);
         _assertPixelApprox(canvas, 50,25, 2,253,0,255, "50,25", "2,253,0,255", 2);
     }, t_fail);
 }).then(t_pass, t_fail);
-t.done();
 
 });
 done();
--- a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.html
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.html
@@ -34,12 +34,11 @@ var promise = new Promise(function(resol
 promise.then(function(response) {
     createImageBitmap(response).then(bitmap => {
         ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
         ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
         ctx.fillRect(0, 0, 100, 50);
         _assertPixelApprox(canvas, 50,25, 2,253,0,255, "50,25", "2,253,0,255", 2);
     }, t_fail);
 }).then(t_pass, t_fail);
-t.done();
 
 });
 </script>
--- a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.worker.js
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.worker.js
@@ -30,12 +30,11 @@ var promise = new Promise(function(resol
 promise.then(function(response) {
     createImageBitmap(response).then(bitmap => {
         ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
         ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
         ctx.fillRect(0, 0, 100, 50);
         _assertPixelApprox(canvas, 50,25, 2,253,0,255, "50,25", "2,253,0,255", 2);
     }, t_fail);
 }).then(t_pass, t_fail);
-t.done();
 
 });
 done();
--- a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.html
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.html
@@ -1,12 +1,11 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
 <title>OffscreenCanvas test: 2d.drawImage.null</title>
-<meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 
 <h1>2d.drawImage.null</h1>
 <p class="desc"></p>
 
 
--- a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.worker.js
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.worker.js
@@ -1,9 +1,8 @@
-// META: timeout=long
 // DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
 // OffscreenCanvas test in a worker:2d.drawImage.null
 // Description:
 // Note:
 
 importScripts("/resources/testharness.js");
 importScripts("/html/canvas/resources/canvas-tests.js");
 
--- a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.html
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.html
@@ -1,12 +1,11 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
 <title>OffscreenCanvas test: 2d.drawImage.self.1</title>
-<meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 
 <h1>2d.drawImage.self.1</h1>
 <p class="desc"></p>
 
 
@@ -21,16 +20,17 @@ t.step(function() {
 var canvas = new OffscreenCanvas(100, 50);
 var ctx = canvas.getContext('2d');
 
 ctx.fillStyle = '#0f0';
 ctx.fillRect(0, 0, 50, 50);
 ctx.fillStyle = '#f00';
 ctx.fillRect(50, 0, 50, 50);
 ctx.drawImage(canvas, 50, 0);
+
 _assertPixelApprox(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 99,0, 0,255,0,255, "99,0", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 0,49, 0,255,0,255, "0,49", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 99,49, 0,255,0,255, "99,49", "0,255,0,255", 2);
 t.done();
 
 });
 </script>
--- a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.worker.js
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.worker.js
@@ -1,9 +1,8 @@
-// META: timeout=long
 // DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
 // OffscreenCanvas test in a worker:2d.drawImage.self.1
 // Description:
 // Note:
 
 importScripts("/resources/testharness.js");
 importScripts("/html/canvas/resources/canvas-tests.js");
 
@@ -17,16 +16,17 @@ t.step(function() {
 var canvas = new OffscreenCanvas(100, 50);
 var ctx = canvas.getContext('2d');
 
 ctx.fillStyle = '#0f0';
 ctx.fillRect(0, 0, 50, 50);
 ctx.fillStyle = '#f00';
 ctx.fillRect(50, 0, 50, 50);
 ctx.drawImage(canvas, 50, 0);
+
 _assertPixelApprox(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 99,0, 0,255,0,255, "99,0", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 0,49, 0,255,0,255, "0,49", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 99,49, 0,255,0,255, "99,49", "0,255,0,255", 2);
 t.done();
 
 });
 done();
--- a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.html
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.html
@@ -1,12 +1,11 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
 <title>OffscreenCanvas test: 2d.drawImage.self.2</title>
-<meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 
 <h1>2d.drawImage.self.2</h1>
 <p class="desc"></p>
 
 
@@ -23,16 +22,17 @@ var ctx = canvas.getContext('2d');
 
 ctx.fillStyle = '#0f0';
 ctx.fillRect(0, 1, 100, 49);
 ctx.fillStyle = '#f00';
 ctx.fillRect(0, 0, 100, 1);
 ctx.drawImage(canvas, 0, 1);
 ctx.fillStyle = '#0f0';
 ctx.fillRect(0, 0, 100, 2);
+
 _assertPixelApprox(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 99,0, 0,255,0,255, "99,0", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 0,49, 0,255,0,255, "0,49", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 99,49, 0,255,0,255, "99,49", "0,255,0,255", 2);
 t.done();
 
 });
 </script>
--- a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.worker.js
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.worker.js
@@ -1,9 +1,8 @@
-// META: timeout=long
 // DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
 // OffscreenCanvas test in a worker:2d.drawImage.self.2
 // Description:
 // Note:
 
 importScripts("/resources/testharness.js");
 importScripts("/html/canvas/resources/canvas-tests.js");
 
@@ -19,16 +18,17 @@ var ctx = canvas.getContext('2d');
 
 ctx.fillStyle = '#0f0';
 ctx.fillRect(0, 1, 100, 49);
 ctx.fillStyle = '#f00';
 ctx.fillRect(0, 0, 100, 1);
 ctx.drawImage(canvas, 0, 1);
 ctx.fillStyle = '#0f0';
 ctx.fillRect(0, 0, 100, 2);
+
 _assertPixelApprox(canvas, 0,0, 0,255,0,255, "0,0", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 99,0, 0,255,0,255, "99,0", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 0,49, 0,255,0,255, "0,49", "0,255,0,255", 2);
 _assertPixelApprox(canvas, 99,49, 0,255,0,255, "99,49", "0,255,0,255", 2);
 t.done();
 
 });
 done();
--- a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
@@ -1,12 +1,11 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
 <title>OffscreenCanvas test: 2d.drawImage.wrongtype</title>
-<meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 
 <h1>2d.drawImage.wrongtype</h1>
 <p class="desc">Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError</p>
 
 
--- a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.worker.js
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.worker.js
@@ -1,9 +1,8 @@
-// META: timeout=long
 // DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
 // OffscreenCanvas test in a worker:2d.drawImage.wrongtype
 // Description:Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError
 // Note:
 
 importScripts("/resources/testharness.js");
 importScripts("/html/canvas/resources/canvas-tests.js");
 
--- a/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py
+++ b/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py
@@ -391,18 +391,23 @@ def genTestUtils_union(TEMPLATEFILE, NAM
                 'context_args': context_args
             }
 
             # Create test cases for canvas and offscreencanvas.
             if HTMLCanvas_test:
                 f = codecs.open('%s/%s%s.html' % (CANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
                 f.write(templates['w3ccanvas'] % template_params)
             if OffscreenCanvas_test:
-                f = codecs.open('%s/%s%s.html' % (OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
-                f.write(templates['w3coffscreencanvas'] % template_params)
-
-                # Create test case for offscreencanvas worker.
-                timeout = '// META: timeout=%s\n' % test['timeout'] if 'timeout' in test else ''
-                template_params['timeout'] = timeout
-                f = codecs.open('%s/%s%s.worker.js' % (OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
-                f.write(templates['w3cworker'] % template_params)
-
+                f_html = codecs.open('%s/%s%s.html' % (OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
+                f_worker = codecs.open('%s/%s%s.worker.js' % (OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
+                if ("then(t_pass, t_fail);" in code_canvas):
+                    temp_offscreen = templates['w3coffscreencanvas'].replace("t.done();\n", "")
+                    temp_worker = templates['w3cworker'].replace("t.done();\n", "")
+                    f_html.write(temp_offscreen % template_params)
+                    timeout = '// META: timeout=%s\n' % test['timeout'] if 'timeout' in test else ''
+                    template_params['timeout'] = timeout
+                    f_worker.write(temp_worker % template_params)
+                else:
+                    f_html.write(templates['w3coffscreencanvas'] % template_params)
+                    timeout = '// META: timeout=%s\n' % test['timeout'] if 'timeout' in test else ''
+                    template_params['timeout'] = timeout
+                    f_worker.write(templates['w3cworker'] % template_params)
     print()
rename from testing/web-platform/tests/html/canvas/tools/yaml/offscreen/drawing-images-to-the-canvas.yaml
rename to testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
--- a/testing/web-platform/tests/html/canvas/tools/yaml/offscreen/drawing-images-to-the-canvas.yaml
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
@@ -1,12 +1,668 @@
 - name: 2d.drawImage.3arg
   testing:
   - 2d.drawImage.defaultsource
   - 2d.drawImage.defaultdest
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  - green.png
+  code: |
+    ctx.drawImage(document.getElementById('green.png'), 0, 0);
+    ctx.drawImage(document.getElementById('red.png'), -100, 0);
+    ctx.drawImage(document.getElementById('red.png'), 100, 0);
+    ctx.drawImage(document.getElementById('red.png'), 0, -50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 50);
+
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.5arg
+  testing:
+  - 2d.drawImage.defaultsource
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  - green.png
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('green.png'), 50, 0, 50, 50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0, 50, 50);
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 50, 50);
+
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.9arg.basic
+  testing:
+  - 2d.drawImage.paint
+  canvasType: ['HTMLCanvas']
+  images:
+  - green.png
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('green.png'), 0, 0, 100, 50, 0, 0, 100, 50);
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.9arg.sourcepos
+  testing:
+  - 2d.drawImage.paint
+  canvasType: ['HTMLCanvas']
+  images:
+  - rgrg-256x256.png
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('rgrg-256x256.png'), 140, 20, 100, 50, 0, 0, 100, 50);
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.9arg.sourcesize
+  testing:
+  - 2d.drawImage.paint
+  canvasType: ['HTMLCanvas']
+  images:
+  - rgrg-256x256.png
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('rgrg-256x256.png'), 0, 0, 256, 256, 0, 0, 100, 50);
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 51, 26);
+    ctx.fillRect(49, 24, 51, 26);
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+    @assert pixel 20,20 ==~ 0,255,0,255;
+    @assert pixel 80,20 ==~ 0,255,0,255;
+    @assert pixel 20,30 ==~ 0,255,0,255;
+    @assert pixel 80,30 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.9arg.destpos
+  testing:
+  - 2d.drawImage.paint
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  - green.png
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('green.png'), 0, 0, 100, 50, 0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -100, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -50, 100, 50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, 50, 100, 50);
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.9arg.destsize
+  testing:
+  - 2d.drawImage.paint
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  - green.png
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('green.png'), 1, 1, 1, 1, 0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -50, 0, 50, 50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 50, 50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -25, 100, 25);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, 50, 100, 25);
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.canvas
+  testing:
+  - 2d.drawImage.paint
+  canvasType: ['HTMLCanvas']
+  code: |
+    var canvas2 = document.createElement('canvas');
+    canvas2.width = 100;
+    canvas2.height = 50;
+    var ctx2 = canvas2.getContext('2d');
+    ctx2.fillStyle = '#0f0';
+    ctx2.fillRect(0, 0, 100, 50);
+
+    ctx.fillStyle = '#f00';
+    ctx.drawImage(canvas2, 0, 0);
+
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+
+    ctx.drawImage(document.createElement('canvas'), 0, 0);
+
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.self.1
+  testing:
+  - 2d.drawImage.self
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 50, 50);
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(50, 0, 50, 50);
+    ctx.drawImage(canvas, 50, 0);
+
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.self.2
+  testing:
+  - 2d.drawImage.self
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 1, 100, 49);
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 1);
+    ctx.drawImage(canvas, 0, 1);
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 2);
+
+    @assert pixel 0,0 ==~ 0,255,0,255;
+    @assert pixel 99,0 ==~ 0,255,0,255;
+    @assert pixel 0,49 ==~ 0,255,0,255;
+    @assert pixel 99,49 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.null
+  testing:
+  - 2d.drawImage.IDL
+  code: |
+    @assert throws TypeError ctx.drawImage(null, 0, 0);
+
+- name: 2d.drawImage.wrongtype
+  desc: Incorrect image types in drawImage do not match any defined overloads, so
+    WebIDL throws a TypeError
+  testing:
+  - 2d.drawImage.IDL
+  code: |
+    @assert throws TypeError ctx.drawImage(undefined, 0, 0);
+    @assert throws TypeError ctx.drawImage(0, 0, 0);
+    @assert throws TypeError ctx.drawImage("", 0, 0);
+
+- name: 2d.drawImage.wrongtype.paragraph
+  desc: Incorrect image types in drawImage do not match any defined overloads, so
+    WebIDL throws a TypeError
+  notes: &bindings Defined in "Web IDL" (draft)
+  testing:
+  - 2d.drawImage.IDL
+  canvasType: ['HTMLCanvas']
+  code: |
+    @assert throws TypeError ctx.drawImage(document.createElement('p'), 0, 0);
+
+- name: 2d.drawImage.floatsource
+  testing:
+  - 2d.drawImage.paint
+  canvasType: ['HTMLCanvas']
+  images:
+  - green.png
+  code: |
+    ctx.drawImage(document.getElementById('green.png'), 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.zerosource
+  desc: drawImage with zero-sized source rectangle draws nothing without exception
+  testing:
+  - 2d.drawImage.zerosource
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 1, 0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 0, 0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 0, 0, 0, 100, 50);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.zerosource.image
+  desc: drawImage with zero-sized source rectangle from image draws nothing without exception
+  testing:
+  - 2d.drawImage.zerosource
+  canvasType: ['HTMLCanvas']
+  images:
+  - red-zerowidth.svg
+  - red-zeroheight.svg
+  - red-zerosize.svg
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red-zerowidth.svg'), 0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red-zeroheight.svg'), 0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red-zerosize.svg'), 0, 0, 100, 50);
+    @assert pixel 50,25 == 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.negativesource
+  desc: Negative source width/height represents the correct rectangle
+  testing:
+  - 2d.drawImage.direction
+  canvasType: ['HTMLCanvas']
+  mozilla: {throws: !!null ''}
+  images:
+  - ggrr-256x256.png
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 78, -100, 50, 0, 0, 50, 50);
+    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 128, -100, -50, 50, 0, 50, 50);
+    @assert pixel 1,1 ==~ 0,255,0,255;
+    @assert pixel 1,48 ==~ 0,255,0,255;
+    @assert pixel 98,1 ==~ 0,255,0,255;
+    @assert pixel 98,48 ==~ 0,255,0,255;
+    @assert pixel 48,1 ==~ 0,255,0,255;
+    @assert pixel 48,48 ==~ 0,255,0,255;
+    @assert pixel 51,1 ==~ 0,255,0,255;
+    @assert pixel 51,48 ==~ 0,255,0,255;
+    @assert pixel 25,25 ==~ 0,255,0,255;
+    @assert pixel 75,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.negativedest
+  desc: Negative destination width/height represents the correct rectangle
+  testing:
+  - 2d.drawImage.direction
+  canvasType: ['HTMLCanvas']
+  mozilla: {throws: !!null ''}
+  images:
+  - ggrr-256x256.png
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 78, 50, 50, 0, 50, 50, -50);
+    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 128, 50, -50, 100, 50, -50, -50);
+    @assert pixel 1,1 ==~ 0,255,0,255;
+    @assert pixel 1,48 ==~ 0,255,0,255;
+    @assert pixel 98,1 ==~ 0,255,0,255;
+    @assert pixel 98,48 ==~ 0,255,0,255;
+    @assert pixel 48,1 ==~ 0,255,0,255;
+    @assert pixel 48,48 ==~ 0,255,0,255;
+    @assert pixel 51,1 ==~ 0,255,0,255;
+    @assert pixel 51,48 ==~ 0,255,0,255;
+    @assert pixel 25,25 ==~ 0,255,0,255;
+    @assert pixel 75,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.negativedir
+  desc: Negative dimensions do not affect the direction of the image
+  testing:
+  - 2d.drawImage.direction
+  canvasType: ['HTMLCanvas']
+  mozilla: {throws: !!null ''}
+  images:
+  - ggrr-256x256.png
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 0, 178, 50, -100, 0, 0, 50, 100);
+    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 0, 78, 50, 100, 50, 100, 50, -100);
+    @assert pixel 1,1 ==~ 0,255,0,255;
+    @assert pixel 1,48 ==~ 0,255,0,255;
+    @assert pixel 98,1 ==~ 0,255,0,255;
+    @assert pixel 98,48 ==~ 0,255,0,255;
+    @assert pixel 48,1 ==~ 0,255,0,255;
+    @assert pixel 48,48 ==~ 0,255,0,255;
+    @assert pixel 51,1 ==~ 0,255,0,255;
+    @assert pixel 51,48 ==~ 0,255,0,255;
+    @assert pixel 25,25 ==~ 0,255,0,255;
+    @assert pixel 75,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.outsidesource
+  DISABLED: fix this to match the current spec (transparent black outside source)
+  testing:
+  - 2d.drawImage.outsidesource
+  canvasType: ['HTMLCanvas']
+  mozilla: {throws: !!null ''}
+  images:
+  - green.png
+  - red.png
+  code: |
+    ctx.drawImage(document.getElementById('green.png'), 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('green.png'), 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('green.png'), 100, 50, -5, -5, 0, 0, 100, 50);
+    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), -0.001, 0, 100, 50, 0, 0, 100, 50);
+    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, -0.001, 100, 50, 0, 0, 100, 50);
+    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100.001, 50, 0, 0, 100, 50);
+    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50.001, 0, 0, 100, 50);
+    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 50, 0, 50.001, 50, 0, 0, 100, 50); @moz-todo
+    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, -5, 5, 0, 0, 100, 50);
+    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 5, -5, 0, 0, 100, 50);
+    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 110, 60, -20, -20, 0, 0, 100, 50);
+    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+  expected: green
+
+- name: 2d.drawImage.incomplete.nosrc
+  testing:
+  - 2d.drawImage.incomplete.image
+  canvasType: ['HTMLCanvas']
+  mozilla: {throws: !!null ''}
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    var img = new Image();
+    ctx.drawImage(img, 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.incomplete.immediate
+  testing:
+  - 2d.drawImage.incomplete.image
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    var img = new Image();
+    img.src = '../images/red.png';
+    // This triggers the "update the image data" algorithm.
+    // The image will not go to the "completely available" state
+    // until a fetch task in the networking task source is processed,
+    // so the image must not be fully decodable yet:
+    ctx.drawImage(img, 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+  expected: green
+
+- name: 2d.drawImage.incomplete.reload
+  testing:
+  - 2d.drawImage.incomplete.image
+  canvasType: ['HTMLCanvas']
+  images:
+  - yellow.png
+  - red.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    var img = document.getElementById('yellow.png');
+    img.src = '../images/red.png';
+    // This triggers the "update the image data" algorithm,
+    // and resets the image to the "unavailable" state.
+    // The image will not go to the "completely available" state
+    // until a fetch task in the networking task source is processed,
+    // so the image must not be fully decodable yet:
+    ctx.drawImage(img, 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+  expected: green
+
+- name: 2d.drawImage.incomplete.emptysrc
+  testing:
+  - 2d.drawImage.incomplete.image
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  mozilla: {throws: !!null ''}
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    var img = document.getElementById('red.png');
+    img.src = "";
+    ctx.drawImage(img, 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.incomplete.removedsrc
+  testing:
+  - 2d.drawImage.incomplete.image
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  mozilla: {throws: !!null ''}
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    var img = document.getElementById('red.png');
+    img.removeAttribute('src');
+    ctx.drawImage(img, 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.broken
+  testing:
+  - 2d.drawImage.incomplete.image
+  canvasType: ['HTMLCanvas']
+  images:
+  - broken.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    var img = document.getElementById('broken.png');
+    ctx.drawImage(img, 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+  expected: green
+
+- name: 2d.drawImage.nonexistent
+  testing:
+  - 2d.drawImage.incomplete.image
+  canvasType: ['HTMLCanvas']
+  images:
+  - not-found-at-all.png
+  code: |
+    var img = document.getElementById('not-found-at-all.png');
+    @assert throws INVALID_STATE_ERR ctx.drawImage(img, 0, 0);
+
+- name: 2d.drawImage.zerocanvas
+  desc: drawImage with zero-sized canvas as the source shoud throw exception
+  testing:
+  - 2d.drawImage.zerocanvas
+  code: |
+    var canvas2 = document.createElement('canvas');
+    canvas2.width = 0;
+    canvas2.height = 50;
+    @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
+
+    canvas2.width = 50;
+    canvas2.height = 0;
+    @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
+
+    canvas2.width = 0;
+    canvas2.height = 0;
+    @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
+
+- name: 2d.drawImage.svg
+  desc: drawImage() of an SVG image
+  testing:
+  - 2d.drawImage.svg
+  canvasType: ['HTMLCanvas']
+  images:
+  - green.svg
+  code: |
+    ctx.drawImage(document.getElementById('green.svg'), 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.animated.gif
+  desc: drawImage() of an animated GIF draws the first frame
+  testing:
+  - 2d.drawImage.animated.image
+  canvasType: ['HTMLCanvas']
+  images:
+  - anim-gr.gif
+  code: |
+    deferTest();
+    step_timeout(t.step_func_done(function () {
+        ctx.drawImage(document.getElementById('anim-gr.gif'), 0, 0);
+        @assert pixel 50,25 ==~ 0,255,0,255;
+    }), 500);
+  expected: green
+
+- name: 2d.drawImage.animated.apng
+  desc: drawImage() of an APNG with no poster frame draws the first frame
+  testing:
+  - 2d.drawImage.animated.image
+  canvasType: ['HTMLCanvas']
+  images:
+  - anim-gr.png
+  code: |
+    deferTest();
+    step_timeout(t.step_func_done(function () {
+        ctx.drawImage(document.getElementById('anim-gr.png'), 0, 0);
+        @assert pixel 50,25 ==~ 0,255,0,255;
+    }), 500);
+  expected: green
+
+- name: 2d.drawImage.animated.poster
+  desc: drawImage() of an APNG draws the poster frame
+  testing:
+  - 2d.drawImage.animated.image
+  canvasType: ['HTMLCanvas']
+  images:
+  - anim-poster-gr.png
+  code: |
+    ctx.drawImage(document.getElementById('anim-poster-gr.png'), 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+  expected: green
+
+- name: 2d.drawImage.path
+  testing:
+  - 2d.drawImage.unaffect
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.rect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0);
+    ctx.fill();
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.transform
+  testing:
+  - 2d.drawImage.subject
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.translate(100, 0);
+    ctx.drawImage(document.getElementById('red.png'), 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+# TODO: drawImage shadows
+
+- name: 2d.drawImage.alpha
+  testing:
+  - 2d.drawImage.subject
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.globalAlpha = 0;
+    ctx.drawImage(document.getElementById('red.png'), 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.clip
+  testing:
+  - 2d.drawImage.subject
+  images:
+  - red.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.rect(-10, -10, 1, 1);
+    ctx.clip();
+    ctx.drawImage(document.getElementById('red.png'), 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.composite
+  testing:
+  - 2d.drawImage.subject
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.globalCompositeOperation = 'destination-over';
+    ctx.drawImage(document.getElementById('red.png'), 0, 0);
+    @assert pixel 50,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.nowrap
+  desc: Stretched images do not get pixels wrapping around the edges
+  canvasType: ['HTMLCanvas']
+  images:
+  - redtransparent.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.drawImage(document.getElementById('redtransparent.png'), -1950, 0, 2000, 50);
+    @assert pixel 45,25 ==~ 0,255,0,255;
+    @assert pixel 50,25 ==~ 0,255,0,255;
+    @assert pixel 55,25 ==~ 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.nonfinite
+  desc: drawImage() with Infinity/NaN is ignored
+  testing:
+  - 2d.nonfinite
+  canvasType: ['HTMLCanvas']
+  images:
+  - red.png
+  code: |
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    var red = document.getElementById('red.png');
+    @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
+    @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+    @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+    @assert pixel 50,25 == 0,255,0,255;
+  expected: green
+
+- name: 2d.drawImage.3arg
+  testing:
+  - 2d.drawImage.defaultsource
+  - 2d.drawImage.defaultdest
+  canvasType: ['OffscreenCanvas']
   timeout: long
   images:
   - red.png
   - green.png
   code: |
     var promise1 = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
         xhr.open("GET", '/images/red.png');
@@ -42,16 +698,17 @@
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.5arg
   testing:
   - 2d.drawImage.defaultsource
   images:
   - red.png
   - green.png
+  canvasType: ['OffscreenCanvas']
   timeout: long
   code: |
     ctx.fillStyle = '#f00';
     ctx.fillRect(0, 0, 100, 50);
     var promise1 = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
         xhr.open("GET", '/images/red.png');
         xhr.responseType = 'blob';
@@ -82,16 +739,17 @@
             @assert pixel 0,49 ==~ 0,255,0,255;
             @assert pixel 99,49 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.9arg.basic
   testing:
   - 2d.drawImage.paint
+  canvasType: ['OffscreenCanvas']
   images:
   - green.png
   timeout: long
   code: |
     ctx.fillStyle = '#f00';
     ctx.fillRect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
@@ -110,16 +768,17 @@
             @assert pixel 0,49 ==~ 0,255,0,255;
             @assert pixel 99,49 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.9arg.sourcepos
   testing:
   - 2d.drawImage.paint
+  canvasType: ['OffscreenCanvas']
   images:
   - rgrg-256x256.png
   timeout: long
   code: |
     ctx.fillStyle = '#f00';
     ctx.fillRect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
@@ -138,16 +797,17 @@
             @assert pixel 0,49 ==~ 0,255,0,255;
             @assert pixel 99,49 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.9arg.sourcesize
   testing:
   - 2d.drawImage.paint
+  canvasType: ['OffscreenCanvas']
   images:
   - rgrg-256x256.png
   timeout: long
   code: |
     ctx.fillStyle = '#f00';
     ctx.fillRect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
@@ -173,16 +833,17 @@
             @assert pixel 20,30 ==~ 0,255,0,255;
             @assert pixel 80,30 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.9arg.destpos
   testing:
   - 2d.drawImage.paint
+  canvasType: ['OffscreenCanvas']
   images:
   - red.png
   - green.png
   timeout: long
   code: |
     ctx.fillStyle = '#f00';
     ctx.fillRect(0, 0, 100, 50);
     var promise1 = new Promise(function(resolve, reject) {
@@ -217,16 +878,17 @@
             @assert pixel 0,49 ==~ 0,255,0,255;
             @assert pixel 99,49 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.9arg.destsize
   testing:
   - 2d.drawImage.paint
+  canvasType: ['OffscreenCanvas']
   images:
   - red.png
   - green.png
   timeout: long
   code: |
     ctx.fillStyle = '#f00';
     ctx.fillRect(0, 0, 100, 50);
     var promise1 = new Promise(function(resolve, reject) {
@@ -261,104 +923,51 @@
             @assert pixel 0,49 ==~ 0,255,0,255;
             @assert pixel 99,49 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.canvas
   testing:
   - 2d.drawImage.paint
+  canvasType: ['OffscreenCanvas']
   timeout: long
   code: |
     var offscreenCanvas2 = new OffscreenCanvas(100, 50);
     var ctx2 = offscreenCanvas2.getContext('2d');
     ctx2.fillStyle = '#0f0';
     ctx2.fillRect(0, 0, 100, 50);
     ctx.fillStyle = '#f00';
     ctx.drawImage(offscreenCanvas2, 0, 0);
     @assert pixel 0,0 ==~ 0,255,0,255;
     @assert pixel 99,0 ==~ 0,255,0,255;
     @assert pixel 0,49 ==~ 0,255,0,255;
     @assert pixel 99,49 ==~ 0,255,0,255;
-    t.done();
-
-- name: 2d.drawImage.self.1
-  testing:
-  - 2d.drawImage.self
-  timeout: long
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 50, 50);
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(50, 0, 50, 50);
-    ctx.drawImage(canvas, 50, 0);
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-    t.done();
-
-- name: 2d.drawImage.self.2
-  testing:
-  - 2d.drawImage.self
-  timeout: long
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 1, 100, 49);
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 1);
-    ctx.drawImage(canvas, 0, 1);
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 2);
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-    t.done();
-
-- name: 2d.drawImage.null
-  testing:
-  - 2d.drawImage.IDL
-  timeout: long
-  code: |
-    @assert throws TypeError ctx.drawImage(null, 0, 0);
-    t.done();
 
 - name: 2d.drawImage.zerocanvas
   testing:
   - 2d.drawImage.zerocanvas
+  canvasType: ['OffscreenCanvas']
   timeout: long
   code: |
     var offscreenCanvas2 = new OffscreenCanvas(0, 10);
     @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
 
     offscreenCanvas2.width = 10;
     offscreenCanvas2.height = 0;
     @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
 
     offscreenCanvas2.width = 0;
     offscreenCanvas2.height = 0;
     @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
-    t.done();
-
-- name: 2d.drawImage.wrongtype
-  desc: Incorrect image types in drawImage do not match any defined overloads, so
-    WebIDL throws a TypeError
-  testing:
-  - 2d.drawImage.IDL
-  timeout: long
-  code: |
-    @assert throws TypeError ctx.drawImage(undefined, 0, 0);
-    @assert throws TypeError ctx.drawImage(0, 0, 0);
-    @assert throws TypeError ctx.drawImage("", 0, 0);
-    t.done();
 
 - name: 2d.drawImage.floatsource
   testing:
   - 2d.drawImage.paint
+  canvasType: ['OffscreenCanvas']
   timeout: long
   code: |
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
         xhr.open("GET", '/images/green.png');
         xhr.responseType = 'blob';
         xhr.send();
         xhr.onload = function() {
@@ -371,16 +980,17 @@
             @assert pixel 50,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.zerosource
   desc: drawImage with zero-sized source rectangle draws nothing without exception
   testing:
   - 2d.drawImage.zerosource
+  canvasType: ['OffscreenCanvas']
   timeout: long
   images:
   - red.png
   code: |
     ctx.fillStyle = '#0f0';
     ctx.fillRect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
@@ -399,16 +1009,17 @@
             @assert pixel 50,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.zerosource.image
   desc: drawImage with zero-sized source rectangle from image draws nothing without exception
   testing:
   - 2d.drawImage.zerosource
+  canvasType: ['OffscreenCanvas']
   images:
   - red-zerowidth.svg
   - red-zeroheight.svg
   - red-zerosize.svg
   timeout: long
   code: |
     ctx.fillStyle = '#0f0';
     ctx.fillRect(0, 0, 100, 50);
@@ -429,16 +1040,17 @@
             @assert pixel 50,25 == 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.negativesource
   desc: Negative source width/height represents the correct rectangle
   testing:
   - 2d.drawImage.direction
+  canvasType: ['OffscreenCanvas']
   mozilla: {throws: !!null ''}
   images:
   - ggrr-256x256.png
   timeout: long
   code: |
     ctx.fillStyle = '#f00';
     ctx.fillRect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
@@ -466,16 +1078,17 @@
             @assert pixel 75,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.negativedest
   desc: Negative destination width/height represents the correct rectangle
   testing:
   - 2d.drawImage.direction
+  canvasType: ['OffscreenCanvas']
   mozilla: {throws: !!null ''}
   timeout: long
   images:
   - ggrr-256x256.png
   code: |
     ctx.fillStyle = '#f00';
     ctx.fillRect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
@@ -503,16 +1116,17 @@
             @assert pixel 75,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.negativedir
   desc: Negative dimensions do not affect the direction of the image
   testing:
   - 2d.drawImage.direction
+  canvasType: ['OffscreenCanvas']
   mozilla: {throws: !!null ''}
   timeout: long
   images:
   - ggrr-256x256.png
   code: |
     ctx.fillStyle = '#f00';
     ctx.fillRect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
@@ -540,16 +1154,17 @@
             @assert pixel 75,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.outsidesource
   DISABLED: fix this to match the current spec (transparent black outside source)
   testing:
   - 2d.drawImage.outsidesource
+  canvasType: ['OffscreenCanvas']
   code: |
     var promise1 = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
         xhr.open("GET", '/images/red.png');
         xhr.responseType = 'blob';
         xhr.send();
         xhr.onload = function() {
             resolve(xhr.response);
@@ -581,16 +1196,17 @@
             @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 110, 60, -20, -20, 0, 0, 100, 50);
             @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.broken
   testing:
   - 2d.drawImage.incomplete.image
+  canvasType: ['OffscreenCanvas']
   timeout: long
   code: |
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
         xhr.open("GET", '/images/broken.png');
         xhr.responseType = 'blob';
         xhr.send();
         xhr.onload = function() {
@@ -605,16 +1221,17 @@
             @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.svg
   desc: drawImage() of an SVG image
   testing:
   - 2d.drawImage.svg
+  canvasType: ['OffscreenCanvas']
   timeout: long
   code: |
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
         xhr.open("GET", '/images/green.svg');
         xhr.responseType = 'blob';
         xhr.send();
         xhr.onload = function() {
@@ -627,16 +1244,17 @@
             @assert pixel 50,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.animated.poster
   desc: drawImage() of an APNG draws the poster frame
   testing:
   - 2d.drawImage.animated.image
+  canvasType: ['OffscreenCanvas']
   images:
   - anim-poster-gr.png
   timeout: long
   code: |
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
         xhr.open("GET", '/images/anim-poster-gr.png');
         xhr.responseType = 'blob';
@@ -650,16 +1268,17 @@
             ctx.drawImage(bitmap, 0, 0);
             @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.path
   testing:
   - 2d.drawImage.unaffect
+  canvasType: ['OffscreenCanvas']
   timeout: long
   code: |
     ctx.fillStyle = '#0f0';
     ctx.rect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
         xhr.open("GET", '/images/red.png');
         xhr.responseType = 'blob';
@@ -674,16 +1293,17 @@
             ctx.fill();
             @assert pixel 50,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.transform
   testing:
   - 2d.drawImage.subject
+  canvasType: ['OffscreenCanvas']
   images:
   - red.png
   timeout: long
   code: |
     ctx.fillStyle = '#0f0';
     ctx.fillRect(0, 0, 100, 50);
     ctx.translate(100, 0);
     var promise = new Promise(function(resolve, reject) {
@@ -700,16 +1320,17 @@
             ctx.drawImage(bitmap, 0, 0);
             @assert pixel 50,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.alpha
   testing:
   - 2d.drawImage.subject
+  canvasType: ['OffscreenCanvas']
   images:
   - red.png
   timeout: long
   code: |
     ctx.fillStyle = '#0f0';
     ctx.fillRect(0, 0, 100, 50);
     ctx.globalAlpha = 0;
     var promise = new Promise(function(resolve, reject) {
@@ -726,16 +1347,17 @@
             ctx.drawImage(bitmap, 0, 0);
             @assert pixel 50,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.clip
   testing:
   - 2d.drawImage.subject
+  canvasType: ['OffscreenCanvas']
   images:
   - red.png
   timeout: long
   code: |
     ctx.fillStyle = '#0f0';
     ctx.fillRect(0, 0, 100, 50);
     ctx.rect(-10, -10, 1, 1);
     ctx.clip();
@@ -753,16 +1375,17 @@
             ctx.drawImage(bitmap, 0, 0);
             @assert pixel 50,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.composite
   testing:
   - 2d.drawImage.subject
+  canvasType: ['OffscreenCanvas']
   images:
   - red.png
   timeout: long
   code: |
     ctx.fillStyle = '#0f0';
     ctx.fillRect(0, 0, 100, 50);
     ctx.globalCompositeOperation = 'destination-over';
     var promise = new Promise(function(resolve, reject) {
@@ -778,16 +1401,17 @@
         createImageBitmap(response).then(bitmap => {
             ctx.drawImage(bitmap, 0, 0);
             @assert pixel 50,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.nowrap
   desc: Stretched images do not get pixels wrapping around the edges
+  canvasType: ['OffscreenCanvas']
   images:
   - redtransparent.png
   timeout: long
   code: |
     ctx.fillStyle = '#0f0';
     ctx.fillRect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
@@ -806,16 +1430,17 @@
             @assert pixel 55,25 ==~ 0,255,0,255;
         }, t_fail);
     }).then(t_pass, t_fail);
 
 - name: 2d.drawImage.nonfinite
   desc: drawImage() with Infinity/NaN is ignored
   testing:
   - 2d.nonfinite
+  canvasType: ['OffscreenCanvas']
   images:
   - red.png
   timeout: long
   code: |
     ctx.fillStyle = '#0f0';
     ctx.fillRect(0, 0, 100, 50);
     var promise = new Promise(function(resolve, reject) {
         var xhr = new XMLHttpRequest();
deleted file mode 100644
--- a/testing/web-platform/tests/html/canvas/tools/yaml/element/drawing-images-to-the-canvas.yaml
+++ /dev/null
@@ -1,617 +0,0 @@
-- name: 2d.drawImage.3arg
-  testing:
-  - 2d.drawImage.defaultsource
-  - 2d.drawImage.defaultdest
-  images:
-  - red.png
-  - green.png
-  code: |
-    ctx.drawImage(document.getElementById('green.png'), 0, 0);
-    ctx.drawImage(document.getElementById('red.png'), -100, 0);
-    ctx.drawImage(document.getElementById('red.png'), 100, 0);
-    ctx.drawImage(document.getElementById('red.png'), 0, -50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 50);
-
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.5arg
-  testing:
-  - 2d.drawImage.defaultsource
-  images:
-  - red.png
-  - green.png
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('green.png'), 50, 0, 50, 50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0, 50, 50);
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 50, 50);
-
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.9arg.basic
-  testing:
-  - 2d.drawImage.paint
-  images:
-  - green.png
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('green.png'), 0, 0, 100, 50, 0, 0, 100, 50);
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.9arg.sourcepos
-  testing:
-  - 2d.drawImage.paint
-  images:
-  - rgrg-256x256.png
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('rgrg-256x256.png'), 140, 20, 100, 50, 0, 0, 100, 50);
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.9arg.sourcesize
-  testing:
-  - 2d.drawImage.paint
-  images:
-  - rgrg-256x256.png
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('rgrg-256x256.png'), 0, 0, 256, 256, 0, 0, 100, 50);
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 51, 26);
-    ctx.fillRect(49, 24, 51, 26);
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-    @assert pixel 20,20 ==~ 0,255,0,255;
-    @assert pixel 80,20 ==~ 0,255,0,255;
-    @assert pixel 20,30 ==~ 0,255,0,255;
-    @assert pixel 80,30 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.9arg.destpos
-  testing:
-  - 2d.drawImage.paint
-  images:
-  - red.png
-  - green.png
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('green.png'), 0, 0, 100, 50, 0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -100, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -50, 100, 50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, 50, 100, 50);
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.9arg.destsize
-  testing:
-  - 2d.drawImage.paint
-  images:
-  - red.png
-  - green.png
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('green.png'), 1, 1, 1, 1, 0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -50, 0, 50, 50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 50, 50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -25, 100, 25);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, 50, 100, 25);
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.canvas
-  testing:
-  - 2d.drawImage.paint
-  code: |
-    var canvas2 = document.createElement('canvas');
-    canvas2.width = 100;
-    canvas2.height = 50;
-    var ctx2 = canvas2.getContext('2d');
-    ctx2.fillStyle = '#0f0';
-    ctx2.fillRect(0, 0, 100, 50);
-
-    ctx.fillStyle = '#f00';
-    ctx.drawImage(canvas2, 0, 0);
-
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-
-    ctx.drawImage(document.createElement('canvas'), 0, 0);
-
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.self.1
-  testing:
-  - 2d.drawImage.self
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 50, 50);
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(50, 0, 50, 50);
-    ctx.drawImage(canvas, 50, 0);
-
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.self.2
-  testing:
-  - 2d.drawImage.self
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 1, 100, 49);
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 1);
-    ctx.drawImage(canvas, 0, 1);
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 2);
-
-    @assert pixel 0,0 ==~ 0,255,0,255;
-    @assert pixel 99,0 ==~ 0,255,0,255;
-    @assert pixel 0,49 ==~ 0,255,0,255;
-    @assert pixel 99,49 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.null
-  testing:
-  - 2d.drawImage.IDL
-  code: |
-    @assert throws TypeError ctx.drawImage(null, 0, 0);
-
-- name: 2d.drawImage.wrongtype
-  desc: Incorrect image types in drawImage do not match any defined overloads, so
-    WebIDL throws a TypeError
-  notes: &bindings Defined in "Web IDL" (draft)
-  testing:
-  - 2d.drawImage.IDL
-  code: |
-    @assert throws TypeError ctx.drawImage(undefined, 0, 0);
-    @assert throws TypeError ctx.drawImage(0, 0, 0);
-    @assert throws TypeError ctx.drawImage("", 0, 0);
-    @assert throws TypeError ctx.drawImage(document.createElement('p'), 0, 0);
-
-- name: 2d.drawImage.floatsource
-  testing:
-  - 2d.drawImage.paint
-  images:
-  - green.png
-  code: |
-    ctx.drawImage(document.getElementById('green.png'), 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.zerosource
-  desc: drawImage with zero-sized source rectangle draws nothing without exception
-  testing:
-  - 2d.drawImage.zerosource
-  images:
-  - red.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 1, 0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 0, 0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 0, 0, 0, 100, 50);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.zerosource.image
-  desc: drawImage with zero-sized source rectangle from image draws nothing without exception
-  testing:
-  - 2d.drawImage.zerosource
-  images:
-  - red-zerowidth.svg
-  - red-zeroheight.svg
-  - red-zerosize.svg
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red-zerowidth.svg'), 0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red-zeroheight.svg'), 0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red-zerosize.svg'), 0, 0, 100, 50);
-    @assert pixel 50,25 == 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.negativesource
-  desc: Negative source width/height represents the correct rectangle
-  testing:
-  - 2d.drawImage.direction
-  mozilla: {throws: !!null ''}
-  images:
-  - ggrr-256x256.png
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 78, -100, 50, 0, 0, 50, 50);
-    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 128, -100, -50, 50, 0, 50, 50);
-    @assert pixel 1,1 ==~ 0,255,0,255;
-    @assert pixel 1,48 ==~ 0,255,0,255;
-    @assert pixel 98,1 ==~ 0,255,0,255;
-    @assert pixel 98,48 ==~ 0,255,0,255;
-    @assert pixel 48,1 ==~ 0,255,0,255;
-    @assert pixel 48,48 ==~ 0,255,0,255;
-    @assert pixel 51,1 ==~ 0,255,0,255;
-    @assert pixel 51,48 ==~ 0,255,0,255;
-    @assert pixel 25,25 ==~ 0,255,0,255;
-    @assert pixel 75,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.negativedest
-  desc: Negative destination width/height represents the correct rectangle
-  testing:
-  - 2d.drawImage.direction
-  mozilla: {throws: !!null ''}
-  images:
-  - ggrr-256x256.png
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 78, 50, 50, 0, 50, 50, -50);
-    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 128, 50, -50, 100, 50, -50, -50);
-    @assert pixel 1,1 ==~ 0,255,0,255;
-    @assert pixel 1,48 ==~ 0,255,0,255;
-    @assert pixel 98,1 ==~ 0,255,0,255;
-    @assert pixel 98,48 ==~ 0,255,0,255;
-    @assert pixel 48,1 ==~ 0,255,0,255;
-    @assert pixel 48,48 ==~ 0,255,0,255;
-    @assert pixel 51,1 ==~ 0,255,0,255;
-    @assert pixel 51,48 ==~ 0,255,0,255;
-    @assert pixel 25,25 ==~ 0,255,0,255;
-    @assert pixel 75,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.negativedir
-  desc: Negative dimensions do not affect the direction of the image
-  testing:
-  - 2d.drawImage.direction
-  mozilla: {throws: !!null ''}
-  images:
-  - ggrr-256x256.png
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 0, 178, 50, -100, 0, 0, 50, 100);
-    ctx.drawImage(document.getElementById('ggrr-256x256.png'), 0, 78, 50, 100, 50, 100, 50, -100);
-    @assert pixel 1,1 ==~ 0,255,0,255;
-    @assert pixel 1,48 ==~ 0,255,0,255;
-    @assert pixel 98,1 ==~ 0,255,0,255;
-    @assert pixel 98,48 ==~ 0,255,0,255;
-    @assert pixel 48,1 ==~ 0,255,0,255;
-    @assert pixel 48,48 ==~ 0,255,0,255;
-    @assert pixel 51,1 ==~ 0,255,0,255;
-    @assert pixel 51,48 ==~ 0,255,0,255;
-    @assert pixel 25,25 ==~ 0,255,0,255;
-    @assert pixel 75,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.outsidesource
-  DISABLED: fix this to match the current spec (transparent black outside source)
-  testing:
-  - 2d.drawImage.outsidesource
-  mozilla: {throws: !!null ''}
-  images:
-  - green.png
-  - red.png
-  code: |
-    ctx.drawImage(document.getElementById('green.png'), 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('green.png'), 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('green.png'), 100, 50, -5, -5, 0, 0, 100, 50);
-    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), -0.001, 0, 100, 50, 0, 0, 100, 50);
-    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, -0.001, 100, 50, 0, 0, 100, 50);
-    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100.001, 50, 0, 0, 100, 50);
-    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50.001, 0, 0, 100, 50);
-    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 50, 0, 50.001, 50, 0, 0, 100, 50); @moz-todo
-    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, -5, 5, 0, 0, 100, 50);
-    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 5, -5, 0, 0, 100, 50);
-    @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 110, 60, -20, -20, 0, 0, 100, 50);
-    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
-  expected: green
-
-- name: 2d.drawImage.incomplete.nosrc
-  testing:
-  - 2d.drawImage.incomplete.image
-  mozilla: {throws: !!null ''}
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    var img = new Image();
-    ctx.drawImage(img, 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.incomplete.immediate
-  testing:
-  - 2d.drawImage.incomplete.image
-  images:
-  - red.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    var img = new Image();
-    img.src = '../images/red.png';
-    // This triggers the "update the image data" algorithm.
-    // The image will not go to the "completely available" state
-    // until a fetch task in the networking task source is processed,
-    // so the image must not be fully decodable yet:
-    ctx.drawImage(img, 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
-  expected: green
-
-- name: 2d.drawImage.incomplete.reload
-  testing:
-  - 2d.drawImage.incomplete.image
-  images:
-  - yellow.png
-  - red.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    var img = document.getElementById('yellow.png');
-    img.src = '../images/red.png';
-    // This triggers the "update the image data" algorithm,
-    // and resets the image to the "unavailable" state.
-    // The image will not go to the "completely available" state
-    // until a fetch task in the networking task source is processed,
-    // so the image must not be fully decodable yet:
-    ctx.drawImage(img, 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
-  expected: green
-
-- name: 2d.drawImage.incomplete.emptysrc
-  testing:
-  - 2d.drawImage.incomplete.image
-  images:
-  - red.png
-  mozilla: {throws: !!null ''}
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    var img = document.getElementById('red.png');
-    img.src = "";
-    ctx.drawImage(img, 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.incomplete.removedsrc
-  testing:
-  - 2d.drawImage.incomplete.image
-  images:
-  - red.png
-  mozilla: {throws: !!null ''}
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    var img = document.getElementById('red.png');
-    img.removeAttribute('src');
-    ctx.drawImage(img, 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.broken
-  testing:
-  - 2d.drawImage.incomplete.image
-  images:
-  - broken.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    var img = document.getElementById('broken.png');
-    ctx.drawImage(img, 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
-  expected: green
-
-- name: 2d.drawImage.nonexistent
-  testing:
-  - 2d.drawImage.incomplete.image
-  images:
-  - not-found-at-all.png
-  code: |
-    var img = document.getElementById('not-found-at-all.png');
-    @assert throws INVALID_STATE_ERR ctx.drawImage(img, 0, 0);
-
-- name: 2d.drawImage.zerocanvas
-  desc: drawImage with zero-sized canvas as the source shoud throw exception
-  testing:
-  - 2d.drawImage.zerocanvas
-  code: |
-    var canvas2 = document.createElement('canvas');
-    canvas2.width = 0;
-    canvas2.height = 50;
-    @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
-
-    canvas2.width = 50;
-    canvas2.height = 0;
-    @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
-
-    canvas2.width = 0;
-    canvas2.height = 0;
-    @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
-
-- name: 2d.drawImage.svg
-  desc: drawImage() of an SVG image
-  testing:
-  - 2d.drawImage.svg
-  images:
-  - green.svg
-  code: |
-    ctx.drawImage(document.getElementById('green.svg'), 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.animated.gif
-  desc: drawImage() of an animated GIF draws the first frame
-  testing:
-  - 2d.drawImage.animated.image
-  images:
-  - anim-gr.gif
-  code: |
-    deferTest();
-    step_timeout(t.step_func_done(function () {
-        ctx.drawImage(document.getElementById('anim-gr.gif'), 0, 0);
-        @assert pixel 50,25 ==~ 0,255,0,255;
-    }), 500);
-  expected: green
-
-- name: 2d.drawImage.animated.apng
-  desc: drawImage() of an APNG with no poster frame draws the first frame
-  testing:
-  - 2d.drawImage.animated.image
-  images:
-  - anim-gr.png
-  code: |
-    deferTest();
-    step_timeout(t.step_func_done(function () {
-        ctx.drawImage(document.getElementById('anim-gr.png'), 0, 0);
-        @assert pixel 50,25 ==~ 0,255,0,255;
-    }), 500);
-  expected: green
-
-- name: 2d.drawImage.animated.poster
-  desc: drawImage() of an APNG draws the poster frame
-  testing:
-  - 2d.drawImage.animated.image
-  images:
-  - anim-poster-gr.png
-  code: |
-    ctx.drawImage(document.getElementById('anim-poster-gr.png'), 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
-  expected: green
-
-- name: 2d.drawImage.path
-  testing:
-  - 2d.drawImage.unaffect
-  images:
-  - red.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.rect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0);
-    ctx.fill();
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.transform
-  testing:
-  - 2d.drawImage.subject
-  images:
-  - red.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.translate(100, 0);
-    ctx.drawImage(document.getElementById('red.png'), 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-# TODO: drawImage shadows
-
-- name: 2d.drawImage.alpha
-  testing:
-  - 2d.drawImage.subject
-  images:
-  - red.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.globalAlpha = 0;
-    ctx.drawImage(document.getElementById('red.png'), 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.clip
-  testing:
-  - 2d.drawImage.subject
-  images:
-  - red.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.rect(-10, -10, 1, 1);
-    ctx.clip();
-    ctx.drawImage(document.getElementById('red.png'), 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.composite
-  testing:
-  - 2d.drawImage.subject
-  images:
-  - red.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.globalCompositeOperation = 'destination-over';
-    ctx.drawImage(document.getElementById('red.png'), 0, 0);
-    @assert pixel 50,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.nowrap
-  desc: Stretched images do not get pixels wrapping around the edges
-  images:
-  - redtransparent.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.drawImage(document.getElementById('redtransparent.png'), -1950, 0, 2000, 50);
-    @assert pixel 45,25 ==~ 0,255,0,255;
-    @assert pixel 50,25 ==~ 0,255,0,255;
-    @assert pixel 55,25 ==~ 0,255,0,255;
-  expected: green
-
-- name: 2d.drawImage.nonfinite
-  desc: drawImage() with Infinity/NaN is ignored
-  testing:
-  - 2d.nonfinite
-  images:
-  - red.png
-  code: |
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    var red = document.getElementById('red.png');
-    @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
-    @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
-    @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
-    @assert pixel 50,25 == 0,255,0,255;
-  expected: green
-
-
-