In the code below, why do I have to repeat cy.wrap(article)
instead of wrapping it once and storing the wrapped result in a reusable variable as shown on line three?
verifyArticleContent(article: JQuery<HTMLElement>, expected_article: Topic) {
// Wrapping once does not work.
// const article2 = cy.wrap(article)
// Title
cy.wrap(article).find('h2 a')
.should('have.text', expected_article.title)
.and('have.attr', 'href', '/forum/discussion/' + expected_article.id)
// Description
cy.wrap(article).find('p.data-description').should('have.text',
expected_article.description.substring(0, 300) + ' ...')
// Details
cy.wrap(article).find('p.data-author-date').should('have.text',
expected_article.user?.username + ', ' + // username
Util.dateToString(expected_article.date, 'en')) // date
}
Further clarification and an example of how I thought it would work:
verifyArticleContent(article: JQuery<HTMLElement>, expected_article: Topic) {
// Wrapping once does not work.
const article2 = cy.wrap(article)
// Title
article2.find('h2 a')
.should('have.text', expected_article.title)
.and('have.attr', 'href', '/forum/discussion/' + expected_article.id)
// STOPS WORKING HERE. If I comment out this description check, it fails on the details with the same (almost) error.
// Description
article2.find('p.data-description').should('have.text',
expected_article.description.substring(0, 300) + ' ...')
// Details
article2.find('p.data-author-date').should('have.text',
expected_article.user?.username + ', ' + // username
Util.dateToString(expected_article.date, 'en')) // date
}
Cypress works on chained commands where the "subject" of the test is passed down through the chain.
The strong advice given here Core concepts is not to use the assigned value of the chain, since this subject can be altered during the chain.
You cannot assign or work with the return values of any Cypress command. Commands are enqueued and run asynchronously.
To illustrate, here is a minimal example that does exactly what your code is doing.
cy.visit('https://example.com');
cy.get('body').then($body => {
const body = cy.wrap($body)
body.find('p a')
.should('have.text', 'More information...')
.and('have.attr', 'href', 'https://www.iana.org/domains/example')
.then($subject => {
console.log($subject[0])
})
body.find('h1')
.should('have.text', 'Example Domain')
})
I'm creating your article: JQuery<HTMLElement>
parameter by cy.get('body').then($body =>
and applying cy.wrap()
to it the same as you have.
After .and('have.attr', 'href', ...
I added a console log to inspect the current subject.
The console output is
<a href="https://www.iana.org/domains/example">More information...</a>
so the subject is no longer body
, it is the <a>
element.
The Cypress fail message tells you exactly what's going on:
Expected to find element: h1, but never found it. Queried from:
<a>