Refine web test runner style (text wrapping, console colors, etc.). (#10273)

Still more to do around running batches of tests, but this makes the test runner a bit nicer to work with.

Before (wide, note the overflow and whitespace on the sides):
![image](https://user-images.githubusercontent.com/4010439/188008046-a03040b3-eb68-489a-97a2-c2d3aec64821.png)

After (wide):
![image](https://user-images.githubusercontent.com/4010439/188008005-77852054-ceb1-4258-94cc-86822c755754.png)

After (narrow, note the wrapping):
![image](https://user-images.githubusercontent.com/4010439/188008418-9db44e04-c01e-4be2-8f14-e439c26430c9.png)
diff --git a/experimental/web/testing/index_template.html b/experimental/web/testing/index_template.html
index adcc0e5..c03ec4e 100644
--- a/experimental/web/testing/index_template.html
+++ b/experimental/web/testing/index_template.html
@@ -31,6 +31,12 @@
     .monospace {
       font-family: monospace;
     }
+
+    .tests-list {
+      max-height: 100%;
+      overflow-y: scroll;
+      overflow-wrap: anywhere;
+    }
   </style>
 
   <!-- https://getbootstrap.com/ for some webpage styling-->
@@ -39,14 +45,15 @@
 </head>
 
 <body class="d-flex">
-  <div class="container full-height d-flex flex-column">
+  <div class="container-fluid full-height d-flex flex-column">
     <h1>IREE Web Test Runner</h1>
 
-    <!-- TODO(scotttodd): adjust CSS overflow/wrapping for these columns -->
-    <div class="row flex-1">
+    <div class="row flex-1" style="overflow: hidden">
       <!-- Left column: list of tests -->
-      <div class="col-4 bg-dark bg-opacity-10">
-        <ul class="monospace">
+      <!-- TODO(scotttodd): search/filtering -->
+      <!-- TODO(scotttodd): tree view with "run tests in subtree" -->
+      <div class="col-4 bg-dark bg-opacity-10 tests-list pt-2">
+        <ul class="monospace" style="font-size: small;">
           {{TEST_LIST}}
         </ul>
       </div>
diff --git a/experimental/web/testing/test-runner.html b/experimental/web/testing/test-runner.html
index e2ad2cf..1640d09 100644
--- a/experimental/web/testing/test-runner.html
+++ b/experimental/web/testing/test-runner.html
@@ -16,15 +16,26 @@
   <link rel="icon" href="./ghost.svg" type="image/svg+xml">
 
   <style>
-    .test-output {
+    .test-output-container {
       font-family: monospace;
-      white-space: pre;
-      overflow-x: scroll;
+      background-color: #111122;
+      color: #88EE33;
+      overflow-wrap: anywhere;
+    }
+
+    .test-output {
+      white-space: pre-wrap;
+      display: inline;
     }
 
     .stderr {
       color: red;
     }
+
+    .start-of-line {
+      user-select: none;
+      color: #eeeeff;
+    }
   </style>
 
   <!-- https://getbootstrap.com/ for some webpage styling-->
@@ -33,18 +44,22 @@
 </head>
 
 <body class="bg-dark bg-opacity-10">
-  <div class="container p-2 mx-2">
-    <div style="font-family: monospace;">
+  <div class="container-fluid p-2" style="font-family: monospace;">
+    <div>
       Test name: <span id="test-name"></span>
       <br>
       Test output:
     </div>
-    <div id="test-output" class="test-output border border-dark shadow-sm p-3 mb-3 bg-body rounded"></div>
+    <div id="test-output" class="test-output-container border border-dark shadow-sm p-3 mb-2 rounded"></div>
+    <div>
+      Test result: <span id="test-result"></span>
+    </div>
   </div>
 
   <script>
     const testNameElement = document.getElementById("test-name");
     const testOutputElement = document.getElementById("test-output");
+    const testResultElement = document.getElementById("test-result")
 
     const searchParams = new URLSearchParams(window.location.search);
     const testName = searchParams.get("testName");
@@ -73,18 +88,40 @@
     function handleMessageFromWorker(messageEvent) {
       const {messageType, payload} = messageEvent.data;
 
+      function addStartOfLine() {
+        const startOfLine = document.createElement("span");
+        startOfLine.textContent = "> ";
+        startOfLine.classList.add("start-of-line");
+        testOutputElement.appendChild(startOfLine);
+      }
+
+      function addEndOfLine() {
+        const endOfLine = document.createElement("br");
+        testOutputElement.appendChild(endOfLine);
+      }
+
       if (messageType == "testResult") {
-        // TODO(scotttodd): handle result (check in UI, pass/fail #s for suites)
-        console.log("test result:", payload);
+        // TODO(scotttodd): do more with result (pass/fail #s for suites)
+        if (payload == 0) {
+          testResultElement.innerText = "PASS";
+        } else {
+          testResultElement.innerText = "FAIL";
+        }
       } else if (messageType == "print") {
+        addStartOfLine();
         const div = document.createElement("div");
         div.textContent = payload;
+        div.classList.add("test-output");
         testOutputElement.appendChild(div);
+        addEndOfLine();
       } else if (messageType == "printErr") {
+        addStartOfLine();
         const div = document.createElement("div");
         div.textContent = payload;
+        div.classList.add("test-output");
         div.classList.add("stderr");
         testOutputElement.appendChild(div);
+        addEndOfLine();
       }
     }