courses.spec.js 4.18 KB
/*
 * @Date: 2026-01-28 22:00:00
 * @Description: 课程功能 E2E 测试(使用 authenticated fixture)
 */
import { test, expect } from '@playwright/test'
import { login } from './helpers/auth'

// 扩展 test,添加 authenticatedPage fixture
const authenticatedTest = test.extend({
  authenticatedPage: async ({ page }, use) => {
    // 自动登录
    await login(page)
    // 使用已认证的页面
    await use(page)
  },
})

authenticatedTest.describe('课程浏览(已登录)', () => {
  authenticatedTest('可以浏览课程列表', async ({ authenticatedPage }) => {
    // 页面已经登录,直接访问
    await authenticatedPage.goto('/courses-list')

    // 等待课程列表加载
    await authenticatedPage.waitForSelector('.course-card', { timeout: 5000 })

    // 验证课程卡片存在
    const courseCards = authenticatedPage.locator('.course-card')
    const count = await courseCards.count()

    expect(count).toBeGreaterThan(0)

    console.log(`找到 ${count} 个课程`)
  })

  authenticatedTest('可以查看课程详情', async ({ authenticatedPage }) => {
    // 访问课程详情页
    await authenticatedPage.goto('/courses/123')

    // 等待页面加载
    await authenticatedPage.waitForLoadState('networkidle')

    // 验证关键元素
    const courseTitle = authenticatedPage
      .locator('h1')
      .or(authenticatedPage.locator('.course-title'))
    await expect(courseTitle).toBeVisible()
  })

  authenticatedTest('可以收藏课程', async ({ authenticatedPage }) => {
    // 访问课程详情页
    await authenticatedPage.goto('/courses/123')

    // 点击收藏按钮
    const favoriteButton = authenticatedPage
      .locator('button:has-text("收藏")')
      .or(authenticatedPage.locator('[class*="favorite"]'))

    // 记录点击前的状态
    const isFavoritedBefore = await favoriteButton.getAttribute('class')

    await favoriteButton.click()

    // 等待状态更新
    await authenticatedPage.waitForTimeout(500)

    // 验证收藏状态改变
    const isFavoritedAfter = await favoriteButton.getAttribute('class')
    expect(isFavoritedAfter).not.toBe(isFavoritedBefore)
  })
})

authenticatedTest.describe('学习进度(已登录)', () => {
  authenticatedTest('可以查看学习记录', async ({ authenticatedPage }) => {
    // 访问学习记录页面
    await authenticatedPage.goto('/study/records')

    // 等待加载
    await authenticatedPage.waitForLoadState('networkidle')

    // 验证页面内容
    const recordsList = authenticatedPage
      .locator('.study-records')
      .or(authenticatedPage.locator('[class*="records"]'))
    await expect(recordsList).toBeVisible()
  })

  authenticatedTest('可以继续学习', async ({ authenticatedPage }) => {
    // 访问学习页面
    await authenticatedPage.goto('/study/course/123')

    // 等待视频播放器加载
    const videoPlayer = authenticatedPage
      .locator('video')
      .or(authenticatedPage.locator('[class*="video-js"]'))

    await expect(videoPlayer).toBeVisible({ timeout: 10000 })
  })
})

// 不需要登录的测试仍然使用普通 test
test.describe('课程浏览(未登录)', () => {
  test('游客可以浏览课程列表', async ({ page }) => {
    await page.goto('/courses-list')

    // 等待课程列表加载
    await page.waitForSelector('.course-card', { timeout: 5000 })

    // 验证课程卡片存在
    const courseCards = page.locator('.course-card')
    const count = await courseCards.count()

    expect(count).toBeGreaterThan(0)
  })

  test('游客可以查看课程详情', async ({ page }) => {
    await page.goto('/courses/123')

    // 验证页面加载
    const courseTitle = page.locator('h1').or(page.locator('.course-title'))
    await expect(courseTitle).toBeVisible()
  })

  test('游客查看详情提示登录', async ({ page }) => {
    await page.goto('/courses/123')

    // 查找"开始学习"或"购买"按钮
    const startButton = page
      .locator('button:has-text("开始学习")')
      .or(page.locator('button:has-text("购买")'))

    if (await startButton.isVisible()) {
      await startButton.click()

      // 验证跳转到登录页
      await expect(page).toHaveURL(/\/login/)
    }
  })
})