|
- import type { Locator, Page } from '@playwright/test'
-
- import { expect } from './fixtures'
-
- export interface Credentials {
- username: string
- password: string
- roleCode?: 'admin' | 'administrative' | 'teacher' | 'student'
- }
-
- const roleLabels = {
- admin: '管理员',
- administrative: '行政',
- teacher: '教员',
- student: '学员',
- } as const
-
- const readRequired = (name: string) => {
- const value = process.env[name]?.trim()
- if (!value) throw new Error(`缺少环境变量 ${name};请参考 ute2e/.env.example 配置测试凭据。`)
- return value
- }
-
- const readOptional = (name: string) => process.env[name]?.trim() || ''
-
- export const missingLoginOrganizationEnvironment = (roleCode: Credentials['roleCode']) => {
- if (roleCode === 'administrative') {
- return readOptional('E2E_LOGIN_DEPARTMENT_NAME') ? [] : ['E2E_LOGIN_DEPARTMENT_NAME']
- }
- if (roleCode === 'teacher') {
- return [
- !readOptional('E2E_LOGIN_PARENT_DEPARTMENT_NAME') && 'E2E_LOGIN_PARENT_DEPARTMENT_NAME',
- !readOptional('E2E_LOGIN_DEPARTMENT_NAME') && 'E2E_LOGIN_DEPARTMENT_NAME',
- ].filter((name): name is string => Boolean(name))
- }
- return []
- }
-
- const selectVisibleOption = async (select: Locator, requestedLabel: string, aliases: string[] = []) => {
- await expect(select).toBeVisible()
- await expect(select).toBeEnabled()
- const availableLabels = (await select.locator('option:not([disabled])').allTextContents()).map((label) => label.trim())
- const selectedLabel = [requestedLabel, ...aliases].find((label) => availableLabels.includes(label))
- if (!selectedLabel) {
- throw new Error(`登录组织选项中找不到“${requestedLabel}”;当前可选项:${availableLabels.join('、') || '无'}。`)
- }
- await select.selectOption({ label: selectedLabel })
- }
-
- export async function selectLoginOrganization(page: Page, roleCode: Credentials['roleCode']) {
- if (roleCode !== 'administrative' && roleCode !== 'teacher') return
-
- const missingEnvironment = missingLoginOrganizationEnvironment(roleCode)
- if (missingEnvironment.length) {
- throw new Error(`角色“${roleLabels[roleCode]}”登录需要配置 ${missingEnvironment.join('、')}。`)
- }
-
- const departmentName = readOptional('E2E_LOGIN_DEPARTMENT_NAME')
- if (roleCode === 'administrative') {
- await selectVisibleOption(page.getByTestId('login-department'), departmentName)
- return
- }
-
- const parentDepartmentName = readOptional('E2E_LOGIN_PARENT_DEPARTMENT_NAME')
- await selectVisibleOption(page.getByTestId('login-organization'), parentDepartmentName)
- await selectVisibleOption(
- page.getByTestId('login-department'),
- departmentName,
- departmentName === parentDepartmentName ? [`${departmentName}(本级)`] : [],
- )
- }
-
- export const adminCredentials = (): Credentials => ({
- username: readRequired('E2E_ADMIN_USERNAME'),
- password: readRequired('E2E_ADMIN_PASSWORD'),
- roleCode: 'admin',
- })
-
- export async function login(page: Page, credentials: Credentials) {
- await page.goto('/login')
- const roleCode = credentials.roleCode ?? 'admin'
- await page.locator(`[data-role-code="${roleCode}"]`).click()
- await selectLoginOrganization(page, roleCode)
- await page.locator('input[name="username"]').fill(credentials.username)
- await page.locator('input[name="password"]').fill(credentials.password)
- await page.getByRole('button', { name: /登录系统|正在验证身份/ }).click()
- await expect(page).not.toHaveURL(/\/login(?:\?|$)/)
- await expect(page.locator('.platform-shell')).toBeVisible()
- }
-
- export async function loginAsAdmin(page: Page) {
- await login(page, adminCredentials())
- }
-
- export const visibleDialog = (page: Page) => page.locator('.el-dialog:visible').last()
-
- export const formItem = (scope: Locator, label: string | RegExp) => scope
- .locator('.el-form-item')
- .filter({ hasText: label })
- .first()
-
- export async function fillFormItem(scope: Locator, label: string | RegExp, value: string) {
- const control = formItem(scope, label).locator('input:not([type="hidden"]), textarea').first()
- await expect(control).toBeVisible()
- await control.fill(value)
- }
-
- export async function chooseSelectOption(
- page: Page,
- scope: Locator,
- label: string | RegExp,
- option: string | RegExp,
- ) {
- const item = formItem(scope, label)
- await item.locator('.el-select').click()
- const dropdown = page.locator('.el-select-dropdown:visible').last()
- await expect(dropdown).toBeVisible()
- await dropdown.locator('.el-select-dropdown__item').filter({ hasText: option }).first().click()
- }
-
- export async function confirmMessageBox(page: Page, buttonName: string | RegExp) {
- const box = page.locator('.el-message-box:visible').last()
- await expect(box).toBeVisible()
- await box.getByRole('button', { name: buttonName }).click()
- }
-
- export async function dismissOverlays(page: Page) {
- for (let index = 0; index < 3; index += 1) await page.keyboard.press('Escape')
- }
-
- export const tableRowByText = (page: Page, text: string) => page
- .locator('.el-table__body-wrapper .el-table__row')
- .filter({ hasText: text })
- .first()
-
- export const roleCardByText = (page: Page, text: string) => page
- .locator('.roles-table .el-table__body-wrapper .el-table__row')
- .filter({ hasText: text })
- .first()
|