Reputation: 135
I have a scenario I'm writing an automated test for. Currently the backend for a new api is not built out, but modules for the front end of the new experience are functioning. I want to write a test for the new experience so it's ready when we are switching to the new api. The new api has enough function to be authenticated via jwt token, and show a validation in console. The problem I'm having is that it works, but is not efficient.
Currently, I am using a beforeEach() block to get the authorized jwt token via POST request. The access token taken from there is used to go to a url, then set the token in session storage. After which, the page with expected content loads.
In context blocks, I validate the expectation of each page (There are 3 for this specific test flow). I would like to make it so that I only hit the API and return the jwt token once, then can call that jwt token for each time the browser is loaded.
Things I have tried:
Current structure of test file:
describe('New experience test', () => {
beforeEach(() => {
cy.interceptFeatureFlags({
'new-experience-feature-flags': true
})
cy.visit(Cypress.config('baseUrl'));
cy.window().then(w => {
cy.request({
method: 'POST',
url: 'yadda',
headers: 'stuff',
body: { payload }
}).then((response) => {
expect.(response).property('status').to.equal(200)
const oc_token = response.body.access_token;
w.sessionStorage.setItem(
'jwt',
oc_token
)
w.sessionStorage.setItem(
'other_jwt',
oc_token
)
})
});
cy.fixture('new_experience_context.json').then((context) => {
button(cy).click();
});
});
context('first page', () => {
it('shows condition', () => {
thing.should('exist');
});
context('second page', () => {
beforeEach(() => {
//steps that get to the second page
});
it('shows condition', () => {
thing.should('exist');
});
});
context('third page', () => {
beforeEach(() => {
//steps that get to the second page
//steps that get to the third page
});
it('shows condition', () => {
thing.should('exist');
});
});
});
//functions that identify things in the DOM
Structure I've tried:
describe('New experience test', () => {
before(() => {
cy.request({
method: 'POST',
url: 'yadda',
headers: 'stuff',
body: { payload }
}).then((response) => {
expect.(response).property('status').to.equal(200)
const oc_token = response.body.access_token;
});
beforeEach(() => {
cy.interceptFeatureFlags({
'new-experience-feature-flags': true
})
cy.visit(Cypress.config('baseUrl'));
cy.window().then(w => {
w.sessionStorage.setItem(
'jwt',
oc_token
)
w.sessionStorage.setItem(
'other_jwt',
oc_token
)
})
});
cy.fixture('new_experience_context.json').then((context) => {
button(cy).click();
});
});
Upvotes: 5
Views: 1426
Reputation: 225
If I'm reading this correctly, you can do this by declaring the variable in an outer context, the variable will be a "closure" variable.
describe('New experience test', () => {
let oc_token;
before(() => {
cy.request({...}).then((response) => {
oc_token = response.body.access_token; // set outer ("closure") variable
})
});
beforeEach(() => {
cy.interceptFeatureFlags({...})
cy.visit('/') // uses baseUrl from config
.then(w => {
w.sessionStorage.setItem('jwt', oc_token)
w.sessionStorage.setItem('other_jwt', oc_token)
})
...
})
})
The only problem you might have is if Cypress resets the browser, but it's unlikely if you are visiting baseUrl
set in configuration.
There are other methods such as alias
describe('New experience test', () => {
before(() => {
cy.request({...}).then((response) => {
cy.wrap(response.body.access_token).as('oc_token'); // alias variable
})
});
beforeEach(() => {
cy.interceptFeatureFlags({...})
cy.visit('/') // uses baseUrl from config
.then(w => {
cy.get('@oc_token').then(oc_token => { // retrieve alias value
w.sessionStorage.setItem('jwt', oc_token)
w.sessionStorage.setItem('other_jwt', oc_token)
})
})
...
})
})
or environment variable
describe('New experience test', () => {
before(() => {
cy.request({...}).then((response) => {
Cypress.env('oc_token', response.body.access_token); // env variable
})
});
beforeEach(() => {
cy.interceptFeatureFlags({...})
cy.visit('/') // uses baseUrl from config
.then(w => {
w.sessionStorage.setItem('jwt', Cypress.env('oc_token'))
w.sessionStorage.setItem('other_jwt', Cypress.env('oc_token'))
})
...
})
})
Upvotes: 4