In the Cypress documentation for Variables and Aliases it uses the dollar sign before the variables in the then
-clauses. Like this:
cy.get('button').then(($btn) => {
// $btn is the object that the previous
// command yielded us
})
But I can't figure out why.
There are many other posts simply saying a bunch of stuff about "that it's just another character" so nothing special. And also a bunch of mentions of jQuery, obviously.
I just had an example of a complex Cypress-command, that didn't work, because I didn't have the dollar sign. Here is my code:
The Command
Cypress.Commands.add( "verifyUsersAccessToArticle", ( articleFixture, userType ) => {
cy.fixture( articleFixture, "utf8" ).as( 'article' );
// Intercept async-loaded content XHR
cy.get( "@article" ).then( ($article) => {
cy.intercept({
method: 'GET',
url: '/wp-json/sn/public/v1/article/' + $article.postId,
}).as('postContentFull');
});
// Log in
cy.visit( Cypress.env( 'baseUrl' ) );
if( userType !== 'noUser' ){
cy.loginUser( userType );
}
// Go to article
cy.get( "@article" ).then( ($article) => {
cy.visit( Cypress.env( 'baseUrl' ) + $article.url );
});
// Let content load
cy.wait( 1000 );
if( userType !== 'noUser' ){
cy.userIsLoggedIn();
}
cy.get( "@article" ).then( ($article) => {
// Have access
if( $article[ userType ].hasAccess ){
cy.get( '@postContentFull' ).then( ( $postContentFull ) => {
expect( $postContentFull.response.statusCode ).to.equal( 200 );
cy.get( '#main .post-content' ).children().its( 'length' ).should( 'be.gte', 4 ); // 4 <p>'s
cy.get('.react-pay-product-paywall').should( 'not.exist' );
});
}
// Doesn't have access
if( ! $article[ userType ].hasAccess ){
cy.get( '@postContentFull' ).then( ( $postContentFull ) => {
expect( $postContentFull.response.statusCode ).to.equal( 402 );
cy.get( '#main .post-content' ).children().its( 'length' ).should( 'be.lte', 4 ); // 4 <p>'s
cy.get('.react-pay-title').contains( $article[ userType ].paywallTitle );
cy.get('.react-pay-card-price > span').contains( $article[ userType ].paywallPrice );
});
}
});
});
The Test
it( 'Verify users access to article', () => {
let articles = [
'foo-article',
'bar-article'
];
articles.forEach( (article) => {
cy.verifyUsersAccessToArticle( Cypress.env( 'name' ) + '/' + article, 'subscriptionTypeZero' );
});
});
If I wrote postContentFull
instead of $postContentFull
, then I'm getting an error on the second run (when it runs the iteration for the bar-article
):
- then function(){}
TypeError
Cannot read properties of undefined (reading 'statusCode')
Overarching question
What does that dollar sign do?
And am I blind - or why can I not find it in the Cypress documentation?
Update 1: I might have misunderstood something
I think I have a flakey test - and have incorrectly assumed that the dollar sign was the solution. But I'm pretty sure that it's simply because the @article
(that is intercepted) hasn't resolved, when the cy.get( "@article" ).then( ($article) => {
is executed.
And when I added the dollar sign, the server simply returned faster.
I still would like to figure out, what the dollar sign does. :-)
Ditto comments above, but further info -
You should
wait
on the intercept, notget
it.cy.get('@postContentFull')
will only work if the intercept has already intercepted.Also, since you construct a new intercept for each article make the alias unique (otherwise you can't be sure which intercept you get).