blob: 374ada6fdc38bf865fa7e705099efc55d1eef39d [file] [log] [blame]
[email protected]1758e882010-11-01 16:16:501<html><head>
[email protected]849b0712011-04-28 19:15:082<meta http-equiv="Pragma" content="no-cache" />
3<meta http-equiv="Expires" content="-1" />
[email protected]1758e882010-11-01 16:16:504<link rel="stylesheet" href="test_page.css">
5<script>
[email protected]e87640bd2014-06-18 16:44:006// Do a deep comparison of two values. Return true if their values are
7// identical, false otherwise.
8function 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;
19 }
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;
32 }
33 delete right_keys[key];
34 }
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;
40}
41
[email protected]1758e882010-11-01 16:16:5042function AdjustHeight(frameWin) {
43 var div = frameWin.document.getElementsByTagName("div")[0];
44 var height = frameWin.getComputedStyle(div).height;
45 frameWin.frameElement.style.height = height;
46}
47
[email protected]e7425db2013-07-17 20:15:2148// 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.
50function DidExecuteTests(result) {
[email protected]13e343c2012-03-16 22:34:2251 var plugin = document.getElementById("plugin");
[email protected]9e998c0f2013-11-02 13:27:5252 if (plugin.parentNode.removePlugin) {
[email protected]e7425db2013-07-17 20:15:2153 plugin.parentNode.removeChild(plugin);
54 plugin = undefined;
55 }
56 if (CheckPostConditions())
57 sendAutomationMessage(result);
[email protected]13e343c2012-03-16 22:34:2258
[email protected]1758e882010-11-01 16:16:5059 if (window == top)
60 return;
61
62 // Otherwise, we are in a subframe, so we can use this opportunity to resize
alexmosd93138eb2016-07-13 15:38:4763 // ourselves. This can only be done if the parent frame has the same origin.
64 if (window.frameElement)
65 AdjustHeight(window);
[email protected]1758e882010-11-01 16:16:5066}
67
68function AppendFrame(testcase, i) {
69 var p = document.createElement("P");
70 p.setAttribute("class", "frame-container");
71
72 var title = document.createElement("H2");
73 title.appendChild(document.createTextNode(testcase));
74 p.appendChild(title);
75
76 var frame = document.createElement("IFRAME");
[email protected]849b0712011-04-28 19:15:0877 var mode = ExtractSearchParameter("mode");
[email protected]21de9cb22013-02-14 13:07:3478 var websocket_host = ExtractSearchParameter("websocket_host");
[email protected]bedf8742012-03-16 16:44:1179 var websocket_port = ExtractSearchParameter("websocket_port");
[email protected]6c113402012-03-23 01:31:5180 var ssl_server_port = ExtractSearchParameter("ssl_server_port");
[email protected]bedf8742012-03-16 16:44:1181 var src = "?testcase=" + testcase;
[email protected]849b0712011-04-28 19:15:0882 if (mode == "nacl")
[email protected]bedf8742012-03-16 16:44:1183 src += "&mode=nacl";
[email protected]21de9cb22013-02-14 13:07:3484 if (websocket_host != "")
85 src += "&websocket_host=" + websocket_host;
[email protected]bedf8742012-03-16 16:44:1186 if (websocket_port != "")
87 src += "&websocket_port=" + websocket_port;
[email protected]6c113402012-03-23 01:31:5188 if (ssl_server_port != "")
89 src += "&ssl_server_port=" + ssl_server_port;
[email protected]bedf8742012-03-16 16:44:1190 frame.setAttribute("src", src);
91
[email protected]1758e882010-11-01 16:16:5092 frame.setAttribute("onload", "LoadNext(" + (i + 1) + ")");
93 p.appendChild(frame);
94
95 document.body.appendChild(p);
96}
97
98function LoadNext(i) {
99 var links = document.links;
100 if (links.length > i)
101 AppendFrame(links[i].firstChild.nodeValue, i);
102}
103
104function RunAll() {
105 // Remove any existing frames.
106 var existing = document.getElementsByClassName("frame-container");
107 while (existing.length)
108 existing[0].parentNode.removeChild(existing[0]);
109
110 // Add new frames for each test, but do so one frame at a time.
111 LoadNext(0);
112}
113
[email protected]52d2c8e02010-11-16 20:59:23114function ExtractSearchParameter(name) {
115 var nameIndex = location.search.indexOf(name + "=");
116 if (nameIndex != -1) {
117 var value = location.search.substring(nameIndex + name.length + 1);
118 var endIndex = value.indexOf("&");
119 if (endIndex != -1)
120 value = value.substring(0, endIndex);
121 return value;
122 }
123 return "";
124}
[email protected]1758e882010-11-01 16:16:50125
[email protected]7f801d82011-07-08 23:30:11126// Parses the message, looking for strings of the form:
127// TESTING_MESSAGE:<message_type>:<message_contents>
128//
129// If the message_data is not a string or does not match the above format, then
130// undefined is returned.
131//
132// Otherwise, returns an array containing 2 items. The 0th element is the
133// message_type, one of:
[email protected]13e343c2012-03-16 22:34:22134// - AddPostCondition
[email protected]e7425db2013-07-17 20:15:21135// - ClearConsole
136// - DidExecuteTests
137// - EvalScript
138// - LogHTML
139// - RemovePluginWhenFinished
140// - ReportProgress
[email protected]7f801d82011-07-08 23:30:11141// The second item is the verbatim message_contents.
142function ParseTestingMessage(message_data) {
[email protected]13e343c2012-03-16 22:34:22143 if (typeof(message_data) != "string")
[email protected]7f801d82011-07-08 23:30:11144 return undefined;
145 var testing_message_prefix = "TESTING_MESSAGE";
146 var delim_str = ":";
147 var delim1 = message_data.indexOf(delim_str);
148 if (message_data.substring(0, delim1) !== testing_message_prefix)
149 return undefined;
150 var delim2 = message_data.indexOf(delim_str, delim1 + 1);
151 if (delim2 == -1)
152 delim2 = message_data.length;
153 var message_type = message_data.substring(delim1 + 1, delim2);
154 var message_contents = message_data.substring(delim2 + 1);
155 return [message_type, message_contents];
156}
157
158function ClearConsole() {
159 window.document.getElementById("console").innerHTML = "";
160}
161
162function LogHTML(html) {
163 window.document.getElementById("console").innerHTML += html;
164}
165
[email protected]e7425db2013-07-17 20:15:21166function RemovePluginWhenFinished() {
[email protected]9e998c0f2013-11-02 13:27:52167 window.document.getElementById("container").removePlugin = true;
[email protected]e7425db2013-07-17 20:15:21168}
169
[email protected]00d8e0d2013-01-11 15:52:36170function sendAutomationMessage(msg) {
lukasza08a95212017-07-12 01:58:07171 if (window.domAutomationController)
[email protected]00d8e0d2013-01-11 15:52:36172 window.domAutomationController.send(msg);
[email protected]00d8e0d2013-01-11 15:52:36173}
174
[email protected]a33a08982013-10-31 17:23:29175function LogTestTime(test_time) {
176 console.log(test_time);
177}
178
[email protected]52d6a082012-12-06 22:47:42179// If something goes really wrong, the test running inside the plugin may not
180// terminate. For example, if the plugin does not load, the test will never
181// send "PASS" to the browser. In this case we should explicitly use the
182// automation controller to terminate the test.
183function InternalError(msg) {
184 LogHTML("<p>" + msg);
[email protected]79efedbd2013-01-11 21:53:20185 sendAutomationMessage(msg);
[email protected]52d6a082012-12-06 22:47:42186}
187
[email protected]08610102011-12-17 14:24:30188function EvalScript(script) {
189 try {
190 eval(script);
191 } catch(ex) {
192 }
193}
194
[email protected]13e343c2012-03-16 22:34:22195var conditions = [];
196// Add a "PostCondition". These are bits of script that are run after the plugin
197// is destroyed. If they evaluate to false or throw an exception, it's
198// considered a failure.
199function AddPostCondition(script) {
200 conditions.push(script);
201}
202// Update the HTML to show the failure and update cookies so that ui_tests
203// doesn't count this as a pass.
204function ConditionFailed(error) {
205 error_string = "Post condition check failed: " + error;
[email protected]e7425db2013-07-17 20:15:21206 InternalError(error_string);
[email protected]13e343c2012-03-16 22:34:22207}
208// Iterate through the post conditions defined in |conditions| and check that
209// they all pass.
210function CheckPostConditions() {
[email protected]e7425db2013-07-17 20:15:21211 var success = true;
[email protected]13e343c2012-03-16 22:34:22212 for (var i = 0; i < conditions.length; ++i) {
213 var script = conditions[i];
214 try {
215 if (!eval(script)) {
216 ConditionFailed("\"" + script + "\"");
[email protected]e7425db2013-07-17 20:15:21217 success = false;
[email protected]13e343c2012-03-16 22:34:22218 }
219 } catch (ex) {
220 ConditionFailed("\"" + script + "\"" + " failed with exception: " +
221 "\"" + ex.toString() + "\"");
[email protected]e7425db2013-07-17 20:15:21222 success = false;
[email protected]13e343c2012-03-16 22:34:22223 }
224 }
[email protected]e7425db2013-07-17 20:15:21225 return success;
[email protected]13e343c2012-03-16 22:34:22226}
227
[email protected]7f801d82011-07-08 23:30:11228function IsTestingMessage(message_data) {
229 return (ParseTestingMessage(message_data) != undefined);
230}
231
232function handleTestingMessage(message_event) {
233 var type_contents_tuple = ParseTestingMessage(message_event.data);
234 if (type_contents_tuple) {
235 var type = type_contents_tuple[0];
236 var contents = type_contents_tuple[1];
[email protected]e7425db2013-07-17 20:15:21237 if (type === "AddPostCondition")
238 AddPostCondition(contents);
239 else if (type === "ClearConsole")
[email protected]7f801d82011-07-08 23:30:11240 ClearConsole();
241 else if (type === "DidExecuteTests")
[email protected]e7425db2013-07-17 20:15:21242 DidExecuteTests(contents);
[email protected]08610102011-12-17 14:24:30243 else if (type === "EvalScript")
244 EvalScript(contents);
[email protected]e7425db2013-07-17 20:15:21245 else if (type === "LogHTML")
246 LogHTML(contents);
247 else if (type === "RemovePluginWhenFinished")
248 RemovePluginWhenFinished();
249 else if (type === "ReportProgress")
250 sendAutomationMessage(contents);
[email protected]a33a08982013-10-31 17:23:29251 else if (type === "LogTestTime")
252 LogTestTime(contents);
[email protected]7f801d82011-07-08 23:30:11253 }
254}
255
[email protected]00d8e0d2013-01-11 15:52:36256function sendProgress() {
[email protected]00d8e0d2013-01-11 15:52:36257 // We send "..." to signal that we're still working. See
258 // ppapi/tests/testing_instance.h for how this works.
259 sendAutomationMessage("...");
260}
261
[email protected]52d2c8e02010-11-16 20:59:23262onload = function() {
263 var testcase = ExtractSearchParameter("testcase");
264 var mode = ExtractSearchParameter("mode");
265 document.title = 'Test ' + testcase;
266 var obj;
[email protected]4223f8d2012-06-07 01:10:06267 if (mode == "nacl_newlib") {
[email protected]88bfb432011-05-23 22:43:59268 obj = document.createElement("EMBED");
[email protected]4223f8d2012-06-07 01:10:06269 obj.setAttribute("src", "ppapi_nacl_tests_newlib.nmf");
270 obj.setAttribute("type", "application/x-nacl");
271 obj.setAttribute("mode", mode);
272 } else if (mode == "nacl_glibc") {
273 obj = document.createElement("EMBED");
274 obj.setAttribute("src", "ppapi_nacl_tests_glibc.nmf");
[email protected]849b0712011-04-28 19:15:08275 obj.setAttribute("type", "application/x-nacl");
[email protected]52d2c8e02010-11-16 20:59:23276 obj.setAttribute("mode", mode);
[email protected]1e40ba002013-03-07 22:07:33277 } else if (mode == "nacl_pnacl") {
278 obj = document.createElement("EMBED");
279 obj.setAttribute("src", "ppapi_nacl_tests_pnacl.nmf");
280 obj.setAttribute("type", "application/x-nacl");
281 obj.setAttribute("mode", mode);
[email protected]2c8a5092014-04-03 12:01:49282 } else if (mode == "nacl_pnacl_nonsfi") {
283 obj = document.createElement("EMBED");
284 obj.setAttribute("src", "ppapi_nacl_tests_pnacl_nonsfi.nmf");
285 obj.setAttribute("type", "application/x-nacl");
286 obj.setAttribute("mode", mode);
teravest8e2d2b72014-12-29 22:52:23287 } else if (mode == "mojo") {
288 obj = document.createElement("EMBED");
289 obj.setAttribute("src",
290 "test_data/ppapi/tests/mojo/pnacl/ppapi_tests_mojo.nmf");
291 obj.setAttribute("type", "application/x-pnacl");
292 obj.setAttribute("mode", mode);
[email protected]52d2c8e02010-11-16 20:59:23293 } else {
294 var mimeType = "application/x-ppapi-tests";
295 if (mimeType in navigator.mimeTypes) {
[email protected]ebc5c8be2011-05-20 22:52:59296 obj = document.createElement("EMBED");
[email protected]88bfb432011-05-23 22:43:59297 obj.setAttribute("src", "http://a.b.c/test");
[email protected]52d2c8e02010-11-16 20:59:23298 obj.setAttribute("type", mimeType);
299 } else {
300 document.getElementById("console").innerHTML =
301 '<span class="fail">FAIL</span>: ' +
tommyclie86b2982015-03-16 20:16:45302 '<span class="err_msg">Test plugin is not registered.</span>';
[email protected]52d2c8e02010-11-16 20:59:23303 }
304 }
teravest8e2d2b72014-12-29 22:52:23305
[email protected]52d2c8e02010-11-16 20:59:23306 if (obj) {
[email protected]09c37ba2012-01-05 18:00:33307 obj.setAttribute("width", 80);
308 obj.setAttribute("height", 80);
309 obj.setAttribute("style",
310 "background-color:#AAAAAA;border:1px solid black;");
[email protected]1758e882010-11-01 16:16:50311 obj.setAttribute("id", "plugin");
[email protected]1758e882010-11-01 16:16:50312 obj.setAttribute("testcase", testcase);
[email protected]7f801d82011-07-08 23:30:11313 obj.setAttribute("protocol", window.location.protocol);
[email protected]21de9cb22013-02-14 13:07:34314 var websocket_host = ExtractSearchParameter("websocket_host");
315 if (websocket_host != "")
316 obj.setAttribute("websocket_host", websocket_host);
[email protected]bedf8742012-03-16 16:44:11317 var websocket_port = ExtractSearchParameter("websocket_port");
318 if (websocket_port != "")
319 obj.setAttribute("websocket_port", websocket_port);
[email protected]6c113402012-03-23 01:31:51320 var ssl_server_port = ExtractSearchParameter("ssl_server_port");
321 if (ssl_server_port != "")
322 obj.setAttribute("ssl_server_port", ssl_server_port);
323
[email protected]7f801d82011-07-08 23:30:11324 var container = document.getElementById("container");
[email protected]7f801d82011-07-08 23:30:11325 container.addEventListener("message", handleTestingMessage, true);
[email protected]00d8e0d2013-01-11 15:52:36326
[email protected]52d6a082012-12-06 22:47:42327 // "error" and "crash" events will only fire for NaCl, but adding these
328 // listeners doesn't hurt in the non-NaCl cases.
329 obj.addEventListener("error", function() {
330 InternalError("Plugin did not load. '" + obj.lastError + "'");
331 }, true);
332 obj.addEventListener("crash", function() {
333 InternalError("Plugin crashed. '" + obj.lastError + "'");
334 }, true);
[email protected]00d8e0d2013-01-11 15:52:36335
336 // NaCl sends progress events while loading. When we get one, notify the
337 // domAutomationController so that it knows we're still working.
338 obj.addEventListener("loadstart", sendProgress, true);
339 obj.addEventListener("progress", sendProgress, true);
340 obj.addEventListener("load", sendProgress, true);
341 obj.addEventListener("loadend", sendProgress, true);
342
[email protected]c4cc74c2011-11-17 17:06:34343 // Register a bad dispatchEvent to make sure it isn't used. See 'EVIL' note
344 // below.
[email protected]52d6a082012-12-06 22:47:42345 var original = obj.dispatchEvent;
[email protected]c4cc74c2011-11-17 17:06:34346 obj.dispatchEvent = function() {
[email protected]67239b12013-11-09 01:37:29347 InternalError("Bad dispatchEvent called!");
[email protected]c4cc74c2011-11-17 17:06:34348 }
[email protected]2deab8c2011-11-15 23:30:04349 container.appendChild(obj);
[email protected]1758e882010-11-01 16:16:50350 }
351}
[email protected]c4cc74c2011-11-17 17:06:34352
353// EVIL Note:
354// This part of the script does some nefarious things to make sure that it
355// doesn't affect the behavior of PostMessage (on which all the tests rely). In
356// particular, we replace document.createEvent, MessageEvent.initMessageEvent,
[email protected]67239b12013-11-09 01:37:29357// and the MessageEvent constructor. Previously, the NaCl integration
358// implementation made use of these and would fail (http://crbug.com/82604
359// and http://crbug.com/109775).
[email protected]c4cc74c2011-11-17 17:06:34360document.createEvent = function() {
[email protected]72876e12013-01-11 20:58:03361 InternalError("Bad document.createEvent called!");
[email protected]c4cc74c2011-11-17 17:06:34362}
363function MessageEvent() {
[email protected]72876e12013-01-11 20:58:03364 InternalError("Bad MessageEvent constructor called!");
[email protected]c4cc74c2011-11-17 17:06:34365}
366MessageEvent.prototype.initMessageEvent = function() {
[email protected]72876e12013-01-11 20:58:03367 InternalError("Bad MessageEvent.initMessageEvent called!");
[email protected]c4cc74c2011-11-17 17:06:34368}
369
[email protected]1758e882010-11-01 16:16:50370</script>
371</head><body>
372<div>
373 <div id="container"></div>
[email protected]8f080382012-12-05 16:13:06374 <div id="console"><span class="load_msg">loading...</span></div>
[email protected]1758e882010-11-01 16:16:50375</div>
376</body></html>