From 439f4a213fcdcb94b1a83b3ec6298789e1a6ba7d Mon Sep 17 00:00:00 2001 From: pablodanswer Date: Sun, 15 Dec 2024 15:11:43 -0800 Subject: [PATCH] k --- web/playwright.config.ts | 45 ++++++------------- web/tests/e2e/auth.setup.ts | 38 ++++++++++++++++ web/tests/e2e/constants.js | 5 +++ .../core_flows/assistant_management.test.ts | 0 ...test.ts => search_settings_update.test.ts} | 8 ++-- web/tests/e2e/global-setup.ts | 44 ++++++++++++++++++ web/tests/e2e/user_auth.setup.ts | 40 +++++++++++++++++ web/tests/e2e/utils/auth.ts | 19 ++++++++ web/user_auth.json | 15 +++++++ 9 files changed, 179 insertions(+), 35 deletions(-) create mode 100644 web/tests/e2e/auth.setup.ts create mode 100644 web/tests/e2e/core_flows/assistant_management.test.ts rename web/tests/e2e/core_flows/{search_update.test.ts => search_settings_update.test.ts} (65%) create mode 100644 web/tests/e2e/global-setup.ts create mode 100644 web/tests/e2e/user_auth.setup.ts create mode 100644 web/tests/e2e/utils/auth.ts create mode 100644 web/user_auth.json diff --git a/web/playwright.config.ts b/web/playwright.config.ts index c8cfcdee664..0954b2e3b38 100644 --- a/web/playwright.config.ts +++ b/web/playwright.config.ts @@ -1,51 +1,32 @@ import { defineConfig, devices } from "@playwright/test"; +import path from "path"; export default defineConfig({ - workers: 1, // temporary change to see if single threaded testing stabilizes the tests - testDir: "./tests/e2e", // Folder for test files + workers: 1, + testDir: "./tests/e2e", reporter: "list", - // Configure paths for screenshots - // expect: { - // toMatchSnapshot: { - // threshold: 0.2, // Adjust the threshold for visual diffs - // }, - // }, - // reporter: [["html", { outputFolder: "test-results/output/report" }]], // HTML report location - // outputDir: "test-results/output/screenshots", // Set output folder for test artifacts + globalSetup: path.join(__dirname, "tests/e2e/global-setup.ts"), + use: { + baseURL: "http://localhost:3000", + trace: "on-first-retry", + }, projects: [ { - // dependency for admin workflows - name: "admin_setup", - testMatch: /.*\admin_auth\.setup\.ts/, - }, - { - // tests admin workflows - name: "chromium-admin", - grep: /@admin/, + name: "chromium", use: { ...devices["Desktop Chrome"], - // Use prepared auth state. - storageState: "admin_auth.json", }, - dependencies: ["admin_setup"], }, { - // tests core flows - name: "chromium-core-flows", - testMatch: /.*\/core_flows\/.*/, + name: "firefox", use: { - ...devices["Desktop Chrome"], - // Use prepared auth state. - storageState: "admin_auth.json", + ...devices["Desktop Firefox"], }, - dependencies: ["admin_setup"], }, { - // tests logged out / guest workflows - name: "chromium-guest", - grep: /@guest/, + name: "webkit", use: { - ...devices["Desktop Chrome"], + ...devices["Desktop Safari"], }, }, ], diff --git a/web/tests/e2e/auth.setup.ts b/web/tests/e2e/auth.setup.ts new file mode 100644 index 00000000000..c9c615327eb --- /dev/null +++ b/web/tests/e2e/auth.setup.ts @@ -0,0 +1,38 @@ +import { test as setup, expect } from "@playwright/test"; +import { loginAs } from "./utils/auth"; + +setup("create auth states", async ({ browser }) => { + // Setup admin auth + const adminContext = await browser.newContext(); + const adminPage = await adminContext.newPage(); + await loginAs(adminPage, "admin"); + await adminContext.storageState({ path: "admin_auth.json" }); + await adminContext.close(); + + // Setup user auth + const userContext = await browser.newContext(); + const userPage = await userContext.newPage(); + + // Login as admin to create user + await loginAs(userPage, "admin"); + await userPage.goto("http://localhost:3000/admin/indexing/status"); + await userPage.getByRole("button", { name: "Users" }).click(); + await userPage.getByRole("button", { name: "Invite Users" }).click(); + await userPage.locator("#emails").fill("user_user@test.com"); + await userPage.getByRole("button", { name: "Add!" }).click(); + + // Logout admin + await userPage.getByText("A", { exact: true }).click(); + await userPage.getByText("Log out").click(); + + // Create and login as new user + await userPage.goto("http://localhost:3000/auth/login"); + await userPage.getByRole("link", { name: "Create an account" }).click(); + await userPage.getByTestId("email").fill("user_user@test.com"); + await userPage.getByTestId("password").fill("test"); + await userPage.getByRole("button", { name: "Sign Up" }).click(); + await userPage.waitForURL("http://localhost:3000/chat"); + + await userContext.storageState({ path: "user_auth.json" }); + await userContext.close(); +}); diff --git a/web/tests/e2e/constants.js b/web/tests/e2e/constants.js index b33de05897e..667428e1805 100644 --- a/web/tests/e2e/constants.js +++ b/web/tests/e2e/constants.js @@ -2,3 +2,8 @@ export const TEST_CREDENTIALS = { email: "admin_user@test.com", password: "test", }; + +export const TEST_USER_CREDENTIALS = { + email: "basic_user@test.com", + password: "test", +}; diff --git a/web/tests/e2e/core_flows/assistant_management.test.ts b/web/tests/e2e/core_flows/assistant_management.test.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/web/tests/e2e/core_flows/search_update.test.ts b/web/tests/e2e/core_flows/search_settings_update.test.ts similarity index 65% rename from web/tests/e2e/core_flows/search_update.test.ts rename to web/tests/e2e/core_flows/search_settings_update.test.ts index d1739b3c914..e1fc343eb67 100644 --- a/web/tests/e2e/core_flows/search_update.test.ts +++ b/web/tests/e2e/core_flows/search_settings_update.test.ts @@ -1,13 +1,15 @@ import { test, expect } from "@playwright/test"; +import { loginAs } from "../utils/auth"; -test("test", async ({ page }) => { - await page.goto("http://localhost:3000/admin/configuration/search"); +test("update search settings", async ({ page }) => { + await loginAs(page, "admin"); + await page.goto("http://localhost:3000/admin/indexing/status"); + await page.getByRole("button", { name: "Search Settings" }).click(); await page.getByRole("button", { name: "Update Search Settings" }).click(); await page.getByRole("button", { name: "Continue" }).click(); await page.getByRole("button", { name: "Self-hosted" }).click(); await page.getByText("MixedBread XSmallFastest,").click(); await page.getByRole("button", { name: "Update Search" }).click(); - await page.waitForSelector("text=mixedbread-ai/mxbai-rerank-xsmall-v1"); await expect(page.locator("body")).toContainText( "mixedbread-ai/mxbai-rerank-xsmall-v1" ); diff --git a/web/tests/e2e/global-setup.ts b/web/tests/e2e/global-setup.ts new file mode 100644 index 00000000000..f69d7a0cf81 --- /dev/null +++ b/web/tests/e2e/global-setup.ts @@ -0,0 +1,44 @@ +import { chromium, FullConfig } from "@playwright/test"; +import { loginAs } from "./utils/auth"; + +async function globalSetup(config: FullConfig) { + const browser = await chromium.launch(); + + // Setup admin auth + const adminContext = await browser.newContext(); + const adminPage = await adminContext.newPage(); + await loginAs(adminPage, "admin"); + await adminContext.storageState({ path: "admin_auth.json" }); + await adminContext.close(); + + // Setup user auth + const userContext = await browser.newContext(); + const userPage = await userContext.newPage(); + + // Login as admin to create user + await loginAs(userPage, "admin"); + await userPage.goto("/admin/indexing/status"); + await userPage.getByRole("button", { name: "Users" }).click(); + await userPage.getByRole("button", { name: "Invite Users" }).click(); + await userPage.locator("#emails").fill("user_user@test.com"); + await userPage.getByRole("button", { name: "Add!" }).click(); + + // Logout admin + await userPage.getByText("A", { exact: true }).click(); + await userPage.getByText("Log out").click(); + + // Create and login as new user + await userPage.goto("/auth/login"); + await userPage.getByRole("link", { name: "Create an account" }).click(); + await userPage.getByTestId("email").fill("user_user@test.com"); + await userPage.getByTestId("password").fill("test"); + await userPage.getByRole("button", { name: "Sign Up" }).click(); + await userPage.waitForURL("/chat"); + + await userContext.storageState({ path: "user_auth.json" }); + await userContext.close(); + + await browser.close(); +} + +export default globalSetup; diff --git a/web/tests/e2e/user_auth.setup.ts b/web/tests/e2e/user_auth.setup.ts new file mode 100644 index 00000000000..48532590c4a --- /dev/null +++ b/web/tests/e2e/user_auth.setup.ts @@ -0,0 +1,40 @@ +import { test as setup, expect } from "@playwright/test"; +import { loginAs } from "./utils/auth"; + +setup("create test user", async ({ page, context }) => { + // Login as admin + await loginAs(page, "admin"); + + // Create test user + await page.goto("http://localhost:3000/admin/indexing/status"); + await page.getByRole("button", { name: "Users" }).click(); + await page.getByRole("button", { name: "Invite Users" }).click(); + await page.locator("#emails").click(); + await page.locator("#emails").fill("user_user@test.com"); + await page.getByRole("button", { name: "Add!" }).click(); + + // Logout + await page.getByText("A", { exact: true }).click(); + await page.getByText("Log out").click(); + + // Create account for the invited user + await page.goto("http://localhost:3000/auth/login"); + await page.getByRole("link", { name: "Create an account" }).click(); + await page.getByTestId("email").click(); + await page.waitForTimeout(500); + await page.getByTestId("email").fill("user_user@test.com"); + await page.waitForTimeout(500); + await page.getByTestId("password").click(); + await page.waitForTimeout(500); + await page.getByTestId("password").fill("test"); + await page.waitForTimeout(500); + await page.getByRole("button", { name: "Sign Up" }).click(); + await page.waitForTimeout(2000); + + // Verify successful account creation + await page.waitForURL("http://localhost:3000/chat"); + await expect(page).toHaveURL("http://localhost:3000/chat"); + + // Save authentication state + await context.storageState({ path: "user_auth.json" }); +}); diff --git a/web/tests/e2e/utils/auth.ts b/web/tests/e2e/utils/auth.ts new file mode 100644 index 00000000000..82f84f91cb7 --- /dev/null +++ b/web/tests/e2e/utils/auth.ts @@ -0,0 +1,19 @@ +import { Page } from "@playwright/test"; +import { TEST_CREDENTIALS, TEST_USER_CREDENTIALS } from "../constants"; + +export async function loginAs(page: Page, userType: "admin" | "user") { + const { email, password } = + userType === "admin" ? TEST_CREDENTIALS : TEST_USER_CREDENTIALS; + + await page.goto("http://localhost:3000/chat"); + + await page.waitForURL("http://localhost:3000/auth/login?next=%2Fchat"); + + await page.fill("#email", email); + await page.fill("#password", password); + + // Click the login button + await page.click('button[type="submit"]'); + + await page.waitForURL("http://localhost:3000/chat"); +} diff --git a/web/user_auth.json b/web/user_auth.json new file mode 100644 index 00000000000..e27ec60fa63 --- /dev/null +++ b/web/user_auth.json @@ -0,0 +1,15 @@ +{ + "cookies": [ + { + "name": "fastapiusersauth", + "value": "lbgX6spEvhdzvCE6uNugvMQE3AqtSW1JVEZb1hXF79A", + "domain": "localhost", + "path": "/", + "expires": 1734908599.292503, + "httpOnly": true, + "secure": false, + "sameSite": "Lax" + } + ], + "origins": [] +} \ No newline at end of file