How to run a test against a certain predefined timestamp in playwright

Viewed 250

I'm trying to run a playwright test that keeps failing the screenshot match because of timestamps (ex. 3 hours ago, 1 day ago, 5 days ago) that are posted on the page next to some content, not matching the current timestamps that have changed because the test is being run after the initial baseline screenshot is taken.

What is a way that I can store the current date and time at the time of capturing baseline screenshots and telling playwright this is always the timestamp I want to compare against in all tests?

2 Answers

As I see it, as long as you don't ignore the date comparison in your screenshots, they will keep throwing errors. Take into account your snapshot is just a moment in time, we may say. so if your baseline snapshot (the one you compare your current status against) contains the text "5 days ago", that's unchangeable unless you update the snapshot, but the whole comparing snapshots is all about comparing current state vs previous state to check there are no unwanted regressions, so updating the snapshot for this test every time would not make much sense.

In my opinion, you should ignore the given text. A good way to do it is using the option "mask" included in version 1.20. So imagine you want to ignore the number of stars the playwright repo has in its homepage. You could do this:

test('homepage', async({ page }) => {
    await page.goto('https://playwright.dev/');
    const stars = page.locator('.gh-count');
    expect(await page.screenshot({ mask: [stars] })).toMatchSnapshot();
});

This would take a snapshot of playwright's homepage, masking the element with the stars count, sticking the element into a pink-coloured box. That would prevent the snapshots from failing, no matter how many stars the repo gets.

If for whatever reason you cannot update your version up to 1.20, you can also "fake" the element with the evaluate() function, from changing the text before you take the snapshot to a fixed text (with the innerHTML property) or even making the element itself disappear changing its visibility with the setAttribute property. It's all about getting creative on this regard.

I know the question is old, but maybe someone will find the answer useful. What we did to go around the issue is inject css to hide the time stamps:

await page.addStyleTag({
    content: `
    .timestamp { display: none !important; }
`})

You just need to find the selector for the timestamp and use this code to hide it.

Related