Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions tools/simulation/ui/specs/dialog-actions.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { test, expect } from "../src/fixtures";
import { owner } from "../src/cast";
import { tEn } from "../src/i18n";
import { openSeededExpenses } from "../src/expenses";

for (const width of [1280, 390]) {
test(`Expenses correction keeps Save reachable ${width === 390 ? "@phone" : ""}`, async ({ page, signIn }) => {
test(`Expenses correction keeps Save reachable ${width === 390 ? "@phone" : ""}`, async ({ page, signIn, farm, shellLayout }) => {
await page.setViewportSize({ width, height: width === 390 ? 844 : 800 });
await signIn(owner());
await page.goto("/expenses");
await openSeededExpenses({ page, farm, shellLayout });
if (width === 390) {
await page.getByRole("list", { name: tEn("expenses:ledgerHeading") }).locator("li")
.filter({ hasText: "Sim Feeder Replacement Part" }).getByRole("button").click();
Expand Down
5 changes: 3 additions & 2 deletions tools/simulation/ui/specs/optical-size.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { test, expect } from "../src/fixtures";
import { owner } from "../src/cast";
import { tEn } from "../src/i18n";
import { openSeededExpenses } from "../src/expenses";

// #835 — the one assertion that needs a real font engine.
//
Expand Down Expand Up @@ -91,9 +92,9 @@ test("display text renders at a display optical size", async ({ page, signIn })
// the display cut. Check both the computed pin and the same rendered letters'
// width against a forced opsz 14 cut. The desktop test above still covers the
// display figure; Expenses no longer shows that large figure on phones.
test("real body text stays at the text cut on a phone", { tag: "@phone" }, async ({ page, signIn }) => {
test("real body text stays at the text cut on a phone", { tag: "@phone" }, async ({ page, signIn, farm, shellLayout }) => {
await signIn(owner());
await page.goto("/expenses");
await openSeededExpenses({ page, farm, shellLayout });
await expect(page.getByRole("heading", { level: 2 })).toBeVisible();
await expect(page.getByRole("list", { name: tEn("expenses:ledgerHeading") })).toBeVisible();

Expand Down
11 changes: 6 additions & 5 deletions tools/simulation/ui/specs/phone.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { expect, type Locator, type Page } from "../src/fixtures";
import { test } from "../src/dashboard-fixtures";
import { owner, readmeFarmOwner } from "../src/cast";
import { tEn } from "../src/i18n";
import { openSeededExpenses } from "../src/expenses";

/** Owner's four thumb tabs, in the order `tabEntries` picks them (nav.tsx TAB_PRIORITY). */
const OWNER_TABS = ["nav:dashboard", "nav:dailyEntry", "nav:stock", "nav:sales"];
Expand Down Expand Up @@ -895,14 +896,14 @@ test.describe("Two-line ledgers at phone width", { tag: "@phone" }, () => {
["/sales", "sales:ordersHeading"],
["/inventory", "inventory:itemsHeading"],
] as const) {
test(`${route} shows ten complete rows above the bottom navigation`, async ({ page, signIn }) => {
test(`${route} shows ten complete rows above the bottom navigation`, async ({ page, signIn, farm, shellLayout }) => {
await signIn(owner());
await page.goto(route);
if (route === "/expenses") await openSeededExpenses({ page, farm, shellLayout });
else await page.goto(route);
const rows = page.getByRole("list", { name: tEn(heading) }).locator("li");
await expect(rows.first()).toBeVisible();
// The simulation fixture has eight Water/Feed rows, seven expenses this
// month and two inventory items. Repeat a rendered row to measure twelve
// row heights without adding permanent records to the shared
// Repeat a rendered row to measure twelve row heights where the fixture
// has fewer records, without adding permanent records to the shared
// quick-suite database.
await rows.evaluateAll((items) => {
const first = items[0];
Expand Down
34 changes: 34 additions & 0 deletions tools/simulation/ui/src/expenses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect, type Fixtures, type Page } from "./fixtures";
import { daysBefore, farmToday } from "./farm";
import { tEn } from "./i18n";

export async function openSeededExpenses({ page, farm, shellLayout }: Pick<Fixtures, "farm" | "shellLayout"> & { page: Page }) {
// A fresh seed's recent expenses can all fall in the previous farm month.
const to = farmToday(farm.timeZoneId);
const from = daysBefore(to, 30);
// At a 31-day month's end, the initial request already has this range.
const loaded = page.waitForResponse((response) => {
const url = new URL(response.url());
return response.request().method() === "GET" && url.pathname === "/api/v1/expenses"
&& url.searchParams.get("from") === from && url.searchParams.get("to") === to;
});
loaded.catch(() => undefined);
await page.goto("/expenses");
if (shellLayout === "phone") {
await page.getByRole("button", { name: tEn("expenses:allCategoriesOption"), exact: true }).click();
}

await page.getByLabel(tEn("expenses:fromLabel"), { exact: true }).fill(from);
await page.getByLabel(tEn("expenses:toLabel"), { exact: true }).fill(to);
const response = await loaded;
expect(response.ok()).toBe(true);
await response.finished();

if (shellLayout === "phone") {
await page.getByRole("dialog", { name: tEn("expenses:filtersTitle") })
.getByRole("button", { name: tEn("common:close"), exact: true }).click();
await expect(page.getByRole("list", { name: tEn("expenses:ledgerHeading") })).toBeVisible();
} else {
await expect(page.getByRole("table")).toBeVisible();
}
}
Loading