I'm not sure if it's a bug or a feature request.
Data stored in local-session storage is not ready before the app needs it.
I've set up my basic router-level authentication (Redux-router) to check local and session storages before the decision on what to show to users.
Right now the data gets to be ready long after the app has been loaded.
Try consuming the local storage data (create-react-app) in the application but populate it through the test. I've used the ClientFunction to access the storage and then in .beforeEach to populate it.
Basically, the authenticate method should not
// In the test
import { ClientFunction } from 'testcafe';
const localStorageSet = ClientFunction((key, value) => localStorage.setItem(key, value));
fixture.only('AutoCompleteField:')
.page('http://localhost:3000/products')
.beforeEach(async (t) => {
await localStorageSet('test123', 'ccc'); // Does not get populated on time
});
// In the app, anywhere in the body - it gets the data way to late
{localStorage.getItem('test123')}
Hi @mnemanja,
Now TestCafe executes ClientFunctions in the test after the page is loaded. It's too late in your case because you need to set a local storage item before page initialization.
We have planned this feature (take a look at #1739). It seems it should fit your needs. If so then we can close the issue as a duplicate.
As a workaround you can set the item and reload a page:
// In the test
import { ClientFunction, Role } from 'testcafe';
const localStorageSet = ClientFunction((key, value) => localStorage.setItem(key, value));
const pageUrl = 'http://localhost:3000/products';
fixture.only('AutoCompleteField:')
.page(pageUrl)
.beforeEach(async t => {
await localStorageSet('test123', 'ccc');
await t.navigateTo(pageUrl);
});
Hi @AlexanderMoskovkin,
Thanks for this quick and helpful answer!
Looking forward to the addScriptToEachPage feature in the future.
For now, the navigateTo feature will do the trick. I must have missed it in the documentation because I was looking for something like that.
Worked like a charm.
Thanks again!
You're always welcome!
Hi! Sorry for possible necroposting. I encountered a similar problem and tried this approach, but it didn't work.
What I need: I want to populate localStorage with user session data to skip sign-in-via-UI procedure.
What I do: I send a POST request to our Auth endpoint, receive a response and put it into local storage. I expect that after navigateTo() command I will see a landing page, not a login form.
What happens: I end up on login page, never going further.
Code sample
const pageUrl = "https://localhost:3000";
fixture.only('Start:')
.page(pageUrl)
.beforeEach(async t => {
const options = {
method: 'POST',
uri: 'https://<api URL>/login',
body: {
email: '<email>',
password: '<password>'
},
json: true
};
let response = await request(options);
const sessionInfo = Object.assign({}, {createdAt: <timestamp>}, response);
await localStorageSet('appState', `'${JSON.stringify({
session: sessionInfo,
settings: {}
})}'`);
await t.navigateTo(pageUrl);
});
test('Login in background', async t => {
await t.expect(Selector('#<landing-page-header>').visible).ok();
});
I checked localStorage with a few expects, and they confirm that the value is placed where it belongs.
Can you elaborate please?
Nevermind, that was my mistake :) works like a charm now.
Hi @darina-techery, I assume your login page checks authorization tokens while it is loading. It means you can't set tokens in a beforeEach hooks, because its code is executed only after the page loading is finished.
I think you can extract your auth procedure into a Role. Roles execute their auth code only once, and then restore cookies and storages before login page is loaded.
navigateTo does not work for a single page app with hash history. Any news alternative?
@nicgirault,
It is not quite clear why the approach with using the navigateTo feature does not work in your case. Would you please describe your scenario in more detail?
Since you are using hash-based navigation, you may consider using the workaround suggested in the https://github.com/DevExpress/testcafe/issues/2195 thread. If this does not help, we need more details on why the suggested workaround does not work to be able to look for a solution.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs or feature requests. For TestCafe API, usage and configuration inquiries, we recommend asking them on StackOverflow.
Most helpful comment
Hi @darina-techery, I assume your login page checks authorization tokens while it is loading. It means you can't set tokens in a
beforeEachhooks, because its code is executed only after the page loading is finished.I think you can extract your auth procedure into a Role. Roles execute their auth code only once, and then restore cookies and storages before login page is loaded.