Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
116 lines
3.9 KiB
TypeScript
116 lines
3.9 KiB
TypeScript
/**
|
|
* Plugin Marketplace E2E Tests
|
|
*
|
|
* Tests the plugin marketplace admin pages:
|
|
* - Browse page at /plugins/marketplace
|
|
* - Detail page at /plugins/marketplace/{pluginId}
|
|
*
|
|
* These tests run against a mock marketplace server (port 4445) that serves
|
|
* canned plugin data. The proxy endpoints in the EmDash admin forward
|
|
* requests to the mock, so we're testing the full UI flow.
|
|
*/
|
|
|
|
import { test, expect } from "../fixtures";
|
|
|
|
// URL patterns (module scope for e18e/prefer-static-regex)
|
|
const PLUGIN_DETAIL_URL_PATTERN = /\/plugins\/marketplace\/seo-toolkit/;
|
|
const MARKETPLACE_BROWSE_URL_PATTERN = /\/plugins\/marketplace\/?$/;
|
|
|
|
test.describe("Plugin Marketplace", () => {
|
|
test.beforeEach(async ({ admin }) => {
|
|
await admin.devBypassAuth();
|
|
});
|
|
|
|
test.describe("Browse page", () => {
|
|
test("renders marketplace page with plugin cards", async ({ admin, page }) => {
|
|
await admin.goto("/plugins/marketplace");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
// Wait for at least one plugin card to appear (the mock serves SEO Toolkit)
|
|
await expect(page.getByText("SEO Toolkit")).toBeVisible({ timeout: 15000 });
|
|
});
|
|
|
|
test("plugin card shows name, author, version", async ({ admin, page }) => {
|
|
await admin.goto("/plugins/marketplace");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
// Wait for cards to load
|
|
await expect(page.getByText("SEO Toolkit")).toBeVisible({ timeout: 15000 });
|
|
|
|
// The card is a link element containing plugin info
|
|
const seoCard = page.locator("a", { hasText: "SEO Toolkit" }).first();
|
|
|
|
// Author
|
|
await expect(seoCard.getByText("Labs")).toBeVisible();
|
|
|
|
// Version
|
|
await expect(seoCard.getByText("v2.1.0")).toBeVisible();
|
|
});
|
|
|
|
test("search filters plugins by name", async ({ admin, page }) => {
|
|
await admin.goto("/plugins/marketplace");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
await expect(page.getByText("SEO Toolkit")).toBeVisible({ timeout: 15000 });
|
|
|
|
// Type in the search box
|
|
const searchInput = page.getByPlaceholder("Search plugins...");
|
|
await searchInput.fill("nonexistent-plugin-xyz");
|
|
|
|
// Wait for the debounced search to complete
|
|
await page.waitForTimeout(1000);
|
|
|
|
// No plugins should match
|
|
await expect(page.getByText("SEO Toolkit")).not.toBeVisible({ timeout: 5000 });
|
|
});
|
|
});
|
|
|
|
test.describe("Plugin detail page", () => {
|
|
test("navigates to detail page on card click", async ({ admin, page }) => {
|
|
await admin.goto("/plugins/marketplace");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
// Wait for cards
|
|
const seoCard = page.locator("a", { hasText: "SEO Toolkit" }).first();
|
|
await expect(seoCard).toBeVisible({ timeout: 15000 });
|
|
|
|
// Click the card
|
|
await seoCard.click();
|
|
|
|
// URL should include the plugin ID
|
|
await expect(page).toHaveURL(PLUGIN_DETAIL_URL_PATTERN, { timeout: 10000 });
|
|
});
|
|
|
|
test("detail page shows plugin info", async ({ admin, page }) => {
|
|
await admin.goto("/plugins/marketplace/seo-toolkit");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
// Plugin name in heading (use first() since sidebar may also have an h1)
|
|
await expect(page.locator("h1").first()).toContainText("SEO Toolkit", { timeout: 15000 });
|
|
|
|
// Author
|
|
await expect(page.getByText("EmDash Labs").first()).toBeVisible();
|
|
});
|
|
|
|
test("back link navigates to browse page", async ({ admin, page }) => {
|
|
await admin.goto("/plugins/marketplace/seo-toolkit");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
await expect(page.locator("h1").first()).toContainText("SEO Toolkit", { timeout: 15000 });
|
|
|
|
// Click the back link (look for any link going back to marketplace)
|
|
const backLink = page.locator("a", { hasText: "Marketplace" }).first();
|
|
await backLink.click();
|
|
|
|
// Should navigate back to browse page
|
|
await expect(page).toHaveURL(MARKETPLACE_BROWSE_URL_PATTERN, { timeout: 10000 });
|
|
});
|
|
});
|
|
});
|