Reputation: 31
I am new to Cypress, and trying to write an assertion for some text inputs for a username. A valid text for a username should fulfill two conditions, which are,
My code is as follows.
getUserFirstName(textInput) {
cy.get('[testid="user-self-update-form"]')
.get('input[name="firstName"]')
.clear()
.type(textInput)
.blur()
.invoke('val')
.should(($el) => {
expect($el).to
.match(/[a-zA-Z]+$/)
.to
.have
.greaterThan(1)
.to
.be
.lessThan(20)
}).then(() => {
cy.log("Invalid text input");
})
}
My requirement: When a username text is inserted, the above test should check whether it meets with imposed conditions, if not, log a message in the console. I am now trying to do the above test for 4 inputs separately, which are 'abcd123', '123', 'textwithmorethantwentyletters', and 'belowtwenty'. When running this test for the first input text of 'abcd123'. How may I correct this code? Highly appreciate your help.
I get the following error, and the test is failed:
Upvotes: 2
Views: 1149
Reputation: 1098
To get elegant log of conditions, use Cypress.log
getUserFirstName(textInput) {
cy.get('[testid="user-self-update-form"]')
.find('input[name="firstName"]')
.clear().type(textInput).blur()
.invoke('val')
.then(val => {
// Conditions
const lettersOnly = val.match(/[a-zA-Z]+$/)
const correctLength = val.length > 1 && val.length < 20
Cypress.log({
name: 'firstNameCheck',
displayName: `Testing "${textInput}"`,
message: ` - lettersOnly: ${lettersOnly ? 'pass' : 'fail'}`
})
Cypress.log({
name: 'firstNameCheck',
displayName: `Testing "${textInput}"`,
message: ` - correctLength : ${correctLength ? 'pass' : 'fail'}`
})
// now fail if you want, or omit this to perform next textInput
expect( lettersOnly && correctLength ).to.eq(true)
})
}
const textInputs = ['abcd123', '123', 'textwithmorethantwentyletters', 'belowtwenty']
textInputs.forEach(textInput => getUserFirstName(textInput))
You can also suppress the log of find
, type
, invoke
with {log:false}
option.
Upvotes: 2
Reputation: 18650
Your answer is mostly correct, but it just needs a few changes.
expect($el).to.match(/[a-zA-Z]+$/)
expect($el.length).to.have.greaterThan(1).to.be.lessThan(20)
You can also use within which basically checks for greater and less than.
expect($el.length).to.be.within(1,20)
cy.log("Invalid text input");
you can directly pass custom log messages in expect statements.expect($el.length).to.be.within(1,20, "Some Log message")
So implementing these two changes your code should look like:
cy.get('[testid="user-self-update-form"]')
.get('input[name="firstName"]')
.clear()
.type(textInput)
.blur()
.invoke('val')
.should((val) => {
expect(val.trim()).to.match(/[a-zA-Z]+$/,
`Checking username ${val} for regex match`
)
expect(val.trim().length).to.be.within(1,20,
`Checking username ${val} for length match`
)
})
Upvotes: 1
Reputation: 4430
You can try chaining the conditions with Cypress .and()
getUserFirstName(textInput) {
cy.get('[testid="user-self-update-form"]')
.find('input[name="firstName"]')
.clear()
.type(textInput).blur()
.invoke('val')
.should('match', /[a-zA-Z]+$/)
.and('have.length.gt', 1)
.and('have.length.lt', 20)
}
The input abc123
does not meet the first criteria, why did you think the test would pass?
If you want to just log bu not fail the test, try
getUserFirstName(textInput) {
cy.get('[testid="user-self-update-form"]')
.find('input[name="firstName"]')
.clear()
.type(textInput).blur()
.invoke('val')
.then(val => {
const lettersOnly = val.match(/[a-zA-Z]+$/)
const gt1 = val.length > 1
const lt20 = val.length < 20
if (!lettersOnly || !gt1 || !lt20) {
cy.log('Failed conditions')
// to fail the test now, throw an error
throw 'Failed conditions'
})
})
}
In the 2nd example I did not use .should()
, .and()
or expect()
because if any of those fail Cypress will fail the test at that point (and not check the other conditions).
Note also, .find(('input[name="firstName"]')
instead of .get('input[name="firstName"]')
because your intention is to find the firstname input within the form.
.get()
also may work if there is only one 'input[name="firstName"]'
on the page, but be aware that it ignores the line before and queries DOM from the root element <body>
.
Upvotes: 2