Fix browser launch on the login screen.
[chromium-blink-merge.git] / ppapi / tests / test_case.html
blob579557250d4d45c55d32d7702becb07a2f01eb49
1 <html><head>
2 <meta http-equiv="Pragma" content="no-cache" />
3 <meta http-equiv="Expires" content="-1" />
4 <link rel="stylesheet" href="test_page.css">
5 <script>
6 // Do a deep comparison of two values. Return true if their values are
7 // identical, false otherwise.
8 function deepCompare(left, right) {
9 if (typeof(left) !== typeof(right))
10 return false;
11 // If their identity is the same or they're basic types with the same value,
12 // they are equal.
13 if (left === right)
14 return true;
15 // If it's a basic type and we got here, we know they're not equal.
16 if (["undefined", "boolean", "number", "string", "function"].indexOf(
17 typeof(left)) > -1) {
18 return false;
20 // Use right_keys as a set containing all keys from |right| which we haven't
21 // yet compared.
22 var right_keys = {};
23 for (var key in right)
24 right_keys[key] = true;
25 for (var key in left) {
26 if (key in right_keys) {
27 if (!deepCompare(left[key], right[key]))
28 return false;
29 } else {
30 // |left| had a key that |right| didn't.
31 return false;
33 delete right_keys[key];
35 // If there are keys left in |right_keys|, it means they didn't exist in
36 // |left|, so the objects aren't equal.
37 if (Object.keys(right_keys).length > 0)
38 return false;
39 return true;
42 function AdjustHeight(frameWin) {
43 var div = frameWin.document.getElementsByTagName("div")[0];
44 var height = frameWin.getComputedStyle(div).height;
45 frameWin.frameElement.style.height = height;
48 // Called when the tests are completed. |result| should be "PASS" if the test(s)
49 // passed, or information about the failure if the test(s) did not pass.
50 function DidExecuteTests(result) {
51 var plugin = document.getElementById("plugin");
52 if (plugin.parentNode.removePlugin) {
53 plugin.parentNode.removeChild(plugin);
54 plugin = undefined;
56 if (CheckPostConditions())
57 sendAutomationMessage(result);
59 if (window == top)
60 return;
62 // Otherwise, we are in a subframe, so we can use this opportunity to resize
63 // ourselves.
64 AdjustHeight(window);
67 function AppendFrame(testcase, i) {
68 var p = document.createElement("P");
69 p.setAttribute("class", "frame-container");
71 var title = document.createElement("H2");
72 title.appendChild(document.createTextNode(testcase));
73 p.appendChild(title);
75 var frame = document.createElement("IFRAME");
76 var mode = ExtractSearchParameter("mode");
77 var websocket_host = ExtractSearchParameter("websocket_host");
78 var websocket_port = ExtractSearchParameter("websocket_port");
79 var ssl_server_port = ExtractSearchParameter("ssl_server_port");
80 var src = "?testcase=" + testcase;
81 if (mode == "nacl")
82 src += "&mode=nacl";
83 if (websocket_host != "")
84 src += "&websocket_host=" + websocket_host;
85 if (websocket_port != "")
86 src += "&websocket_port=" + websocket_port;
87 if (ssl_server_port != "")
88 src += "&ssl_server_port=" + ssl_server_port;
89 frame.setAttribute("src", src);
91 frame.setAttribute("onload", "LoadNext(" + (i + 1) + ")");
92 p.appendChild(frame);
94 document.body.appendChild(p);
97 function LoadNext(i) {
98 var links = document.links;
99 if (links.length > i)
100 AppendFrame(links[i].firstChild.nodeValue, i);
103 function RunAll() {
104 // Remove any existing frames.
105 var existing = document.getElementsByClassName("frame-container");
106 while (existing.length)
107 existing[0].parentNode.removeChild(existing[0]);
109 // Add new frames for each test, but do so one frame at a time.
110 LoadNext(0);
113 function ExtractSearchParameter(name) {
114 var nameIndex = location.search.indexOf(name + "=");
115 if (nameIndex != -1) {
116 var value = location.search.substring(nameIndex + name.length + 1);
117 var endIndex = value.indexOf("&");
118 if (endIndex != -1)
119 value = value.substring(0, endIndex);
120 return value;
122 return "";
125 // Parses the message, looking for strings of the form:
126 // TESTING_MESSAGE:<message_type>:<message_contents>
128 // If the message_data is not a string or does not match the above format, then
129 // undefined is returned.
131 // Otherwise, returns an array containing 2 items. The 0th element is the
132 // message_type, one of:
133 // - AddPostCondition
134 // - ClearConsole
135 // - DidExecuteTests
136 // - EvalScript
137 // - LogHTML
138 // - RemovePluginWhenFinished
139 // - ReportProgress
140 // The second item is the verbatim message_contents.
141 function ParseTestingMessage(message_data) {
142 if (typeof(message_data) != "string")
143 return undefined;
144 var testing_message_prefix = "TESTING_MESSAGE";
145 var delim_str = ":";
146 var delim1 = message_data.indexOf(delim_str);
147 if (message_data.substring(0, delim1) !== testing_message_prefix)
148 return undefined;
149 var delim2 = message_data.indexOf(delim_str, delim1 + 1);
150 if (delim2 == -1)
151 delim2 = message_data.length;
152 var message_type = message_data.substring(delim1 + 1, delim2);
153 var message_contents = message_data.substring(delim2 + 1);
154 return [message_type, message_contents];
157 function ClearConsole() {
158 window.document.getElementById("console").innerHTML = "";
161 function LogHTML(html) {
162 window.document.getElementById("console").innerHTML += html;
165 function RemovePluginWhenFinished() {
166 window.document.getElementById("container").removePlugin = true;
169 function sendAutomationMessage(msg) {
170 if (window.domAutomationController) {
171 window.domAutomationController.setAutomationId(0);
172 window.domAutomationController.send(msg);
176 function LogTestTime(test_time) {
177 console.log(test_time);
180 // If something goes really wrong, the test running inside the plugin may not
181 // terminate. For example, if the plugin does not load, the test will never
182 // send "PASS" to the browser. In this case we should explicitly use the
183 // automation controller to terminate the test.
184 function InternalError(msg) {
185 LogHTML("<p>" + msg);
186 sendAutomationMessage(msg);
189 function EvalScript(script) {
190 try {
191 eval(script);
192 } catch(ex) {
196 var conditions = [];
197 // Add a "PostCondition". These are bits of script that are run after the plugin
198 // is destroyed. If they evaluate to false or throw an exception, it's
199 // considered a failure.
200 function AddPostCondition(script) {
201 conditions.push(script);
203 // Update the HTML to show the failure and update cookies so that ui_tests
204 // doesn't count this as a pass.
205 function ConditionFailed(error) {
206 error_string = "Post condition check failed: " + error;
207 InternalError(error_string);
209 // Iterate through the post conditions defined in |conditions| and check that
210 // they all pass.
211 function CheckPostConditions() {
212 var success = true;
213 for (var i = 0; i < conditions.length; ++i) {
214 var script = conditions[i];
215 try {
216 if (!eval(script)) {
217 ConditionFailed("\"" + script + "\"");
218 success = false;
220 } catch (ex) {
221 ConditionFailed("\"" + script + "\"" + " failed with exception: " +
222 "\"" + ex.toString() + "\"");
223 success = false;
226 return success;
229 function IsTestingMessage(message_data) {
230 return (ParseTestingMessage(message_data) != undefined);
233 function handleTestingMessage(message_event) {
234 var type_contents_tuple = ParseTestingMessage(message_event.data);
235 if (type_contents_tuple) {
236 var type = type_contents_tuple[0];
237 var contents = type_contents_tuple[1];
238 if (type === "AddPostCondition")
239 AddPostCondition(contents);
240 else if (type === "ClearConsole")
241 ClearConsole();
242 else if (type === "DidExecuteTests")
243 DidExecuteTests(contents);
244 else if (type === "EvalScript")
245 EvalScript(contents);
246 else if (type === "LogHTML")
247 LogHTML(contents);
248 else if (type === "RemovePluginWhenFinished")
249 RemovePluginWhenFinished();
250 else if (type === "ReportProgress")
251 sendAutomationMessage(contents);
252 else if (type === "LogTestTime")
253 LogTestTime(contents);
257 function sendProgress() {
258 // We send "..." to signal that we're still working. See
259 // ppapi/tests/testing_instance.h for how this works.
260 sendAutomationMessage("...");
263 onload = function() {
264 var testcase = ExtractSearchParameter("testcase");
265 var mode = ExtractSearchParameter("mode");
266 document.title = 'Test ' + testcase;
267 var obj;
268 if (mode == "nacl_newlib") {
269 obj = document.createElement("EMBED");
270 obj.setAttribute("src", "ppapi_nacl_tests_newlib.nmf");
271 obj.setAttribute("type", "application/x-nacl");
272 obj.setAttribute("mode", mode);
273 } else if (mode == "nacl_glibc") {
274 obj = document.createElement("EMBED");
275 obj.setAttribute("src", "ppapi_nacl_tests_glibc.nmf");
276 obj.setAttribute("type", "application/x-nacl");
277 obj.setAttribute("mode", mode);
278 } else if (mode == "nacl_pnacl") {
279 obj = document.createElement("EMBED");
280 obj.setAttribute("src", "ppapi_nacl_tests_pnacl.nmf");
281 obj.setAttribute("type", "application/x-nacl");
282 obj.setAttribute("mode", mode);
283 } else if (mode == "nacl_pnacl_nonsfi") {
284 obj = document.createElement("EMBED");
285 obj.setAttribute("src", "ppapi_nacl_tests_pnacl_nonsfi.nmf");
286 obj.setAttribute("type", "application/x-nacl");
287 obj.setAttribute("mode", mode);
288 } else if (mode == "mojo") {
289 obj = document.createElement("EMBED");
290 obj.setAttribute("src",
291 "test_data/ppapi/tests/mojo/pnacl/ppapi_tests_mojo.nmf");
292 obj.setAttribute("type", "application/x-pnacl");
293 obj.setAttribute("mode", mode);
294 } else {
295 var mimeType = "application/x-ppapi-tests";
296 if (mimeType in navigator.mimeTypes) {
297 obj = document.createElement("EMBED");
298 obj.setAttribute("src", "http://a.b.c/test");
299 obj.setAttribute("type", mimeType);
300 } else {
301 document.getElementById("console").innerHTML =
302 '<span class="fail">FAIL</span>: ' +
303 '<span class="err_msg">Test plug-in is not registered.</span>';
307 if (obj) {
308 obj.setAttribute("width", 80);
309 obj.setAttribute("height", 80);
310 obj.setAttribute("style",
311 "background-color:#AAAAAA;border:1px solid black;");
312 obj.setAttribute("id", "plugin");
313 obj.setAttribute("testcase", testcase);
314 obj.setAttribute("protocol", window.location.protocol);
315 var websocket_host = ExtractSearchParameter("websocket_host");
316 if (websocket_host != "")
317 obj.setAttribute("websocket_host", websocket_host);
318 var websocket_port = ExtractSearchParameter("websocket_port");
319 if (websocket_port != "")
320 obj.setAttribute("websocket_port", websocket_port);
321 var ssl_server_port = ExtractSearchParameter("ssl_server_port");
322 if (ssl_server_port != "")
323 obj.setAttribute("ssl_server_port", ssl_server_port);
325 var container = document.getElementById("container");
326 container.addEventListener("message", handleTestingMessage, true);
328 // "error" and "crash" events will only fire for NaCl, but adding these
329 // listeners doesn't hurt in the non-NaCl cases.
330 obj.addEventListener("error", function() {
331 InternalError("Plugin did not load. '" + obj.lastError + "'");
332 }, true);
333 obj.addEventListener("crash", function() {
334 InternalError("Plugin crashed. '" + obj.lastError + "'");
335 }, true);
337 // NaCl sends progress events while loading. When we get one, notify the
338 // domAutomationController so that it knows we're still working.
339 obj.addEventListener("loadstart", sendProgress, true);
340 obj.addEventListener("progress", sendProgress, true);
341 obj.addEventListener("load", sendProgress, true);
342 obj.addEventListener("loadend", sendProgress, true);
344 // Register a bad dispatchEvent to make sure it isn't used. See 'EVIL' note
345 // below.
346 var original = obj.dispatchEvent;
347 obj.dispatchEvent = function() {
348 InternalError("Bad dispatchEvent called!");
350 container.appendChild(obj);
354 // EVIL Note:
355 // This part of the script does some nefarious things to make sure that it
356 // doesn't affect the behavior of PostMessage (on which all the tests rely). In
357 // particular, we replace document.createEvent, MessageEvent.initMessageEvent,
358 // and the MessageEvent constructor. Previously, the NaCl integration
359 // implementation made use of these and would fail (http://crbug.com/82604
360 // and http://crbug.com/109775).
361 document.createEvent = function() {
362 InternalError("Bad document.createEvent called!");
364 function MessageEvent() {
365 InternalError("Bad MessageEvent constructor called!");
367 MessageEvent.prototype.initMessageEvent = function() {
368 InternalError("Bad MessageEvent.initMessageEvent called!");
371 </script>
372 </head><body>
373 <div>
374 <div id="container"></div>
375 <div id="console"><span class="load_msg">loading...</span></div>
376 </div>
377 </body></html>