'Override the browser date with puppeteer
I'm trying to setup puppeteer to run a few performance tests. I'd like to override the date to a specific value so that I can mock the data my app needs without needing to generate content dynamically based on the date.
How to override the date of the puppeteer browser?
Solution 1:[1]
We found a much simpler way to mock out the date in puppeteer. Here is our example:
page.evaluate(() => {
Date.now = () => {
return 1539806611024;
};
});
Solution 2:[2]
I ended up having the same problem. This is how I managed to solve it:
// mock date of document
if (!page.dateIsMocked) {
page.dateIsMocked = true
await page.evaluateOnNewDocument(() => {
var _Date = Date,
_getTimezoneOffset = Date.prototype.getTimezoneOffset,
now = null
function MockDate(y, m, d, h, M, s, ms) {
var date
switch (arguments.length) {
case 0:
if (now !== null) {
date = new _Date(now)
} else {
date = new _Date()
}
break
case 1:
date = new _Date(y)
break
default:
d = typeof d === 'undefined' ? 1 : d
h = h || 0
M = M || 0
s = s || 0
ms = ms || 0
date = new _Date(y, m, d, h, M, s, ms)
break
}
return date
}
MockDate.UTC = _Date.UTC
MockDate.now = function() {
return new MockDate().valueOf()
}
MockDate.parse = function(dateString) {
return _Date.parse(dateString)
}
MockDate.toString = function() {
return _Date.toString()
}
MockDate.prototype = _Date.prototype
function set(date, timezoneOffset) {
var dateObj = new Date(date)
if (isNaN(dateObj.getTime())) {
throw new TypeError(
'mockdate: The time set is an invalid date: ' + date
)
}
if (typeof timezoneOffset === 'number') {
MockDate.prototype.getTimezoneOffset = function() {
return timezoneOffset
}
}
Date = MockDate
now = dateObj.valueOf()
}
// mock date
set(1577840400000)
})
}
The actual logic for mocking the Date is borrowed from the MockDate library.
Solution 3:[3]
Based on the lighthouse documentation around puppeteer I got it working. https://github.com/GoogleChrome/lighthouse/blob/master/docs/puppeteer.md
Basicly did this to override Date.now
:
browser.on('targetchanged', async target => {
const targetPage = await target.page();
const client = await targetPage.target().createCDPSession();
await client.send('Runtime.evaluate', {
expression: `Date.now = function() { return 0; }`
});
});
Solution 4:[4]
Based on gergof answer https://stackoverflow.com/a/60166824/3641075, it seems it is possible to use MockDate library directly, following the same approach as in puppeteer doc here : https://pptr.dev/#?product=Puppeteer&version=v13.7.0&show=api-pageevaluateonnewdocumentpagefunction-args
if (page.mockDate) return;
page.mockDate = true;
const MockDate = fs.readFileSync('./node_modules/mockdate/lib/mockdate.js', 'utf8');
await page.evaluateOnNewDocument(`
${MockDate}
MockDate.set(new Date(2021, 5, 22), 0);
`);
I'm trying to mock the date with @storybook/addon-storyshots-puppeteer, and this approach works for me with imageSnapshot API, by using the customizePage option. Here is a full config :
import initStoryshots from "@storybook/addon-storyshots";
import { imageSnapshot } from "@storybook/addon-storyshots-puppeteer";
import fs from "fs";
initStoryshots({
test: imageSnapshot({
storybookUrl: "http://localhost:6007",
customizePage: async (page) => {
const MockDate = fs.readFileSync('./node_modules/mockdate/lib/mockdate.js', 'utf8');
await page.evaluateOnNewDocument(`
${MockDate}
MockDate.set(new Date(2021, 5, 22), 0);
`);
},
}),
});
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 | athornburg |
Solution 2 | gergof |
Solution 3 | RĂ©mi Gebski |
Solution 4 |