Skip to content

Commit

Permalink
add per test timeout recipe (#543)
Browse files Browse the repository at this point in the history
  • Loading branch information
bahmutov authored Aug 10, 2020
1 parent 1d82032 commit 318f5a8
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ Recipe | Description
[Cypress module API](./examples/fundamentals__module-api) | Run Cypress via its module API
[Wrapping Cypress module API](./examples/fundamentals__module-api-wrap) | Writing a wrapper around "cypress run" command line parsing
[Custom browsers](./examples/fundamentals__custom-browsers) | Control which browsers the project can use, or even add a custom browser into the list
[use Chrome Remote Interface](./examples/fundamentals__chrome-remote-debugging) | Use Chrome debugger protocol to trigger hover state and print media style
[Use Chrome Remote Interface](./examples/fundamentals__chrome-remote-debugging) | Use Chrome debugger protocol to trigger hover state and print media style
[Per-test timeout](./examples/fundamentals__timeout) | Fail a test if it runs longer than the specified time limit

## Testing the DOM

Expand Down
6 changes: 6 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ jobs:
<<: *defaults
fundamentals__fixtures:
<<: *defaults
fundamentals__timeout:
<<: *defaults
fundamentals__add-custom-command:
<<: *defaults
fundamentals__add-custom-command-ts:
Expand Down Expand Up @@ -510,6 +512,9 @@ all_jobs: &all_jobs
- fundamentals__fixtures:
requires:
- build
- fundamentals__timeout:
requires:
- build
- fundamentals__module-api:
requires:
- build
Expand Down Expand Up @@ -543,6 +548,7 @@ all_jobs: &all_jobs
- file-upload-react
- fundamentals__node-modules
- fundamentals__fixtures
- fundamentals__timeout
- fundamentals__dynamic-tests
- fundamentals__module-api
- fundamentals__module-api-wrap
Expand Down
13 changes: 13 additions & 0 deletions examples/fundamentals__timeout/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Test timeout

The example shows how to stop a test if it takes too long to execute, similar to [Mocha's timeout](https://mochajs.org/#test-level) option. See [cypress/integration/spec.js](cypress/integration/spec.js)

```js
// this test fails after two seconds due to timeout
it('does not finish long tests', () => {
testTimeout(2 * 1000)
cy.wait(10 * 1000)
})
```

![Test is too long](images/test-is-too-long.png)
5 changes: 5 additions & 0 deletions examples/fundamentals__timeout/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"fixturesFolder": false,
"pluginsFile": false,
"supportFile": false
}
59 changes: 59 additions & 0 deletions examples/fundamentals__timeout/cypress/integration/spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/// <reference types="cypress" />
/* eslint-disable no-console */

const seconds = (n) => n * 1000

/**
* Stops the current Cypress test if it takes longer than the provided timeout
* @param {number} ms Test timeout in milliseconds
* @example
* // stop and fail the test if it runs for longer than 10 seconds
* testTimeout(10 * 1000)
*/
function testTimeout (ms) {
// get the current test reference using
// the cy.state() magic method
const currentTest = cy.state('runnable')
const startedAt = +new Date()

setTimeout(() => {
const testNow = cy.state('runnable')

console.log('test started', currentTest)
console.log('test now', testNow)
console.log('test now state', testNow.state)

if (currentTest !== testNow) {
// different test already
return
}

if (testNow.state) {
// test has finished
return
}

const timeNow = +new Date()

console.log('elapsed %d limit %d', timeNow - startedAt, ms)
if (timeNow - startedAt >= ms) {
throw new Error(`Test ran longer than ${ms}ms`)
}
}, ms)
}

describe('Test timeout', () => {
// this test runs fine, because it finishes
// before the ten second limit expires
it('allows short tests', () => {
testTimeout(seconds(10))
cy.wait(seconds(5))
})

// this test fails after two seconds due to timeout
// NOTE: enable to see test timeout in action
it.skip('does not finish long tests', () => {
testTimeout(seconds(2))
cy.wait(seconds(10))
})
})
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions examples/fundamentals__timeout/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "test-timeout",
"version": "1.0.0",
"description": "Test throws an error if it runs over the time limit",
"scripts": {
"cypress:open": "../../node_modules/.bin/cypress open",
"cypress:run": "../../node_modules/.bin/cypress run",
"test:ci": "npm run cypress:run"
}
}

0 comments on commit 318f5a8

Please sign in to comment.