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,
- Text should contain ONLY English letters.
- Text length should be greater than 1, and less than 20.
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:
CodePudding user response:
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>
.
CodePudding user response:
Your answer is mostly correct, but it just needs a few changes.
- You are applying two assertions - to check that the username text matches the regex value and the text length is between 1 and 20. In your case, two different assertions will work better.
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)
- Instead of using
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`
)
})