/** * E2E 测试支持文件 */ // 导入 Cypress 命令 import './commands' // 全局配置 Cypress.on('uncaught:exception', (err, runnable) => { // 忽略某些预期的错误 if (err.message.includes('ResizeObserver loop limit exceeded')) { return false } if (err.message.includes('Non-Error promise rejection captured')) { return false } // 返回 false 阻止 Cypress 失败测试 return false }) // 测试前钩子 beforeEach(() => { // 清除本地存储 cy.clearLocalStorage() cy.clearCookies() // 设置视口 cy.viewport(1280, 720) // 拦截 API 请求(可选) cy.intercept('GET', '/api/user/profile', { fixture: 'user.json' }).as('getUserProfile') cy.intercept('POST', '/api/auth/login', { fixture: 'auth.json' }).as('login') cy.intercept('POST', '/api/auth/logout', { statusCode: 200 }).as('logout') }) // 测试后钩子 afterEach(() => { // 清理工作 cy.clearLocalStorage() // 截图(失败时) cy.screenshot({ capture: 'runner', onlyOnFailure: true }) }) // 自定义断言 declare global { namespace Cypress { interface Chainable { /** * 登录用户 */ login(username?: string, password?: string): Chainable /** * 登出用户 */ logout(): Chainable /** * 等待页面加载完成 */ waitForPageLoad(): Chainable /** * 检查元素是否可见 */ shouldBeVisible(selector: string): Chainable /** * 检查元素是否包含文本 */ shouldContainText(selector: string, text: string): Chainable /** * 上传文件 */ uploadFile(selector: string, fileName: string): Chainable /** * 等待 API 请求完成 */ waitForApi(alias: string): Chainable /** * 模拟网络延迟 */ simulateNetworkDelay(delay: number): Chainable /** * 检查无障碍性 */ checkA11y(): Chainable } } }