diff --git a/e2e/journeys/user-auth-journey.spec.ts b/e2e/journeys/user-auth-journey.spec.ts new file mode 100644 index 0000000..423ffad --- /dev/null +++ b/e2e/journeys/user-auth-journey.spec.ts @@ -0,0 +1,75 @@ +import { test, expect } from '@playwright/test'; +import { testFixtures } from '../fixtures/test-data'; + +test.describe('用户认证旅程 @journey @auth', () => { + test('管理员成功登录流程', async ({ page }) => { + await test.step('步骤1: 访问登录页面', async () => { + await page.goto('/admin/login'); + await expect(page).toHaveURL(/\/admin\/login/); + }); + + await test.step('步骤2: 填写登录信息', async () => { + await page.fill('#email', testFixtures.adminUser.email); + await page.fill('#password', testFixtures.adminUser.password); + }); + + await test.step('步骤3: 提交登录表单', async () => { + await page.click('button[type="submit"]'); + await page.waitForURL(/\/admin(?!\/login)/); + }); + + await test.step('步骤4: 验证登录成功', async () => { + await expect(page).toHaveURL(/\/admin(?!\/login)/); + }); + }); + + test('管理员登录失败处理', async ({ page }) => { + await test.step('步骤1: 访问登录页面', async () => { + await page.goto('/admin/login'); + }); + + await test.step('步骤2: 填写错误信息', async () => { + await page.fill('#email', 'wrong@example.com'); + await page.fill('#password', 'wrongpassword'); + }); + + await test.step('步骤3: 提交登录表单', async () => { + await page.click('button[type="submit"]'); + }); + + await test.step('步骤4: 验证错误提示', async () => { + await expect(page.locator('[role="alert"], .error-message')).toBeVisible({ timeout: 5000 }); + }); + }); + + test('管理员登出流程', async ({ page }) => { + await test.step('步骤1: 登录系统', async () => { + await page.goto('/admin/login'); + await page.fill('#email', testFixtures.adminUser.email); + await page.fill('#password', testFixtures.adminUser.password); + await page.click('button[type="submit"]'); + await page.waitForURL(/\/admin(?!\/login)/); + }); + + await test.step('步骤2: 点击登出按钮', async () => { + const logoutButton = page.locator('button:has-text("退出"), a:has-text("退出"), button:has-text("登出")'); + if (await logoutButton.count() > 0) { + await logoutButton.click(); + } + }); + + await test.step('步骤3: 验证登出成功', async () => { + await page.waitForURL(/\/admin\/login|\/$/); + }); + }); + + test('未登录用户访问管理页面重定向', async ({ page }) => { + await test.step('步骤1: 直接访问管理页面', async () => { + await page.goto('/admin/content'); + }); + + await test.step('步骤2: 验证重定向到登录页', async () => { + await expect(page).toHaveURL(/\/admin\/login/); + }); + }); +}); diff --git a/e2e/journeys/visitor-browse-journey.spec.ts b/e2e/journeys/visitor-browse-journey.spec.ts new file mode 100644 index 0000000..1621d27 --- /dev/null +++ b/e2e/journeys/visitor-browse-journey.spec.ts @@ -0,0 +1,95 @@ +import { test, expect } from '@playwright/test'; + +test.describe('访客浏览旅程 @journey @visitor', () => { + test('访客浏览首页并了解公司信息', async ({ page }) => { + await test.step('步骤1: 访问首页', async () => { + await page.goto('/'); + await expect(page).toHaveTitle(/四川睿新致远科技有限公司/); + }); + + await test.step('步骤2: 查看Hero区域', async () => { + await expect(page.locator('h1')).toBeVisible(); + await expect(page.locator('text=专业')).toBeVisible(); + }); + + await test.step('步骤3: 滚动查看服务介绍', async () => { + await page.locator('#services').scrollIntoViewIfNeeded(); + await expect(page.locator('#services')).toBeVisible(); + }); + + await test.step('步骤4: 查看产品展示', async () => { + await page.locator('#products').scrollIntoViewIfNeeded(); + await expect(page.locator('#products')).toBeVisible(); + }); + + await test.step('步骤5: 查看最新资讯', async () => { + await page.locator('#news').scrollIntoViewIfNeeded(); + await expect(page.locator('#news')).toBeVisible(); + }); + }); + + test('访客浏览新闻列表并查看详情', async ({ page }) => { + await test.step('步骤1: 访问新闻列表页', async () => { + await page.goto('/news'); + await expect(page).toHaveURL(/\/news/); + }); + + await test.step('步骤2: 查看新闻列表', async () => { + const newsCards = page.locator('article, [data-testid="news-card"]'); + const count = await newsCards.count(); + expect(count).toBeGreaterThan(0); + }); + + await test.step('步骤3: 点击第一条新闻', async () => { + const firstNews = page.locator('article a, [data-testid="news-card"] a').first(); + if (await firstNews.count() > 0) { + await firstNews.click(); + await page.waitForLoadState('networkidle'); + await expect(page.locator('h1')).toBeVisible(); + } + }); + }); + + test('访客浏览产品并了解详情', async ({ page }) => { + await test.step('步骤1: 访问产品列表页', async () => { + await page.goto('/products'); + await expect(page).toHaveURL(/\/products/); + }); + + await test.step('步骤2: 查看产品列表', async () => { + const productCards = page.locator('article, [data-testid="product-card"]'); + const count = await productCards.count(); + expect(count).toBeGreaterThan(0); + }); + + await test.step('步骤3: 点击第一个产品', async () => { + const firstProduct = page.locator('article a, [data-testid="product-card"] a').first(); + if (await firstProduct.count() > 0) { + await firstProduct.click(); + await page.waitForLoadState('networkidle'); + await expect(page.locator('h1')).toBeVisible(); + } + }); + }); + + test('访客查看联系信息并提交表单', async ({ page }) => { + await test.step('步骤1: 访问联系页面', async () => { + await page.goto('/contact'); + await expect(page).toHaveURL(/\/contact/); + }); + + await test.step('步骤2: 查看联系信息', async () => { + await expect(page.locator('text=电话')).toBeVisible(); + await expect(page.locator('text=邮箱')).toBeVisible(); + }); + + await test.step('步骤3: 填写联系表单', async () => { + const form = page.locator('form'); + 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"]', '这是一条测试留言'); + } + }); + }); +});