Skip to content

Commit f743a45

Browse files
feat: Expose setSystemTime on clock object (#23329)
Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
1 parent f88536b commit f743a45

File tree

4 files changed

+123
-0
lines changed

4 files changed

+123
-0
lines changed

cli/types/cypress.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5784,6 +5784,26 @@ declare namespace Cypress {
57845784
* cy.clock().invoke('restore')
57855785
*/
57865786
restore(): void
5787+
/**
5788+
* Change the time without invoking any timers.
5789+
*
5790+
* Default value with no argument or undefined is 0.
5791+
*
5792+
* This can be useful if you need to change the time by an hour
5793+
* while there is a setInterval registered that may otherwise run thousands
5794+
* of times.
5795+
* @see https://on.cypress.io/clock
5796+
* @example
5797+
* cy.clock()
5798+
* cy.visit('/')
5799+
* ...
5800+
* cy.clock().then(clock => {
5801+
* clock.setSystemTime(60 * 60 * 1000)
5802+
* })
5803+
* // or use this shortcut
5804+
* cy.clock().invoke('setSystemTime', 60 * 60 * 1000)
5805+
*/
5806+
setSystemTime(now?: number | Date): void
57875807
}
57885808

57895809
interface Cookie {

cli/types/tests/cypress-tests.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,24 @@ namespace CypressClockTests {
682682
})
683683
// restoring the clock shortcut
684684
cy.clock().invoke('restore')
685+
// setting system time with no argument
686+
cy.clock().then(clock => {
687+
clock.setSystemTime()
688+
})
689+
// setting system time with timestamp
690+
cy.clock().then(clock => {
691+
clock.setSystemTime(1000)
692+
})
693+
// setting system time with date object
694+
cy.clock().then(clock => {
695+
clock.setSystemTime(new Date(2019, 3, 2))
696+
})
697+
// setting system time with no argument and shortcut
698+
cy.clock().invoke('setSystemTime')
699+
// setting system time with timestamp and shortcut
700+
cy.clock().invoke('setSystemTime', 1000)
701+
// setting system time with date object and shortcut
702+
cy.clock().invoke('setSystemTime', new Date(2019, 3, 2))
685703
}
686704

687705
namespace CypressContainsTests {

packages/driver/cypress/e2e/commands/clock.cy.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,85 @@ describe('src/cy/commands/clock', () => {
5959
})
6060
})
6161

62+
context('setSystemTime', () => {
63+
it('takes number now arg', () => {
64+
const now = 1111111111111
65+
66+
cy.clock().then(function (clock) {
67+
expect(new this.window.Date().getTime()).to.equal(0)
68+
clock.setSystemTime(now)
69+
expect(new this.window.Date().getTime()).to.equal(now)
70+
})
71+
})
72+
73+
it('takes Date now arg', () => {
74+
// April 15, 2017
75+
const now = new Date(2017, 3, 15)
76+
const nowTimestamp = now.getTime()
77+
78+
cy.clock().then(function (clock) {
79+
expect(new this.window.Date().getTime()).to.equal(0)
80+
clock.setSystemTime(now)
81+
expect(new this.window.Date().getTime()).to.equal(nowTimestamp)
82+
})
83+
})
84+
85+
it('defaults to 0 ms with no argument', () => {
86+
const now = 1111111111111
87+
88+
cy.clock(now).then(function (clock) {
89+
expect(new this.window.Date().getTime()).to.equal(now)
90+
clock.setSystemTime()
91+
expect(new this.window.Date().getTime()).to.equal(0)
92+
})
93+
})
94+
95+
it('combines correctly with tick', () => {
96+
const now = 1111111111111
97+
98+
cy.clock().then(function (clock) {
99+
expect(new this.window.Date().getTime()).to.equal(0)
100+
clock.tick(4321)
101+
expect(new this.window.Date().getTime()).to.equal(4321)
102+
clock.setSystemTime(now)
103+
expect(new this.window.Date().getTime()).to.equal(now)
104+
clock.tick(4321)
105+
expect(new this.window.Date().getTime()).to.equal(now + 4321)
106+
})
107+
})
108+
109+
it('doesn\'t call timers on setSystemTime, but does on tick', function () {
110+
cy.clock().then(function (clock) {
111+
let callCount = 0
112+
113+
this.window.setTimeout(() => {
114+
callCount++
115+
})
116+
117+
clock.setSystemTime(1111111)
118+
expect(callCount).to.equal(0)
119+
clock.tick()
120+
expect(callCount).to.equal(1)
121+
})
122+
})
123+
124+
it('doesn\'t shift the time left for timers to trigger', function () {
125+
cy.clock(0).then(function (clock) {
126+
let callCount = 0
127+
128+
this.window.setTimeout(() => {
129+
callCount++
130+
}, 100)
131+
132+
clock.setSystemTime(1111111)
133+
clock.tick(99)
134+
expect(callCount).to.equal(0)
135+
clock.tick(1)
136+
expect(callCount).to.equal(1)
137+
})
138+
})
139+
})
140+
62141
it('restores window time methods when calling restore', (done) => {
63142
cy.clock().then(function (clock) {
64143
this.window.setTimeout(() => {

packages/driver/src/cypress/clock.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,17 @@ export const create = (win, now, methods) => {
4646
return _.pick(clock, 'now', 'methods')
4747
}
4848

49+
const setSystemTime = (now) => {
50+
clock.setSystemTime(now)
51+
}
52+
4953
return {
5054
tick,
5155

5256
restore,
5357

58+
setSystemTime,
59+
5460
bind,
5561

5662
details,

0 commit comments

Comments
 (0)