login.spec.ts
3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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$/);
});
});