Files
paseo/packages/app/e2e/browser/usage-settings.spec.ts
T
paseo-bot[bot]andMichael Wu 62dc5f6f57 fix(app): clarify and localize provider usage
Usage windows displayed consumed percentages without saying what they
meant, and their copy did not follow the app language. Translate the
usage surface while retaining the last successful values and timestamps
when refreshes fail. Preserve customized provider labels.

Co-authored-by: Michael Wu <michaelmwu@gmail.com>
2026-10-19 09:01:53 +02:00

157 lines
5.7 KiB
TypeScript

import type { UsageReportEntry } from "@getpaseo/protocol/messages";
import { expect, test } from "../support/fixtures";
import { gotoAppShell, openSettings } from "../support/helpers/app";
import { getServerId } from "../support/helpers/server-id";
import { openSettingsHostSection } from "../support/helpers/settings";
import {
installUsageReportsFixture,
type UsageReportsFixture,
} from "../support/helpers/usage-reports";
import {
openUsageFromIcon,
refreshAllUsage,
showUsageAs,
} from "../support/helpers/usage-sidebar-item";
const ICON = '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="8" fill="currentColor"/></svg>';
function forcedRefreshCount(usage: UsageReportsFixture): number {
return usage.listRequests().filter((request) => request.forceRefresh).length;
}
function report(input: {
sourceId: string;
sourceLabel: string;
report:
| Partial<Extract<UsageReportEntry["report"], { status: "available" }>>
| Exclude<UsageReportEntry["report"], { status: "available" }>;
}): UsageReportEntry {
return {
id: `${input.sourceId}:account`,
account: { label: input.sourceId === "alpha" ? "dev@example.com" : undefined },
fetchedAt: "2026-01-01T00:00:00.000Z",
sourceId: input.sourceId,
sourceLabel: input.sourceLabel,
icon: ICON,
report:
input.report.status === "error" || input.report.status === "unavailable"
? input.report
: {
status: "available",
windows: [],
...input.report,
},
};
}
test.describe("usage settings", () => {
test("renders every report returned by usage.list_reports", async ({ page }) => {
test.setTimeout(120_000);
const serverId = getServerId();
const usage = await installUsageReportsFixture(page, {
lists: [
[
report({
sourceId: "alpha",
sourceLabel: "Alpha plan",
report: {
planLabel: "Max",
windows: [{ id: "session", label: "Session", usedPct: 7 }],
},
}),
report({
sourceId: "beta",
sourceLabel: "Beta plan",
report: {
planLabel: "Coding plan",
windows: [
{ id: "biweekly", label: "Biweekly", usedPct: 23 },
{ id: "daily", label: "Daily", remainingPct: 30 },
],
balances: [
{ id: "credits", label: "Credits", remaining: 1234, unit: "credits" },
{ id: "extra", label: "Extra usage", used: 5, limit: 20, unit: "usd" },
],
details: [{ id: "valid", label: "Valid until", value: "2026-12-31" }],
},
}),
report({
sourceId: "gamma",
sourceLabel: "Gamma plan",
report: { status: "error", error: "Gamma auth expired" },
}),
],
],
});
await gotoAppShell(page);
await openSettings(page);
await openSettingsHostSection(page, serverId, "usage");
await usage.waitForListRequests(1);
const card = page.getByTestId("usage-card");
await expect(card.getByText("Alpha plan", { exact: true })).toBeVisible({ timeout: 10_000 });
await expect(card.getByText("dev@example.com", { exact: true })).toBeVisible();
await expect(card.getByText("Beta plan", { exact: true })).toBeVisible();
await expect(card.getByText("70% used")).toBeVisible();
await expect(card.getByText("1,234 left", { exact: true })).toBeVisible();
await expect(card.getByText("$5.00 / $20.00", { exact: true })).toBeVisible();
await expect(card.getByText("2026-12-31", { exact: true })).toBeVisible();
await expect(card.getByText("Gamma auth expired", { exact: true })).toBeVisible();
// The shared percentages setting applies to the host section.
await expect(page.getByTestId("usage-options-menu")).toBeVisible();
const hostUsageUrl = page.url();
await gotoAppShell(page);
await openUsageFromIcon(page);
await showUsageAs(page, "remaining");
await page.goto(hostUsageUrl);
await expect(card.getByText("30% left")).toBeVisible();
await expect(card.getByText("93% left")).toBeVisible();
});
test("refresh forces a fresh report", async ({ page }) => {
test.setTimeout(120_000);
const serverId = getServerId();
const windows = (usedPct: number) => [{ id: "w", label: "Weekly", usedPct }];
// The sidebar summary and the section each load reports; only Refresh forces one.
const usage = await installUsageReportsFixture(page, {
lists: [
(request) => [
report({
sourceId: "alpha",
sourceLabel: "Alpha plan",
report: { windows: windows(request.forceRefresh ? 64 : 23) },
}),
],
],
});
await gotoAppShell(page);
await openSettings(page);
await openSettingsHostSection(page, serverId, "usage");
const card = page.getByTestId("usage-card");
await expect(card.getByText("23% used")).toBeVisible({ timeout: 10_000 });
await refreshAllUsage(page);
await expect.poll(() => forcedRefreshCount(usage)).toBe(1);
await expect(card.getByText("64% used")).toBeVisible();
});
test("asks to update a host without usage support and never calls it", async ({ page }) => {
test.setTimeout(120_000);
const serverId = getServerId();
const usage = await installUsageReportsFixture(page, { usageSupported: false });
await gotoAppShell(page);
await openSettings(page);
await openSettingsHostSection(page, serverId, "usage");
await expect(
// Names the host: "Update Laptop to see usage".
page.getByTestId("usage-card").getByText(/^Update (?!the host ).+ to see usage$/),
).toBeVisible({ timeout: 10_000 });
expect(usage.listRequests()).toHaveLength(0);
});
});