I am using Protractor to test whether a value gets set in localStorage after a login submit. If I bind the localStorage value to a DOM-element, Protractor automatically waits for the REST response (after the login submit), checks the value and tests it. But I would like test the value of localStorage without writing it to the DOM. Before each test I clear the localStorage.
browser.executeScript("window.localStorage.clear();");
I can get the value in the test.
var key = browser.executeScript("return window.localStorage.getItem('ngStorage-initKey');")
But that happens too early.
I also tried returning that value in a browser.wait() statement, but in that case, it seems like the return value is not usable by wait(). probably because it's not a promise.
I would even consider giving protractor access to the the $localStorage instance from ngStorage if that would solve this.
Can anyone tell me if watching localStorage values async with Protractor is possible, and if so, how to approach this?
What turned out to be the solution, was how to handle the promise which browser.executeScript returns.
And it's good news: Protractor is already async, so custom waiting is not necessary. However, you should not just check if the returned value is of type string or isEqual to an expected string. But matching it via regular expressions works fine, whether you get a string or a promise returned. For example, if I expect a hash of 40 characters, you can match it like this:
it('should store key in localStorage when logging in', function() {
loginFormSubmitButton.click();
var newUserKey = browser.executeScript("return window.localStorage.getItem('ngStorage-userKey');");
expect(newUserKey).toMatch(/^\"[a-f0-9]{40}\"$/i);
});
Feels like magic, but the expect statement actually waits for the promise to resolve. In this case that means a call to the server is made or mocked, the result is written into localStorage and detected as-it-happens by the expect statement.
No need for custom timeouts.
You probably aren't waiting correctly in your browser.wait() function, the value doesnt have to be a promise, just a simple boolean value, that exits the wait once it's true, the following will work:
browser.wait(function () {
return browser.executeScript("return window.localStorage.getItem('ngStorage-initKey');")
== theValueYouExpect;
}, 5000);
read more about protractors wait !
Alternatively, browser.executeScript("window.localStorage.clear();"); returns a promise AFTER the script was executed, (but not neccessarily the script finished, if it is async), so here another solution will be:
browser.executeScript("window.localStorage.clear();")
.then(function (){
browser.executeScript("return window.localStorage.getItem('ngStorage-initKey');")
.then(function (key) {//do something with the key});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With