'Strange behaiver of localStorage with Puppeteer
Im trying to save the localStorage to a variable outside of the page.evaluate(). But it seems that i cant do it. Below is the code im trying to use and outputs of consloe.log()'s , how i can make it to work and save the localStorage to a variable ? Inside the callback i can see the localStorage, but it dont act regular as getItem isnt working.
I'm trying several ways to get the data but none seems to work... any idea why?
await page.click("[id=Login-button]");
let savedLocalStorage = "";
const result = await page.evaluate(savedLocalStorage => {
console.log(localStorage); //output: {AUTH: 12345}
console.log(localStorage.key(0)); //output: null
console.log(localStorage.getItem("AUTH")); //output: null
localStorage.setItem("Test", "1234"); //working
console.log(localStorage); //output: {AUTH: 12345, Test: 1234}
savedLocalStorage = localStorage;
//savedLocalStorage = localStorage.AUTH; - same result as savedLocalStorage = localStorage;
return localStorage;
}, savedLocalStorage);
console.log(savedLocalStorage); //output: ""
console.log(result); //output: {}
Solution 1:[1]
Try serializing the data,:
async function saveLocalStorage(page, filePath) {
const json = await page.evaluate(() => {
const json = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
json[key] = localStorage.getItem(key);
}
return json;
});
fs.writeFileSync(filePath, 'utf8', JSON.stringify(json));
}
async function restoreLocalStorage(page, filePath) {
const json = JSON.parse(fs.readFileSync(filePath, 'utf8'));
await page.evaluate(json => {
localStorage.clear();
for (let key in json)
localStorage.setItem(key, json[key]);
}, json);
}
Solution 2:[2]
First of all, you won't be able to pass savedLocalStorage as a reference. The script inside the evaluate will get a serialized copy of that variable.
Regarding the result. Puppetter won't return a serialized localStorage but a pointer (JSHandle) to the object inside the browser. It's basically a puppeteer object you can pass to another evaluate function, in this case "as a reference".
What you could do is serialize the localStorage and then parse it on the other side.
const result = await page.evaluate(() => {
localStorage.setItem("Test", "1234"); //working
return JSON.stringify(localStorage);
});
console.log(JSON.parse(result));
<!DOCTYPE html>
<html>
<head>
<title>console.log test</title>
</head>
<body>
<script>
localStorage.setItem("AUTH", 12345);
</script>
</body>
</html>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | fortunee |
| Solution 2 |
