', trOpen);
+ const row = after.slice(trOpen, rowEnd);
+ assert.ok(
+ /| ]*class="mono"[^>]*data-value="\$\{[^}]*o\.client_version[^}]*\}"| | ]*data-value="\$\{[^}]*o\.client_version[^}]*\}"[^>]*class="mono"/.test(row),
+ 'client_version | with data-value reading o.client_version and class="mono" not found in row template'
+ );
+});
+
+test('firmware display truncates "Build:" suffix and preserves full string in title=', () => {
+ // Look for any helper or inline expression that strips Build:... when
+ // rendering, AND a title= attribute carrying the unmodified firmware string.
+ assert.ok(
+ /Build:/.test(src),
+ 'firmware truncation marker "Build:" not referenced anywhere in observers.js'
+ );
+ assert.ok(
+ /title="\$\{[^}]*escapeHtml\([^)]*o\.firmware[^)]*\)[^}]*\}"/.test(src) ||
+ /title="\$\{[^}]*o\.firmware[^}]*\}"/.test(src),
+ 'firmware cell does not carry a title= with full o.firmware string'
+ );
+});
+
+test('thead+tbody column counts stay balanced after adding new columns', () => {
+ const thead = extractBlock(src, //, /<\/tr><\/thead>/);
+ const thCount = (thead.match(/| ');
+ const after = src.slice(tbodyStart);
+ const trOpen = after.search(/` | ', trOpen);
+ const row = after.slice(trOpen, rowEnd);
+ const tdCount = (row.match(/| vs ${tdCount} | `);
+});
+
+console.log(`\n${passed} passed, ${failed} failed`);
+process.exit(failed === 0 ? 0 : 1);
diff --git a/test-observers-headings.js b/test-observers-headings.js
index 305b6af7..f980c002 100644
--- a/test-observers-headings.js
+++ b/test-observers-headings.js
@@ -58,7 +58,8 @@ test('expected headings present and ordered', () => {
let m;
while ((m = re.exec(thead)) !== null) labels.push(m[1].trim());
const expected = ['Status', 'Name', 'Region', 'Last Status', 'Last Packet',
- 'Packet Health', 'Total Packets', 'Packets/Hour', 'Clock Offset', 'Uptime'];
+ 'Packet Health', 'Total Packets', 'Packets/Hour', 'Clock Offset', 'Uptime',
+ 'Firmware', 'Client'];
assert.deepStrictEqual(labels, expected,
`Headings out of sync.\nGot: ${JSON.stringify(labels)}\nExpected: ${JSON.stringify(expected)}`);
});
| |