我开始使用 Cypress 并进行一般编程。我正在开发一个非常简单的个人项目,在网页中执行 TC。
我在“registrationPage.js”中有这段代码
/// <reference types="cypress" />
import registrationData from '../fixtures/registrationData.json'
import AccountInfoPage from './accountInfoPage'
import commands from '../support/commands'
class RegistrationPage{
//Fill out Registration form with valid credentials
fillRegistrationForm(){
const userData = cy.getRegistrationData()
cy.getRegistrationData()
cy.get('[title="First Name"]').type(userData.firstname)
cy.get('#lastname').type(userData)
cy.get('[autocomplete="email"]').type(userData)
cy.get('#password').type(userData)
cy.get('#password-confirmation').type(userData)
}
//Click on submit button of Registration form
submitRegistrationForm(){
cy.contains('button', 'Create an Account').click()
}
//Verify the registration was sucesfull and user was created
verifyRegistration(){
const accountInfoPage = new AccountInfoPage();
const validUser = registrationData.validData.user1
cy.contains('Thank you for registering with Main Website Store.').should('be.visible')
cy.get('#block-collapsible-nav').find('li').contains('Account Information').click()
accountInfoPage.getFirstNameInput().invoke('val')
.should('equal', validUser.firstname)
accountInfoPage.getLastNameInput().invoke('val')
.should('equal', validUser.lastname)
}
}
export default RegistrationPage;
由于这是我想重复使用的逻辑(仅获取数据的部分,而不是输入数据),我认为将其作为命令放在“commands.js”文件中是一个不错的选择。
我有一个数据集位于registrationData.json,但我也想使用环境变量,以防我想快速覆盖数据集的内容(我也想听听是否有更好的选项来处理这个问题)
我将逻辑放入commands.js中:
import registrationData from '../fixtures/registrationData.json'
import loginData from '../fixtures/loginData.json'
Cypress.Commands.add('getRegistrationData', () => {
const validUser = Cypress.env('validUser') || registrationData.validData.user1
return {
firstname: Cypress.env('firstname') || validUser.firstname,
lastname: Cypress.env('lastname') || validUser.lastname,
email: Cypress.env('email') || validUser.email,
password: Cypress.env('password') || validUser.password,
passConfirm: Cypress.env('passConfirm') || validUser.passConfirm
}
})
但是当我尝试以这种方式在 Registration.spec.js 中使用它时:
import RegistrationPage from "../page-objects/registrationPage"
import LoginPage from "../page-objects/loginPage"
describe('Registration page scenario mapping', () => {
it.only('Executes a sucessfull registration in the form', () => {
const registrationPage = new RegistrationPage()
cy.visit('customer/account/create')
registrationPage.fillRegistrationForm()
registrationPage.submitRegistrationForm()
registrationPage.verifyRegistration()
})
it('login', function(){
const loginPage = new LoginPage()
cy.visit('/')
cy.contains('a', 'Sign In').should('be.visible').click()
cy.contains('h1', 'Customer Login').should('be.visible')
loginPage.fillLoginForm()
})
})
它在 RegistrationPage.js 中给我一个错误,指出 .type() 中的值未定义。 我尝试使用 validUser.firstname 代替,但出现同样的错误,如果我仅使用“validUser”作为值,它会说这是一个对象,您无法键入它。我不明白为什么如果我输入 validUser.firstname 无法识别该值。
CypressError
cy.type() can only accept a string or number. You passed in: undefinedLearn more
cypress/page-objects/registrationPage.js:14:40
12 |
13 | cy.getRegistrationData()
> 14 | cy.get('[title="First Name"]').type(userData.firstname)
| ^
15 | cy.get('#lastname').type(userData)
16 | cy.get('[autocomplete="email"]').type(userData)
17 | cy.get('#password').type(userData)
抱歉,如果我以错误的方式提出了问题或其他问题,我希望有人能帮助我。谢谢
函数和自定义命令之间的区别在于,函数返回一个可以分配给变量的值,但自定义命令将返回值沿链传递。
功能
const getRegistrationData = () => {
...
return ...
})
const registrationData = getRegistrationData()
自定义命令
Cypress.Commands.add('getRegistrationData', () => {
...
return ...
})
cy.getRegistrationData().then((registrationData) => { // access value here
...
})
所以要在注册页面使用自定义命令,
class RegistrationPage{
fillRegistrationForm() {
cy.getRegistrationData().then((userData) => {
cy.get('[title="First Name"]').type(userData.firstname)
cy.get('#lastname').type(userData)
cy.get('[autocomplete="email"]').type(userData)
cy.get('#password').type(userData)
cy.get('#password-confirmation').type(userData)
})
此外,您不需要在注册页面中
import commands from '../support/commands'
,因为自定义命令是全局设置的