diff --git a/example-apps/dashrate/public/dashrate-lite.html b/example-apps/dashrate/public/dashrate-lite.html new file mode 100644 index 0000000..36fc1b1 --- /dev/null +++ b/example-apps/dashrate/public/dashrate-lite.html @@ -0,0 +1,519 @@ + + + + + + + DashRate Lite + + + + + + +
+ + +
+
+
+
+

Resource

+

+
+ Open resource +
+ +
+ + + +
+ +
+
+ +
+

Recent reviews

+
+
+ +

+ Contract: +

+
+
+ + + + diff --git a/example-apps/dashrate/test/e2e/lite.spec.ts b/example-apps/dashrate/test/e2e/lite.spec.ts new file mode 100644 index 0000000..6b3e9d1 --- /dev/null +++ b/example-apps/dashrate/test/e2e/lite.spec.ts @@ -0,0 +1,98 @@ +import { test, expect } from "@playwright/test"; + +const LITE_URL = "/dashrate-lite.html"; + +test.describe("dashrate-lite (single-file companion)", () => { + test("connects to testnet and enables controls on load", async ({ page }) => { + await page.goto(LITE_URL); + + await expect(page.locator("#status")).toHaveText(/Connected to testnet/, { + timeout: 60_000, + }); + await expect(page.locator("#refresh-btn")).toBeEnabled({ + timeout: 60_000, + }); + await expect(page.locator("#rating-filter")).toBeEnabled(); + }); + + test("renders resource navigation, aggregate panel, and recent reviews", async ({ + page, + }) => { + await page.goto(LITE_URL); + await expect(page.locator("#status")).toHaveText(/Connected to testnet/, { + timeout: 60_000, + }); + + await expect( + page.getByRole("heading", { name: "Platform Introduction", level: 2 }), + ).toBeVisible(); + await expect(page.locator("#aggregate-result .summary-grid")).toBeVisible({ + timeout: 60_000, + }); + await expect(page.locator("#reviews-result")).toContainText( + /review|No reviews/i, + { timeout: 60_000 }, + ); + }); + + test("selecting a resource updates the detail view", async ({ page }) => { + await page.goto(LITE_URL); + await expect(page.locator("#status")).toHaveText(/Connected to testnet/, { + timeout: 60_000, + }); + + await page + .locator('nav[aria-label="Tutorial resources"] button') + .filter({ hasText: "Tokens" }) + .click(); + + await expect( + page.getByRole("heading", { name: "Tokens", level: 2 }), + ).toBeVisible(); + await expect(page.locator("#aggregate-result .summary-grid")).toBeVisible({ + timeout: 60_000, + }); + }); + + test("rating filter updates the review query view", async ({ page }) => { + await page.goto(LITE_URL); + await expect(page.locator("#status")).toHaveText(/Connected to testnet/, { + timeout: 60_000, + }); + + await page.locator("#rating-filter").selectOption("5"); + await expect( + page.getByRole("heading", { name: "5-star reviews", level: 2 }), + ).toBeVisible({ timeout: 60_000 }); + await expect(page.locator("#reviews-result")).toContainText( + /5-star review|No 5-star reviews/i, + { timeout: 60_000 }, + ); + }); + + test("refresh keeps the selected resource usable", async ({ page }) => { + await page.goto(LITE_URL); + await expect(page.locator("#status")).toHaveText(/Connected to testnet/, { + timeout: 60_000, + }); + + await page + .locator('nav[aria-label="Tutorial resources"] button') + .filter({ hasText: "Dashnote" }) + .click(); + await expect( + page.getByRole("heading", { name: "Dashnote", level: 2 }), + ).toBeVisible(); + + await page.locator("#refresh-btn").click(); + await expect(page.locator("#refresh-btn")).toBeEnabled({ + timeout: 60_000, + }); + await expect( + page.getByRole("heading", { name: "Dashnote", level: 2 }), + ).toBeVisible(); + await expect(page.locator("#aggregate-result .summary-grid")).toBeVisible({ + timeout: 60_000, + }); + }); +});