mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-23 17:52:49 +00:00
The ring's quarter-turn lived in a Unistyles style on the react-native-svg root. On web, Unistyles only turns styles into classes for the React Native components its Babel plugin rewrites, so the Svg received an empty style and the arc started at three o'clock. The rotation now lives on the progress circle as an SVG transform, which renders the same on web and native. Closes #5596 Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
72 lines
2.8 KiB
TypeScript
72 lines
2.8 KiB
TypeScript
import type { Locator } from "@playwright/test";
|
|
import { expect, test } from "../support/fixtures";
|
|
import { expectComposerVisible } from "../support/helpers/composer";
|
|
import { openAgentRoute, seedMockAgentWorkspace } from "../support/helpers/mock-agent";
|
|
|
|
// Where the progress arc is painted, as its centroid relative to the ring's centre in pixels.
|
|
// Reads the rendered pixels, so any rotation that does not reach the screen counts as none.
|
|
async function progressArcCentroid(meter: Locator): Promise<{ x: number; y: number }> {
|
|
const ring = meter.locator("svg");
|
|
const progressColor = await ring
|
|
.locator("circle")
|
|
.last()
|
|
.evaluate((circle) => getComputedStyle(circle).stroke);
|
|
const screenshot = await ring.screenshot();
|
|
return ring.evaluate(
|
|
async (_svg, { png, color }) => {
|
|
const image = await createImageBitmap(
|
|
await (await fetch(`data:image/png;base64,${png}`)).blob(),
|
|
);
|
|
const canvas = new OffscreenCanvas(image.width, image.height);
|
|
const context = canvas.getContext("2d")!;
|
|
context.drawImage(image, 0, 0);
|
|
const { data } = context.getImageData(0, 0, image.width, image.height);
|
|
const [r, g, b] = color.match(/\d+/g)!.map(Number);
|
|
let sumX = 0;
|
|
let sumY = 0;
|
|
let count = 0;
|
|
for (let y = 0; y < image.height; y += 1) {
|
|
for (let x = 0; x < image.width; x += 1) {
|
|
const i = (y * image.width + x) * 4;
|
|
const distance =
|
|
Math.abs(data[i] - r) + Math.abs(data[i + 1] - g) + Math.abs(data[i + 2] - b);
|
|
if (distance < 40) {
|
|
sumX += x;
|
|
sumY += y;
|
|
count += 1;
|
|
}
|
|
}
|
|
}
|
|
if (count === 0) {
|
|
throw new Error(`No pixels painted in the progress colour ${color}`);
|
|
}
|
|
return { x: sumX / count - image.width / 2, y: sumY / count - image.height / 2 };
|
|
},
|
|
{ png: screenshot.toString("base64"), color: progressColor },
|
|
);
|
|
}
|
|
|
|
test.describe("context window meter", () => {
|
|
test("draws usage clockwise from twelve o'clock", async ({ page }) => {
|
|
test.setTimeout(180_000);
|
|
// 32,000 of the mock's 128,000-token window: a quarter, from twelve to three o'clock.
|
|
const session = await seedMockAgentWorkspace({
|
|
repoPrefix: "context-window-meter-",
|
|
title: "Context window meter e2e",
|
|
initialPrompt: "emit 32000 byte file agent stream payload",
|
|
});
|
|
try {
|
|
await openAgentRoute(page, session);
|
|
await expectComposerVisible(page);
|
|
const meter = page.getByTestId("context-window-meter");
|
|
await expect(meter).toHaveAccessibleName(/25%/, { timeout: 30_000 });
|
|
|
|
const centroid = await progressArcCentroid(meter);
|
|
expect(centroid.x).toBeGreaterThan(1);
|
|
expect(centroid.y).toBeLessThan(-1);
|
|
} finally {
|
|
await session.cleanup();
|
|
}
|
|
});
|
|
});
|