Custom Commands是替代PageObject模式非常好的选择,使用Custom Commands可以创建自定义命令或替换现有命令,自定义命令默认存放在/cypress/support/commands.js文件中,它是在任何测试文件被导入之前加载(在cypress/support/index.js文件中)

CustomCommands语法

Cypress.Commands.add(name, callbackFn)
Cypress.Commands.add(name, options, callbackFn)
Cypress.Commands.overwrite(name, callbackFn)
  • name:表示自定义命令的名称
  • callbackFn:表示自定义命令的回调函数,回调函数里定义自定义函数所需要完成的操作
  • options:允许定义自定义命令的隐性行为

通常情况下,options的参数选择如下

参数 可选值 默认值
prevSubject true,false,optional false

代码示例

cypress/support/command.js中添加如下定义

Cypress.Commands.add('login', (username, password)=>{
	cy.get('input[name=username]').type(username)
	cy.get('input[name=password]').type('${password}{enter}')
})

然后在testLogin.js中做如下更改

//修改如下语句
loginInstance.login(username,password)
//替换为
cy.login(username,password)

修改后变的代码为

/// <reference types="cypress" />
import LoginPage from "../pages/login"
import mainPage from "../pages/main"
describe('登录测试,PageObject模式', function () {
    // we can use these values to log in
    const username = 'davie.yang'
    const password = 'alex005x'
    it('登录成功', function () {
        const loginInstance = new LoginPage()
        loginInstance.visitPage()
        loginInstance.isTargetPage()
        cy.login(username, password)
        cy.url().should('include', '/dashboard')
        const mainInstance = new mainPage()
        mainInstance.isTargetPage()
        mainInstance.welComeText.should('contain', 'davie.yang')
    })
})

代码分析

  • 定义在cypress/support/commands.js中的命令可以像Cypress内置命令那样直接使用,无需import对应的page,实际上PO模式在Cypress中无非就是数据和操作的共享
  • 自定义命令模式比PO模式运行更快,因为Cypress与应用程序运行在同一个浏览器中,可以直接发送请求到应用程序并设置运行测试所需要的用户状态,切这通常无需通过页面操作,因此自定义命令模式也更加稳定
  • 自定义命令允许重写Cypress内置命令,这意味着可以自定义测试框架并立即全局应用

实例应用

在cypress/support/commands.js中,写入如下代码

Cypress.Commands.add('login', (username, password) => {
    Cypress.log({
        name: 'login',
        message: `${username} | ${password}`,
    })

    return cy.request({
        method: 'POST',
        url: '/login',
        form: true,
        body: {
            username,
            password,
        },
    })
})

修改testLogin.js文件,内容如下

//testLogin.js
/// <reference types="cypress" />

describe('登录测试,自定义命令行模式', function () {
    const username = 'jane.lane'
    const password = 'password123'

    beforeEach(function () {
        cy.login(username, password)
    })

    it('可以访问受保护页', function () {
        //cy.request()登录成功后,Cypress会自动保存session cookie,
        //所以我们可以访问登录后才能访问的页面。
        cy.visit('/dashboard')
        cy.url().should('eq', 'http://localhost:7077/dashboard')
        cy.get('h1').should('contain', 'jane.lane')
    })
})

重写Cypress内置命令

//cy.visit()为例,在cypress/support/commands.js中,添加如下定义
Cypress.Commands.overwrite('visit', (originalFn, url) => {
    //仅为演示如何重新内置命令,您可以根据实际需要更改
    //重写visit命令,使每个visit命令都打印一行++符号在console里。

    console.log('++++++++++++++')

    //originalFn代表传入进来的原`visit`命令
    //url是visit里的url地址
    return originalFn(url)
})
//此后,任何使用到cy.visit的命令,都将在浏览器console里打印出一行“++”符号。