refactor(test): enhance page objects and use them in visitor-browse-journey
This commit is contained in:
@@ -1,95 +1,91 @@
|
|||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
|
import {
|
||||||
|
FrontendHomePage,
|
||||||
|
FrontendNewsPage,
|
||||||
|
FrontendProductPage,
|
||||||
|
FrontendContactPage
|
||||||
|
} from '../pages/frontend';
|
||||||
|
import { TestDataFactory } from '../fixtures/test-data-factory';
|
||||||
|
|
||||||
test.describe('访客浏览旅程 @journey @visitor', () => {
|
test.describe('访客浏览旅程 @journey @visitor', () => {
|
||||||
test('访客浏览首页并了解公司信息', async ({ page }) => {
|
let homePage: FrontendHomePage;
|
||||||
|
let newsPage: FrontendNewsPage;
|
||||||
|
let productPage: FrontendProductPage;
|
||||||
|
let contactPage: FrontendContactPage;
|
||||||
|
|
||||||
|
test.beforeEach(async ({ page }) => {
|
||||||
|
homePage = new FrontendHomePage(page);
|
||||||
|
newsPage = new FrontendNewsPage(page);
|
||||||
|
productPage = new FrontendProductPage(page);
|
||||||
|
contactPage = new FrontendContactPage(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('访客浏览首页并了解公司信息', async () => {
|
||||||
await test.step('步骤1: 访问首页', async () => {
|
await test.step('步骤1: 访问首页', async () => {
|
||||||
await page.goto('/');
|
await homePage.goto();
|
||||||
await expect(page).toHaveTitle(/四川睿新致远科技有限公司/);
|
await expect(homePage.page).toHaveTitle(/四川睿新致远科技有限公司/);
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤2: 查看Hero区域', async () => {
|
await test.step('步骤2: 查看Hero区域', async () => {
|
||||||
await expect(page.locator('h1')).toBeVisible();
|
await homePage.expectHeroVisible();
|
||||||
await expect(page.locator('text=专业')).toBeVisible();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤3: 滚动查看服务介绍', async () => {
|
await test.step('步骤3: 滚动查看服务介绍', async () => {
|
||||||
await page.locator('#services').scrollIntoViewIfNeeded();
|
await homePage.scrollToSection('services');
|
||||||
await expect(page.locator('#services')).toBeVisible();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤4: 查看产品展示', async () => {
|
await test.step('步骤4: 查看产品展示', async () => {
|
||||||
await page.locator('#products').scrollIntoViewIfNeeded();
|
await homePage.scrollToSection('products');
|
||||||
await expect(page.locator('#products')).toBeVisible();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤5: 查看最新资讯', async () => {
|
await test.step('步骤5: 查看最新资讯', async () => {
|
||||||
await page.locator('#news').scrollIntoViewIfNeeded();
|
await homePage.scrollToSection('news');
|
||||||
await expect(page.locator('#news')).toBeVisible();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('访客浏览新闻列表并查看详情', async ({ page }) => {
|
test('访客浏览新闻列表并查看详情', async () => {
|
||||||
await test.step('步骤1: 访问新闻列表页', async () => {
|
await test.step('步骤1: 访问新闻列表页', async () => {
|
||||||
await page.goto('/news');
|
await newsPage.goto();
|
||||||
await expect(page).toHaveURL(/\/news/);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤2: 查看新闻列表', async () => {
|
await test.step('步骤2: 查看新闻列表', async () => {
|
||||||
const newsCards = page.locator('article, [data-testid="news-card"]');
|
await newsPage.expectNewsListVisible();
|
||||||
const count = await newsCards.count();
|
|
||||||
expect(count).toBeGreaterThan(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤3: 点击第一条新闻', async () => {
|
await test.step('步骤3: 点击第一条新闻', async () => {
|
||||||
const firstNews = page.locator('article a, [data-testid="news-card"] a').first();
|
await newsPage.clickFirstNews();
|
||||||
if (await firstNews.count() > 0) {
|
await newsPage.expectNewsDetailVisible();
|
||||||
await firstNews.click();
|
|
||||||
await page.waitForLoadState('networkidle');
|
|
||||||
await expect(page.locator('h1')).toBeVisible();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('访客浏览产品并了解详情', async ({ page }) => {
|
test('访客浏览产品并了解详情', async () => {
|
||||||
await test.step('步骤1: 访问产品列表页', async () => {
|
await test.step('步骤1: 访问产品列表页', async () => {
|
||||||
await page.goto('/products');
|
await productPage.goto();
|
||||||
await expect(page).toHaveURL(/\/products/);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤2: 查看产品列表', async () => {
|
await test.step('步骤2: 查看产品列表', async () => {
|
||||||
const productCards = page.locator('article, [data-testid="product-card"]');
|
await productPage.expectProductListVisible();
|
||||||
const count = await productCards.count();
|
|
||||||
expect(count).toBeGreaterThan(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤3: 点击第一个产品', async () => {
|
await test.step('步骤3: 点击第一个产品', async () => {
|
||||||
const firstProduct = page.locator('article a, [data-testid="product-card"] a').first();
|
await productPage.clickFirstProduct();
|
||||||
if (await firstProduct.count() > 0) {
|
await productPage.expectProductDetailVisible();
|
||||||
await firstProduct.click();
|
|
||||||
await page.waitForLoadState('networkidle');
|
|
||||||
await expect(page.locator('h1')).toBeVisible();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('访客查看联系信息并提交表单', async ({ page }) => {
|
test('访客查看联系信息并提交表单', async () => {
|
||||||
|
const contactData = TestDataFactory.createContactForm();
|
||||||
|
|
||||||
await test.step('步骤1: 访问联系页面', async () => {
|
await test.step('步骤1: 访问联系页面', async () => {
|
||||||
await page.goto('/contact');
|
await contactPage.goto();
|
||||||
await expect(page).toHaveURL(/\/contact/);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤2: 查看联系信息', async () => {
|
await test.step('步骤2: 查看联系信息', async () => {
|
||||||
await expect(page.locator('text=电话')).toBeVisible();
|
await contactPage.expectContactInfoVisible();
|
||||||
await expect(page.locator('text=邮箱')).toBeVisible();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('步骤3: 填写联系表单', async () => {
|
await test.step('步骤3: 填写联系表单', async () => {
|
||||||
const form = page.locator('form');
|
await contactPage.fillForm(contactData);
|
||||||
if (await form.count() > 0) {
|
|
||||||
await page.fill('input[name="name"]', '测试用户');
|
|
||||||
await page.fill('input[name="email"]', 'test@example.com');
|
|
||||||
await page.fill('textarea[name="message"]', '这是一条测试留言');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,29 +1,53 @@
|
|||||||
import { Page, expect } from '@playwright/test';
|
import { Page, expect } from '@playwright/test';
|
||||||
|
|
||||||
export class FrontendNewsPage {
|
export class FrontendNewsPage {
|
||||||
constructor(private page: Page) {}
|
readonly page: Page;
|
||||||
|
|
||||||
|
constructor(page: Page) {
|
||||||
|
this.page = page;
|
||||||
|
}
|
||||||
|
|
||||||
async goto() {
|
async goto() {
|
||||||
await this.page.goto('/news');
|
await this.page.goto('/news');
|
||||||
await this.page.waitForLoadState('networkidle');
|
await this.page.waitForLoadState('domcontentloaded');
|
||||||
|
}
|
||||||
|
|
||||||
|
async expectNewsListVisible() {
|
||||||
|
const newsCards = this.page.locator('article, [data-testid="news-card"]');
|
||||||
|
await expect(newsCards.first()).toBeVisible({ timeout: 10000 });
|
||||||
|
const count = await newsCards.count();
|
||||||
|
expect(count).toBeGreaterThan(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
async clickFirstNews() {
|
||||||
|
const firstNews = this.page.locator('article a, [data-testid="news-card"] a').first();
|
||||||
|
if (await firstNews.count() > 0) {
|
||||||
|
await firstNews.click();
|
||||||
|
await this.page.waitForLoadState('domcontentloaded');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async expectNewsDetailVisible(expectedContent?: string) {
|
||||||
|
await expect(this.page.locator('h1')).toBeVisible();
|
||||||
|
if (expectedContent) {
|
||||||
|
await expect(this.page.locator(`text=${expectedContent}`)).toBeVisible();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async expectNewsVisible(title: string) {
|
async expectNewsVisible(title: string) {
|
||||||
const newsCard = this.page.locator(`text="${title}"`);
|
await this.goto();
|
||||||
|
const newsCard = this.page.locator(`article:has-text("${title}"), [data-testid="news-card"]:has-text("${title}")`);
|
||||||
await expect(newsCard).toBeVisible();
|
await expect(newsCard).toBeVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
async expectNewsNotVisible(title: string) {
|
async expectNewsNotVisible(title: string) {
|
||||||
const newsCard = this.page.locator(`text="${title}"`);
|
await this.goto();
|
||||||
|
const newsCard = this.page.locator(`article:has-text("${title}"), [data-testid="news-card"]:has-text("${title}")`);
|
||||||
await expect(newsCard).not.toBeVisible();
|
await expect(newsCard).not.toBeVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickNews(title: string) {
|
async clickNews(title: string) {
|
||||||
await this.page.locator(`text="${title}"`).click();
|
await this.page.locator(`text="${title}"`).click();
|
||||||
await this.page.waitForLoadState('networkidle');
|
await this.page.waitForLoadState('domcontentloaded');
|
||||||
}
|
|
||||||
|
|
||||||
async expectNewsDetailVisible(content: string) {
|
|
||||||
await expect(this.page.locator(`text=${content}`)).toBeVisible();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,55 @@
|
|||||||
import { Page, expect } from '@playwright/test';
|
import { Page, expect } from '@playwright/test';
|
||||||
|
|
||||||
export class FrontendProductPage {
|
export class FrontendProductPage {
|
||||||
constructor(private page: Page) {}
|
readonly page: Page;
|
||||||
|
|
||||||
|
constructor(page: Page) {
|
||||||
|
this.page = page;
|
||||||
|
}
|
||||||
|
|
||||||
async goto() {
|
async goto() {
|
||||||
await this.page.goto('/products');
|
await this.page.goto('/products');
|
||||||
await this.page.waitForLoadState('networkidle');
|
await this.page.waitForLoadState('domcontentloaded');
|
||||||
|
}
|
||||||
|
|
||||||
|
async expectProductListVisible() {
|
||||||
|
const productCards = this.page.locator('article, [data-testid="product-card"]');
|
||||||
|
await expect(productCards.first()).toBeVisible({ timeout: 10000 });
|
||||||
|
const count = await productCards.count();
|
||||||
|
expect(count).toBeGreaterThan(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
async clickFirstProduct() {
|
||||||
|
const firstProduct = this.page.locator('article a, [data-testid="product-card"] a').first();
|
||||||
|
if (await firstProduct.count() > 0) {
|
||||||
|
await firstProduct.click();
|
||||||
|
await this.page.waitForLoadState('domcontentloaded');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async expectProductDetailVisible() {
|
||||||
|
await expect(this.page.locator('h1')).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
async expectProductDetailsVisible() {
|
||||||
|
await expect(this.page.locator('h1')).toBeVisible();
|
||||||
|
await expect(this.page.locator('article, .product-details')).toBeVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
async expectProductVisible(title: string) {
|
async expectProductVisible(title: string) {
|
||||||
const productCard = this.page.locator(`text="${title}"`);
|
await this.goto();
|
||||||
|
const productCard = this.page.locator(`article:has-text("${title}"), [data-testid="product-card"]:has-text("${title}")`);
|
||||||
await expect(productCard).toBeVisible();
|
await expect(productCard).toBeVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async expectProductNotVisible(title: string) {
|
||||||
|
await this.goto();
|
||||||
|
const productCard = this.page.locator(`article:has-text("${title}"), [data-testid="product-card"]:has-text("${title}")`);
|
||||||
|
await expect(productCard).not.toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
async clickProduct(title: string) {
|
async clickProduct(title: string) {
|
||||||
await this.page.locator(`text="${title}"`).click();
|
await this.page.locator(`text="${title}"`).click();
|
||||||
await this.page.waitForLoadState('networkidle');
|
await this.page.waitForLoadState('domcontentloaded');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user