Release Healer Man 0.1.48
This commit is contained in:
1 parent
2162039b49
commit
39425f2494
9 files changed
+219
-40
No files matched your search
@@ -2,6 +2,7 @@ const { chromium } = require('C:/Users/phenom/.cache/codex-runtimes/codex-primar
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const assert = require('node:assert/strict');
|
||||
const crypto = require('node:crypto');
|
||||
const selectedBossName = process.env.BOSS_TEST_BOSS || 'Lady Anacondra';
|
||||
const directory = path.resolve(process.env.BOSS_TEST_ARTIFACT_DIR || path.join(
|
||||
'playtest-artifacts',
|
||||
@@ -38,6 +39,30 @@ const base = process.env.BOSS_TEST_URL || 'http://127.0.0.1:4187';
|
||||
await page.screenshot({ path: path.join(directory, `${name}.png`) });
|
||||
console.log(`Captured ${name}`);
|
||||
};
|
||||
const canvasHash = async () => {
|
||||
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 {
|
||||
return crypto.createHash('sha256').update(await canvas.screenshot()).digest('hex');
|
||||
} finally {
|
||||
await page.evaluate(() => window.__restoreCanvasCapture?.());
|
||||
}
|
||||
};
|
||||
try {
|
||||
await page.goto(base, { waitUntil: 'domcontentloaded' });
|
||||
console.log('Production menu loaded');
|
||||
@@ -66,6 +91,13 @@ const base = process.env.BOSS_TEST_URL || 'http://127.0.0.1:4187';
|
||||
return game.assetStatus === 'ready' && game.bossTest?.runtimeIds.every((id) => useCombatStore.getState().mobs[id]);
|
||||
}, null, { timeout: 90000 });
|
||||
await page.waitForTimeout(4000);
|
||||
const bossFrameBefore = await canvasHash();
|
||||
await page.waitForTimeout(500);
|
||||
assert.notEqual(
|
||||
await canvasHash(),
|
||||
bossFrameBefore,
|
||||
'Boss Testing redraws the WebGL scene independently from its HUD and nameplates',
|
||||
);
|
||||
await capture('03-empty-room');
|
||||
const before = await page.evaluate(async () => {
|
||||
const { useGameStore, useCombatStore, useShellStore } = await window.bossTestingStores();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const assert = require("node:assert/strict");
|
||||
const crypto = require("node:crypto");
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const { chromium } = require("C:/Users/phenom/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright");
|
||||
@@ -14,6 +15,31 @@ fs.mkdirSync(directory, { recursive: true });
|
||||
const errors = [];
|
||||
page.on("pageerror", (error) => errors.push(error.message));
|
||||
|
||||
const canvasHash = async () => {
|
||||
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 {
|
||||
return crypto.createHash("sha256").update(await canvas.screenshot()).digest("hex");
|
||||
} finally {
|
||||
await page.evaluate(() => window.__restoreCanvasCapture?.());
|
||||
}
|
||||
};
|
||||
|
||||
const gameState = () => page.evaluate(async () => {
|
||||
const storeEntry = performance.getEntriesByType("resource")
|
||||
.findLast((entry) => new URL(entry.name).pathname === "/src/game/store.ts");
|
||||
@@ -74,6 +100,7 @@ fs.mkdirSync(directory, { recursive: true });
|
||||
const cdp = await page.context().newCDPSession(page);
|
||||
const start = { x: bounds.x + bounds.width * 0.55, y: bounds.y + bounds.height * 0.55 };
|
||||
const before = await gameState();
|
||||
const frameBefore = await canvasHash();
|
||||
assert.equal(before.cameraLookActive, false);
|
||||
await page.mouse.move(start.x, start.y);
|
||||
await page.mouse.down({ button: "right" });
|
||||
@@ -99,6 +126,11 @@ fs.mkdirSync(directory, { recursive: true });
|
||||
await page.waitForTimeout(350);
|
||||
const moved = await gameState();
|
||||
assert.notEqual(moved.cameraYaw, before.cameraYaw);
|
||||
assert.notEqual(
|
||||
await canvasHash(),
|
||||
frameBefore,
|
||||
"regular dungeon camera input redraws the WebGL scene independently from its HUD and nameplates",
|
||||
);
|
||||
await page.screenshot({ path: path.join(directory, "right-drag-camera.png") });
|
||||
|
||||
await page.mouse.up({ button: "right" });
|
||||
|
||||
Reference in new issue
Block a user