Skip to content

Commit

Permalink
Merge branch 'develop' into issue-7881
Browse files Browse the repository at this point in the history
  • Loading branch information
jennifer-shehane committed Jul 20, 2020
2 parents 46b6a7e + 775f444 commit a1de94d
Show file tree
Hide file tree
Showing 15 changed files with 178 additions and 78 deletions.
54 changes: 48 additions & 6 deletions cli/types/cypress.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,18 @@ declare namespace Cypress {
* This means that when you instantiate new Date in your application,
* it will have a time of January 1st, 1970.
*
* To restore the real clock call `.restore()`
*
* @example
* cy.clock()
* ...
* // restore the application clock
* cy.clock().then(clock => {
* clock.restore()
* })
* // or use this shortcut
* cy.clock().invoke('restore')
*
* @see https://on.cypress.io/clock
*/
clock(): Chainable<Clock>
Expand All @@ -716,15 +728,22 @@ declare namespace Cypress {
*
* @see https://on.cypress.io/clock
* @example
* // your app code
* // in your app code
* $('#date').text(new Date().toJSON())
* // from spec file
* const now = new Date(2017, 3, 14).getTime() // March 14, 2017 timestamp
* // in the spec file
* // March 14, 2017 timestamp or Date object
* const now = new Date(2017, 2, 14).getTime()
* cy.clock(now)
* cy.visit('/index.html')
* cy.get('#date').contains('2017-03-14')
* // to restore the real clock
* cy.clock().then(clock => {
* clock.restore()
* })
* // or use this shortcut
* cy.clock().invoke('restore')
*/
clock(now: number, options?: Loggable): Chainable<Clock>
clock(now: number|Date, options?: Loggable): Chainable<Clock>
/**
* Mocks global clock but only overrides specific functions.
*
Expand All @@ -733,7 +752,7 @@ declare namespace Cypress {
* // keep current date but override "setTimeout" and "clearTimeout"
* cy.clock(null, ['setTimeout', 'clearTimeout'])
*/
clock(now: number, functions?: Array<'setTimeout' | 'clearTimeout' | 'setInterval' | 'clearInterval' | 'Date'>, options?: Loggable): Chainable<Clock>
clock(now: number|Date, functions?: Array<'setTimeout' | 'clearTimeout' | 'setInterval' | 'clearInterval' | 'Date'>, options?: Loggable): Chainable<Clock>
/**
* Mocks global clock and all functions.
*
Expand Down Expand Up @@ -1797,6 +1816,17 @@ declare namespace Cypress {
* `cy.clock()` must be called before `cy.tick()`
*
* @see https://on.cypress.io/clock
* @example
* cy.clock()
* ...
* // advance time by 10 minutes
* cy.tick(600*1000)
* // you can restore the real clock
* cy.tick(1000).then(clock => {
* clock.restore()
* })
* // or use this shortcut
* cy.tick(5000).invoke('restore')
*/
tick(milliseconds: number): Chainable<Clock>

Expand Down Expand Up @@ -4754,10 +4784,22 @@ declare namespace Cypress {
* Move the clock the specified number of `milliseconds`.
* Any timers within the affected range of time will be called.
* @param time Number in ms to advance the clock
* @see https://on.cypress.io/tick
*/
tick(time: number): void
/**
* Restore all overridden native functions. This is automatically called between tests, so should not generally be needed.
* Restore all overridden native functions.
* This is automatically called between tests, so should not generally be needed.
* @see https://on.cypress.io/clock
* @example
* cy.clock()
* cy.visit('/')
* ...
* cy.clock().then(clock => {
* clock.restore()
* })
* // or use this shortcut
* cy.clock().invoke('restore')
*/
restore(): void
}
Expand Down
16 changes: 14 additions & 2 deletions cli/types/tests/cypress-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,20 @@ namespace CypressTriggerTests {
})
}

const now = new Date(2019, 3, 2).getTime()
cy.clock(now, ['Date'])
namespace CypressClockTests {
// timestamp
cy.clock(new Date(2019, 3, 2).getTime(), ['Date'])
// timestamp shortcut
cy.clock(+ new Date(), ['Date'])
// Date object
cy.clock(new Date(2019, 3, 2))
// restoring the clock
cy.clock().then(clock => {
clock.restore()
})
// restoring the clock shortcut
cy.clock().invoke('restore')
}

namespace CypressContainsTests {
cy.contains('#app')
Expand Down
11 changes: 11 additions & 0 deletions packages/driver/cypress/fixtures/issue-6099.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<html>
<body>
<main style="background: linear-gradient(yellow, blue); height: 250vh; transition: 10s;"></main>
<script>
window.addEventListener('scroll', () => {
const main = document.getElementsByTagName('main')[0]
main.style.height = "50vh";
})
</script>
</body>
</html>
14 changes: 13 additions & 1 deletion packages/driver/cypress/integration/commands/clock_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('src/cy/commands/clock', () => {
})
})

it('takes now arg', () => {
it('takes number now arg', () => {
const now = 1111111111111

cy.clock(now).then(function (clock) {
Expand All @@ -47,6 +47,18 @@ describe('src/cy/commands/clock', () => {
})
})

it('takes Date now arg', () => {
// April 15, 2017
const now = new Date(2017, 3, 15)
const nowTimestamp = now.getTime()

cy.clock(now).then(function (clock) {
expect(new this.window.Date().getTime()).to.equal(nowTimestamp)
clock.tick(4321)
expect(new this.window.Date().getTime()).to.equal(nowTimestamp + 4321)
})
})

it('restores window time methods when calling restore', (done) => {
cy.clock().then(function (clock) {
this.window.setTimeout(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,12 @@ describe('src/cy/commands/screenshot', () => {
})
})
})

// https://github.com/cypress-io/cypress/issues/6099
it('can screenshot when element height changes on scroll', () => {
cy.visit('fixtures/issue-6099.html')
cy.get('main').screenshot()
})
})

describe('timeout', () => {
Expand Down
4 changes: 4 additions & 0 deletions packages/driver/src/cy/commands/clock.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ module.exports = function (Commands, Cypress, cy, state) {
return clock
}

if (_.isDate(now)) {
now = now.getTime()
}

if (_.isObject(now)) {
userOptions = now
now = undefined
Expand Down
8 changes: 8 additions & 0 deletions packages/driver/src/cy/commands/screenshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ const scrollOverrides = (win, doc) => {
// hide scrollbars
doc.documentElement.style.overflow = 'hidden'

// in the case that an element might change size on scroll
// we trigger a scroll event to ensure that all elements are
// at their final size before we calculate the total height
// since we scroll down the page in takeScrollingScreenshots
// and don't want the page size to change once we start
// https://github.com/cypress-io/cypress/issues/6099
win.dispatchEvent(new win.Event('scroll'))

return () => {
doc.documentElement.style.overflow = originalOverflow
if (doc.body) {
Expand Down
24 changes: 24 additions & 0 deletions packages/reporter/cypress/integration/tests_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,30 @@ describe('controls', function () {
expect($span).to.have.css('width', '0px')
})
})

it('recalculates correct width after being closed', function () {
const { wallClockStartedAt } = this.runnables.suites[0].suites[0].tests[1].commands[0]

// take the wallClockStartedAt of this command and add 1000 milliseconds to it
// in order to simulate the command having run for 1 second of the total 4000 timeout
const date = new Date(wallClockStartedAt).setMilliseconds(1000)

cy.clock(date, ['Date'])
cy.get('.runnable-active').click()
cy.get('.command-progress > span').should(($span) => {
expect($span.attr('style')).to.contain('animation-duration: 3000ms')
expect($span.attr('style')).to.contain('width: 75%')
})

// set the clock ahead as if time has passed
cy.tick(2000)

cy.get('.runnable-active > .collapsible > .runnable-wrapper').click().click()
cy.get('.command-progress > span').should(($span) => {
expect($span.attr('style')).to.contain('animation-duration: 1000ms')
expect($span.attr('style')).to.contain('width: 25%')
})
})
})
})
})
16 changes: 9 additions & 7 deletions packages/reporter/src/collapsible/collapsible.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('<Collapsible />', () => {
it('renders with headerStyle when specified', () => {
const component = shallow(<Collapsible headerStyle={{ margin: 0 }} />)

expect(component.find('.collapsible-header')).to.have.style('margin', '0')
expect(component.find('.collapsible-header-inner')).to.have.style('margin', '0')
})

it('renders the header', () => {
Expand All @@ -40,19 +40,21 @@ describe('<Collapsible />', () => {
expect(component.find('.collapsible-content')).to.have.className('bar')
})

it('renders the children', () => {
const component = shallow(<Collapsible><main>A child</main></Collapsible>)

expect(component.find('.collapsible-content main')).to.have.text('A child')
})

it('opens when clicking header', () => {
const component = shallow(<Collapsible />)

component.find('.collapsible-header').simulate('click', { stopPropagation () {} })
expect(component).to.have.className('is-open')
})

it('renders the children only when open', () => {
const component = shallow(<Collapsible><main>A child</main></Collapsible>)

expect(component.find('.collapsible-content')).not.to.have.text('A child')
component.find('.collapsible-header').simulate('click', { stopPropagation () {} })
expect(component.find('.collapsible-content main')).to.have.text('A child')
})

it('closes when clicking header twice', () => {
const component = shallow(<Collapsible />)

Expand Down
15 changes: 7 additions & 8 deletions packages/reporter/src/collapsible/collapsible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,13 @@ class Collapsible extends Component<Props, State> {
onClick={this._onClick}
onKeyPress={onEnterOrSpace(this._onKeyPress)}
role='button'
style={this.props.headerStyle}
tabIndex={0}
>
<div className='collapsible-header-inner' tabIndex={-1}>
<div
className='collapsible-header-inner'
style={this.props.headerStyle}
tabIndex={-1}
>
<i className='collapsible-indicator fa-fw fas' />
<span className='collapsible-header-text'>
{this.props.header}
Expand All @@ -61,18 +64,14 @@ class Collapsible extends Component<Props, State> {
{this.props.headerExtras}
</div>
<div className={cs('collapsible-content', this.props.contentClass)}>
{this.props.children}
{this.state.isOpen && this.props.children}
</div>
</div>
)
}

_toggleOpen = () => {
this.setState({ isOpen: !this.state.isOpen }, () => {
if (this.props.toggleOpen) {
this.props.toggleOpen(this.state.isOpen)
}
})
this.setState({ isOpen: !this.state.isOpen })
}

_onClick = (e: MouseEvent) => {
Expand Down

0 comments on commit a1de94d

Please sign in to comment.