auth.spec.js 5.7 KB
/*
 * @Date: 2026-01-28 22:00:00
 * @Description: 认证相关 E2E 测试示例
 */
import { test, expect } from '@playwright/test'
import { login, logout, isLoggedIn, quickLogin, TEST_ACCOUNT } from './helpers/auth'

test.describe('用户认证', () => {
  test('应该成功登录', async ({ page }) => {
    // 1. 访问登录页
    await page.goto('/#/login')

    // 2. 检查登录表单元素
    const phoneInput = page.locator('input[name="mobile"]')
    await expect(phoneInput).toBeVisible()

    // 3. 执行登录
    await login(page)

    // 4. 验证登录成功
    await expect(page).toHaveURL(/\/#\/(home|index)?/)

    // 5. 验证用户信息已保存
    const loggedIn = await isLoggedIn(page)
    expect(loggedIn).toBe(true)
  })

  test('应该显示登录错误信息(手机号格式错误)', async ({ page }) => {
    await page.goto('/#/login')

    // 输入错误格式的手机号
    await page.fill('input[name="mobile"]', '12345')

    // 点击发送验证码
    await page.click('button:has-text("获取验证码")')

    // 验证错误提示
    const errorToast = page.locator('.van-toast--fail').or(page.locator('.van-toast--error'))

    // 等待错误提示出现
    await expect(errorToast).toBeVisible({ timeout: 3000 })
  })

  test('应该成功登出', async ({ page }) => {
    // 先登录
    await login(page)

    // 验证已登录
    let loggedIn = await isLoggedIn(page)
    expect(loggedIn).toBe(true)

    // 执行登出
    await logout(page)

    // 验证已登出
    loggedIn = await isLoggedIn(page)
    expect(loggedIn).toBe(false)

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

test.describe('需要登录的功能', () => {
  test('访问受保护页面应跳转到登录页', async ({ page }) => {
    // 直接访问需要登录的页面
    await page.goto('/#/profile')

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

  test('登录后可以访问个人中心', async ({ page }) => {
    // 先登录
    await login(page)

    // 访问个人中心
    await page.goto('/#/profile')

    // 验证页面加载成功
    await expect(page).toHaveURL(/\/#\/profile/)

    // 检查页面元素
    const profileContent = page.locator('.profile').or(page.locator('[class*="profile"]'))
    await expect(profileContent).toBeVisible()
  })

  test('登录后可以查看课程学习进度', async ({ page }) => {
    // 登录
    await login(page)

    // 访问学习进度页面
    await page.goto('/#/study/progress')

    // 验证页面内容
    const progressContent = page.locator('.study-progress').or(page.locator('[class*="progress"]'))
    await expect(progressContent).toBeVisible({ timeout: 5000 })
  })
})

test.describe('购买流程(需要登录)', () => {
  test('登录后可以购买课程', async ({ page }) => {
    // 登录
    await login(page)

    // 访问课程详情页(假设课程ID为123)
    await page.goto('/#/courses/123')

    // 点击购买按钮
    const buyButton = page
      .locator('button:has-text("购买")')
      .or(page.locator('button:has-text("立即购买")'))

    // 等待按钮可点击
    await buyButton.waitFor({ state: 'visible', timeout: 5000 })
    await buyButton.click()

    // 验证跳转到结算页或支付页
    await expect(page).toHaveURL(/\/#\/(checkout|payment)/)

    // 检查结算页内容
    const checkoutContent = page.locator('.checkout').or(page.locator('[class*="checkout"]'))
    await expect(checkoutContent).toBeVisible()
  })

  test('未登录购买课程应跳转到登录页', async ({ page }) => {
    // 访问课程详情页
    await page.goto('/#/courses/123')

    // 点击购买按钮
    const buyButton = page
      .locator('button:has-text("购买")')
      .or(page.locator('button:has-text("立即购买")'))

    await buyButton.click()

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

test.describe('打卡功能(需要登录)', () => {
  test('登录后可以提交打卡', async ({ page }) => {
    // 登录
    await login(page)

    // 访问打卡页面
    await page.goto('/#/checkin')

    // 填写打卡内容
    const textarea = page.locator('textarea').or(page.locator('input[type="text"]'))
    await textarea.fill('今天的打卡内容')

    // 点击提交按钮
    const submitButton = page
      .locator('button:has-text("提交")')
      .or(page.locator('button:has-text("打卡")'))
    await submitButton.click()

    // 验证提交成功(显示成功提示)
    const successToast = page.locator('.van-toast--success')
    await expect(successToast).toBeVisible({ timeout: 3000 })
  })

  test('未登录打卡应跳转到登录页', async ({ page }) => {
    // 访问打卡页面
    await page.goto('/#/checkin')

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

test.describe('使用快速登录', () => {
  test('快速登录跳过输入流程', async ({ page }) => {
    // 使用快速登录(首次会执行正常登录获取 token)
    await quickLogin(page)

    // 访问需要登录的页面
    await page.goto('/#/profile')

    // 验证页面正常访问
    await expect(page).toHaveURL(/\/#\/profile/)
  })

  test('复用 token 多次测试', async ({ page }) => {
    // 第一次登录获取 token
    await login(page)

    // 获取用户信息
    const token = await page.evaluate(() => {
      const currentUser = localStorage.getItem('currentUser')
      return JSON.parse(currentUser)
    })

    // 登出
    await logout(page)

    // 使用 token 快速登录
    await quickLogin(page, token)

    // 验证登录状态
    const loggedIn = await isLoggedIn(page)
    expect(loggedIn).toBe(true)
  })
})