first commit
This commit is contained in:
58
pages/BasePage.ts
Normal file
58
pages/BasePage.ts
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 页面基类
|
||||
* 提供所有页面共享的方法和属性
|
||||
*/
|
||||
|
||||
import { Page, expect } from '@playwright/test';
|
||||
import { TestConfig } from '../config/test.config';
|
||||
|
||||
export class BasePage {
|
||||
protected page: Page;
|
||||
protected config = TestConfig;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待页面稳定
|
||||
*/
|
||||
async waitForPageStable(timeout: number = this.config.waits.pageStable): Promise<void> {
|
||||
console.log(`等待 ${timeout / 1000} 秒让页面稳定...`);
|
||||
await this.page.waitForTimeout(timeout);
|
||||
console.log('页面已稳定,继续下一步');
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航到指定URL
|
||||
*/
|
||||
async goto(url: string): Promise<void> {
|
||||
await this.page.goto(url, { timeout: this.config.timeouts.navigation });
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击元素
|
||||
*/
|
||||
async click(selector: string): Promise<void> {
|
||||
await this.page.click(selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充输入框
|
||||
*/
|
||||
async fill(selector: string, text: string): Promise<void> {
|
||||
await this.page.fill(selector, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查元素是否可见
|
||||
*/
|
||||
async isVisible(selector: string, timeout?: number): Promise<boolean> {
|
||||
try {
|
||||
await expect(this.page.locator(selector)).toBeVisible({ timeout });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
pages/DreamiExplorePage.ts
Normal file
31
pages/DreamiExplorePage.ts
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* DreamiExplore 页面对象
|
||||
* 封装 DreamiExplore 相关的操作
|
||||
*/
|
||||
|
||||
import { Page, expect } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
|
||||
export class DreamiExplorePage extends BasePage {
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入 DreamiExplore
|
||||
*/
|
||||
async enterDreamiExplore(): Promise<void> {
|
||||
await this.page.getByRole('link').filter({ hasText: 'DreamiExplore Everything' }).click();
|
||||
await expect(this.page.getByRole('heading', { name: 'Hello, Admin' })).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试聊天功能
|
||||
*/
|
||||
async testChatFunction(message: string = 'hello'): Promise<void> {
|
||||
await this.page.getByRole('textbox').click();
|
||||
await this.page.getByRole('textbox').fill(message);
|
||||
await this.page.getByRole('button', { name: 'send' }).click();
|
||||
await expect(this.page.getByRole('button', { name: '复制' })).toBeVisible({ timeout: 10000 });
|
||||
}
|
||||
}
|
||||
229
pages/EssayWritingPage.ts
Normal file
229
pages/EssayWritingPage.ts
Normal file
@ -0,0 +1,229 @@
|
||||
/**
|
||||
* Essay Writing 页面对象
|
||||
* 封装文书写作相关的所有操作
|
||||
*/
|
||||
|
||||
import { Page, expect } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
|
||||
export class EssayWritingPage extends BasePage {
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入 Essay Writing
|
||||
*/
|
||||
async enterEssayWriting(): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'documents Essay Writing' }).first().click();
|
||||
await expect(this.page.getByText('Notes')).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加材料
|
||||
*/
|
||||
async addMaterial(title: string, content: string, expectedButtonText: string): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'Add Material' }).click();
|
||||
await this.page.getByRole('menuitem', { name: 'Manual Add' }).click();
|
||||
await expect(
|
||||
this.page.getByText('ClassificationGeneralGeneralAcademic Interests and AchievementsInternship and')
|
||||
).toBeVisible();
|
||||
|
||||
await this.page.getByRole('textbox', { name: 'Title' }).click();
|
||||
await this.page.getByRole('textbox', { name: 'Title' }).fill(title);
|
||||
await this.page.getByRole('paragraph').filter({ hasText: /^$/ }).click();
|
||||
await this.page.locator('.tiptap').fill(content);
|
||||
await this.page.getByRole('button', { name: 'icon Get Suggestions' }).click();
|
||||
await expect(this.page.getByRole('heading', { name: 'More Suggestions' })).toBeVisible();
|
||||
await this.page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await expect(this.page.getByRole('button', { name: expectedButtonText })).toBeVisible({
|
||||
timeout: 15000
|
||||
});
|
||||
|
||||
await this.waitForPageStable(this.config.waits.shortWait);
|
||||
}
|
||||
|
||||
/**
|
||||
* 探索 Essay Idea
|
||||
*/
|
||||
async exploreEssayIdea(): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'icon Explore Essay Idea' }).click();
|
||||
await expect(this.page.getByRole('heading', { name: 'Select an essay prompt or' })).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载 Recommendation
|
||||
*/
|
||||
async loadRecommendation(): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'icon Recommendation' }).click();
|
||||
await this.page.waitForTimeout(10000);
|
||||
console.log('等待 Recommendation 加载完成...');
|
||||
await expect(this.page.getByRole('heading', { name: 'Recommendation Material' })).toBeVisible({
|
||||
timeout: this.config.timeouts.grammarCheck
|
||||
});
|
||||
console.log('Recommendation Material 已出现');
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 Essay Idea
|
||||
*/
|
||||
async generateEssayIdea(): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'icon Generate Essay Idea' }).click();
|
||||
await this.page.getByRole('button', { name: 'Generate' }).click();
|
||||
await expect(this.page.getByRole('heading', { name: 'Essay Idea' })).toBeVisible({
|
||||
timeout: this.config.timeouts.aiGeneration
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 Essay
|
||||
*/
|
||||
async generateEssay(): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'icon Generate Essay' }).click();
|
||||
await this.page.getByRole('button', { name: 'Generate' }).click();
|
||||
|
||||
console.log('等待 Essay 生成完成...');
|
||||
const loadingMessage = this.page.getByText(/正在生成文书,预计需要30秒,请耐心等待/i);
|
||||
|
||||
console.log('等待加载消息出现...');
|
||||
await loadingMessage.waitFor({ state: 'visible', timeout: 10000 });
|
||||
console.log('加载消息已出现,文书正在生成中...');
|
||||
|
||||
await loadingMessage.waitFor({ state: 'hidden', timeout: this.config.timeouts.longAiGeneration });
|
||||
console.log('Essay 生成完成,加载消息已消失');
|
||||
|
||||
await this.waitForPageStable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 语法检查
|
||||
*/
|
||||
async performGrammarCheck(): Promise<void> {
|
||||
await this.page.getByRole('img', { name: 'trigger' }).first().click();
|
||||
await this.page.getByRole('button', { name: 'Start Grammar Check' }).click();
|
||||
console.log('等待 Grammar Check 加载完成...');
|
||||
await expect(this.page.getByRole('heading', { name: 'suggestions' })).toBeVisible({
|
||||
timeout: this.config.timeouts.grammarCheck
|
||||
});
|
||||
console.log('suggestions 已出现');
|
||||
await expect(this.page.getByLabel('suggestions')).toBeVisible({ timeout: 30000 });
|
||||
}
|
||||
|
||||
/**
|
||||
* 查重检查
|
||||
*/
|
||||
async performPlagiarismCheck(): Promise<void> {
|
||||
await this.page.getByRole('img', { name: 'trigger' }).nth(1).click();
|
||||
await this.page.getByRole('button', { name: 'Start Plagiarism Check' }).click();
|
||||
console.log('等待 Plagiarism Check 加载完成...');
|
||||
await expect(this.page.getByRole('button', { name: 'Re-check' })).toBeVisible({
|
||||
timeout: this.config.timeouts.plagiarismCheck
|
||||
});
|
||||
console.log('Re-check 已出现');
|
||||
}
|
||||
|
||||
/**
|
||||
* AI检测
|
||||
*/
|
||||
async performAIDetection(): Promise<void> {
|
||||
await this.page.getByRole('img', { name: 'trigger' }).nth(2).click();
|
||||
await this.page.getByRole('button', { name: 'Start AI Detection' }).click();
|
||||
console.log('等待 AI Detection 加载完成...');
|
||||
await expect(this.page.getByRole('heading', { name: 'GPTZero Premium' })).toBeVisible({
|
||||
timeout: this.config.timeouts.aiDetection
|
||||
});
|
||||
console.log('GPTZero Premium 已出现');
|
||||
}
|
||||
|
||||
/**
|
||||
* 人性化处理
|
||||
*/
|
||||
async performHumanize(): Promise<void> {
|
||||
await this.page.getByRole('img', { name: 'trigger' }).nth(3).click();
|
||||
await this.page.getByRole('button', { name: 'Start Humanize' }).click();
|
||||
console.log('等待 Humanize 加载完成...');
|
||||
await expect(this.page.getByText('Accept all')).toBeVisible({
|
||||
timeout: this.config.timeouts.humanize
|
||||
});
|
||||
console.log('Accept all 已出现');
|
||||
}
|
||||
|
||||
/**
|
||||
* 润色
|
||||
*/
|
||||
async performPolish(): Promise<void> {
|
||||
await this.page.getByRole('img', { name: 'trigger' }).nth(4).click();
|
||||
await this.page.getByRole('button', { name: 'Start Polish' }).click();
|
||||
console.log('等待 Polish 加载完成...');
|
||||
await expect(this.page.getByText('All Suggestions')).toBeVisible({
|
||||
timeout: this.config.timeouts.polish
|
||||
});
|
||||
console.log('All Suggestions 已出现');
|
||||
}
|
||||
|
||||
/**
|
||||
* 评分
|
||||
*/
|
||||
async performGetRated(): Promise<void> {
|
||||
await this.page.getByRole('img', { name: 'trigger' }).nth(5).click();
|
||||
await this.page.getByRole('button', { name: 'Get Rated' }).click();
|
||||
console.log('等待 Get Rated 加载完成...');
|
||||
await expect(this.page.getByRole('heading', { name: 'Your essay rating is:' })).toBeVisible({
|
||||
timeout: this.config.timeouts.rated
|
||||
});
|
||||
console.log('Your essay rating is: 已出现');
|
||||
}
|
||||
|
||||
/**
|
||||
* Improvement 检查
|
||||
*/
|
||||
async performImprovementCheck(): Promise<void> {
|
||||
await this.page.getByRole('tab', { name: 'Improvement' }).click();
|
||||
console.log('等待 Improvement 加载完成...');
|
||||
await expect(this.page.getByText('Accept all')).toBeVisible({
|
||||
timeout: this.config.timeouts.improvement
|
||||
});
|
||||
console.log('Accept all 已出现');
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回 Essay Writing (从其他页面)
|
||||
*/
|
||||
async returnToEssayWriting(): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'Essay Writing' }).click();
|
||||
await expect(this.page.getByRole('button', { name: 'icon Explore Essay Idea' })).toBeVisible({
|
||||
timeout: 15000
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 Outline
|
||||
*/
|
||||
async generateOutline(): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'icon Generate Outline First' }).click();
|
||||
await this.page.getByRole('button', { name: 'Generate' }).click();
|
||||
console.log('等待 Outline 生成...');
|
||||
await expect(this.page.getByRole('heading', { name: 'Untitled Document' })).toBeVisible({
|
||||
timeout: this.config.timeouts.aiGeneration
|
||||
});
|
||||
console.log('Outline 生成完成');
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 Draft
|
||||
*/
|
||||
async generateDraft(level: string, length: string): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'icon Generate Draft' }).click();
|
||||
await this.page.getByRole('button', { name: level }).click();
|
||||
await this.page.getByPlaceholder('Enter the expected length...').click();
|
||||
await this.page.getByPlaceholder('Enter the expected length...').fill(length);
|
||||
await this.page.getByRole('button', { name: 'Generate' }).click();
|
||||
|
||||
console.log('等待 Draft 生成完成...');
|
||||
const loadingMessage = this.page.getByText(/正在生成文书,预计需要30秒,请耐心等待/i);
|
||||
|
||||
console.log('等待加载消息出现...');
|
||||
await loadingMessage.waitFor({ state: 'visible', timeout: 10000 });
|
||||
console.log('加载消息已出现,文书正在生成中...');
|
||||
}
|
||||
}
|
||||
50
pages/LoginPage.ts
Normal file
50
pages/LoginPage.ts
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 登录页面对象
|
||||
* 封装登录相关的操作
|
||||
*/
|
||||
|
||||
import { Page, expect } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
|
||||
export class LoginPage extends BasePage {
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问首页
|
||||
*/
|
||||
async visitHomePage(): Promise<void> {
|
||||
await this.goto(this.config.env.baseUrl);
|
||||
await expect(this.page.getByRole('button', { name: 'Log in' })).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击登录按钮
|
||||
*/
|
||||
async clickLoginButton(): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'Log in' }).click();
|
||||
await expect(this.page.getByRole('textbox', { name: 'Email Address' })).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* 输入登录凭证并登录
|
||||
*/
|
||||
async login(email: string, password: string): Promise<void> {
|
||||
await this.page.getByRole('textbox', { name: 'Email Address' }).click();
|
||||
await this.page.getByRole('textbox', { name: 'Email Address' }).fill(email);
|
||||
await this.page.getByRole('textbox', { name: 'Psssword' }).click();
|
||||
await this.page.getByRole('textbox', { name: 'Psssword' }).fill(password);
|
||||
await this.page.getByRole('button', { name: 'Log in' }).click();
|
||||
await expect(this.page.getByRole('link').filter({ hasText: '学生工作台' })).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* 完整登录流程
|
||||
*/
|
||||
async performLogin(): Promise<void> {
|
||||
await this.visitHomePage();
|
||||
await this.clickLoginButton();
|
||||
await this.login(this.config.credentials.email, this.config.credentials.password);
|
||||
}
|
||||
}
|
||||
64
pages/StudentPage.ts
Normal file
64
pages/StudentPage.ts
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 学生工作台页面对象
|
||||
* 封装学生管理相关的操作
|
||||
*/
|
||||
|
||||
import { Page, expect } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
|
||||
export interface StudentData {
|
||||
name: string;
|
||||
branchText: RegExp;
|
||||
branchValue: RegExp;
|
||||
counselorEmail: RegExp;
|
||||
contractCategory: string;
|
||||
contractName: string;
|
||||
}
|
||||
|
||||
export class StudentPage extends BasePage {
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回学生工作台
|
||||
*/
|
||||
async goToStudentWorkbench(): Promise<void> {
|
||||
await this.page.getByRole('link').filter({ hasText: '学生工作台' }).click();
|
||||
await expect(this.page.getByText('Student Name')).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新学生
|
||||
*/
|
||||
async createNewStudent(studentData: StudentData): Promise<void> {
|
||||
await this.page.getByRole('button', { name: 'New Student' }).click();
|
||||
|
||||
// 填写学生名称
|
||||
await this.page.getByRole('textbox', { name: 'Name *', exact: true }).click();
|
||||
await this.page.getByRole('textbox', { name: 'Name *', exact: true }).fill(studentData.name);
|
||||
|
||||
// 选择分公司
|
||||
await this.page.locator('div').filter({ hasText: studentData.branchText }).nth(2).click();
|
||||
await this.page.locator('div').filter({ hasText: studentData.branchValue }).nth(1).click();
|
||||
|
||||
// 选择顾问
|
||||
await this.page.getByText('Select counselor').click();
|
||||
await this.page.locator('div').filter({ hasText: studentData.counselorEmail }).nth(1).click();
|
||||
|
||||
// 点击日期选择器关闭按钮
|
||||
await this.page.locator('svg').nth(5).click();
|
||||
|
||||
// 填写合同信息
|
||||
await this.page.getByRole('textbox', { name: 'Contract Category *' }).click();
|
||||
await this.page.getByRole('textbox', { name: 'Contract Category *' }).fill(studentData.contractCategory);
|
||||
await this.page.getByRole('textbox', { name: 'Contract Name *' }).click();
|
||||
await this.page.getByRole('textbox', { name: 'Contract Name *' }).fill(studentData.contractName);
|
||||
|
||||
// 确认创建
|
||||
await this.page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
// 验证学生创建成功
|
||||
await expect(this.page.getByText(studentData.name).first()).toBeVisible();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user