..

Test Time with Playwright!

Playwright released the new Clock API in v1.45 which allows us to mock the datetime object on our websites while testing. Having spent the last 3 months testing a calendar-based application via the API, and just starting to add UI E2E tests, this couldn’t have come at a better time!

In this short post I’ll dive into how it’s used in Python, how we can do arithmetic on dates with dateutil, and my initial thoughts on how I’ll use it in my tests.

First we need to initialize the clock object with a time. Either datetime.now() to get the current time, or a date object for some time in the future.

from datetime import datetime

...
# datetime.datetime(year, month, day, hour, minute, second)
page.clock.install(time=datetime.datetime(2024, 6, 28, 9, 0, 0))

The clock will now start from that time. Say we’re testing a 5 minute sale offer; users open the site with a pop up saying “there’s a sale” and after 5 minutes the pop up will show a string saying the “offer has expired”.

from datetime import datetime

...
page.clock.install(time=datetime.now())

expect(page.get_by_text("there's a sale")).to_be_visible()

# fast forward 5 minutes and 1 second
page.clock.fast_forward("05:01")

expect(page.get_by_text("offer has expired")).to_be_visible()

When we’re testing times we may want to be specific that something happens before, on the second, and immediately after. This is a little hard if time is rolling but the Clock API does let us pause at times too.

page.clock.pause_at(datetime.datetime(2024, 12, 31, 23, 59, 59))
# do something

page.clock.pause_at(datetime.datetime(2025, 01, 01, 00, 00, 00))
# do something else

page.clock.pause_at(datetime.datetime(2025, 01, 01, 00, 00, 01))
# do something else again

If we want to start time from that point it’s a simple clock.resume().

Date Arithmetic

Working with dates in Python can be slightly awkward for common testing scenarios, such as “one week from now”. There’s a great library called dateutil that has a type named relativedelta just for this use case.

Say we’re testing a 14 day sale banner that starts today and ends in a fortnight. We want to be able to specify the start and end dates dynamically.

today = datetime.now()
two_weeks_from_today = today + relativedelta(days=14)

relativedelta can take the following arguments:

relativedelta(arg1=x,arg2=y,arg3=z...)

years, months, weeks, days, hours, minutes, seconds

positive or negative deltas

datetime.now() + relativedelta(months=+1)
datetime.now() + relativedelta(months=-1)

and how long between two dates

relativedelta(datetime.now(), date(2000, 01, 01))

If you try stick to datetime objects in the standard library you’ll probably hit a wall, so try dateutil out.

Good luck testing time! :)