ONOS-4359: continued work on theming UI
- topo view: fixed device/host badge rendering
- added "mojoColor" mock server scenario

Change-Id: I5d2da657580503abd8015875d45d2e715d44033a
(cherry picked from commit 44c440f)
diff --git a/web/gui/src/main/webapp/app/fw/svg/icon.js b/web/gui/src/main/webapp/app/fw/svg/icon.js
index 5cc4171..3a9092d 100644
--- a/web/gui/src/main/webapp/app/fw/svg/icon.js
+++ b/web/gui/src/main/webapp/app/fw/svg/icon.js
@@ -144,31 +144,7 @@
     function loadEmbeddedIcon(div, iconCls, size) {
         loadIconByClass(div, iconCls, size, true);
     }
-
-
-    // configuration for device and host icons in the topology view
-    var config = {
-        device: {
-            dim: 36
-        },
-        host: {
-            badge: {
-                dx: 14,
-                dy: -14
-            },
-            radius: {
-                noGlyph: 9,
-                withGlyph: 14
-            },
-            glyphed: {
-                endstation: 1,
-                bgpSpeaker: 1,
-                router: 1
-            }
-        }
-    };
-
-
+    
     // Adds a device glyph to the specified element.
     // Returns the D3 selection of the glyph (use) element.
     function addDeviceIcon(elem, glyphId, iconDim) {
@@ -254,7 +230,6 @@
                 loadEmbeddedIcon: loadEmbeddedIcon,
                 addDeviceIcon: addDeviceIcon,
                 addHostIcon: addHostIcon,
-                iconConfig: function () { return config; },
                 sortIcons: sortIcons,
                 registerIconMapping: registerIconMapping
             };
diff --git a/web/gui/src/main/webapp/app/view/topo/topo-theme.css b/web/gui/src/main/webapp/app/view/topo/topo-theme.css
index a7bc4b0..e0b88e3 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo-theme.css
+++ b/web/gui/src/main/webapp/app/view/topo/topo-theme.css
@@ -226,7 +226,7 @@
     stroke: #a3a596;
     fill: #e0dfd6;
 }
-#ov-topo svg .node.host.selected circle {
+#ov-topo svg .node.host.selected .hostIcon > circle {
     stroke-width: 2.0;
     stroke: #009fdb;
 }
diff --git a/web/gui/src/main/webapp/app/view/topo/topoD3.js b/web/gui/src/main/webapp/app/view/topo/topoD3.js
index 278fc25..5e2c7c5 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoD3.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoD3.js
@@ -39,24 +39,23 @@
      */
 
     // configuration
-    var devIconDim = 36;
-    var labelPad = 4;
-
-    var badgeConfig = {
+    var devIconDim = 36,
+        labelPad = 4,
+        hostRadius = 14,
+        badgeConfig = {
             radius: 12,
             yoff: 5,
             gdelta: 10
+        },
+        halfDevIcon = devIconDim / 2,
+        devBadgeOff = { dx: -halfDevIcon, dy: -halfDevIcon },
+        hostBadgeOff = { dx: -hostRadius, dy: -hostRadius },
+        status = {
+            i: 'badgeInfo',
+            w: 'badgeWarn',
+            e: 'badgeError'
         };
 
-    // TODO: remove dependence on this
-    var icfg;
-
-    var status = {
-        i: 'badgeInfo',
-        w: 'badgeWarn',
-        e: 'badgeError'
-    };
-
     // NOTE: this type of hack should go away once we have implemented
     //       the server-side UiModel code.
     // {virtual -> cord} is for the E-CORD demo at ONS 2016
@@ -76,7 +75,7 @@
     var deviceLabelIndex = 0,
         hostLabelIndex = 0;
 
-    // note: these are the device icon colors without affinity
+    // note: these are the device icon colors without affinity (no master)
     var dColTheme = {
         light: {
             online: '#444444',
@@ -160,9 +159,8 @@
             .transition()
             .attr(iconBox(devIconDim, labelWidth));
 
-        // TODO: verify badge placement
         if (bdg) {
-            renderBadge(node, bdg, { dx: devIconDim, dy: 0 });
+            renderBadge(node, bdg, devBadgeOff);
         }
     }
 
@@ -173,7 +171,7 @@
         updateHostLabel(d);
 
         if (bdg) {
-            renderBadge(node, bdg, icfg.host.badge);
+            renderBadge(node, bdg, hostBadgeOff);
         }
     }
 
@@ -243,7 +241,6 @@
         var node = d3.select(this),
             glyphId = mapDeviceTypeToGlyph(d.type),
             label = trimLabel(deviceLabel(d)),
-            xlate = -devIconDim/2,
             rect, text, glyph, labelWidth;
 
         d.el = node;
@@ -253,7 +250,7 @@
         text = node.append('text').text(label)
             .attr('text-anchor', 'left')
             .attr('y', '0.3em')
-            .attr('x', devIconDim / 2 + labelPad);
+            .attr('x', halfDevIcon + labelPad);
 
         glyph = is.addDeviceIcon(node, glyphId, devIconDim);
 
@@ -262,20 +259,18 @@
         rect.attr(iconBox(devIconDim, labelWidth));
         glyph.attr(iconBox(devIconDim, 0));
 
-        node.attr('transform', sus.translate(xlate, xlate));
+        node.attr('transform', sus.translate(-halfDevIcon, -halfDevIcon));
     }
 
     function hostEnter(d) {
         var node = d3.select(this),
             gid = d.type || 'unknown',
-            rad = icfg.host.radius,
-            r = d.type ? rad.withGlyph : rad.noGlyph,
-            textDy = r + 10;
+            textDy = hostRadius + 10;
 
         d.el = node;
         sus.visible(node, api.showHosts());
 
-        is.addHostIcon(node, r, gid);
+        is.addHostIcon(node, hostRadius, gid);
 
         node.append('text')
             .text(hostLabel)
@@ -527,8 +522,6 @@
             ps = _ps_;
             ttbs = _ttbs_;
 
-            icfg = is.iconConfig();
-
             function initD3(_api_) {
                 api = _api_;
             }
diff --git a/web/gui/src/main/webapp/app/view/topo/topoModel.js b/web/gui/src/main/webapp/app/view/topo/topoModel.js
index d104449..7679fe1 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoModel.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoModel.js
@@ -69,7 +69,7 @@
         }
 
         // else if we have [x,y] cached in meta data, use that...
-        if (x && y) {
+        if (x !== undefined && y !== undefined) {
             node.fixed = true;
             node.px = node.x = x;
             node.py = node.y = y;
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_10_addDevice_B.json b/web/gui/src/test/_karma/ev/mojoColors/ev_10_addDevice_B.json
new file mode 100644
index 0000000..3148637
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_10_addDevice_B.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000002",
+    "type": "switch",
+    "online": true,
+    "master": "onos-2",
+    "labels": [
+      "",
+      "sw-B",
+      "of:0000000000000002"
+    ],
+    "metaUi": {
+      "x": 120,
+      "y": 350
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_11_addDevice_B_off.json b/web/gui/src/test/_karma/ev/mojoColors/ev_11_addDevice_B_off.json
new file mode 100644
index 0000000..1f38bc5
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_11_addDevice_B_off.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000102",
+    "type": "switch",
+    "online": false,
+    "master": "",
+    "labels": [
+      "",
+      "sw-B-0",
+      "of:0000000000000102"
+    ],
+    "metaUi": {
+      "x": 120,
+      "y": 450
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_12_addDevice_C.json b/web/gui/src/test/_karma/ev/mojoColors/ev_12_addDevice_C.json
new file mode 100644
index 0000000..411650e
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_12_addDevice_C.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000003",
+    "type": "switch",
+    "online": true,
+    "master": "onos-3",
+    "labels": [
+      "",
+      "sw-C",
+      "of:0000000000000003"
+    ],
+    "metaUi": {
+      "x": 240,
+      "y": 300
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_13_addDevice_C_off.json b/web/gui/src/test/_karma/ev/mojoColors/ev_13_addDevice_C_off.json
new file mode 100644
index 0000000..91f6932
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_13_addDevice_C_off.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000103",
+    "type": "switch",
+    "online": false,
+    "master": "",
+    "labels": [
+      "",
+      "sw-C-0",
+      "of:0000000000000103"
+    ],
+    "metaUi": {
+      "x": 240,
+      "y": 400
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_14_addDevice_D.json b/web/gui/src/test/_karma/ev/mojoColors/ev_14_addDevice_D.json
new file mode 100644
index 0000000..46522bc
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_14_addDevice_D.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000004",
+    "type": "switch",
+    "online": true,
+    "master": "onos-4",
+    "labels": [
+      "",
+      "sw-D",
+      "of:0000000000000004"
+    ],
+    "metaUi": {
+      "x": 360,
+      "y": 350
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_15_addDevice_D_off.json b/web/gui/src/test/_karma/ev/mojoColors/ev_15_addDevice_D_off.json
new file mode 100644
index 0000000..0079bac
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_15_addDevice_D_off.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000104",
+    "type": "switch",
+    "online": false,
+    "master": "",
+    "labels": [
+      "",
+      "sw-D-0",
+      "of:0000000000000104"
+    ],
+    "metaUi": {
+      "x": 360,
+      "y": 450
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_16_addDevice_E.json b/web/gui/src/test/_karma/ev/mojoColors/ev_16_addDevice_E.json
new file mode 100644
index 0000000..95d1449
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_16_addDevice_E.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000005",
+    "type": "switch",
+    "online": true,
+    "master": "onos-5",
+    "labels": [
+      "",
+      "sw-E",
+      "of:0000000000000005"
+    ],
+    "metaUi": {
+      "x": 480,
+      "y": 300
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_17_addDevice_E_off.json b/web/gui/src/test/_karma/ev/mojoColors/ev_17_addDevice_E_off.json
new file mode 100644
index 0000000..16b1588
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_17_addDevice_E_off.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000105",
+    "type": "switch",
+    "online": false,
+    "master": "",
+    "labels": [
+      "",
+      "sw-E-0",
+      "of:0000000000000105"
+    ],
+    "metaUi": {
+      "x": 480,
+      "y": 400
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_18_addDevice_F.json b/web/gui/src/test/_karma/ev/mojoColors/ev_18_addDevice_F.json
new file mode 100644
index 0000000..7482ad7
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_18_addDevice_F.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000006",
+    "type": "switch",
+    "online": true,
+    "master": "onos-6",
+    "labels": [
+      "",
+      "sw-F",
+      "of:0000000000000006"
+    ],
+    "metaUi": {
+      "x": 600,
+      "y": 350
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_19_addDevice_F_off.json b/web/gui/src/test/_karma/ev/mojoColors/ev_19_addDevice_F_off.json
new file mode 100644
index 0000000..1b3894c
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_19_addDevice_F_off.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000106",
+    "type": "switch",
+    "online": false,
+    "master": "",
+    "labels": [
+      "",
+      "sw-F-0",
+      "of:0000000000000106"
+    ],
+    "metaUi": {
+      "x": 600,
+      "y": 450
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_1_addInst_1.json b/web/gui/src/test/_karma/ev/mojoColors/ev_1_addInst_1.json
new file mode 100644
index 0000000..740595d
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_1_addInst_1.json
@@ -0,0 +1,11 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "192.168.56.101",
+    "ip": "192.168.56.101",
+    "online": true,
+    "ready": true,
+    "uiAttached": true,
+    "switches": 4
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_20_addDevice_G.json b/web/gui/src/test/_karma/ev/mojoColors/ev_20_addDevice_G.json
new file mode 100644
index 0000000..4c352c7
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_20_addDevice_G.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000007",
+    "type": "switch",
+    "online": true,
+    "master": "222.222.222.222",
+    "labels": [
+      "",
+      "sw-G",
+      "of:0000000000000007"
+    ],
+    "metaUi": {
+      "x": 720,
+      "y": 300
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_21_addDevice_G_off.json b/web/gui/src/test/_karma/ev/mojoColors/ev_21_addDevice_G_off.json
new file mode 100644
index 0000000..c8363b3
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_21_addDevice_G_off.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000107",
+    "type": "switch",
+    "online": false,
+    "master": "",
+    "labels": [
+      "",
+      "sw-G-0",
+      "of:0000000000000107"
+    ],
+    "metaUi": {
+      "x": 720,
+      "y": 400
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_22_addLink_A_B.json b/web/gui/src/test/_karma/ev/mojoColors/ev_22_addLink_A_B.json
new file mode 100644
index 0000000..e9a7381
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_22_addLink_A_B.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000001/2-of:0000000000000002/1",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000001",
+    "srcPort": "2",
+    "dst": "of:0000000000000002",
+    "dstPort": "1"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_23_addLink_B_A.json b/web/gui/src/test/_karma/ev/mojoColors/ev_23_addLink_B_A.json
new file mode 100644
index 0000000..b0dc531
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_23_addLink_B_A.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000002/1-of:0000000000000001/2",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000002",
+    "srcPort": "1",
+    "dst": "of:0000000000000001",
+    "dstPort": "2"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_24_addLink_B_C.json b/web/gui/src/test/_karma/ev/mojoColors/ev_24_addLink_B_C.json
new file mode 100644
index 0000000..63c743e
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_24_addLink_B_C.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000002/3-of:0000000000000003/2",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000002",
+    "srcPort": "3",
+    "dst": "of:0000000000000003",
+    "dstPort": "2"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_25_addLink_C_B.json b/web/gui/src/test/_karma/ev/mojoColors/ev_25_addLink_C_B.json
new file mode 100644
index 0000000..5740536
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_25_addLink_C_B.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000003/2-of:0000000000000002/3",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000003",
+    "srcPort": "2",
+    "dst": "of:0000000000000002",
+    "dstPort": "3"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_26_addLink_C_D.json b/web/gui/src/test/_karma/ev/mojoColors/ev_26_addLink_C_D.json
new file mode 100644
index 0000000..e24393d
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_26_addLink_C_D.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000003/4-of:0000000000000004/3",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000003",
+    "srcPort": "4",
+    "dst": "of:0000000000000004",
+    "dstPort": "3"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_27_addLink_D_C.json b/web/gui/src/test/_karma/ev/mojoColors/ev_27_addLink_D_C.json
new file mode 100644
index 0000000..9126472
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_27_addLink_D_C.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000004/3-of:0000000000000003/4",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000004",
+    "srcPort": "3",
+    "dst": "of:0000000000000003",
+    "dstPort": "4"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_28_addLink_D_E.json b/web/gui/src/test/_karma/ev/mojoColors/ev_28_addLink_D_E.json
new file mode 100644
index 0000000..ee0f820
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_28_addLink_D_E.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000004/5-of:0000000000000005/4",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000004",
+    "srcPort": "5",
+    "dst": "of:0000000000000005",
+    "dstPort": "4"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_29_addLink_E_D.json b/web/gui/src/test/_karma/ev/mojoColors/ev_29_addLink_E_D.json
new file mode 100644
index 0000000..eac49f4
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_29_addLink_E_D.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000005/4-of:0000000000000004/5",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000005",
+    "srcPort": "4",
+    "dst": "of:0000000000000004",
+    "dstPort": "5"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_2_addInst_2.json b/web/gui/src/test/_karma/ev/mojoColors/ev_2_addInst_2.json
new file mode 100644
index 0000000..2e5a0d6
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_2_addInst_2.json
@@ -0,0 +1,11 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "onos-2",
+    "ip": "192.168.56.102",
+    "online": true,
+    "ready": true,
+    "uiAttached": false,
+    "switches": 3
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_30_addLink_E_F.json b/web/gui/src/test/_karma/ev/mojoColors/ev_30_addLink_E_F.json
new file mode 100644
index 0000000..72d21cb
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_30_addLink_E_F.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000005/6-of:0000000000000006/5",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000005",
+    "srcPort": "6",
+    "dst": "of:0000000000000006",
+    "dstPort": "5"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_31_addLink_F_E.json b/web/gui/src/test/_karma/ev/mojoColors/ev_31_addLink_F_E.json
new file mode 100644
index 0000000..a863bc3
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_31_addLink_F_E.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000006/5-of:0000000000000005/6",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000006",
+    "srcPort": "5",
+    "dst": "of:0000000000000005",
+    "dstPort": "6"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_32_addLink_F_G.json b/web/gui/src/test/_karma/ev/mojoColors/ev_32_addLink_F_G.json
new file mode 100644
index 0000000..5aaef28
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_32_addLink_F_G.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000006/7-of:0000000000000007/6",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000006",
+    "srcPort": "7",
+    "dst": "of:0000000000000007",
+    "dstPort": "6"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_33_addLink_G_F.json b/web/gui/src/test/_karma/ev/mojoColors/ev_33_addLink_G_F.json
new file mode 100644
index 0000000..59bd822
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_33_addLink_G_F.json
@@ -0,0 +1,12 @@
+{
+  "event": "addLink",
+  "payload": {
+    "id": "of:0000000000000007/6-of:0000000000000006/7",
+    "type": "direct",
+    "online": true,
+    "src": "of:0000000000000007",
+    "srcPort": "6",
+    "dst": "of:0000000000000006",
+    "dstPort": "7"
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_34_addHost_01.json b/web/gui/src/test/_karma/ev/mojoColors/ev_34_addHost_01.json
new file mode 100644
index 0000000..e9a19bf
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_34_addHost_01.json
@@ -0,0 +1,21 @@
+{
+  "event": "addHost",
+  "payload": {
+    "id": "0E:2A:69:30:13:01/-1",
+    "ingress": "0E:2A:69:30:13:01/-1/0-of:0000000000000001/95",
+    "egress": "of:0000000000000001/95-0E:2A:69:30:13:01/-1/0",
+    "cp": {
+      "device": "of:0000000000000001",
+      "port": 95
+    },
+    "labels": [
+      "192.168.0.1",
+      "0E:2A:69:30:13:01"
+    ],
+    "metaUi": {
+      "x": -20,
+      "y": 230
+    },
+    "props": {}
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_35_addHost_07.json b/web/gui/src/test/_karma/ev/mojoColors/ev_35_addHost_07.json
new file mode 100644
index 0000000..9b9e0ec
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_35_addHost_07.json
@@ -0,0 +1,21 @@
+{
+  "event": "addHost",
+  "payload": {
+    "id": "0E:2A:69:30:13:07/-1",
+    "ingress": "0E:2A:69:30:13:07/-1/0-of:0000000000000007/95",
+    "egress": "of:0000000000000001/95-0E:2A:69:30:13:07/-1/0",
+    "cp": {
+      "device": "of:0000000000000007",
+      "port": 95
+    },
+    "labels": [
+      "192.168.0.7",
+      "0E:2A:69:30:13:07"
+    ],
+    "metaUi": {
+      "x": 740,
+      "y": 230
+    },
+    "props": {}
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_36_showHighlights_devices.json b/web/gui/src/test/_karma/ev/mojoColors/ev_36_showHighlights_devices.json
new file mode 100644
index 0000000..6fb6741
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_36_showHighlights_devices.json
@@ -0,0 +1,81 @@
+{
+  "event": "showHighlights",
+  "payload": {
+    "devices": [
+      {
+        "id": "of:0000000000000001",
+        "badge": {
+          "status": "i",
+          "gid": "xMark",
+          "msg": "x marks the spot"
+        }
+      },
+      {
+        "id": "of:0000000000000101",
+        "badge": {
+          "status": "w",
+          "gid": "crown",
+          "msg": "it's good to be the King"
+        }
+      },
+      {
+        "id": "of:0000000000000002",
+        "badge": {
+          "status": "e",
+          "gid": "chain",
+          "msg": "the weakest link"
+        }
+      },
+      {
+        "id": "of:0000000000000102",
+        "badge": {
+          "status": "i",
+          "txt": "1",
+          "msg": "singular sensation"
+        }
+      },
+      {
+        "id": "of:0000000000000003",
+        "badge": {
+          "status": "w",
+          "txt": "42",
+          "msg": "life, the universe, and everything!"
+        }
+      },
+      {
+        "id": "of:0000000000000103",
+        "badge": {
+          "status": "e",
+          "txt": "99",
+          "msg": "cadbury's flake"
+        }
+      }
+    ],
+    "hosts": [
+      {
+        "id": "0E:2A:69:30:13:01/-1",
+        "badge": {
+          "status": "w",
+          "gid": "crown"
+        }
+      }
+    ],
+    "links": [
+      {
+        "css": "primary",
+        "id": "of:0000000000000001/2-of:0000000000000002/1",
+        "label": "Foo!"
+      },
+      {
+        "css": "secondary",
+        "id": "of:0000000000000002/3-of:0000000000000003/2",
+        "label": "Bar!"
+      },
+      {
+        "css": "",
+        "id": "of:0000000000000003/4-of:0000000000000004/3",
+        "label": "Baz-a-ma-taz!!"
+      }
+    ]
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_3_addInst_3.json b/web/gui/src/test/_karma/ev/mojoColors/ev_3_addInst_3.json
new file mode 100644
index 0000000..9ef32be
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_3_addInst_3.json
@@ -0,0 +1,11 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "onos-3",
+    "ip": "192.168.56.103",
+    "online": true,
+    "ready": true,
+    "uiAttached": false,
+    "switches": 3
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_4_addInst_4.json b/web/gui/src/test/_karma/ev/mojoColors/ev_4_addInst_4.json
new file mode 100644
index 0000000..03674dc
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_4_addInst_4.json
@@ -0,0 +1,11 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "onos-4",
+    "ip": "192.168.56.104",
+    "online": true,
+    "ready": true,
+    "uiAttached": false,
+    "switches": 0
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_5_addInst_5.json b/web/gui/src/test/_karma/ev/mojoColors/ev_5_addInst_5.json
new file mode 100644
index 0000000..8fcbf56
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_5_addInst_5.json
@@ -0,0 +1,11 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "onos-5",
+    "ip": "192.168.56.105",
+    "online": true,
+    "ready": true,
+    "uiAttached": false,
+    "switches": 17
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_6_addInst_6.json b/web/gui/src/test/_karma/ev/mojoColors/ev_6_addInst_6.json
new file mode 100644
index 0000000..170bf80
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_6_addInst_6.json
@@ -0,0 +1,11 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "onos-6",
+    "ip": "192.168.224.126",
+    "online": true,
+    "ready": true,
+    "uiAttached": false,
+    "switches": 0
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_7_addInst_7.json b/web/gui/src/test/_karma/ev/mojoColors/ev_7_addInst_7.json
new file mode 100644
index 0000000..53a9e8e
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_7_addInst_7.json
@@ -0,0 +1,11 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "222.222.222.222",
+    "ip": "222.222.222.222",
+    "online": true,
+    "ready": true,
+    "uiAttached": false,
+    "switches": 6
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_8_addDevice_A.json b/web/gui/src/test/_karma/ev/mojoColors/ev_8_addDevice_A.json
new file mode 100644
index 0000000..7776218
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_8_addDevice_A.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000001",
+    "type": "switch",
+    "online": true,
+    "master": "192.168.56.101",
+    "labels": [
+      "",
+      "sw-A",
+      "of:0000000000000001"
+    ],
+    "metaUi": {
+      "x": 0,
+      "y": 300
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/ev_9_addDevice_A_off.json b/web/gui/src/test/_karma/ev/mojoColors/ev_9_addDevice_A_off.json
new file mode 100644
index 0000000..d1113f8
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/ev_9_addDevice_A_off.json
@@ -0,0 +1,18 @@
+{
+  "event": "addDevice",
+  "payload": {
+    "id": "of:0000000000000101",
+    "type": "switch",
+    "online": false,
+    "master": "",
+    "labels": [
+      "",
+      "sw-A-0",
+      "of:0000000000000101"
+    ],
+    "metaUi": {
+      "x": 0,
+      "y": 400
+    }
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/mojoColors/scenario.json b/web/gui/src/test/_karma/ev/mojoColors/scenario.json
new file mode 100644
index 0000000..dd6a63e
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/mojoColors/scenario.json
@@ -0,0 +1,12 @@
+{
+  "comments": [
+    "Show all possible Mojo Colors"
+  ],
+  "title": "Color-Tweaking Scenario for Mojo Palette",
+  "params": {
+    "lastAuto": 35
+  },
+  "description": [
+    "Yee-haw! Colors galore!"
+  ]
+}