feat: refactor conversations page into a workbench layout and implement workspace switching
- Migrate ConversationsPage to use ConversationWorkbench component. - Create WorkbenchLayout to handle authentication and layout for workbench. - Add WorkbenchPage to render ConversationWorkbench. - Implement WorkspaceSwitcher for switching between dashboard and workbench. - Update AuthProvider to manage authentication for both dashboard and workbench routes. - Enhance WorkbenchHeader with user menu and workspace switcher. - Add tests for workspace switcher and auth provider functionality. - Update translations for workspace labels in English and Chinese. - Exclude e2e tests from TypeScript compilation.
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
import { mkdirSync } from "node:fs";
|
||||
import { test, expect, type Page } from "@playwright/test";
|
||||
|
||||
const baseUrl = process.env.E2E_BASE_URL ?? "http://localhost:3000";
|
||||
const username = process.env.E2E_USERNAME ?? "admin";
|
||||
const password = process.env.E2E_PASSWORD ?? "";
|
||||
const reportDir =
|
||||
process.env.E2E_REPORT_DIR ??
|
||||
"../docs/superpowers/test-reports/2026-06-13-support-workbench";
|
||||
|
||||
mkdirSync(reportDir, { recursive: true });
|
||||
|
||||
test.use({
|
||||
launchOptions: {
|
||||
channel: "chrome",
|
||||
},
|
||||
});
|
||||
|
||||
async function screenshot(page: Page, name: string) {
|
||||
await page.screenshot({
|
||||
path: `${reportDir}/${name}.png`,
|
||||
fullPage: true,
|
||||
});
|
||||
}
|
||||
|
||||
async function login(page: Page) {
|
||||
await page.goto(`${baseUrl}/workbench/`);
|
||||
await expect(page).toHaveURL(/\/dashboard\/login/);
|
||||
await screenshot(page, "01-login-redirect");
|
||||
|
||||
await page.locator("#username").fill(username);
|
||||
await page.locator("#password").fill(password);
|
||||
await screenshot(page, "02-login-filled");
|
||||
|
||||
const loginResponsePromise = page.waitForResponse(
|
||||
(response) =>
|
||||
response.url().includes("/api/auth/login") && response.status() === 200,
|
||||
{ timeout: 15000 },
|
||||
);
|
||||
await page.locator('form button[type="submit"]').click();
|
||||
const loginResponse = await loginResponsePromise;
|
||||
console.log("login response", loginResponse.status(), loginResponse.url());
|
||||
|
||||
await page.waitForURL((url) => !url.pathname.startsWith("/dashboard/login"), {
|
||||
timeout: 15000,
|
||||
});
|
||||
await expect
|
||||
.poll(() => page.evaluate(() => Boolean(window.localStorage.getItem("agent-desk-session"))))
|
||||
.toBe(true);
|
||||
}
|
||||
|
||||
test.describe("support workbench", () => {
|
||||
test("logs in and switches between workbench and dashboard", async ({ page }) => {
|
||||
const runtimeErrors: string[] = [];
|
||||
page.on("pageerror", (error) => {
|
||||
runtimeErrors.push(error.stack || error.message);
|
||||
});
|
||||
page.on("console", (message) => {
|
||||
if (message.type() === "error") {
|
||||
runtimeErrors.push(message.text());
|
||||
}
|
||||
});
|
||||
|
||||
await login(page);
|
||||
await page.goto(`${baseUrl}/workbench/`);
|
||||
await page.waitForLoadState("networkidle");
|
||||
await screenshot(page, "03-workbench-initial");
|
||||
|
||||
await expect(page.getByText(/客服工作台|Support Workbench/).first()).toBeVisible();
|
||||
await page.getByRole("button", { name: /贝壳AGENT|Shell Agent/i }).first().click();
|
||||
await expect(page.getByText(/切换工作区|Switch workspace/)).toBeVisible();
|
||||
await expect(page.getByRole("menuitem", { name: /管理后台|Admin Dashboard/ })).toBeVisible();
|
||||
await page.waitForTimeout(300);
|
||||
await screenshot(page, "04-workbench-switcher-open");
|
||||
|
||||
await page.getByRole("menuitem", { name: /管理后台|Admin Dashboard/ }).click();
|
||||
await page.waitForURL(/\/dashboard\/?$/, { timeout: 15000 });
|
||||
await page.waitForLoadState("networkidle");
|
||||
await screenshot(page, "05-dashboard-after-switch");
|
||||
await expect(page.getByText(/管理后台|Admin Dashboard/).first()).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: /贝壳AGENT|Shell Agent/i }).first().click();
|
||||
await expect(page.getByRole("menuitem", { name: /客服工作台|Support Workbench/ })).toBeVisible();
|
||||
await page.waitForTimeout(300);
|
||||
await screenshot(page, "06-dashboard-switcher-open");
|
||||
await page.getByRole("menuitem", { name: /客服工作台|Support Workbench/ }).click();
|
||||
await page.waitForURL(/\/workbench\/?$/, { timeout: 15000 });
|
||||
await page.waitForLoadState("networkidle");
|
||||
await screenshot(page, "07-workbench-after-return");
|
||||
await expect(page.getByText(/客服工作台|Support Workbench/).first()).toBeVisible();
|
||||
|
||||
expect(runtimeErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user