Skip to content

Commit

Permalink
cleanup code, add better e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kuceb committed Apr 20, 2020
1 parent 6c7ba0f commit 16e963b
Show file tree
Hide file tree
Showing 10 changed files with 321 additions and 8 deletions.
38 changes: 31 additions & 7 deletions packages/driver/src/cypress/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,16 @@ const create = function (specWindow, mocha, Cypress, cy) {
return _testsById[id]
}

function hasTestAlreadyRun (test) {
if (Cypress._RESUMED_AT_TEST) {
if (+test.id.slice(1) < +Cypress._RESUMED_AT_TEST.slice(1)) {
return true
}
}

return false
}

overrideRunnerHook(Cypress, _runner, getTestById, getTest, setTest, getTests)

return {
Expand Down Expand Up @@ -962,6 +972,27 @@ const create = function (specWindow, mocha, Cypress, cy) {
break
}

// if this isnt a hook, then the name is 'test'
const hookName = runnable.type === 'hook' ? getHookName(runnable) : 'test'

// extract out the next(fn) which mocha uses to
// move to the next runnable - this will be our async seam
const _next = args[0]

if (hasTestAlreadyRun(test)) {
// NOTE: this is a hack to work around another cypress bug
// where the currentTest of a global after hook
// can be the wrong test after top navigation occurs
// (no open issue since it isn't user-facing for the most part)

// A failing after hook will also not show up as a failing test in open mode
// (only a visual bug - does not affect run mode)
// https://github.com/cypress-io/cypress/issues/2296
if (!(hookName === 'after all' && runnable.parent.root)) {
return _next()
}
}

// closure for calculating the actual
// runtime of a runnables fn exection duration
// and also the run of the runnable:after:run:async event
Expand All @@ -986,9 +1017,6 @@ const create = function (specWindow, mocha, Cypress, cy) {
test.wallClockStartedAt = wallClockStartedAt
}

// if this isnt a hook, then the name is 'test'
const hookName = runnable.type === 'hook' ? getHookName(runnable) : 'test'

// if we haven't yet fired this event for this test
// that means that we need to reset the previous state
// of cy - since we now have a new 'test' and all of the
Expand All @@ -997,10 +1025,6 @@ const create = function (specWindow, mocha, Cypress, cy) {
fire(TEST_BEFORE_RUN_EVENT, test, Cypress)
}

// extract out the next(fn) which mocha uses to
// move to the next runnable - this will be our async seam
const _next = args[0]

const next = function (err) {
// now set the duration of the after runnable run async event
afterFnDurationEnd = (wallClockEnd = new Date())
Expand Down
127 changes: 127 additions & 0 deletions packages/server/__snapshots__/3_issue_1987.ts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
exports['e2e issue 1987 / can reload during spec run'] = `
====================================================================================================
(Run Starting)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Cypress: 1.2.3 │
│ Browser: FooBrowser 88 │
│ Specs: 1 found (beforehook-and-test-navigation.js) │
│ Searched: cypress/integration/beforehook-and-test-navigation.js │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
────────────────────────────────────────────────────────────────────────────────────────────────────
Running: beforehook-and-test-navigation.js (1 of 1)
suite
✓ test
✓ causes domain navigation
2 passing
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 2 │
│ Passing: 2 │
│ Failing: 0 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 0 │
│ Video: true │
│ Duration: X seconds │
│ Spec Ran: beforehook-and-test-navigation.js │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
(Video)
- Started processing: Compressing to 32 CRF
- Finished processing: /XXX/XXX/XXX/cypress/videos/beforehook-and-test-navigation. (X second)
js.mp4
====================================================================================================
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ beforehook-and-test-navigation.js XX:XX 2 2 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! XX:XX 2 2 - - -
`

exports['e2e issue 1987 / can run proper amount of hooks'] = `
====================================================================================================
(Run Starting)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Cypress: 1.2.3 │
│ Browser: FooBrowser 88 │
│ Specs: 1 found (afterhooks.spec.js) │
│ Searched: cypress/integration/afterhooks.spec.js │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
────────────────────────────────────────────────────────────────────────────────────────────────────
Running: afterhooks.spec.js (1 of 1)
suite 1
✓ test 1
✓ test 2
suite 2
✓ s2t1
3 passing
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 3 │
│ Passing: 3 │
│ Failing: 0 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 0 │
│ Video: true │
│ Duration: X seconds │
│ Spec Ran: afterhooks.spec.js │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
(Video)
- Started processing: Compressing to 32 CRF
- Finished processing: /XXX/XXX/XXX/cypress/videos/afterhooks.spec.js.mp4 (X second)
====================================================================================================
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ afterhooks.spec.js XX:XX 3 3 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! XX:XX 3 3 - - -
`
29 changes: 29 additions & 0 deletions packages/server/test/e2e/3_issue_1987.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const e2e = require('../support/helpers/e2e')
const Fixtures = require('../support/helpers/fixtures')

describe('e2e issue 1987', () => {
e2e.setup({
servers: [{
port: 3434,
static: true,
},
{
port: 4545,
static: true,
}],
})

// https://github.com/cypress-io/cypress/issues/1987
// before/after hooks should not be rerun on top navigation
e2e.it('can reload during spec run', {
project: Fixtures.projectPath('hooks-after-rerun'),
spec: 'beforehook-and-test-navigation.js',
snapshot: true,
})

e2e.it('can run proper amount of hooks', {
project: Fixtures.projectPath('hooks-after-rerun'),
spec: 'afterhooks.spec.js',
snapshot: true,
})
})
2 changes: 1 addition & 1 deletion packages/server/test/integration/cypress_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe('lib/cypress', () => {
require('mocha-banner').register()

beforeEach(function () {
this.timeout(5000)
this.timeout(8000)

cache.__removeSync()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
describe('suite 1', () => {
before(() => {
cy.task('incrState', 'b1')
})

it('test 1', () => {
cy.task('incrState', 't1')
cy.visit('http://localhost:3434')
})

it('test 2', () => {
cy.task('incrState', 't2')
})

after(() => {
cy.task('incrState', 'a1')
})
})

describe('suite 2', () => {
it('s2t1', () => {
cy.task('incrState', 's2t1')
cy.visit('http://localhost:4545')
})
})

after(() => {
cy.task('incrState', 'a2')
cy.task('getState').then((state) => {
expect(state).deep.eq({
// initial domain change causes 2 runs
'b1': 2,
't1': 2,
't2': 1,
'a1': 1,
// domain change causes 2 runs
's2t1': 2,
'a2': 1,
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
describe('suite', () => {
before(() => {
// will cause infinite top navigation
cy.visit('http://localhost:3434')
})

it('test', () => {
})

it('causes domain navigation', () => {
cy.visit('http://localhost:4545')
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

const state = {}

/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
on('task', {
incrState (arg) {
state[arg] = state[arg] + 1 || 1

return null
},
getState () {
return state
} })

// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')

0 comments on commit 16e963b

Please sign in to comment.