auth.spec.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { test, expect } from '@playwright/test'
  2. // 测试账号配置
  3. const TEST_USERNAME = process.env.TEST_USERNAME || 'admin'
  4. const TEST_PASSWORD = process.env.TEST_PASSWORD || '123456'
  5. test.describe('登录登出测试', () => {
  6. test.beforeEach(async ({ page }) => {
  7. // 清除登录状态
  8. await page.goto('/login')
  9. await page.evaluate(() => {
  10. localStorage.clear()
  11. document.cookie.split(';').forEach((c) => {
  12. document.cookie = c.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date().toUTCString()};path=/`)
  13. })
  14. })
  15. await page.reload()
  16. })
  17. test('登录页面正确显示', async ({ page }) => {
  18. await expect(page.getByPlaceholder('用户名')).toBeVisible()
  19. await expect(page.getByPlaceholder('密码')).toBeVisible()
  20. await expect(page.getByRole('button', { name: '登录' })).toBeVisible()
  21. await expect(page.getByText('记住我')).toBeVisible()
  22. })
  23. test('空表单提交显示验证错误', async ({ page }) => {
  24. await page.getByRole('button', { name: '登录' }).click()
  25. await expect(page.getByText('请输入用户名')).toBeVisible()
  26. await expect(page.getByText('请输入密码')).toBeVisible()
  27. })
  28. test('错误密码登录失败', async ({ page }) => {
  29. await page.getByPlaceholder('用户名').fill(TEST_USERNAME)
  30. await page.getByPlaceholder('密码').fill('wrongpassword')
  31. const loginBtn = page.getByRole('button', { name: '登录' })
  32. await loginBtn.click()
  33. // 等待一段时间后验证仍在登录页
  34. await page.waitForTimeout(3000)
  35. await expect(page).toHaveURL(/\/login/)
  36. // 验证登录按钮恢复可用状态(加载结束)
  37. await expect(loginBtn).toBeEnabled()
  38. })
  39. test('登录成功并显示用户名 admin', async ({ page }) => {
  40. // 输入登录信息
  41. await page.getByPlaceholder('用户名').fill(TEST_USERNAME)
  42. await page.getByPlaceholder('密码').fill(TEST_PASSWORD)
  43. // 等待登录按钮可用并点击
  44. const loginBtn = page.getByRole('button', { name: '登录' })
  45. await expect(loginBtn).toBeEnabled()
  46. await loginBtn.click()
  47. // 等待登录 API 响应并跳转
  48. await page.waitForURL(/^(?!.*\/login).*$/, { timeout: 15000 })
  49. // 验证用户名显示为 admin (layout__username 类)
  50. await expect(page.locator('.layout__username')).toBeVisible({ timeout: 10000 })
  51. await expect(page.locator('.layout__username')).toContainText('admin')
  52. })
  53. test('记住我功能保存用户名', async ({ page }) => {
  54. // 确保记住我选中
  55. const rememberCheckbox = page.locator('.login__checkbox')
  56. await rememberCheckbox.check()
  57. // 输入用户名并登录
  58. await page.getByPlaceholder('用户名').fill(TEST_USERNAME)
  59. await page.getByPlaceholder('密码').fill(TEST_PASSWORD)
  60. await page.getByRole('button', { name: '登录' }).click()
  61. // 等待登录成功
  62. await page.waitForURL(/^(?!.*\/login).*$/, { timeout: 15000 })
  63. // 验证 localStorage 保存了用户名
  64. const savedUsername = await page.evaluate(() => localStorage.getItem('login_remember'))
  65. expect(savedUsername).toBe(TEST_USERNAME)
  66. })
  67. test('登录后可以正常登出', async ({ page }) => {
  68. // 先登录
  69. await page.getByPlaceholder('用户名').fill(TEST_USERNAME)
  70. await page.getByPlaceholder('密码').fill(TEST_PASSWORD)
  71. const loginBtn = page.getByRole('button', { name: '登录' })
  72. await expect(loginBtn).toBeEnabled()
  73. await loginBtn.click()
  74. await page.waitForURL(/^(?!.*\/login).*$/, { timeout: 15000 })
  75. // 点击用户下拉菜单 (layout__user 类)
  76. await page.locator('.layout__user').click()
  77. await page.waitForTimeout(500)
  78. // 点击退出登录
  79. await page.getByText('退出登录').first().click()
  80. // 验证跳转到登录页
  81. await expect(page).toHaveURL(/\/login/, { timeout: 10000 })
  82. })
  83. test('修改密码弹窗可以打开', async ({ page }) => {
  84. // 先登录
  85. await page.getByPlaceholder('用户名').fill(TEST_USERNAME)
  86. await page.getByPlaceholder('密码').fill(TEST_PASSWORD)
  87. const loginBtn = page.getByRole('button', { name: '登录' })
  88. await expect(loginBtn).toBeEnabled()
  89. await loginBtn.click()
  90. await page.waitForURL(/^(?!.*\/login).*$/, { timeout: 15000 })
  91. // 点击用户下拉菜单
  92. await page.locator('.layout__user').click()
  93. await page.waitForTimeout(500)
  94. // 点击修改密码
  95. await page.locator('.layout__dropdown-item').filter({ hasText: '修改密码' }).click()
  96. // 验证弹窗显示
  97. await expect(page.getByRole('dialog')).toBeVisible()
  98. await expect(page.locator('.el-dialog__title')).toContainText('修改密码')
  99. })
  100. test('密码显示/隐藏切换', async ({ page }) => {
  101. const passwordInput = page.getByPlaceholder('密码')
  102. const toggleBtn = page.locator('.login__password-toggle')
  103. // 默认是密码模式
  104. await expect(passwordInput).toHaveAttribute('type', 'password')
  105. // 点击切换按钮显示密码
  106. await toggleBtn.click()
  107. await expect(passwordInput).toHaveAttribute('type', 'text')
  108. // 再次点击隐藏密码
  109. await toggleBtn.click()
  110. await expect(passwordInput).toHaveAttribute('type', 'password')
  111. })
  112. })