login.spec.ts 3.56 KB
import { test, expect, type Page } from '@playwright/test';

// 桩后端:版本下拉与登录端点(page.route),不依赖真实后端起服。
async function stubCompanies(page: Page) {
  await page.route('**/api/usr/companies', async (route) => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        code: 0,
        message: 'success',
        data: [
          { id: 1, sCompanyName: '甲公司', sVersion: '标准版' },
          { id: 2, sCompanyName: '乙公司', sVersion: null },
        ],
      }),
    });
  });
}

test.describe('登录页关键旅程', () => {
  test('loads /login and shows version options', async ({ page }) => {
    await stubCompanies(page);
    await page.goto('/login');
    await expect(page.getByText('用户登录')).toBeVisible();
    // 打开版本下拉,应渲染桩返回项
    await page.getByRole('combobox').click();
    await expect(page.getByText('甲公司(标准版)')).toBeVisible();
    await expect(page.getByText('乙公司', { exact: true })).toBeVisible();
  });

  test('blocks submit with validation when empty', async ({ page }) => {
    await stubCompanies(page);
    let loginCalled = false;
    await page.route('**/api/usr/login', async (route) => {
      loginCalled = true;
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ code: 0, message: 'success', data: {} }),
      });
    });
    await page.goto('/login');
    await page.getByRole('button', { name: /登\s*录/ }).click();
    await expect(page.getByText('请输入用户名')).toBeVisible();
    await expect(page.getByText('请输入密码')).toBeVisible();
    expect(loginCalled).toBe(false);
  });

  test('successful login navigates away from /login', async ({ page }) => {
    await stubCompanies(page);
    await page.route('**/api/usr/login', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          code: 0,
          message: 'success',
          data: {
            token: 'tk-e2e',
            user: { id: 1, sUserName: 'admin', sUserType: '超级管理员', sLanguage: '中文' },
          },
        }),
      });
    });
    await page.goto('/login');
    await page.getByPlaceholder('请输入你的用户名').fill('admin');
    await page.getByPlaceholder('请输入你的密码').fill('secret');
    // 选版本
    await page.getByRole('combobox').click();
    await page.getByText('甲公司(标准版)').click();
    await page.getByRole('button', { name: /登\s*录/ }).click();
    await expect(page.getByText('登录成功')).toBeVisible();
    await expect(page).not.toHaveURL(/\/login$/);
  });

  test('failed login stays on /login with error', async ({ page }) => {
    await stubCompanies(page);
    await page.route('**/api/usr/login', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ code: 40101, message: '认证失败', data: null }),
      });
    });
    await page.goto('/login');
    await page.getByPlaceholder('请输入你的用户名').fill('admin');
    await page.getByPlaceholder('请输入你的密码').fill('wrong');
    await page.getByRole('combobox').click();
    await page.getByText('甲公司(标准版)').click();
    await page.getByRole('button', { name: /登\s*录/ }).click();
    await expect(page.getByText('用户名或密码错误')).toBeVisible();
    await expect(page).toHaveURL(/\/login$/);
  });
});