Etapa 1 inteira (logica com 100% de cobertura, cena 3D, toque, sons, bancada de desempenho, e2e) e a base da etapa 2 (mapa novo no Tiled, texturas, imagens dos itens, sons conferidos, golpe recortado e medido). Pagina /jogo fora do menu e do sitemap ate a medicao no celular.
116 lines
4.2 KiB
TypeScript
116 lines
4.2 KiB
TypeScript
import {
|
||
type Browser,
|
||
chromium,
|
||
expect,
|
||
type Page,
|
||
test,
|
||
} from "@playwright/test";
|
||
import type { ResultadoDaBancada } from "../app/jogo/Bancada";
|
||
import { DESKTOP } from "./helpers";
|
||
|
||
/** Abre a bancada, espera `window.__bancada` aparecer e o devolve. */
|
||
async function medir(page: Page, busca: string, espera: number) {
|
||
const resposta = await page.goto(`/jogo/bancada?${busca}`);
|
||
expect(resposta?.status()).toBe(200);
|
||
await page.waitForFunction(() => window.__bancada !== undefined, null, {
|
||
timeout: espera,
|
||
});
|
||
const resultado = (await page.evaluate(
|
||
() => window.__bancada,
|
||
)) as ResultadoDaBancada;
|
||
console.log(`bancada ${busca}: ${JSON.stringify(resultado)}`);
|
||
return resultado;
|
||
}
|
||
|
||
test("a bancada abre sem indexação, mede e publica o resultado sem erro no console", async ({
|
||
page,
|
||
}) => {
|
||
const erros: string[] = [];
|
||
page.on("console", (mensagem) => {
|
||
if (mensagem.type() === "error") erros.push(mensagem.text());
|
||
});
|
||
page.on("pageerror", (erro) => erros.push(erro.message));
|
||
|
||
const resultado = await medir(page, "zumbis=4&seg=2", 60_000);
|
||
|
||
await expect(page.locator('meta[name="robots"]')).toHaveAttribute(
|
||
"content",
|
||
"noindex, nofollow",
|
||
);
|
||
if ("erro" in resultado) expect(resultado.erro).toBe("sem-webgl");
|
||
else {
|
||
expect(resultado.zumbis).toBe(4);
|
||
expect(resultado.quadros).toBeGreaterThan(0);
|
||
expect(resultado.p95).toBeGreaterThan(0);
|
||
expect(typeof resultado.trabalhoP95).toBe("number");
|
||
}
|
||
expect(erros).toEqual([]);
|
||
});
|
||
|
||
test.describe("com GPU (BANCADA_GPU=1)", () => {
|
||
test.skip(!process.env.BANCADA_GPU, "precisa de GPU: BANCADA_GPU=1");
|
||
// O Playwright recusa `test.use({ launchOptions })` dentro de um describe (exigiria outro worker): o navegador com
|
||
// os argumentos de GPU abre aqui, só para este bloco, com o mesmo `PW_CHROMIUM` da configuração.
|
||
let navegador: Browser;
|
||
test.beforeAll(async () => {
|
||
navegador = await chromium.launch({
|
||
executablePath: process.env.PW_CHROMIUM || undefined,
|
||
args: [
|
||
"--enable-gpu",
|
||
"--ignore-gpu-blocklist",
|
||
"--use-angle=vulkan",
|
||
"--enable-features=Vulkan",
|
||
],
|
||
});
|
||
});
|
||
test.afterAll(() => navegador?.close());
|
||
|
||
test("16 zumbis em 1440×900: p95 até 16,7 ms", async ({ baseURL }) => {
|
||
const contexto = await navegador.newContext({ viewport: DESKTOP, baseURL });
|
||
const resultado = await medir(
|
||
await contexto.newPage(),
|
||
"zumbis=16&seg=20",
|
||
90_000,
|
||
);
|
||
if ("erro" in resultado) throw new Error("sem WebGL com GPU");
|
||
expect(resultado.p95).toBeLessThanOrEqual(16.7);
|
||
});
|
||
|
||
test("16 zumbis com a CPU 4× mais lenta: p95 até 33 ms", async ({
|
||
baseURL,
|
||
}) => {
|
||
const contexto = await navegador.newContext({ viewport: DESKTOP, baseURL });
|
||
const page = await contexto.newPage();
|
||
const cdp = await contexto.newCDPSession(page);
|
||
await cdp.send("Emulation.setCPUThrottlingRate", { rate: 4 });
|
||
const resultado = await medir(page, "zumbis=16&seg=20", 110_000);
|
||
if ("erro" in resultado) throw new Error("sem WebGL com GPU");
|
||
expect(resultado.p95).toBeLessThanOrEqual(33);
|
||
});
|
||
|
||
test("memória (CA9): 3ª medição com as mesmas geometrias e texturas da 1ª", async ({
|
||
baseURL,
|
||
}) => {
|
||
const contexto = await navegador.newContext({ viewport: DESKTOP, baseURL });
|
||
const page = await contexto.newPage();
|
||
const primeira = await medir(page, "zumbis=16&seg=3", 90_000);
|
||
if ("erro" in primeira) throw new Error("sem WebGL com GPU");
|
||
let ultima: ResultadoDaBancada = primeira;
|
||
for (let i = 0; i < 2; i += 1) {
|
||
const botao = page.getByRole("button", { name: "Medir de novo" });
|
||
await botao.click();
|
||
await botao.waitFor({ state: "detached", timeout: 30_000 });
|
||
await page.waitForFunction(() => window.__bancada !== undefined, null, {
|
||
timeout: 90_000,
|
||
});
|
||
ultima = (await page.evaluate(
|
||
() => window.__bancada,
|
||
)) as ResultadoDaBancada;
|
||
console.log(`bancada medição ${i + 2}: ${JSON.stringify(ultima)}`);
|
||
}
|
||
if ("erro" in ultima) throw new Error("sem WebGL com GPU");
|
||
expect(ultima.geometrias).toBe(primeira.geometrias);
|
||
expect(ultima.texturas).toBe(primeira.texturas);
|
||
});
|
||
});
|