Merge pull request #31 from nathanAndrinoid/open-swe/91ab36d5-3b7d-484f-99d7-07b03cfc6932
fix: Resolve Deno check errors for Playwright and implicit any types
This commit is contained in:
commit
32e46f7ca0
@ -61,7 +61,9 @@ LOCAL_DEV_MODE="true"
|
|||||||
rm deno-x86_64-unknown-linux-gnu.zip
|
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.
|
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
|
2. Clone repository and navigate to project directory
|
||||||
3. Set up environment variables (copy `.env.example` to `.env`)
|
3. Set up environment variables (copy `.env.example` to `.env`)
|
||||||
@ -81,7 +83,9 @@ Ensure the `deno` executable is available in your system's PATH. The above instr
|
|||||||
2. Run `deno task check` to validate code quality
|
2. Run `deno task check` to validate code quality
|
||||||
3. Test with `deno task test` and `deno task e2e`
|
3. Test with `deno task test` and `deno task e2e`
|
||||||
4. Deno KV handles data persistence automatically
|
4. Deno KV handles data persistence automatically
|
||||||
5. **File-Level Validation**: When coding, ensure compliance by running the following commands on the specific file being modified (replace `routes/index.tsx` with your file path):
|
5. **File-Level Validation**: When coding, ensure compliance by running the
|
||||||
|
following commands on the specific file being modified (replace
|
||||||
|
`routes/index.tsx` with your file path):
|
||||||
```bash
|
```bash
|
||||||
deno check routes/index.tsx
|
deno check routes/index.tsx
|
||||||
deno fmt routes/index.tsx
|
deno fmt routes/index.tsx
|
||||||
@ -154,4 +158,3 @@ Ensure the `deno` executable is available in your system's PATH. The above instr
|
|||||||
- Follow OWASP security guidelines
|
- Follow OWASP security guidelines
|
||||||
- Use local authentication to avoid external dependencies
|
- Use local authentication to avoid external dependencies
|
||||||
- Regular security audits and dependency updates
|
- Regular security audits and dependency updates
|
||||||
|
|
||||||
|
|||||||
92
TODO.md
92
TODO.md
@ -1,68 +1,34 @@
|
|||||||
# TODO - Deno Check Errors
|
# Project TODO List
|
||||||
|
|
||||||
## TypeScript Errors Found (34 total)
|
This document outlines the remaining tasks, incomplete features, and future development plans for the application.
|
||||||
|
|
||||||
### Primary Issue: Missing Playwright Dependency
|
## High Priority
|
||||||
Multiple files have `TS2307: Import "@playwright/test" not a dependency and not in import map`
|
- **Implement Payment Processing**: The current rent payment system in `routes/tenant/rent/pay/index.tsx` is a placeholder. It needs to be fully implemented with a payment provider like Stripe to handle real transactions securely.
|
||||||
|
|
||||||
**Affected Files:**
|
## Backend & API
|
||||||
- tests/e2e/document-api.spec.ts:1:36
|
- **Add Well-Known Endpoint**: Implement a `/.well-known/acme-challenge/:token` endpoint in `main.ts` to support services like Let's Encrypt for SSL certificate validation in production.
|
||||||
- tests/e2e/documents.spec.ts:1:36
|
- **Enforce Database Constraints**: Ensure the `owner_id` field in the `AccessTokenResponse` interface is unique for each entry, as noted in `utils/database.ts`. This is crucial for maintaining data integrity.
|
||||||
- tests/e2e/financial-api.spec.ts:1:36
|
|
||||||
- tests/e2e/financial-ui.spec.ts:1:36
|
|
||||||
- tests/e2e/guest-home.spec.ts:1:36
|
|
||||||
- tests/e2e/helpers.ts:1:36
|
|
||||||
- tests/e2e/invite-tenant.spec.ts:1:36
|
|
||||||
- tests/e2e/landlord-dashboard.spec.ts:1:36
|
|
||||||
- tests/e2e/landlord-messages.spec.ts:1:36
|
|
||||||
- tests/e2e/landlord-onboarding.spec.ts:1:36
|
|
||||||
- tests/e2e/multi-property.spec.ts:1:36
|
|
||||||
- tests/e2e/onboarding.spec.ts:1:36
|
|
||||||
- tests/e2e/reminders.spec.ts:1:36
|
|
||||||
- tests/e2e/tenant-dashboard.spec.ts:1:36
|
|
||||||
|
|
||||||
### Secondary Issue: Implicit Any Types
|
## Feature Development
|
||||||
`TS7031: Binding element` errors for untyped parameters:
|
- **Complete Landlord Dashboard**: Flesh out all features under the `routes/landlord/` directory. This includes:
|
||||||
|
- Property management
|
||||||
|
- Tenant invitation and management (`islands/LandlordInviteTenant.tsx`)
|
||||||
|
- Messaging with tenants (`islands/LandlordMessageThreads.tsx`)
|
||||||
|
- Financial tracking and reporting
|
||||||
|
- **Complete Tenant Dashboard**: Finalize all features under the `routes/tenant/` directory. This includes:
|
||||||
|
- Viewing lease documents
|
||||||
|
- Tracking rent payments and financial obligations
|
||||||
|
- Messaging with landlords (`islands/TenantMessageThreads.tsx`)
|
||||||
|
- Managing settings (`islands/TenantSettings.tsx`)
|
||||||
|
- **Enhance User Onboarding**: Improve the onboarding flow for both new landlords and tenants in `routes/onboarding/`.
|
||||||
|
- **Develop User Profile Management**: Complete the user profile editing and management features in `routes/user-profile/`.
|
||||||
|
|
||||||
**Files with untyped `page` parameter:**
|
## Future Features & Refinements
|
||||||
- tests/e2e/documents.spec.ts (lines 4:61, 29:63)
|
- **AI/ML Feature Integration**: The advanced features found in the `islands/` directory need further development and integration into the user experience. This includes:
|
||||||
- tests/e2e/financial-ui.spec.ts (lines 4:60, 19:71)
|
- `BrainStudy.tsx`
|
||||||
- tests/e2e/guest-home.spec.ts (lines 4:26, 8:62, 24:58)
|
- `Quizzing.tsx`
|
||||||
- tests/e2e/tenant-dashboard.spec.ts (lines 4:68, 18:67, 31:58, 50:68, 70:62)
|
- `ImageGenerater.tsx`
|
||||||
|
- `VoiceRecorder.tsx`
|
||||||
**Files with untyped `request` parameter:**
|
- **Calendar Functionality**: Expand the calendar features in `routes/calendar/` and improve the `islands/FinancialCalendar.tsx` component to be more interactive and informative.
|
||||||
- tests/e2e/document-api.spec.ts (lines 4:75, 70:78)
|
- **Document Management**: Build out a robust document upload, storage, and sharing system for leases, notices, and other rental-related documents.
|
||||||
- tests/e2e/financial-api.spec.ts (lines 4:68, 19:59, 40:65, 76:66)
|
- **Reminders and Notifications**: Implement a system for sending automated reminders for rent payments, lease renewals, and other important events.
|
||||||
|
|
||||||
**Files with other untyped parameters:**
|
|
||||||
- tests/e2e/helpers.ts:7:8 - `({ now })` parameter
|
|
||||||
- tests/e2e/helpers.ts:82:31 - `({ id })` parameter
|
|
||||||
|
|
||||||
## Required Actions
|
|
||||||
|
|
||||||
1. **Install Playwright dependency:**
|
|
||||||
```bash
|
|
||||||
deno add jsr:@playwright/test
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Add proper TypeScript types for Playwright test parameters:**
|
|
||||||
- Import types from `@playwright/test`
|
|
||||||
- Type the `page`, `request`, `now`, and `id` parameters
|
|
||||||
|
|
||||||
3. **Example fix pattern:**
|
|
||||||
```typescript
|
|
||||||
import { Page, Request, TestInfo } from '@playwright/test';
|
|
||||||
|
|
||||||
test("example test", async ({ page }: { page: Page }) => {
|
|
||||||
// test code
|
|
||||||
});
|
|
||||||
|
|
||||||
test("api test", async ({ request }: { request: Request }) => {
|
|
||||||
// test code
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Run deno check again after fixes to verify all errors resolved:**
|
|
||||||
```bash
|
|
||||||
deno check 2>&1 | head -c 5000
|
|
||||||
```
|
|
||||||
|
|||||||
@ -45,7 +45,8 @@
|
|||||||
"gcs": "https://deno.land/x/google_cloud_storage/mod.ts",
|
"gcs": "https://deno.land/x/google_cloud_storage/mod.ts",
|
||||||
"google-cloud-storage": "npm:@google-cloud/storage",
|
"google-cloud-storage": "npm:@google-cloud/storage",
|
||||||
"gLog": "npm:google-logging-utils",
|
"gLog": "npm:google-logging-utils",
|
||||||
"cosmos": "npm:@azure/cosmos"
|
"cosmos": "npm:@azure/cosmos",
|
||||||
|
"@playwright/test": "npm:@playwright/test"
|
||||||
},
|
},
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"lib": [
|
"lib": [
|
||||||
|
|||||||
@ -61,46 +61,45 @@ export default define.page(function TenantSettingsPage({
|
|||||||
}: {
|
}: {
|
||||||
data: SettingsPageData;
|
data: SettingsPageData;
|
||||||
}) {
|
}) {
|
||||||
const { user, error } = data as SettingsPageData;
|
const { user, error } = data as SettingsPageData;
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return (
|
|
||||||
<div class="min-h-screen bg-gray-50 p-8">
|
|
||||||
<div class="max-w-4xl mx-auto">
|
|
||||||
<h1 class="text-3xl font-bold text-red-600 mb-4">Error</h1>
|
|
||||||
<p class="text-gray-700">{error}</p>
|
|
||||||
<div class="mt-6">
|
|
||||||
<a
|
|
||||||
href="/tenant/dashboard"
|
|
||||||
class="text-blue-600 hover:text-blue-500 font-medium"
|
|
||||||
>
|
|
||||||
Go to Dashboard
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (error) {
|
||||||
return (
|
return (
|
||||||
<div class="min-h-screen bg-gray-50">
|
<div class="min-h-screen bg-gray-50 p-8">
|
||||||
{/* Header */}
|
<div class="max-w-4xl mx-auto">
|
||||||
<div class="bg-white shadow">
|
<h1 class="text-3xl font-bold text-red-600 mb-4">Error</h1>
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<p class="text-gray-700">{error}</p>
|
||||||
<div class="py-6">
|
<div class="mt-6">
|
||||||
<h1 class="text-3xl font-bold text-gray-900">Tenant Settings</h1>
|
<a
|
||||||
<p class="mt-1 text-sm text-gray-500">
|
href="/tenant/dashboard"
|
||||||
Manage your notification and payment preferences.
|
class="text-blue-600 hover:text-blue-500 font-medium"
|
||||||
</p>
|
>
|
||||||
</div>
|
Go to Dashboard
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main Content */}
|
|
||||||
<div class="max-w-4xl mx-auto sm:px-6 lg:px-8 py-8">
|
|
||||||
<TenantSettings user={user} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
);
|
|
||||||
|
return (
|
||||||
|
<div class="min-h-screen bg-gray-50">
|
||||||
|
{/* Header */}
|
||||||
|
<div class="bg-white shadow">
|
||||||
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
<div class="py-6">
|
||||||
|
<h1 class="text-3xl font-bold text-gray-900">Tenant Settings</h1>
|
||||||
|
<p class="mt-1 text-sm text-gray-500">
|
||||||
|
Manage your notification and payment preferences.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Main Content */}
|
||||||
|
<div class="max-w-4xl mx-auto sm:px-6 lg:px-8 py-8">
|
||||||
|
<TenantSettings user={user} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { type APIRequestContext, expect, test } from "@playwright/test";
|
||||||
import { e2eHeaders } from "./helpers.ts";
|
import { e2eHeaders } from "./helpers.ts";
|
||||||
|
|
||||||
test("lease document API supports create, retrieve, and delete", async ({ request }) => {
|
test("lease document API supports create, retrieve, and delete", async ({ request }: { request: APIRequestContext }) => {
|
||||||
const createResponse = await request.post("/api/create/lease_document", {
|
const createResponse = await request.post("/api/create/lease_document", {
|
||||||
headers: {
|
headers: {
|
||||||
...e2eHeaders("landlord"),
|
...e2eHeaders("landlord"),
|
||||||
@ -67,7 +67,7 @@ test("lease document API supports create, retrieve, and delete", async ({ reques
|
|||||||
expect(afterData.document).toBeNull();
|
expect(afterData.document).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("lease document API returns main document and signing status", async ({ request }) => {
|
test("lease document API returns main document and signing status", async ({ request }: { request: APIRequestContext }) => {
|
||||||
const createResponse = await request.post("/api/create/lease_document", {
|
const createResponse = await request.post("/api/create/lease_document", {
|
||||||
headers: {
|
headers: {
|
||||||
...e2eHeaders("landlord"),
|
...e2eHeaders("landlord"),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, type Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("tenant can review and sign lease documents", async ({ page }) => {
|
test("tenant can review and sign lease documents", async ({ page }: { page: Page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
await useE2EUser(page, "tenant");
|
await useE2EUser(page, "tenant");
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ test("tenant can review and sign lease documents", async ({ page }) => {
|
|||||||
await expect(updatedRow).toContainText("Signed");
|
await expect(updatedRow).toContainText("Signed");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("landlord can review and sign lease documents", async ({ page }) => {
|
test("landlord can review and sign lease documents", async ({ page }: { page: Page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
await useE2EUser(page, "landlord");
|
await useE2EUser(page, "landlord");
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { type APIRequestContext, expect, test } from "@playwright/test";
|
||||||
import { e2eHeaders } from "./helpers.ts";
|
import { e2eHeaders } from "./helpers.ts";
|
||||||
|
|
||||||
test("tenant payment methods API returns default method", async ({ request }) => {
|
test("tenant payment methods API returns default method", async ({ request }: { request: APIRequestContext }) => {
|
||||||
const response = await request.get(
|
const response = await request.get(
|
||||||
"/api/retrieve/payment_methods?default_only=true",
|
"/api/retrieve/payment_methods?default_only=true",
|
||||||
{
|
{
|
||||||
@ -16,7 +16,7 @@ test("tenant payment methods API returns default method", async ({ request }) =>
|
|||||||
expect(data.payment_methods[0].id).toBe("e2e-pay-method-1");
|
expect(data.payment_methods[0].id).toBe("e2e-pay-method-1");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("tenant can create payment method via API", async ({ request }) => {
|
test("tenant can create payment method via API", async ({ request }: { request: APIRequestContext }) => {
|
||||||
const response = await request.post("/api/create/payment_method", {
|
const response = await request.post("/api/create/payment_method", {
|
||||||
headers: {
|
headers: {
|
||||||
...e2eHeaders("tenant"),
|
...e2eHeaders("tenant"),
|
||||||
@ -37,7 +37,7 @@ test("tenant can create payment method via API", async ({ request }) => {
|
|||||||
expect(data.payment_method.bank_name).toBe("Test Bank");
|
expect(data.payment_method.bank_name).toBe("Test Bank");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("tenant payment transaction API records history", async ({ request }) => {
|
test("tenant payment transaction API records history", async ({ request }: { request: APIRequestContext }) => {
|
||||||
const createResponse = await request.post(
|
const createResponse = await request.post(
|
||||||
"/api/create/payment_transaction",
|
"/api/create/payment_transaction",
|
||||||
{
|
{
|
||||||
@ -73,7 +73,7 @@ test("tenant payment transaction API records history", async ({ request }) => {
|
|||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("landlord dashboard API includes payment summary", async ({ request }) => {
|
test("landlord dashboard API includes payment summary", async ({ request }: { request: APIRequestContext }) => {
|
||||||
const response = await request.get("/api/retrieve/landlord_dashboard", {
|
const response = await request.get("/api/retrieve/landlord_dashboard", {
|
||||||
headers: e2eHeaders("landlord"),
|
headers: e2eHeaders("landlord"),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, type Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("tenant payment history surfaces late fees", async ({ page }) => {
|
test("tenant payment history surfaces late fees", async ({ page }: { page: Page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
await useE2EUser(page, "tenant");
|
await useE2EUser(page, "tenant");
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ test("tenant payment history surfaces late fees", async ({ page }) => {
|
|||||||
await expect(page.getByText(/late fees due/i)).toBeVisible();
|
await expect(page.getByText(/late fees due/i)).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("landlord rent collection highlights overdue payments", async ({ page }) => {
|
test("landlord rent collection highlights overdue payments", async ({ page }: { page: Page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
await useE2EUser(page, "landlord");
|
await useE2EUser(page, "landlord");
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, type Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage } from "./helpers.ts";
|
import { applyDeterministicPage } from "./helpers.ts";
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("guest landing shows primary calls to action", async ({ page }) => {
|
test("guest landing shows primary calls to action", async ({ page }: { page: Page }) => {
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
@ -21,7 +21,7 @@ test("guest landing shows primary calls to action", async ({ page }) => {
|
|||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("guest landing shows system ready banner", async ({ page }) => {
|
test("guest landing shows system ready banner", async ({ page }: { page: Page }) => {
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
|
|||||||
@ -4,7 +4,7 @@ const FIXED_TIME_MS = new Date("2024-01-01T00:00:00.000Z").getTime();
|
|||||||
|
|
||||||
export async function applyDeterministicPage(page: Page) {
|
export async function applyDeterministicPage(page: Page) {
|
||||||
await page.addInitScript(
|
await page.addInitScript(
|
||||||
({ now }) => {
|
({ now }: { now: number }) => {
|
||||||
Math.random = () => 0.42;
|
Math.random = () => 0.42;
|
||||||
|
|
||||||
const OriginalDate = Date;
|
const OriginalDate = Date;
|
||||||
@ -77,8 +77,8 @@ export async function useE2EUser(page: Page, userKey: string) {
|
|||||||
landlord: "e2e-landlord-1",
|
landlord: "e2e-landlord-1",
|
||||||
"landlord-onboarding": "e2e-landlord-setup-1",
|
"landlord-onboarding": "e2e-landlord-setup-1",
|
||||||
tenant: "e2e-tenant-1",
|
tenant: "e2e-tenant-1",
|
||||||
};
|
} as Record<string, string>;
|
||||||
const userId = userIdMap[userKey] ?? userKey;
|
const userId: string = userIdMap[userKey] ?? userKey;
|
||||||
await page.addInitScript(({ id }: { id: string }) => {
|
await page.addInitScript(({ id }: { id: string }) => {
|
||||||
(window as { __E2E_SKIP_ENCRYPTION__?: boolean }).__E2E_SKIP_ENCRYPTION__ =
|
(window as { __E2E_SKIP_ENCRYPTION__?: boolean }).__E2E_SKIP_ENCRYPTION__ =
|
||||||
true;
|
true;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { expect, test, Page } from "@playwright/test";
|
import { expect, Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, e2eHeaders, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, e2eHeaders, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("landlord can generate a tenant invite email", async ({ page }: { page: Page }) => {
|
test("landlord can generate a tenant invite email", async ({ page }: { page: Page }) => {
|
||||||
@ -102,4 +102,3 @@ test("tenant invite preview shows property details and actions", async ({ page }
|
|||||||
await expect(page.getByRole("button", { name: /decline/i })).toBeVisible();
|
await expect(page.getByRole("button", { name: /decline/i })).toBeVisible();
|
||||||
await expect(page.getByRole("link", { name: /cancel/i })).toBeVisible();
|
await expect(page.getByRole("link", { name: /cancel/i })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { expect, test, Page } from "@playwright/test";
|
import { expect, Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("landlord dashboard surfaces portfolio activity", async ({ page }: { page: Page }) => {
|
test("landlord dashboard surfaces portfolio activity", async ({ page }: { page: Page }) => {
|
||||||
@ -75,4 +75,3 @@ test("landlord can update maintenance status", async ({ page }: { page: Page })
|
|||||||
await expect(page).toHaveURL(/\/landlord\/maintenance/);
|
await expect(page).toHaveURL(/\/landlord\/maintenance/);
|
||||||
await expect(statusSelect).toHaveValue("in_progress");
|
await expect(statusSelect).toHaveValue("in_progress");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { expect, test, Page } from "@playwright/test";
|
import { expect, Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("landlord messages view paginates conversations", async ({ page }: { page: Page }) => {
|
test("landlord messages view paginates conversations", async ({ page }: { page: Page }) => {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { expect, test, Page } from "@playwright/test";
|
import { expect, Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("landlord profile setup advances to property details", async ({ page }: { page: Page }) => {
|
test("landlord profile setup advances to property details", async ({ page }: { page: Page }) => {
|
||||||
@ -49,4 +49,3 @@ test("property setup submits and lands on landlord dashboard", async ({ page }:
|
|||||||
await expect(page.getByRole("heading", { name: /landlord dashboard/i }))
|
await expect(page.getByRole("heading", { name: /landlord dashboard/i }))
|
||||||
.toBeVisible();
|
.toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { expect, test, Page } from "@playwright/test";
|
import { expect, Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("landlord sees multi-property portfolio overview", async ({ page }: { page: Page }) => {
|
test("landlord sees multi-property portfolio overview", async ({ page }: { page: Page }) => {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { expect, test, Page } from "@playwright/test";
|
import { expect, Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, e2eHeaders, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, e2eHeaders, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("tenant onboarding lets renters apply and reach dashboard", async ({ page }: { page: Page }) => {
|
test("tenant onboarding lets renters apply and reach dashboard", async ({ page }: { page: Page }) => {
|
||||||
@ -77,4 +77,3 @@ test("invite links highlight the selected rental on onboarding", async ({ page }
|
|||||||
await expect(page.getByText("Skyline Lofts")).toBeVisible();
|
await expect(page.getByText("Skyline Lofts")).toBeVisible();
|
||||||
await expect(page.getByLabel(/select a property/i)).toHaveCount(0);
|
await expect(page.getByLabel(/select a property/i)).toHaveCount(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { expect, test, Page } from "@playwright/test";
|
import { expect, Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("landlord can send reminder and tenant receives it", async ({ page }: { page: Page }) => {
|
test("landlord can send reminder and tenant receives it", async ({ page }: { page: Page }) => {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, type Page, test } from "@playwright/test";
|
||||||
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
import { applyDeterministicPage, useE2EUser } from "./helpers.ts";
|
||||||
|
|
||||||
test("tenant dashboard shows lease summary and activity", async ({ page }) => {
|
test("tenant dashboard shows lease summary and activity", async ({ page }: { page: Page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
await useE2EUser(page, "tenant");
|
await useE2EUser(page, "tenant");
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ test("tenant dashboard shows lease summary and activity", async ({ page }) => {
|
|||||||
await expect(page.getByRole("cell", { name: "ach" }).first()).toBeVisible();
|
await expect(page.getByRole("cell", { name: "ach" }).first()).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("tenant maintenance list includes active requests", async ({ page }) => {
|
test("tenant maintenance list includes active requests", async ({ page }: { page: Page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
await useE2EUser(page, "tenant");
|
await useE2EUser(page, "tenant");
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ test("tenant maintenance list includes active requests", async ({ page }) => {
|
|||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("tenant can submit a maintenance request", async ({ page }) => {
|
test("tenant can submit a maintenance request", async ({ page }: { page: Page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
await useE2EUser(page, "tenant");
|
await useE2EUser(page, "tenant");
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ test("tenant can submit a maintenance request", async ({ page }) => {
|
|||||||
await expect(page.getByText(/submitted successfully/i)).toBeVisible();
|
await expect(page.getByText(/submitted successfully/i)).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("tenant messages list shows landlord communication", async ({ page }) => {
|
test("tenant messages list shows landlord communication", async ({ page }: { page: Page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
await useE2EUser(page, "tenant");
|
await useE2EUser(page, "tenant");
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ test("tenant messages list shows landlord communication", async ({ page }) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test("tenant rent pay flow accepts payment method", async ({ page }) => {
|
test("tenant rent pay flow accepts payment method", async ({ page }: { page: Page }) => {
|
||||||
await applyDeterministicPage(page);
|
await applyDeterministicPage(page);
|
||||||
await useE2EUser(page, "tenant");
|
await useE2EUser(page, "tenant");
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user