1. 程式人生 > >Cypress系列(63)- 使用 Custom Commands

Cypress系列(63)- 使用 Custom Commands

如果想從頭學起Cypress,可以看下面的系列文章哦

https://www.cnblogs.com/poloyy/category/1768839.html

 

Custom Commands 自定義命令介紹

  • Custom Commands 被認為是替代 PageObject 的良好選擇
  • 使用 Custom Commands 可以建立自定義命令和替換現有命令
  • Custom Commands 預設存放在 cypress/support/commands.js 檔案中,它會在任何測試檔案被匯入之前載入( 定義在 cypress/support/index.js )

 

語法格式

Cypress.Commands.add(name, callbackFn)
Cypress.Commands.add(name, options, callbackFn)
Cypress.Commands.overwrite(name, callbackFn)

 

引數說明

  • name:要新增或覆蓋的命令的名稱
  • callbackFn :自定義命令的回撥函式,回撥函式裡自定義函式所需完成的操作步驟
  • options:允許自定義命令的隱性行為

 

options 可選引數列表

引數

可接受的值型別

預設

描述

prevSubject

Boolean, String or Array

false

如何處理前面產生的物件

prevSubject 可選值

  • false:忽略任何以前的主題(父命令)
  • true:接收上一個主題(子命令)
  • optional:可以啟動鏈,也可以使用現有鏈(雙命令)

 

除了控制命令的隱式行為,您還可以新增宣告性主題驗證,例如:

  • element:要求上一個主題是DOM元素
  • document:要求上一個主題為文件
  • window:要求上一個主題是視窗

 

Cypress 內建命令利用了上述可選值組合中的每一個

 

注意:僅在 Cypress.Commands.add() 中支援使用options,而在 Cypress.Commands.overwrite() 中不支援使用options

 

正確用法

Cypress.Commands.add('login', (email, pw) => {})
Cypress.Commands.overwrite('visit', (orig, url, options) => {}) 

 

前期準備

啟動 Cypress 提供的演示專案

cmd 視窗進入下面的資料夾

 

執行下面的命令

npm start

 

Custom Commands 的簡單栗子

command.js 的程式碼

在 cypress/support/commands.js 中寫如下程式碼

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

 

testlogin.js 測試用例檔案的程式碼

context('登入測試,PO 模式', function () {

    const username = 'jane.lane'
    const pwd = 'password123'

    it('登入成功', function () {
        // 建立 po 例項
        const loginInstance = new LoginPage()
        loginInstance.visitPage()
        loginInstance.isTargetPage()

        // 呼叫 Custom Commands 的命令
        cy.login(username, pwd)
        cy.url().should('include', '/dashboard')

        const manInstance = new mainPage()
        manInstance.isTargetPage()
        manInstance.welComeText.should('contain', 'jane.lane')
    });
})

 

測試結果

 

Customn Commands 的好處

  • 定義在 cypress/support/command.js 中的命令可以像 Cypress 內建命令那樣直接使用,無須 import 對應的 page(實際上 PageObject 模式在 Cypress 看來無非是資料/操作函式的共享)
  • 自定義命令可以比 PageObject 模式執行更快,Cypress 和應用程式執行在同一個瀏覽器中,意味著 Cypress 可以直接傳送請求到應用程式並設定執行測試所需要的使用者狀態,而這一切通常無須通過頁面操作,這使得使用了自定義命令的測試會更加穩定
  • 自定義命令允許重寫 Cypress 內建命令,意味著可以自定義測試框架並立刻全域性應用

 

Custom Commands 完全替換 PageObject 模式的栗子

command.js 程式碼

在 cypress/support/commands.js  中寫如下程式碼

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

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

.request() 命令在後面文章會繼續介紹

 

testLogin.js 測試用例檔案程式碼

無須 PageObject 模型,直接在 integration 資料夾下建立 testLogin.js 測試用例檔案

context('登入測試,PO 模式', function () {

    const username = 'jane.lane'
    const pwd = 'password123'

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

    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')
    });
})

 

overwrite 覆蓋 visit 命令的栗子

// 第一個引數代表需要覆蓋的命令
Cypress.Commands.overwrite('visit', (originalFn, url, options) => {
    const domain = Cypress.env('BASE_DOMAIN')

    if (domain === '...') {
        url = '...'
    }

    if (options.something === 'else') {
        url = '...'
    }

    // originalFn 代表傳入進來的原 visit 命令
    //
    // 記得需要在最後 return
    return originalFn(url, options)
})

 

overwrite 覆蓋 type 命令的栗子

如果在密碼欄位中鍵入內容,密碼輸入將在應用程式中自動遮蔽。但是 .type() 會自動將所有鍵入的內容記錄到測試執行程式的命令日誌中

cy.get('#username').type('[email protected]')
cy.get('#password').type('superSecret123')

 

實際情況

  1. 可能需要遮蔽傳遞給 .type() 命令的某些值,以便敏感資料不會顯示在測試執行的螢幕截圖或視訊中
  2. 下面的示例將覆蓋 .type() 命令,以允許遮蔽測試執行程式的命令日誌中的敏感資料

 

Cypress.Command.overwrite() 程式碼

Cypress.Commands.overwrite('type', (originalFn, element, text, options) => {
    if (options && options.sensitive) {
        options.log = false
        // 建立自己的日誌
        Cypress.log({
            $el: element,
            name: 'type',
            message: '*'.repeat(text.length),
        })
    }

    return originalFn(element, text, options)
})

 

測試用例程式碼

cy.get('input[name=username]').type(username)
cy.get('input[name=password]').type(pwd, {sensitive: true})

 

測試結果