Cypress.IO WordPress Login Management
Keeping the WordPress login intact between Cypress.IO tests was a challenge. There are plenty of Cypress.IO articles about login management and just as many about “anti-pattern” which lean toward the “login/authenticate between each test”. I don’t really want to test the WordPress login that often. I’m pretty damn sure it works. What I want to do is run my tests efficiently.
Unfortunately the “out of the box” examples, which I’ve been following, forgets about your login state between each test. Take my original Cypress.IO test — it logs in, configured the WordPress permalinks, logs out, does the Cypress.IO WordPress login again, sets the theme.
describe('Configure WordPress', function() { beforeEach(function () { cy.visit('/wp-login.php'); cy.get( '#user_login' ).type( Cypress.env( 'sa_user' ) ); cy.get( '#user_pass' ).type( Cypress.env( 'sa_pass' ) ); cy.get('#wp-submit').click(); }); it('Configures WordPress permalinks for SLP testing', function() { cy.visit( '/wp-admin/options-permalink.php' ); cy.get( '#custom_selection' ).click(); cy.get( '#permalink_structure' ).clear().type('/%postname%/'); cy.get( '#submit' ).click(); }); it('Configures the WordPress theme for SLP testing', function() { cy.visit( '/wp-admin/themes.php' ); cy.get( '#store-locator-plus' ).trigger( 'mouseover' ).then( cy.get('a[arial-label="Store Locator Plus Activate"]').click(); ); }); });
As I built this out to configure the environment visiting a dozen different settings pages I was being logged in a dozen times, once between each test segment. A huge pain in the ass and a extremely inefficient way to test.
Trying to do things before()
I tried replacing beforeEach(), which runs that snippet of code as if it prepends each block of code inside the it() blocks, with before(). before() runs once — as if the raw code was at the start of the describe() block (but don’t do that — it can mess up more complex test configurations.
This did not work at all, it does the Cypress.IO WordPress login, runs the first test, logs out, tries to run the second tests and barfs 1’s and 0’s all over the floor. I hate mopping up used 1’s and 0’s.
A Cypress.IO WordPress login trick
Turns out there is a super-simple trick for remembering the Cypress.IO WordPress login info between tests within a test specification. This keeps the “pattern” for all those “it’s anti-pattern” people that still think the real-world follows patterns AND lets you run multiple related tests without logging in with every it call.
The secret is in the cookies. When WordPress first logs in it sets a cookie. Unfortunately the cookie NAME is not the same between sessions so you cannot “fake it” or store something like “wordpress-login-cookie”. Thankfully Cypress.IO has an easy way to deal with this.
First – tell Cypress.IO to whitelist all wordpress_* cookies. Thankfully Cypress.IO supports regex for this. Next, use the before() structure to use the standard form for a WordPress Login, then stack up your it() clauses. By whitelisting the wordpress_* cookies, Cypress.IO will not discard them between tests.
One login, multiple test example
You can learn about configuring sensitive data like login names and passwords on the Cypress.IO env page. I keep the JSON login and other things I want to keep private in the cypress.env.json file on my local test box, outside of the code repository.
describe('Configure WordPress', function() { before(function () { cy.visit('/wp-login.php'); cy.get( '#user_login' ).type( Cypress.env( 'sa_user' ) ); cy.get( '#user_pass' ).type( Cypress.env( 'sa_pass' ) ); cy.get('#wp-submit').click(); }); it('Configures WordPress permalinks for SLP testing', function() { cy.visit( '/wp-admin/options-permalink.php' ); cy.get( '#custom_selection' ).click(); cy.get( '#permalink_structure' ).clear().type('/%postname%/'); cy.get( '#submit' ).click(); }); it('Configures the WordPress theme for SLP testing', function() { cy.visit( '/wp-admin/themes.php' ); cy.get( '#store-locator-plus' ).trigger( 'mouseover' ).then( (el) => { cy.get('a[arial-label="Store Locator Plus Activate"]').click(); }); }); });
The whitelist code
This is put into the Cypress.IO support/index.js file, which is run when the entire Cypress.IO environment is first loaded.
This will “…whitelist a set of Cookies which will always be preserved across tests.”
You can learn more about it on the Cypress.IO cookies page.
Cypress.Cookies.defaults({ whitelist: /wordpress_.*/ })
That’s it — with some very simple code each test specification can remain logged in after the test starts with a fresh session.