summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/test_capture.html
blob: ee37f3046ebe549bbcfd5baea3523eadef129b59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<!DOCTYPE HTML>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />

<title>Canvas2D test: CaptureStream()</title>

<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="captureStream_common.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<body>
<script>
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("Ensuring nothing happens until timing out with good margin");

// CaptureStreamTestHelper holding utility test functions.
const h = new CaptureStreamTestHelper2D();
// Canvas element captured by streams.
const c = h.createAndAppendElement('canvas', 'c');
// Video element with captureStream stream in automatic mode.
const vauto = h.createAndAppendElement('video', 'vauto');
// Video element with captureStream stream in manual (fps 0) mode.
const vmanual = h.createAndAppendElement('video', 'vmanual');
// Video element with captureStream stream with fixed frame rate.
const vrate = h.createAndAppendElement('video', 'vrate');

async function checkDrawColorInitialRed() {
  info("Checking that all video elements become red when initiated just after the first drawColor(red).");

  h.drawColor(c, h.red);

  vauto.srcObject = c.captureStream();
  vmanual.srcObject = c.captureStream(0);
  vrate.srcObject = c.captureStream(10);

  ok(h.isPixel(h.getPixel(vauto), h.blackTransparent, 0),
     "vauto should not be drawn to before stable state");
  ok(h.isPixel(h.getPixel(vrate), h.blackTransparent, 0),
     "vrate should not be drawn to before stable state");
  ok(h.isPixel(h.getPixel(vmanual), h.blackTransparent, 0),
     "vmanual should not be drawn to before stable state");

  await h.pixelMustBecome(vauto, h.red, {
    infoString: "should become red automatically",
  });
  await h.pixelMustBecome(vrate, h.red, {
    infoString: "should become red automatically",
  });
  await h.pixelMustBecome(vmanual, h.red, {
    infoString: "should become red when we get to stable state (first frame)",
  });
}

async function checkDrawColorGreen() {
  info("Checking that drawing green propagates properly to video elements.");

  const drawing = h.startDrawing(() => h.drawColor(c, h.green));

  try {
    await h.pixelMustBecome(vauto, h.green, {
      infoString: "should become green automatically",
    });
    await h.pixelMustBecome(vrate, h.green, {
      infoString: "should become green automatically",
    });
    await h.pixelMustBecome(vmanual, h.red, {
      infoString: "should still be red",
    });
    h.requestFrame(vmanual);
    await h.pixelMustBecome(vmanual, h.green, {
      infoString: "should become green after requstFrame()",
    });
  }
  catch(err) {
    ok(false, "checkDrawColorGreen failed: ", err);
  }
  drawing.stop();
}

async function checkRequestFrameOrderGuarantee() {
  info("Checking that requestFrame() immediately after a drawColor() " +
       "call results in the expected frame seen in the stream.");

  await h.pixelMustBecome(vmanual, h.green, {
    infoString: "should still be green",
  });
  h.drawColor(c, h.red);   // 1. Draw canvas red
  h.requestFrame(vmanual); // 2. Immediately request a frame
  await h.pixelMustBecome(vmanual, h.red, {
    infoString: "should become red after call order test",
  });
}

async function checkDrawImageNotCleanRed() {
  info("Checking that drawImage with not origin-clean image renders streams useless.");
  const ctx = c.getContext('2d');
  const notCleanRed = new Image();

  await new Promise((resolve, reject) => {
    notCleanRed.onload = resolve;
    notCleanRed.onerror = () => reject(new Error("Failed to load tainted image."));
    notCleanRed.src = "http://example.com/tests/dom/canvas/test/image_red_crossorigin_credentials.png";
    document.body.appendChild(notCleanRed);
  });
  const drawing = h.startDrawing(
    () => ctx.drawImage(notCleanRed, 0, 0, c.width, c.height));
  h.testNotClean(c);
  try {
    await h.pixelMustNotBecome(vauto, h.red, {
      timeout: 1000,
      infoString: "should not become red",
    });
    ok(h.isPixelNot(h.getPixel(vrate), h.red, 250),
       "should not have become red");
    await h.pixelMustBecome(vmanual, h.green, {
      infoString: "should still be green",
    });
    h.requestFrame(vmanual);
    await h.pixelMustNotBecome(vmanual, h.red, {
      timeout: 1000,
      infoString: "should not become red",
    });
  } catch(err) {
    ok(false, "checkDrawImageNotCleanRed failed: ", err);
  }
  drawing.stop();
}

async function checkEndedOnStop() {
  const promises = [vauto, vmanual, vrate].map(elem => {
    elem.srcObject.getTracks()[0].stop();
    return new Promise(resolve =>
      elem.addEventListener("ended", function endedListener(event) {
        ok(true, "Element " + elem.id + " ended.");
        resolve();
        elem.removeEventListener("ended", endedListener);
      }));
  });
  await Promise.all(promises);
}

function finish() {
  ok(true, 'Test complete.');
  SimpleTest.finish();
}

(async () => {
  await checkDrawColorInitialRed();
  await checkDrawColorGreen();
  await checkRequestFrameOrderGuarantee();
  await checkDrawColorGreen(); // Restore video elements to green.
  await checkDrawImageNotCleanRed();
  await checkEndedOnStop();
  finish();
})();
</script>