当我编写要在剧作家中运行的测试时,我希望能够设置浏览器认为测试开始的日期。有没有办法使用剧作家来实现这一目标?
更简单的解决方案
page.evaluate(() => {
Date.now = () => {
return 1609477200000; //Jan 1, 2021
};
});
您可以使用TimeShift等模拟工具。 这段代码将注入时移库,然后将日期注入
Feb 02 2012
:
const playwright = require("playwright");
(async () => {
let removed = false;
const browser = await playwright["chromium"].launch({headless: false});
const page = await browser.newPage();
await page.setContent('<a href="#" onclick="document.querySelector(\'span\').innerText = new Date().toString()">Test me</a><span></span>');
await page.click('a');
console.log(await page.innerText('span'));
await page.addScriptTag({ url: 'https://cdn.jsdelivr.net/npm/[email protected]/timeshift.js'});
await page.evaluate(() => {
Date = TimeShift.Date;
TimeShift.setTime(1328230923000);
});
await page.click('a');
console.log(await page.innerText('span'));
browser.close();
})();
输出:
Fri Sep 18 2020 15:06:58 GMT-0300 (Argentina Standard Time)
Thu Feb 02 2012 22:02:03 GMT-0300
我在 GitHub Issue
中找到了一个简单的解决方案 async clock(value) {
const date = new Date(value).valueOf();
await page.addInitScript(`{
// Extend Date constructor to default to fakeNow
Date = class extends Date {
constructor(...args) {
if (args.length === 0) {
super(${date.valueOf()});
} else {
super(...args);
}
}
}
// Override Date.now() to start from fakeNow
const __DateNowOffset =${date.valueOf()} - Date.now();
const __DateNow = Date.now;
Date.now = () => __DateNow() + __DateNowOffset;
}`);
}
await clock("2022/01/01")
不带勾选功能的版本:
page.on('load', () => {
page.evaluate(() => {
const OriginalDate = window.Date;
class MockDate extends OriginalDate {
static currentDate = '18 May 2018 12:00 UTC';
static currentTimeStamp = (new OriginalDate(MockDate.currentDate)).getTime();
constructor(...args) {
const params = (args && args.length) ? args : [MockDate.currentTimeStamp];
super(...params);
}
static [Symbol.hasInstance](instance: Date) {
return typeof instance.getDate === 'function';
}
static now() {
return MockDate.currentTimeStamp;
}
}
window.Date = MockDate;
});
});
await page.goto(yourUrl);
带勾的版本:
page.on('load', () => {
page.evaluate(() => {
const OriginalDate = window.Date;
class MockDate extends OriginalDate {
static currentDate = '18 May 2018 12:00 UTC';
static currentTimeStamp = (new OriginalDate(MockDate.currentDate)).getTime();
static originalNow = OriginalDate.now();
constructor(...args) {
const params = (args && args.length) ? args : [(MockDate.currentTimeStamp + MockDate.getTick())];
super(...params);
}
static [Symbol.hasInstance](instance: Date) {
return typeof instance.getDate === 'function';
}
static getTick() {
return OriginalDate.now() - MockDate.originalNow;
}
static now() {
return MockDate.currentTimeStamp + MockDate.getTick();
}
}
window.Date = MockDate;
});
});
await page.goto(yourUrl);
从
playwright
v1.45.0 开始,我们可以使用新的 Clock API。
await page.clock.setFixedTime(new Date('2024-02-02T10:00:00'));
它还支持暂停和快进时间等用例:
// Initialize clock with some time before the test time and let the page load
// naturally. `Date.now` will progress as the timers fire.
await page.clock.install({ time: new Date('2024-02-02T08:00:00') });
// Pretend that the user closed the laptop lid and opened it again at 10am,
// Pause the time once reached that point.
await page.clock.pauseAt(new Date('2024-02-02T10:00:00'));
// Assert the page state.
await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:00:00 AM');
// Close the laptop lid again and open it at 10:30am.
await page.clock.fastForward('30:00');
请参阅时钟指南了解更多详情。