diff --git a/AGENTS.md b/AGENTS.md index 8b7de41..91c4a85 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,6 +60,9 @@ LOCAL_DEV_MODE="true" sudo mv deno /usr/local/bin/ rm deno-x86_64-unknown-linux-gnu.zip ``` + +Ensure the `deno` executable is available in your system's PATH. The above instructions place it in `/usr/local/bin/`, which is typically included in the PATH. + 2. Clone repository and navigate to project directory 3. Set up environment variables (copy `.env.example` to `.env`) 4. Start development server: `deno task dev` (Deno KV initializes automatically) @@ -151,3 +154,4 @@ LOCAL_DEV_MODE="true" - Follow OWASP security guidelines - Use local authentication to avoid external dependencies - Regular security audits and dependency updates + diff --git a/deno-x86_64-unknown-linux-gnu.zip b/deno-x86_64-unknown-linux-gnu.zip new file mode 100644 index 0000000..ca6651e Binary files /dev/null and b/deno-x86_64-unknown-linux-gnu.zip differ diff --git a/tests/e2e/helpers.ts b/tests/e2e/helpers.ts index 44846a2..db0809f 100644 --- a/tests/e2e/helpers.ts +++ b/tests/e2e/helpers.ts @@ -79,7 +79,7 @@ export async function useE2EUser(page: Page, userKey: string) { tenant: "e2e-tenant-1", }; const userId = userIdMap[userKey] ?? userKey; - await page.addInitScript(({ id }) => { + await page.addInitScript(({ id }: { id: string }) => { (window as { __E2E_SKIP_ENCRYPTION__?: boolean }).__E2E_SKIP_ENCRYPTION__ = true; const skipKey = `realestate_app_skip_user_${id}`; diff --git a/tests/e2e/invite-tenant.spec.ts b/tests/e2e/invite-tenant.spec.ts index ae6b0e7..653b64c 100644 --- a/tests/e2e/invite-tenant.spec.ts +++ b/tests/e2e/invite-tenant.spec.ts @@ -1,7 +1,7 @@ -import { expect, test } from "@playwright/test"; +import { expect, test, Page } from "@playwright/test"; import { applyDeterministicPage, e2eHeaders, useE2EUser } from "./helpers.ts"; -test("landlord can generate a tenant invite email", async ({ page }) => { +test("landlord can generate a tenant invite email", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); @@ -74,7 +74,7 @@ test("landlord can generate a tenant invite email", async ({ page }) => { await expect(emailInput).toHaveValue(/jamie\.roommate@example\.com/i); }); -test("tenant invite preview shows property details and actions", async ({ page }) => { +test("tenant invite preview shows property details and actions", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); const inviteResponse = await page.request.post("/api/update/tenant_invite", { @@ -102,3 +102,4 @@ test("tenant invite preview shows property details and actions", async ({ page } await expect(page.getByRole("button", { name: /decline/i })).toBeVisible(); await expect(page.getByRole("link", { name: /cancel/i })).toBeVisible(); }); + diff --git a/tests/e2e/landlord-dashboard.spec.ts b/tests/e2e/landlord-dashboard.spec.ts index eb260c1..3b1c770 100644 --- a/tests/e2e/landlord-dashboard.spec.ts +++ b/tests/e2e/landlord-dashboard.spec.ts @@ -1,7 +1,7 @@ -import { expect, test } from "@playwright/test"; +import { expect, test, Page } from "@playwright/test"; import { applyDeterministicPage, useE2EUser } from "./helpers.ts"; -test("landlord dashboard surfaces portfolio activity", async ({ page }) => { +test("landlord dashboard surfaces portfolio activity", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); @@ -24,7 +24,7 @@ test("landlord dashboard surfaces portfolio activity", async ({ page }) => { ).toBeVisible(); }); -test("landlord properties list includes active listings", async ({ page }) => { +test("landlord properties list includes active listings", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); @@ -36,7 +36,7 @@ test("landlord properties list includes active listings", async ({ page }) => { await expect(page.getByText("456 Maple St")).toBeVisible(); }); -test("landlord can approve an application", async ({ page }) => { +test("landlord can approve an application", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); @@ -61,7 +61,7 @@ test("landlord can approve an application", async ({ page }) => { await expect(updatedRow).toContainText(/approved/i); }); -test("landlord can update maintenance status", async ({ page }) => { +test("landlord can update maintenance status", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); @@ -75,3 +75,4 @@ test("landlord can update maintenance status", async ({ page }) => { await expect(page).toHaveURL(/\/landlord\/maintenance/); await expect(statusSelect).toHaveValue("in_progress"); }); + diff --git a/tests/e2e/landlord-messages.spec.ts b/tests/e2e/landlord-messages.spec.ts index 20138c8..6e2bed4 100644 --- a/tests/e2e/landlord-messages.spec.ts +++ b/tests/e2e/landlord-messages.spec.ts @@ -1,7 +1,7 @@ -import { expect, test } from "@playwright/test"; +import { expect, test, Page } from "@playwright/test"; import { applyDeterministicPage, useE2EUser } from "./helpers.ts"; -test("landlord messages view paginates conversations", async ({ page }) => { +test("landlord messages view paginates conversations", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); @@ -26,7 +26,7 @@ test("landlord messages view paginates conversations", async ({ page }) => { await expect(page.getByText(/page 2 of 2/i)).toBeVisible(); }); -test("landlord messages view filters unread inbound messages", async ({ page }) => { +test("landlord messages view filters unread inbound messages", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); diff --git a/tests/e2e/landlord-onboarding.spec.ts b/tests/e2e/landlord-onboarding.spec.ts index c0a49b9..5039de8 100644 --- a/tests/e2e/landlord-onboarding.spec.ts +++ b/tests/e2e/landlord-onboarding.spec.ts @@ -1,7 +1,7 @@ -import { expect, test } from "@playwright/test"; +import { expect, test, Page } from "@playwright/test"; import { applyDeterministicPage, useE2EUser } from "./helpers.ts"; -test("landlord profile setup advances to property details", async ({ page }) => { +test("landlord profile setup advances to property details", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord-onboarding"); @@ -25,7 +25,7 @@ test("landlord profile setup advances to property details", async ({ page }) => ).toBeVisible(); }); -test("property setup submits and lands on landlord dashboard", async ({ page }) => { +test("property setup submits and lands on landlord dashboard", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord-onboarding"); @@ -49,3 +49,4 @@ test("property setup submits and lands on landlord dashboard", async ({ page }) await expect(page.getByRole("heading", { name: /landlord dashboard/i })) .toBeVisible(); }); + diff --git a/tests/e2e/multi-property.spec.ts b/tests/e2e/multi-property.spec.ts index 7996136..6c23457 100644 --- a/tests/e2e/multi-property.spec.ts +++ b/tests/e2e/multi-property.spec.ts @@ -1,7 +1,7 @@ -import { expect, test } from "@playwright/test"; +import { expect, test, Page } from "@playwright/test"; import { applyDeterministicPage, useE2EUser } from "./helpers.ts"; -test("landlord sees multi-property portfolio overview", async ({ page }) => { +test("landlord sees multi-property portfolio overview", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); diff --git a/tests/e2e/onboarding.spec.ts b/tests/e2e/onboarding.spec.ts index 1f2d19f..9fdfd51 100644 --- a/tests/e2e/onboarding.spec.ts +++ b/tests/e2e/onboarding.spec.ts @@ -1,7 +1,7 @@ -import { expect, test } from "@playwright/test"; +import { expect, test, Page } from "@playwright/test"; import { applyDeterministicPage, e2eHeaders, useE2EUser } from "./helpers.ts"; -test("tenant onboarding lets renters apply and reach dashboard", async ({ page }) => { +test("tenant onboarding lets renters apply and reach dashboard", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "tenant"); @@ -21,7 +21,7 @@ test("tenant onboarding lets renters apply and reach dashboard", async ({ page } .toBeVisible(); }); -test("landlord onboarding entry points show dashboard access", async ({ page }) => { +test("landlord onboarding entry points show dashboard access", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); @@ -41,7 +41,7 @@ test("landlord onboarding entry points show dashboard access", async ({ page }) ).toBeVisible(); }); -test("onboarded landlord skips profile onboarding", async ({ page }) => { +test("onboarded landlord skips profile onboarding", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord"); @@ -53,7 +53,7 @@ test("onboarded landlord skips profile onboarding", async ({ page }) => { await expect(page.getByLabel(/street address/i)).toBeVisible(); }); -test("invite links highlight the selected rental on onboarding", async ({ page }) => { +test("invite links highlight the selected rental on onboarding", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); const inviteResponse = await page.request.post("/api/update/tenant_invite", { @@ -77,3 +77,4 @@ test("invite links highlight the selected rental on onboarding", async ({ page } await expect(page.getByText("Skyline Lofts")).toBeVisible(); await expect(page.getByLabel(/select a property/i)).toHaveCount(0); }); + diff --git a/tests/e2e/reminders.spec.ts b/tests/e2e/reminders.spec.ts index 3def23a..4942c9a 100644 --- a/tests/e2e/reminders.spec.ts +++ b/tests/e2e/reminders.spec.ts @@ -1,7 +1,7 @@ -import { expect, test } from "@playwright/test"; +import { expect, test, Page } from "@playwright/test"; import { applyDeterministicPage, useE2EUser } from "./helpers.ts"; -test("landlord can send reminder and tenant receives it", async ({ page }) => { +test("landlord can send reminder and tenant receives it", async ({ page }: { page: Page }) => { await applyDeterministicPage(page); await useE2EUser(page, "landlord");