82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
import { Page, Locator, expect } from '@playwright/test';
|
|
|
|
/**
|
|
* Page Object Model for Login/Sign page
|
|
* URL: /sign
|
|
*/
|
|
export class LoginPage {
|
|
readonly page: Page;
|
|
readonly emailInput: Locator;
|
|
readonly passwordInput: Locator;
|
|
readonly loginButton: Locator;
|
|
readonly registerTab: Locator;
|
|
readonly registerNameInput: Locator;
|
|
readonly registerEmailInput: Locator;
|
|
readonly registerPasswordInput: Locator;
|
|
readonly registerButton: Locator;
|
|
|
|
constructor(page: Page) {
|
|
this.page = page;
|
|
|
|
// Login form elements
|
|
this.emailInput = page.locator('input[name="email"], input[type="email"]').first();
|
|
this.passwordInput = page.locator('input[name="password"], input[type="password"]').first();
|
|
this.loginButton = page.locator('button:has-text("登入"), button:has-text("Login")').first();
|
|
|
|
// Register form elements
|
|
this.registerTab = page.locator('text=註冊, text=Register').first();
|
|
this.registerNameInput = page.locator('input[name="name"]');
|
|
this.registerEmailInput = page.locator('input[name="email"]').nth(1);
|
|
this.registerPasswordInput = page.locator('input[name="password"]').nth(1);
|
|
this.registerButton = page.locator('button:has-text("註冊"), button:has-text("Register")');
|
|
}
|
|
|
|
/**
|
|
* Navigate to the login page
|
|
*/
|
|
async goto() {
|
|
await this.page.goto('/sign');
|
|
}
|
|
|
|
/**
|
|
* Login with email and password
|
|
*/
|
|
async login(email: string, password: string) {
|
|
await this.emailInput.fill(email);
|
|
await this.passwordInput.fill(password);
|
|
await this.loginButton.click();
|
|
|
|
// Wait for navigation after login
|
|
await this.page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
/**
|
|
* Register a new account
|
|
*/
|
|
async register(name: string, email: string, password: string) {
|
|
await this.registerTab.click();
|
|
await this.registerNameInput.fill(name);
|
|
await this.registerEmailInput.fill(email);
|
|
await this.registerPasswordInput.fill(password);
|
|
await this.registerButton.click();
|
|
|
|
// Wait for navigation after registration
|
|
await this.page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
/**
|
|
* Check if login was successful by verifying user is redirected
|
|
*/
|
|
async verifyLoginSuccess() {
|
|
// After successful login, user should be redirected away from /sign page
|
|
await expect(this.page).not.toHaveURL(/\/sign/);
|
|
}
|
|
|
|
/**
|
|
* Check if login failed (still on sign page with error)
|
|
*/
|
|
async verifyLoginFailure() {
|
|
await expect(this.page).toHaveURL(/\/sign/);
|
|
}
|
|
}
|