Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,24 @@ which drives the real extension in headless Chromium.
| ![Client Wi-Fi PHY Inspector](mist-toolbox/docs/screenshots/07b-client-wifi-phy.png)<br>**Client Wi-Fi PHY Inspector** | ![BGP Sessions](mist-toolbox/docs/screenshots/09d-bgp-sessions.png)<br>**BGP Sessions** |
| ![SSR post-check, changes highlighted](mist-toolbox/docs/screenshots/11-ssr-post-highlighted.png)<br>**SSR Pre/Post**: changed fields highlighted | ![SSR pre and post side by side](mist-toolbox/docs/screenshots/12-ssr-side-by-side.png)<br>**SSR Pre/Post**: side by side |

**Switch PSU Status** dashboard filters: every switch including disconnected ones, a typed site
name, and a clicked site bar.

| | |
|---|---|
| ![PSU Status, all switches](mist-toolbox/docs/screenshots/09b2-psu-all-switches.png)<br>**All switches**, disconnected ones dashed | ![PSU Status, site search](mist-toolbox/docs/screenshots/09b3-psu-search-site.png)<br>**Search** for a site |

### Workbooks

Every report tool also saves a styled `.xlsx`: a filled header, frozen top row, filters, coloured
tabs and problem rows highlighted. These are rendered from the actual downloaded files.

| | |
|---|---|
| ![PSU workbook, Switches](mist-toolbox/docs/screenshots/30-xlsx-psu-switches.png)<br>**Switch PSU Status**: Switches | ![PSU workbook, PSUs](mist-toolbox/docs/screenshots/31-xlsx-psu-psus.png)<br>**Switch PSU Status**: PSUs |
| ![BGP workbook, Problems](mist-toolbox/docs/screenshots/32-xlsx-bgp-problems.png)<br>**BGP Sessions**: Problems | ![Alarms workbook](mist-toolbox/docs/screenshots/34-xlsx-alarms.png)<br>**Site Alarms**: Alarms |
| ![Port Inventory workbook](mist-toolbox/docs/screenshots/36-xlsx-port-inventory.png)<br>**Switch Port Inventory**: Switch Ports | ![Additional CLI workbook](mist-toolbox/docs/screenshots/38-xlsx-additional-cli.png)<br>**Switch Additional CLI**: CLI Lines |

Every screenshot with a caption: [`mist-toolbox/docs/screenshots/`](mist-toolbox/docs/screenshots/README.md).

## What's in this repository
Expand Down
Binary file modified mist-toolbox/docs/screenshots/00-chrome-extensions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/03-ssid-report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/04-switch-report-single-site.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/05-switch-config-export.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/06-site-alarms.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/07-wifi-clients.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/07b-client-wifi-phy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/08-ip-blocks.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/09-port-inventory.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/09b-switch-psu-status.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/09c-switch-additional-cli.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/09d-bgp-sessions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/10-ssr-pre-check.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/13-disconnect-console.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/14-manage-tools.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/17-manage-copy-prompt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/18-manage-check-passed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/19-manage-installed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified mist-toolbox/docs/screenshots/21-added-tool-run.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mist-toolbox/docs/screenshots/34-xlsx-alarms.png
Binary file added mist-toolbox/docs/screenshots/41-xlsx-ssid.png
68 changes: 66 additions & 2 deletions mist-toolbox/docs/screenshots/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,21 @@ Generated by `scripts/screenshots/capture.mjs` against synthetic data (`fixtures

![Switch Port Inventory](09-port-inventory.png)

### Switch PSU Status β€” a failed supply and a switch without redundancy flagged
### Switch PSU Status β€” failed supplies and switches without redundancy, by site

![Switch PSU Status β€” a failed supply and a switch without redundancy flagged](09b-switch-psu-status.png)
![Switch PSU Status β€” failed supplies and switches without redundancy, by site](09b-switch-psu-status.png)

### Switch PSU Status β€” All switches, disconnected ones dashed with their last known PSU state

![Switch PSU Status β€” All switches, disconnected ones dashed with their last known PSU state](09b2-psu-all-switches.png)

### Switch PSU Status β€” type a site name: its failed, healthy and disconnected switches

![Switch PSU Status β€” type a site name: its failed, healthy and disconnected switches](09b3-psu-search-site.png)

### Switch PSU Status β€” click a site's bar to focus it

![Switch PSU Status β€” click a site's bar to focus it](09b4-psu-focus-site.png)

### Switch Additional CLI β€” template, rule, site and device commands side by side

Expand Down Expand Up @@ -78,6 +90,58 @@ Generated by `scripts/screenshots/capture.mjs` against synthetic data (`fixtures

![Disconnect Console β€” built-in sample investigation](13-disconnect-console.png)

### Switch PSU Status workbook β€” Switches sheet

![Switch PSU Status workbook β€” Switches sheet](30-xlsx-psu-switches.png)

### Switch PSU Status workbook β€” one row per power supply

![Switch PSU Status workbook β€” one row per power supply](31-xlsx-psu-psus.png)

### BGP Sessions workbook β€” Problems sheet

![BGP Sessions workbook β€” Problems sheet](32-xlsx-bgp-problems.png)

### BGP Sessions workbook β€” Peer paths sheet

![BGP Sessions workbook β€” Peer paths sheet](33-xlsx-bgp-paths.png)

### Site Alarms workbook β€” Alarms sheet

![Site Alarms workbook β€” Alarms sheet](34-xlsx-alarms.png)

### Site Alarms workbook β€” By Type sheet

![Site Alarms workbook β€” By Type sheet](35-xlsx-alarms-by-type.png)

### Switch Port Inventory workbook β€” Switch Ports table

![Switch Port Inventory workbook β€” Switch Ports table](36-xlsx-port-inventory.png)

### IP Blocks / IRB Report workbook β€” IRB Interfaces sheet

![IP Blocks / IRB Report workbook β€” IRB Interfaces sheet](37-xlsx-ip-blocks.png)

### Switch Additional CLI workbook β€” CLI Lines sheet

![Switch Additional CLI workbook β€” CLI Lines sheet](38-xlsx-additional-cli.png)

### Client Wi-Fi PHY Inspector workbook β€” Findings sheet

![Client Wi-Fi PHY Inspector workbook β€” Findings sheet](39-xlsx-wifi-phy.png)

### Wi-Fi Clients Export workbook β€” WiFi_Clients sheet

![Wi-Fi Clients Export workbook β€” WiFi_Clients sheet](40-xlsx-wifi-clients.png)

### SSID Report workbook β€” SSIDs by Site sheet

![SSID Report workbook β€” SSIDs by Site sheet](41-xlsx-ssid.png)

### Switch Software Report workbook β€” Switches sheet

![Switch Software Report workbook β€” Switches sheet](42-xlsx-switch-report.png)

### docs/TOOL_PROMPT.md in the docs viewer β€” Copy or Download it

![docs/TOOL_PROMPT.md in the docs viewer β€” Copy or Download it](15-ai-prompt-top.png)
Expand Down
80 changes: 77 additions & 3 deletions mist-toolbox/scripts/screenshots/capture.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@

import { spawn } from "node:child_process";
import { createHash } from "node:crypto";
import { cp, mkdir, mkdtemp, readFile, rm, stat, unlink, writeFile } from "node:fs/promises";
import { cp, mkdir, mkdtemp, readFile, readdir, rm, stat, unlink, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { dirname, join, relative, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";

import { CONDUCTOR, ORG_ID, PHY_MAC, conductor, mist } from "./fixtures.mjs";
import { readXlsx, sheetPage } from "./sheetview.mjs";

const root = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
const outDir = join(root, "docs", "screenshots");
Expand Down Expand Up @@ -91,7 +92,8 @@ await cmd("Page.enable");
await cmd("Runtime.enable");
await cmd("Emulation.setDeviceMetricsOverride", { width: WIDTH, height: 900, deviceScaleFactor: 1, mobile: false });
await cmd("Emulation.setEmulatedMedia", { features: [{ name: "prefers-color-scheme", value: "light" }] });
await send("Browser.setDownloadBehavior", { behavior: "allow", downloadPath: join(work, "downloads") });
const downloads = join(work, "downloads");
await send("Browser.setDownloadBehavior", { behavior: "allow", downloadPath: downloads });

// ---- Fixture network ----------------------------------------------------------

Expand Down Expand Up @@ -204,6 +206,9 @@ async function go(url) {
const click = (sel) => evaluate(`document.querySelector(${JSON.stringify(sel)}).click()`);
const setValue = (sel, v) => evaluate(`(() => { const el = document.querySelector(${JSON.stringify(sel)});
el.value = ${JSON.stringify(v)}; el.dispatchEvent(new Event("input", {bubbles:true})); el.dispatchEvent(new Event("change", {bubbles:true})); })()`);
// For inputs without an id, such as a tool's own filter box.
const typeInto = (sel, v) => evaluate(`(() => { const el = document.querySelector(${JSON.stringify(sel)});
el.value = ${JSON.stringify(v)}; el.dispatchEvent(new Event("input", {bubbles:true})); })()`);
const setChecked = (sel, v) => evaluate(`(() => { const el = document.querySelector(${JSON.stringify(sel)});
el.checked = ${v}; el.dispatchEvent(new Event("change", {bubbles:true})); })()`);

Expand Down Expand Up @@ -253,6 +258,42 @@ async function runTool(id, { params = {}, single } = {}) {
await evaluate("window.scrollTo(0, 0)");
}

// ---- Workbooks --------------------------------------------------------------------
//
// Every tool that builds a workbook saves it straight to the downloads folder.
// grabXlsx waits for the one a run just wrote; the workbook shots at the end
// render each through sheetview.mjs.

const workbooks = {};
const seenFiles = new Set();
async function grabXlsx(id) {
const end = Date.now() + 15000;
while (Date.now() < end) {
const fresh = (await readdir(downloads).catch(() => []))
.filter((f) => f.endsWith(".xlsx") && !seenFiles.has(f));
if (fresh.length) {
await sleep(300);
fresh.forEach((f) => seenFiles.add(f));
workbooks[id] = { name: fresh[0], buf: await readFile(join(downloads, fresh[0])) };
return;
}
await sleep(200);
}
throw new Error(`No .xlsx downloaded for ${id}`);
}

async function sheetShot(name, caption, id, sheetName, opts) {
const wb = workbooks[id];
const book = readXlsx(wb.buf);
const idx = book.sheets.findIndex((sh) => sh.name === sheetName);
if (idx < 0) throw new Error(`${wb.name} has no sheet "${sheetName}" (${book.sheets.map((sh) => sh.name).join(", ")})`);
await go("about:blank");
const { frameTree } = await cmd("Page.getFrameTree");
await cmd("Page.setDocumentContent", { frameId: frameTree.frame.id, html: sheetPage(book, wb.name, idx, opts) });
await sleep(300);
await shot(name, caption);
}

// ---- The tour -----------------------------------------------------------------

await rm(outDir, { recursive: true, force: true });
Expand All @@ -279,36 +320,54 @@ try {
await shot("02-home", "Tool menu with each tool's level (Site Β· Org, Site Β· Client, SSR Conductor)");

await runTool("ssid-report");
await grabXlsx("ssid-report");
await shot("03-ssid-report", "SSID Report β€” every site in the org");

await runTool("switch-report", { single: "site-hq" });
await grabXlsx("switch-report");
await shot("04-switch-report-single-site", "Switch Software Report for one site (All sites unticked, Site picked)");

await runTool("switch-configs");
await shot("05-switch-config-export", "Switch Config Export β€” one .zip with a folder per site");

await runTool("site-alarms", { params: { duration: "7d" } });
await grabXlsx("site-alarms");
await shot("06-site-alarms", "Site Alarms β€” past 7 days, all sites");

await runTool("wifi-clients");
await grabXlsx("wifi-clients");
await shot("07-wifi-clients", "Wi-Fi Clients Export");

await runTool("client-wifi-phy", { params: { mac: PHY_MAC } });
await grabXlsx("client-wifi-phy");
await shot("07b-client-wifi-phy", "Client Wi-Fi PHY Inspector β€” one client's radio link graded, site found automatically");

await runTool("ip-blocks");
await grabXlsx("ip-blocks");
await shot("08-ip-blocks", "IP Blocks / IRB Report β€” duplicate subnet flagged across sites");

await runTool("port-inventory");
await grabXlsx("port-inventory");
await shot("09-port-inventory", "Switch Port Inventory");

await runTool("switch-psu-status");
await shot("09b-switch-psu-status", "Switch PSU Status β€” a failed supply and a switch without redundancy flagged");
await grabXlsx("switch-psu-status");
await shot("09b-switch-psu-status", "Switch PSU Status β€” failed supplies and switches without redundancy, by site");
// The dashboard's own filters: every switch, a typed site name, a clicked site bar.
await click('.psu-ctl [data-mode="all"]');
await shot("09b2-psu-all-switches", "Switch PSU Status β€” All switches, disconnected ones dashed with their last known PSU state", [".psu-v"]);
await typeInto(".psu-ctl input", "vancouver");
await shot("09b3-psu-search-site", "Switch PSU Status β€” type a site name: its failed, healthy and disconnected switches", [".psu-v"]);
await typeInto(".psu-ctl input", "");
await click('.psu-srow[data-site="Branch - Calgary"]');
await shot("09b4-psu-focus-site", "Switch PSU Status β€” click a site's bar to focus it", [".psu-v"]);

await runTool("switch-additional-cli");
await grabXlsx("switch-additional-cli");
await shot("09c-switch-additional-cli", "Switch Additional CLI β€” template, rule, site and device commands side by side");

await runTool("bgp-sessions");
await grabXlsx("bgp-sessions");
await shot("09d-bgp-sessions", "BGP Sessions β€” switch EVPN, WAN-edge BGP and SSR/SRX peer paths, problems first");

// SSR Pre/Post: connect, pre-check, change, post-check.
Expand Down Expand Up @@ -338,6 +397,21 @@ try {
await waitFor("document.body.innerText.includes('sample')", "console demo", 20000);
await shot("13-disconnect-console", "Disconnect Console β€” built-in sample investigation");

// The workbooks the runs above saved, one or two sheets each.
await sheetShot("30-xlsx-psu-switches", "Switch PSU Status workbook β€” Switches sheet", "switch-psu-status", "Switches");
await sheetShot("31-xlsx-psu-psus", "Switch PSU Status workbook β€” one row per power supply", "switch-psu-status", "PSUs");
await sheetShot("32-xlsx-bgp-problems", "BGP Sessions workbook β€” Problems sheet", "bgp-sessions", "Problems");
await sheetShot("33-xlsx-bgp-paths", "BGP Sessions workbook β€” Peer paths sheet", "bgp-sessions", "Peer paths");
await sheetShot("34-xlsx-alarms", "Site Alarms workbook β€” Alarms sheet", "site-alarms", "Alarms");
await sheetShot("35-xlsx-alarms-by-type", "Site Alarms workbook β€” By Type sheet", "site-alarms", "By Type");
await sheetShot("36-xlsx-port-inventory", "Switch Port Inventory workbook β€” Switch Ports table", "port-inventory", "Switch Ports");
await sheetShot("37-xlsx-ip-blocks", "IP Blocks / IRB Report workbook β€” IRB Interfaces sheet", "ip-blocks", "IRB Interfaces");
await sheetShot("38-xlsx-additional-cli", "Switch Additional CLI workbook β€” CLI Lines sheet", "switch-additional-cli", "CLI Lines");
await sheetShot("39-xlsx-wifi-phy", "Client Wi-Fi PHY Inspector workbook β€” Findings sheet", "client-wifi-phy", "Findings");
await sheetShot("40-xlsx-wifi-clients", "Wi-Fi Clients Export workbook β€” WiFi_Clients sheet", "wifi-clients", "WiFi_Clients");
await sheetShot("41-xlsx-ssid", "SSID Report workbook β€” SSIDs by Site sheet", "ssid-report", "SSIDs by Site");
await sheetShot("42-xlsx-switch-report", "Switch Software Report workbook β€” Switches sheet", "switch-report", "Switches");

// ---- Adding a tool with an AI assistant ----------------------------------------
await go(extUrl("docs/view.html?doc=TOOL_PROMPT.md"));
await waitFor("document.getElementById('doc').textContent.length > 1000", "prompt text");
Expand Down
Loading
Loading