-
Notifications
You must be signed in to change notification settings - Fork 44.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: generate simple auth tests (#8709)
- Loading branch information
Showing
12 changed files
with
237 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { test, expect } from "./fixtures"; | ||
|
||
test.describe("Authentication", () => { | ||
test("user can login successfully", async ({ page, loginPage, testUser }) => { | ||
await page.goto("/login"); // Make sure we're on the login page | ||
await loginPage.login(testUser.email, testUser.password); | ||
// expect to be redirected to the home page | ||
await expect(page).toHaveURL("/"); | ||
// expect to see the Monitor text | ||
await expect(page.getByText("Monitor")).toBeVisible(); | ||
}); | ||
|
||
test("user can logout successfully", async ({ | ||
page, | ||
loginPage, | ||
testUser, | ||
}) => { | ||
await page.goto("/login"); // Make sure we're on the login page | ||
await loginPage.login(testUser.email, testUser.password); | ||
|
||
// Expect to be on the home page | ||
await expect(page).toHaveURL("/"); | ||
// Click on the user menu | ||
await page.getByRole("button", { name: "CN" }).click(); | ||
// Click on the logout menu item | ||
await page.getByRole("menuitem", { name: "Log out" }).click(); | ||
// Expect to be redirected to the login page | ||
await expect(page).toHaveURL("/login"); | ||
}); | ||
|
||
test("login in, then out, then in again", async ({ | ||
page, | ||
loginPage, | ||
testUser, | ||
}) => { | ||
await page.goto("/login"); // Make sure we're on the login page | ||
await loginPage.login(testUser.email, testUser.password); | ||
await page.goto("/"); | ||
await page.getByRole("button", { name: "CN" }).click(); | ||
await page.getByRole("menuitem", { name: "Log out" }).click(); | ||
await expect(page).toHaveURL("/login"); | ||
await loginPage.login(testUser.email, testUser.password); | ||
await expect(page).toHaveURL("/"); | ||
await expect(page.getByText("Monitor")).toBeVisible(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { test as base } from "@playwright/test"; | ||
import { createTestUserFixture } from "./test-user.fixture"; | ||
import { createLoginPageFixture } from "./login-page.fixture"; | ||
import type { TestUser } from "./test-user.fixture"; | ||
import { LoginPage } from "../pages/login.page"; | ||
|
||
type Fixtures = { | ||
testUser: TestUser; | ||
loginPage: LoginPage; | ||
}; | ||
|
||
// Combine fixtures | ||
export const test = base.extend<Fixtures>({ | ||
testUser: createTestUserFixture, | ||
loginPage: createLoginPageFixture, | ||
}); | ||
|
||
export { expect } from "@playwright/test"; |
14 changes: 14 additions & 0 deletions
14
autogpt_platform/frontend/src/tests/fixtures/login-page.fixture.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
import { test as base } from "@playwright/test"; | ||
import { LoginPage } from "../pages/login.page"; | ||
|
||
export const loginPageFixture = base.extend<{ loginPage: LoginPage }>({ | ||
loginPage: async ({ page }, use) => { | ||
await use(new LoginPage(page)); | ||
}, | ||
}); | ||
|
||
// Export just the fixture function | ||
export const createLoginPageFixture = async ({ page }, use) => { | ||
await use(new LoginPage(page)); | ||
}; |
83 changes: 83 additions & 0 deletions
83
autogpt_platform/frontend/src/tests/fixtures/test-user.fixture.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
import { createClient, SupabaseClient } from "@supabase/supabase-js"; | ||
import { faker } from "@faker-js/faker"; | ||
|
||
export type TestUser = { | ||
email: string; | ||
password: string; | ||
id?: string; | ||
}; | ||
|
||
let supabase: SupabaseClient; | ||
|
||
function getSupabaseAdmin() { | ||
if (!supabase) { | ||
supabase = createClient( | ||
process.env.SUPABASE_URL!, | ||
process.env.SUPABASE_SERVICE_ROLE_KEY!, | ||
{ | ||
auth: { | ||
autoRefreshToken: false, | ||
persistSession: false, | ||
}, | ||
}, | ||
); | ||
} | ||
return supabase; | ||
} | ||
|
||
async function createTestUser(userData: TestUser): Promise<TestUser> { | ||
const supabase = getSupabaseAdmin(); | ||
|
||
const { data: authUser, error: authError } = await supabase.auth.signUp({ | ||
email: userData.email, | ||
password: userData.password, | ||
}); | ||
|
||
if (authError) { | ||
throw new Error(`Failed to create test user: ${authError.message}`); | ||
} | ||
|
||
return { | ||
...userData, | ||
id: authUser.user?.id, | ||
}; | ||
} | ||
|
||
async function deleteTestUser(userId: string) { | ||
const supabase = getSupabaseAdmin(); | ||
|
||
try { | ||
const { error } = await supabase.auth.admin.deleteUser(userId); | ||
|
||
if (error) { | ||
console.warn(`Warning: Failed to delete test user: ${error.message}`); | ||
} | ||
} catch (error) { | ||
console.warn( | ||
`Warning: Error during user cleanup: ${(error as Error).message}`, | ||
); | ||
} | ||
} | ||
|
||
function generateUserData(): TestUser { | ||
return { | ||
email: `test.${faker.string.uuid()}@example.com`, | ||
password: faker.internet.password({ length: 12 }), | ||
}; | ||
} | ||
|
||
// Export just the fixture function | ||
export const createTestUserFixture = async ({}, use) => { | ||
let user: TestUser | null = null; | ||
|
||
try { | ||
const userData = generateUserData(); | ||
user = await createTestUser(userData); | ||
await use(user); | ||
} finally { | ||
if (user?.id) { | ||
await deleteTestUser(user.id); | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { Page } from "@playwright/test"; | ||
|
||
export class LoginPage { | ||
constructor(private page: Page) {} | ||
|
||
async login(email: string, password: string) { | ||
console.log("Attempting login with:", { email, password }); // Debug log | ||
|
||
// Fill email | ||
const emailInput = this.page.getByPlaceholder("[email protected]"); | ||
await emailInput.waitFor({ state: "visible" }); | ||
await emailInput.fill(email); | ||
|
||
// Fill password | ||
const passwordInput = this.page.getByPlaceholder("password"); | ||
await passwordInput.waitFor({ state: "visible" }); | ||
await passwordInput.fill(password); | ||
|
||
// Check terms | ||
const termsCheckbox = this.page.getByLabel("I agree to the Terms of Use"); | ||
await termsCheckbox.waitFor({ state: "visible" }); | ||
await termsCheckbox.click(); | ||
|
||
// TODO: This is a workaround to wait for the page to load after filling the email and password | ||
const emailInput2 = this.page.getByPlaceholder("[email protected]"); | ||
await emailInput2.waitFor({ state: "visible" }); | ||
await emailInput2.fill(email); | ||
|
||
// Fill password | ||
const passwordInput2 = this.page.getByPlaceholder("password"); | ||
await passwordInput2.waitFor({ state: "visible" }); | ||
await passwordInput2.fill(password); | ||
|
||
// Wait for the button to be ready | ||
const loginButton = this.page.getByRole("button", { name: "Log in" }); | ||
await loginButton.waitFor({ state: "visible" }); | ||
|
||
// Start waiting for navigation before clicking | ||
const navigationPromise = this.page.waitForURL("/", { timeout: 60000 }); | ||
|
||
console.log("About to click login button"); // Debug log | ||
await loginButton.click(); | ||
|
||
console.log("Waiting for navigation"); // Debug log | ||
await navigationPromise; | ||
|
||
console.log("Navigation complete, waiting for network idle"); // Debug log | ||
await this.page.waitForLoadState("networkidle", { timeout: 60000 }); | ||
console.log("Login process complete"); // Debug log | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { faker } from "@faker-js/faker"; | ||
|
||
export function generateUser() { | ||
return { | ||
email: faker.internet.email(), | ||
password: faker.internet.password(), | ||
name: faker.person.fullName(), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters