74 lines
3.2 KiB
TypeScript
74 lines
3.2 KiB
TypeScript
import { createHash } from 'node:crypto';
|
|
import { readFile } from 'node:fs/promises';
|
|
import { resolve } from 'node:path';
|
|
|
|
import { expect, test } from '@playwright/test';
|
|
|
|
const refBaseUrl = process.env.REF_BATTLE_SIM_URL;
|
|
const refPasswordFile = process.env.REF_USER_PASSWORD_FILE;
|
|
const refUsername = process.env.REF_USER_ID ?? 'refuser1';
|
|
const artifactRoot = process.env.BATTLE_SIM_ARTIFACT_DIR;
|
|
const refTest = refBaseUrl && refPasswordFile ? test : test.skip;
|
|
|
|
refTest('runs the legacy simulator in the same Chromium and captures its rendered contract', async ({ page }) => {
|
|
test.setTimeout(120_000);
|
|
if (!refBaseUrl || !refPasswordFile) {
|
|
throw new Error('REF_BATTLE_SIM_URL and REF_USER_PASSWORD_FILE are required');
|
|
}
|
|
const password = (await readFile(refPasswordFile, 'utf8')).trim();
|
|
await page.setViewportSize({ width: 1280, height: 900 });
|
|
await page.goto(refBaseUrl, { waitUntil: 'networkidle' });
|
|
await page.locator('#username').fill(refUsername);
|
|
await page.locator('#password').fill(password);
|
|
const globalSalt = await page.locator('#global_salt').inputValue();
|
|
const passwordHash = createHash('sha512')
|
|
.update(globalSalt + password + globalSalt)
|
|
.digest('hex');
|
|
const loginResponse = await page
|
|
.context()
|
|
.request.post(new URL('api.php?path=Login/LoginByID', refBaseUrl).toString(), {
|
|
data: { username: refUsername, password: passwordHash },
|
|
});
|
|
expect(loginResponse.status()).toBe(200);
|
|
await expect(loginResponse.json()).resolves.toMatchObject({ result: true });
|
|
|
|
await page.goto(new URL('hwe/battle_simulator.php', refBaseUrl).toString(), {
|
|
waitUntil: 'networkidle',
|
|
});
|
|
const battleButton = page.locator('.btn-begin_battle');
|
|
await expect(battleButton).toBeVisible();
|
|
const container = page.locator('#container');
|
|
const rect = await container.boundingBox();
|
|
expect(rect?.width).toBeGreaterThanOrEqual(995);
|
|
expect(rect?.width).toBeLessThanOrEqual(1005);
|
|
|
|
// A login with no game general leaves the legacy nation selects without a
|
|
// selected option. Choose the first legal independent value before running.
|
|
await page.locator('.form_nation_type').evaluateAll((elements) => {
|
|
for (const element of elements) {
|
|
const select = element as HTMLSelectElement;
|
|
select.selectedIndex = 0;
|
|
select.dispatchEvent(new Event('change', { bubbles: true }));
|
|
}
|
|
});
|
|
await expect(page.locator('.form_nation_type').first()).not.toHaveValue('');
|
|
|
|
await battleButton.hover();
|
|
expect(await battleButton.evaluate((element) => getComputedStyle(element).cursor)).toBe('pointer');
|
|
const simulationResponse = page.waitForResponse(
|
|
(response) => response.url().includes('/j_simulate_battle.php') && response.status() === 200,
|
|
{ timeout: 90_000 }
|
|
);
|
|
await battleButton.click();
|
|
await simulationResponse;
|
|
await expect(page.locator('#generalBattleResultLog')).not.toBeEmpty();
|
|
|
|
if (artifactRoot) {
|
|
await page.screenshot({
|
|
path: resolve(artifactRoot, 'battle-simulator-ref-desktop.png'),
|
|
fullPage: true,
|
|
animations: 'disabled',
|
|
});
|
|
}
|
|
});
|