mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-10-09 15:58:35 +00:00
Moves 290 root test-*.js into tests/unit (177, listed in test-all.sh) and tests/e2e (113, classified in scripts/non-unit-tests.json), per #1981 and PR-D of #1385. Root goes from 348 entries to 48. test-all.sh and test-fixtures/ stay put. The inventory guard now fails if a test reappears in the root or sits in the wrong folder.
Verified independently of the diff: the invoked sets are unchanged (test-all.sh 177 before and after, deploy.yml 96 before and after, both identical as sets), and a full local run of test-all.sh on master and on the branch produced 4702 output lines each whose only differences are absolute paths, stack-trace line numbers shifted by the REPO_ROOT line, the inventory wording and two perf ratios. The guard was mutation-checked: a test back in the root, a unit suite in tests/e2e, and a suite dropped from test-all.sh each make it exit 1. CI run 35246304316 ran 97 suites from tests/e2e and is green.
Follow-up 9335c51d finished the instruction files: no bare root test command is left in AGENTS.md, the squad charters, .github or docs, and every tests/ path they name resolves.
Merged by the interim maintainer without a second human reviewer: CI and the local runs above are the independent checks.
Known and deliberately out of scope: 18 of the 113 files in tests/e2e are invoked by no runner at all, and one of them cannot run anywhere because it requires jsdom, which is not a declared dependency. Tracked separately.
141 lines
5.2 KiB
JavaScript
141 lines
5.2 KiB
JavaScript
/**
|
|
* #1380 — Colorblind a11y stretch goal: "Reset to default Wong" button.
|
|
*
|
|
* Deferred from #1361 / PR #1378. This test enforces that the customizer
|
|
* exposes a Reset button which:
|
|
* - Calls MeshCorePresets.applyPreset('default'), AND
|
|
* - Removes localStorage["meshcore-cb-preset"] afterwards.
|
|
*
|
|
* Pure-string + vm.createContext assertions, mirrors test-issue-1361.
|
|
*/
|
|
'use strict';
|
|
const REPO_ROOT = require('path').resolve(__dirname, '..', '..');
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const vm = require('vm');
|
|
|
|
let passed = 0, failed = 0;
|
|
function assert(cond, msg) {
|
|
if (cond) { passed++; console.log(' \u2713 ' + msg); }
|
|
else { failed++; console.error(' \u2717 ' + msg); }
|
|
}
|
|
|
|
const customSrc = fs.readFileSync(path.join(REPO_ROOT, 'public', 'customize-v2.js'), 'utf8');
|
|
const presetsSrc = fs.readFileSync(path.join(REPO_ROOT, 'public', 'cb-presets.js'), 'utf8');
|
|
|
|
console.log('\n=== #1380 Reset A: customize-v2.js renders a Reset-to-Wong button ===');
|
|
assert(/data-cv2-cb-reset/.test(customSrc),
|
|
'customize-v2.js exposes a data-cv2-cb-reset hook on the reset button');
|
|
assert(/Reset[^<]*Wong/i.test(customSrc),
|
|
'customize-v2.js button copy mentions "Reset" and "Wong"');
|
|
|
|
console.log('\n=== #1380 Reset B: handler exposed for tests + behavior ===');
|
|
|
|
function makeSandbox() {
|
|
const stored = {};
|
|
const ls = {
|
|
getItem(k) { return Object.prototype.hasOwnProperty.call(stored, k) ? stored[k] : null; },
|
|
setItem(k, v) { stored[k] = String(v); },
|
|
removeItem(k) { delete stored[k]; },
|
|
};
|
|
const body = {
|
|
_attrs: {},
|
|
setAttribute(k, v) { this._attrs[k] = v; },
|
|
getAttribute(k) { return Object.prototype.hasOwnProperty.call(this._attrs, k) ? this._attrs[k] : null; },
|
|
removeAttribute(k) { delete this._attrs[k]; },
|
|
dataset: {},
|
|
};
|
|
const root = {
|
|
style: {
|
|
_v: {},
|
|
setProperty(k, v) { this._v[k] = v; },
|
|
removeProperty(k) { delete this._v[k]; },
|
|
getPropertyValue(k) { return this._v[k] || ''; },
|
|
},
|
|
dataset: { theme: 'light' },
|
|
getAttribute() { return 'light'; },
|
|
setAttribute() {},
|
|
};
|
|
const handlers = {};
|
|
const sandbox = {
|
|
window: null,
|
|
document: {
|
|
readyState: 'complete',
|
|
body: body,
|
|
documentElement: root,
|
|
head: { appendChild() {} },
|
|
getElementById() { return null; },
|
|
createElement() {
|
|
return {
|
|
id: '', textContent: '', innerHTML: '', className: '',
|
|
setAttribute() {}, appendChild() {}, style: {},
|
|
addEventListener() {}, querySelectorAll() { return []; }, querySelector() { return null; },
|
|
};
|
|
},
|
|
addEventListener(ev, cb) { (handlers[ev] = handlers[ev] || []).push(cb); },
|
|
querySelectorAll() { return []; },
|
|
querySelector() { return null; },
|
|
},
|
|
localStorage: ls,
|
|
console: console,
|
|
setTimeout(fn) { try { fn(); } catch (e) {} },
|
|
clearTimeout() {},
|
|
MutationObserver: class { observe() {} },
|
|
HashChangeEvent: class {},
|
|
CustomEvent: class { constructor(t, o) { this.type = t; this.detail = o && o.detail; } },
|
|
Event: class { constructor(t) { this.type = t; } },
|
|
getComputedStyle() { return { getPropertyValue() { return ''; } }; },
|
|
};
|
|
sandbox.window = {
|
|
addEventListener(ev, cb) { (handlers[ev] = handlers[ev] || []).push(cb); },
|
|
dispatchEvent(ev) { (handlers[ev.type] || []).forEach(function (cb) { try { cb(ev); } catch (_) {} }); return true; },
|
|
localStorage: ls,
|
|
SITE_CONFIG: {},
|
|
location: { hash: '', pathname: '/' },
|
|
CustomEvent: sandbox.CustomEvent,
|
|
Event: sandbox.Event,
|
|
matchMedia() { return { matches: false, addEventListener() {} }; },
|
|
};
|
|
sandbox.self = sandbox.window;
|
|
return { sandbox, body, ls };
|
|
}
|
|
|
|
let envOK = false, env, exposed;
|
|
try {
|
|
env = makeSandbox();
|
|
vm.createContext(env.sandbox);
|
|
// Load cb-presets first so MeshCorePresets exists.
|
|
vm.runInContext(presetsSrc, env.sandbox, { filename: 'cb-presets.js' });
|
|
vm.runInContext(customSrc, env.sandbox, { filename: 'customize-v2.js' });
|
|
exposed = env.sandbox.window._customizerV2;
|
|
envOK = !!exposed;
|
|
} catch (e) {
|
|
console.error(' ! load failed: ' + e.message);
|
|
}
|
|
|
|
assert(envOK, 'cb-presets.js + customize-v2.js both load in vm sandbox');
|
|
|
|
// Seed: pretend the user had picked "trit" earlier.
|
|
env.ls.setItem('meshcore-cb-preset', 'trit');
|
|
env.sandbox.window.MeshCorePresets.applyPreset('trit');
|
|
assert(env.ls.getItem('meshcore-cb-preset') === 'trit',
|
|
'seed: localStorage[meshcore-cb-preset] == "trit" before reset');
|
|
assert(env.body.getAttribute('data-cb-preset') === 'trit',
|
|
'seed: body[data-cb-preset] == "trit" before reset');
|
|
|
|
if (envOK && typeof exposed.resetCbPreset === 'function') {
|
|
exposed.resetCbPreset();
|
|
assert(env.ls.getItem('meshcore-cb-preset') === null,
|
|
'resetCbPreset() removes localStorage["meshcore-cb-preset"]');
|
|
// MeshCorePresets.applyPreset('default') sets body[data-cb-preset="default"].
|
|
assert(env.body.getAttribute('data-cb-preset') === 'default',
|
|
'resetCbPreset() applies the default Wong preset (body[data-cb-preset="default"])');
|
|
} else {
|
|
assert(false, 'customize-v2.js exposes resetCbPreset() helper');
|
|
}
|
|
|
|
console.log('\n=== #1380 Reset summary ===');
|
|
console.log(' passed: ' + passed + ' failed: ' + failed);
|
|
if (failed > 0) process.exit(1);
|