summaryrefslogtreecommitdiffstats
path: root/dom/media/test/test_eme_createMediaKeys_iframes.html
blob: 6fe3dc9809cfa505b874ec6564002f889c4da672 (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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<!DOCTYPE HTML>
<html>
<head>
  <title>Test creation of MediaKeys in iframes</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
  <script type="text/javascript" src="manifest.js"></script>
  <script type="text/javascript" src="eme.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody">
// Helper functions.

// We take navigator explicitly as an argument to avoid ambiguity in fetching
// it. This is to avoid issues with the following
// ```
// iframe.contentWindow.createMediaKeys = createMediaKeys;
// await iframe.contentWindow.createMediaKeys();
// ```
// If we don't pass a navigator, and just use `navigator` in the function, this
// ends up being equivalent to
// ```
// iframe.contentWindow.createMediaKeys = createMediaKeys;
// await iframe.contentWindow.createMediaKeys(window.navigator);
// ```
// i.e. the function will use the navigator from the global window for the top
// browsing context, not the iframe's. This would result in the tests not
// correctly testing within the iframe.
async function createMediaKeys(aNavigator) {
  const clearKeyOptions = [
    {
      initDataTypes: ["webm"],
      videoCapabilities: [{ contentType: 'video/webm; codecs="vp9"' }],
    },
  ];

  let access = await aNavigator.requestMediaKeySystemAccess(
    "org.w3.clearkey",
    clearKeyOptions
  );

  return access.createMediaKeys();
}
// End helper functions.

// These tests check that the following work using different iframe combinations
// - navigator.requestMediaKeySystem(...) successfully grants access.
// - the resulting MediaKeySystemAccess object's createMediaKeys() creates
//   MediaKeys as expected.

// Same origin iframe, using src attribute, wait for onload.
add_task(async () => {
  info(
    "Starting same origin iframe, using src attribute, wait for onload test"
  );
  let iframe = document.createElement("iframe");
  let iframeLoadPromise = new Promise(r => {
    iframe.onload = r;
  });
  iframe.src = "file_eme_createMediaKeys.html";
  document.body.appendChild(iframe);
  await iframeLoadPromise;
  info("iframe loaded");

  // Setup our handler for when the iframe messages to tell us if it
  // created MediaKeys or not.
  let iframeMessagePromise = new Promise(r => {
    window.onmessage = message => {
      is(
        message.data,
        "successCreatingMediaKeys",
        "iframe should have posted us a message saying keys were successfully created"
      );
      r();
    };
  });
  // Post a message to the iframe to ask it to try and create media keys.
  iframe.contentWindow.postMessage("", "*");
  // Wait until we've got a message back from our iframe.
  await iframeMessagePromise;
});

// Same origin iframe, call via JS, wait for onload.
add_task(async () => {
  info("Starting same origin iframe, call via JS, wait for onload test");
  let iframe = document.createElement("iframe");
  let iframeLoadPromise = new Promise(r => {
    iframe.onload = r;
  });
  iframe.src = ""; // No src iframes are same origin.
  document.body.appendChild(iframe);
  await iframeLoadPromise;
  info("iframe loaded");

  try {
    iframe.contentWindow.createMediaKeys = createMediaKeys;
    let mediaKeys = await iframe.contentWindow.createMediaKeys(
      iframe.contentWindow.navigator
    );
    ok(mediaKeys, "Should get media keys");
  } catch (e) {
    ok(
      false,
      `Should not get any errors while trying to get media keys, got ${e}`
    );
  }
});

// Same origin iframe, call via JS, *do not* wait for onload.
//
// Note, sites shouldn't do this, because
// https://bugzilla.mozilla.org/show_bug.cgi?id=543435
// means not waiting for onload results in weird behavior, however
// https://bugzilla.mozilla.org/show_bug.cgi?id=1675360
// shows sites doing this in the wild because historically this worked in
// Firefox.
//
// Breaking this test case isn't necessarily against any specifications
// I'm (bryce) aware of, but it will probably break site compat, so be really
// sure you want to before doing so.
add_task(async () => {
  info(
    "Starting same origin iframe, call via JS, *do not* wait for onload test"
  );
  let iframe = document.createElement("iframe");
  let iframeLoadPromise = new Promise(r => {
    iframe.onload = r;
  });
  iframe.src = ""; // No src iframes are same origin.
  document.body.appendChild(iframe);
  info("iframe appended (we're not waiting for load)");

  try {
    iframe.contentWindow.createMediaKeys = createMediaKeys;
    let mediaKeys = await iframe.contentWindow.createMediaKeys(
      iframe.contentWindow.navigator
    );
    ok(mediaKeys, "Should get media keys");

    // We await the load to see if they keys persist through the load.
    // This could fail if gecko internally associates the keys with the
    // about:blank page that is replaced by the load.
    await iframeLoadPromise;
    ok(mediaKeys, "Media keys should still exist after the load");
  } catch (e) {
    ok(
      false,
      `Should not get any errors while trying to get media keys, got ${e}`
    );
  }
});

// Different origin iframe, using src attribute, wait for onload
add_task(async () => {
  info(
    "Starting different origin iframe, using src attribute, wait for onload test"
  );
  let iframe = document.createElement("iframe");
  let iframeLoadPromise = new Promise(r => {
    iframe.onload = r;
  });
  // Make our iframe cross origin (see build/pgo/server-locations.txt for more
  // info the url used).
  iframe.src =
    "https://w3c-test.org:443/tests/dom/media/test/file_eme_createMediaKeys.html";
  iframe.allow = "encrypted-media";
  document.body.appendChild(iframe);
  await iframeLoadPromise;
  info("iframe loaded");

  // Setup our handler for when the iframe messages to tell us if it
  // created MediaKeys or not.
  let iframeMessagePromise = new Promise(r => {
    window.onmessage = message => {
      is(
        message.data,
        "successCreatingMediaKeys",
        "iframe should have posted us a message saying keys were successfully created"
      );
      r();
    };
  });
  // Post a message to the iframe to ask it to try and create media keys.
  iframe.contentWindow.postMessage("", "*");
  // Wait until we've got a message back from our iframe.
  await iframeMessagePromise;
});
</script>
</pre>
</body>
</html>