Release Healer Man 0.1.48

This commit is contained in:
phenom committed 2026-09-16 20:58:10 -04:00
1 parent 2162039b49
commit 39425f2494
9 files changed
+219 -40

No files matched your search

+30 -7
View File
@@ -34,7 +34,31 @@ fs.rmSync(databaseDirectory, { recursive: true, force: true });
const errors = [];
page.on('pageerror', (error) => errors.push(error.message));
const capture = (name) => page.screenshot({ path: path.join(directory, `${name}.png`), fullPage: true });
const canvasHash = async () => crypto.createHash('sha256').update(await page.locator('canvas').screenshot()).digest('hex');
const captureCanvas = async (name) => {
const canvas = page.locator('canvas');
await canvas.evaluate((element) => {
const hidden = [];
let current = element;
while (current.parentElement) {
for (const sibling of current.parentElement.children) {
if (sibling === current || !(sibling instanceof HTMLElement)) continue;
hidden.push([sibling, sibling.style.visibility]);
sibling.style.visibility = 'hidden';
}
current = current.parentElement;
}
window.__restoreCanvasCapture = () => {
for (const [node, visibility] of hidden) node.style.visibility = visibility;
delete window.__restoreCanvasCapture;
};
});
try {
const image = await canvas.screenshot(name ? { path: path.join(directory, `${name}.png`) } : undefined);
return crypto.createHash('sha256').update(image).digest('hex');
} finally {
await page.evaluate(() => window.__restoreCanvasCapture?.());
}
};
try {
await page.goto('http://127.0.0.1:4189', { waitUntil: 'domcontentloaded' });
@@ -79,22 +103,20 @@ fs.rmSync(databaseDirectory, { recursive: true, force: true });
await page.getByRole('button', { name: 'Free camera' }).click();
assert.equal(await page.getByRole('button', { name: 'Free camera' }).getAttribute('aria-pressed'), 'true');
const beforeFlight = await canvasHash();
const beforeFlight = await captureCanvas('03-canvas-before-flight');
await page.keyboard.down('w');
await page.keyboard.down('e');
await page.waitForTimeout(700);
await page.keyboard.up('e');
await page.keyboard.up('w');
await page.waitForTimeout(150);
const afterFlight = await canvasHash();
assert.notEqual(afterFlight, beforeFlight, 'W/E free-camera input changes the rendered viewpoint');
const afterFlight = await captureCanvas();
assert.notEqual(afterFlight, beforeFlight, 'free-camera movement redraws the 3D dungeon without relying on nameplate overlays');
const canvasBounds = await page.locator('canvas').boundingBox();
assert(canvasBounds, 'simulation canvas is visible');
const lookStart = { x: canvasBounds.x + canvasBounds.width * 0.5, y: canvasBounds.y + canvasBounds.height * 0.55 };
const beforeLook = await page.evaluate(() => window.readSpectatorCameraState());
await page.mouse.move(lookStart.x, lookStart.y);
await page.mouse.down({ button: 'right' });
await page.mouse.move(lookStart.x + 140, lookStart.y - 45, { steps: 10 });
await page.mouse.move(lookStart.x + 220, lookStart.y + 100, { steps: 12 });
await page.waitForTimeout(250);
const duringLook = await page.evaluate(() => window.readSpectatorCameraState());
assert.notEqual(duringLook.yaw, beforeLook.yaw, 'right-drag rotates the free camera');
@@ -108,6 +130,7 @@ fs.rmSync(databaseDirectory, { recursive: true, force: true });
releasedLook.yaw,
'mouse movement after right-button release does not rotate the camera',
);
await page.locator('canvas').screenshot({ path: path.join(directory, '04-canvas-after-flight-look.png') });
await capture('04-paused-free-camera-moved');
await memberButtons.nth(4).click();