Home | History | Annotate | Download | only in tests
      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 function AdjustHeight(frameWin) {
      7   var div = frameWin.document.getElementsByTagName("div")[0];
      8   var height = frameWin.getComputedStyle(div).height;
      9   frameWin.frameElement.style.height = height;
     10 }
     11 
     12 // Called when the tests are completed. |result| should be "PASS" if the test(s)
     13 // passed, or information about the failure if the test(s) did not pass.
     14 function DidExecuteTests(result) {
     15   var plugin = document.getElementById("plugin");
     16   if (plugin.parentNode.removePlugin) {
     17     plugin.parentNode.removeChild(plugin);
     18     plugin = undefined;
     19   }
     20   if (CheckPostConditions())
     21     sendAutomationMessage(result);
     22 
     23   if (window == top)
     24     return;
     25 
     26   // Otherwise, we are in a subframe, so we can use this opportunity to resize
     27   // ourselves.
     28   AdjustHeight(window);
     29 }
     30 
     31 function AppendFrame(testcase, i) {
     32   var p = document.createElement("P");
     33   p.setAttribute("class", "frame-container");
     34 
     35   var title = document.createElement("H2");
     36   title.appendChild(document.createTextNode(testcase));
     37   p.appendChild(title);
     38 
     39   var frame = document.createElement("IFRAME");
     40   var mode = ExtractSearchParameter("mode");
     41   var websocket_host = ExtractSearchParameter("websocket_host");
     42   var websocket_port = ExtractSearchParameter("websocket_port");
     43   var ssl_server_port = ExtractSearchParameter("ssl_server_port");
     44   var src = "?testcase=" + testcase;
     45   if (mode == "nacl")
     46     src += "&mode=nacl";
     47   if (websocket_host != "")
     48     src += "&websocket_host=" + websocket_host;
     49   if (websocket_port != "")
     50     src += "&websocket_port=" + websocket_port;
     51   if (ssl_server_port != "")
     52     src += "&ssl_server_port=" + ssl_server_port;
     53   frame.setAttribute("src", src);
     54 
     55   frame.setAttribute("onload", "LoadNext(" + (i + 1) + ")");
     56   p.appendChild(frame);
     57 
     58   document.body.appendChild(p);
     59 }
     60 
     61 function LoadNext(i) {
     62   var links = document.links;
     63   if (links.length > i)
     64     AppendFrame(links[i].firstChild.nodeValue, i);
     65 }
     66 
     67 function RunAll() {
     68   // Remove any existing frames.
     69   var existing = document.getElementsByClassName("frame-container");
     70   while (existing.length)
     71     existing[0].parentNode.removeChild(existing[0]);
     72 
     73   // Add new frames for each test, but do so one frame at a time.
     74   LoadNext(0);
     75 }
     76 
     77 function ExtractSearchParameter(name) {
     78   var nameIndex = location.search.indexOf(name + "=");
     79   if (nameIndex != -1) {
     80     var value = location.search.substring(nameIndex + name.length + 1);
     81     var endIndex = value.indexOf("&");
     82     if (endIndex != -1)
     83       value = value.substring(0, endIndex);
     84     return value;
     85   }
     86   return "";
     87 }
     88 
     89 // Parses the message, looking for strings of the form:
     90 // TESTING_MESSAGE:<message_type>:<message_contents>
     91 //
     92 // If the message_data is not a string or does not match the above format, then
     93 // undefined is returned.
     94 //
     95 // Otherwise, returns an array containing 2 items. The 0th element is the
     96 // message_type, one of:
     97 //  - AddPostCondition
     98 //  - ClearConsole
     99 //  - DidExecuteTests
    100 //  - EvalScript
    101 //  - LogHTML
    102 //  - RemovePluginWhenFinished
    103 //  - ReportProgress
    104 // The second item is the verbatim message_contents.
    105 function ParseTestingMessage(message_data) {
    106   if (typeof(message_data) != "string")
    107     return undefined;
    108   var testing_message_prefix = "TESTING_MESSAGE";
    109   var delim_str = ":";
    110   var delim1 = message_data.indexOf(delim_str);
    111   if (message_data.substring(0, delim1) !== testing_message_prefix)
    112     return undefined;
    113   var delim2 = message_data.indexOf(delim_str, delim1 + 1);
    114   if (delim2 == -1)
    115     delim2 = message_data.length;
    116   var message_type = message_data.substring(delim1 + 1, delim2);
    117   var message_contents = message_data.substring(delim2 + 1);
    118   return [message_type, message_contents];
    119 }
    120 
    121 function ClearConsole() {
    122   window.document.getElementById("console").innerHTML = "";
    123 }
    124 
    125 function LogHTML(html) {
    126   window.document.getElementById("console").innerHTML += html;
    127 }
    128 
    129 function RemovePluginWhenFinished() {
    130   window.document.getElementById("container").removePlugin = true;
    131 }
    132 
    133 function sendAutomationMessage(msg) {
    134   if (window.domAutomationController) {
    135     window.domAutomationController.setAutomationId(0);
    136     window.domAutomationController.send(msg);
    137   }
    138 }
    139 
    140 function LogTestTime(test_time) {
    141   console.log(test_time);
    142 }
    143 
    144 // If something goes really wrong, the test running inside the plugin may not
    145 // terminate.  For example, if the plugin does not load, the test will never
    146 // send "PASS" to the browser.  In this case we should explicitly use the
    147 // automation controller to terminate the test.
    148 function InternalError(msg) {
    149   LogHTML("<p>" + msg);
    150   sendAutomationMessage(msg);
    151 }
    152 
    153 function EvalScript(script) {
    154   try {
    155     eval(script);
    156   } catch(ex) {
    157   }
    158 }
    159 
    160 var conditions = [];
    161 // Add a "PostCondition". These are bits of script that are run after the plugin
    162 // is destroyed. If they evaluate to false or throw an exception, it's
    163 // considered a failure.
    164 function AddPostCondition(script) {
    165   conditions.push(script);
    166 }
    167 // Update the HTML to show the failure and update cookies so that ui_tests
    168 // doesn't count this as a pass.
    169 function ConditionFailed(error) {
    170   error_string = "Post condition check failed: " + error;
    171   InternalError(error_string);
    172 }
    173 // Iterate through the post conditions defined in |conditions| and check that
    174 // they all pass.
    175 function CheckPostConditions() {
    176   var success = true;
    177   for (var i = 0; i < conditions.length; ++i) {
    178     var script = conditions[i];
    179     try {
    180       if (!eval(script)) {
    181         ConditionFailed("\"" + script + "\"");
    182         success = false;
    183       }
    184     } catch (ex) {
    185       ConditionFailed("\"" + script + "\"" + " failed with exception: " +
    186                       "\"" + ex.toString() + "\"");
    187       success = false;
    188     }
    189   }
    190   return success;
    191 }
    192 
    193 function IsTestingMessage(message_data) {
    194   return (ParseTestingMessage(message_data) != undefined);
    195 }
    196 
    197 function handleTestingMessage(message_event) {
    198   var type_contents_tuple = ParseTestingMessage(message_event.data);
    199   if (type_contents_tuple) {
    200     var type = type_contents_tuple[0];
    201     var contents = type_contents_tuple[1];
    202     if (type === "AddPostCondition")
    203       AddPostCondition(contents);
    204     else if (type === "ClearConsole")
    205       ClearConsole();
    206     else if (type === "DidExecuteTests")
    207       DidExecuteTests(contents);
    208     else if (type === "EvalScript")
    209       EvalScript(contents);
    210     else if (type === "LogHTML")
    211       LogHTML(contents);
    212     else if (type === "RemovePluginWhenFinished")
    213       RemovePluginWhenFinished();
    214     else if (type === "ReportProgress")
    215       sendAutomationMessage(contents);
    216     else if (type === "LogTestTime")
    217       LogTestTime(contents);
    218   }
    219 }
    220 
    221 function sendProgress() {
    222   // We send "..." to signal that we're still working. See
    223   // ppapi/tests/testing_instance.h for how this works.
    224   sendAutomationMessage("...");
    225 }
    226 
    227 onload = function() {
    228   var testcase = ExtractSearchParameter("testcase");
    229   var mode = ExtractSearchParameter("mode");
    230   document.title = 'Test ' + testcase;
    231   var obj;
    232   if (mode == "nacl_newlib") {
    233     obj = document.createElement("EMBED");
    234     obj.setAttribute("src", "ppapi_nacl_tests_newlib.nmf");
    235     obj.setAttribute("type", "application/x-nacl");
    236     obj.setAttribute("mode", mode);
    237   } else if (mode == "nacl_glibc") {
    238     obj = document.createElement("EMBED");
    239     obj.setAttribute("src", "ppapi_nacl_tests_glibc.nmf");
    240     obj.setAttribute("type", "application/x-nacl");
    241     obj.setAttribute("mode", mode);
    242   } else if (mode == "nacl_pnacl") {
    243     obj = document.createElement("EMBED");
    244     obj.setAttribute("src", "ppapi_nacl_tests_pnacl.nmf");
    245     obj.setAttribute("type", "application/x-nacl");
    246     obj.setAttribute("mode", mode);
    247   } else {
    248     var mimeType = "application/x-ppapi-tests";
    249     if (mimeType in navigator.mimeTypes) {
    250       obj = document.createElement("EMBED");
    251       obj.setAttribute("src", "http://a.b.c/test");
    252       obj.setAttribute("type", mimeType);
    253     } else {
    254       document.getElementById("console").innerHTML =
    255           '<span class="fail">FAIL</span>: ' +
    256           '<span class="err_msg">Test plug-in is not registered.</span>';
    257     }
    258   }
    259   if (obj) {
    260     obj.setAttribute("width", 80);
    261     obj.setAttribute("height", 80);
    262     obj.setAttribute("style",
    263                      "background-color:#AAAAAA;border:1px solid black;");
    264     obj.setAttribute("id", "plugin");
    265     obj.setAttribute("testcase", testcase);
    266     obj.setAttribute("protocol", window.location.protocol);
    267     var websocket_host = ExtractSearchParameter("websocket_host");
    268     if (websocket_host != "")
    269       obj.setAttribute("websocket_host", websocket_host);
    270     var websocket_port = ExtractSearchParameter("websocket_port");
    271     if (websocket_port != "")
    272       obj.setAttribute("websocket_port", websocket_port);
    273     var ssl_server_port = ExtractSearchParameter("ssl_server_port");
    274     if (ssl_server_port != "")
    275       obj.setAttribute("ssl_server_port", ssl_server_port);
    276 
    277     var container = document.getElementById("container");
    278     container.addEventListener("message", handleTestingMessage, true);
    279 
    280     // "error" and "crash" events will only fire for NaCl, but adding these
    281     // listeners doesn't hurt in the non-NaCl cases.
    282     obj.addEventListener("error", function() {
    283       InternalError("Plugin did not load. '" + obj.lastError + "'");
    284     }, true);
    285     obj.addEventListener("crash", function() {
    286       InternalError("Plugin crashed. '" + obj.lastError + "'");
    287     }, true);
    288 
    289     // NaCl sends progress events while loading. When we get one, notify the
    290     // domAutomationController so that it knows we're still working.
    291     obj.addEventListener("loadstart", sendProgress, true);
    292     obj.addEventListener("progress", sendProgress, true);
    293     obj.addEventListener("load", sendProgress, true);
    294     obj.addEventListener("loadend", sendProgress, true);
    295 
    296     // Register a bad dispatchEvent to make sure it isn't used. See 'EVIL' note
    297     // below.
    298     var original = obj.dispatchEvent;
    299     obj.dispatchEvent = function() {
    300       InternalError("Bad dispatchEvent called!");
    301     }
    302     container.appendChild(obj);
    303   }
    304 }
    305 
    306 // EVIL Note:
    307 // This part of the script does some nefarious things to make sure that it
    308 // doesn't affect the behavior of PostMessage (on which all the tests rely). In
    309 // particular, we replace document.createEvent, MessageEvent.initMessageEvent,
    310 // and the MessageEvent constructor. Previously, the NaCl integration
    311 // implementation made use of these and would fail (http://crbug.com/82604
    312 // and http://crbug.com/109775).
    313 document.createEvent = function() {
    314   InternalError("Bad document.createEvent called!");
    315 }
    316 function MessageEvent() {
    317   InternalError("Bad MessageEvent constructor called!");
    318 }
    319 MessageEvent.prototype.initMessageEvent = function() {
    320   InternalError("Bad MessageEvent.initMessageEvent called!");
    321 }
    322 
    323 </script>
    324 </head><body>
    325 <div>
    326   <div id="container"></div>
    327   <div id="console"><span class="load_msg">loading...</span></div>
    328 </div>
    329 </body></html>
    330