Skip to content

Commit

Permalink
temp 02/14/20 [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
kuceb committed Feb 14, 2020
1 parent b81af00 commit bf8bc35
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 24 deletions.
82 changes: 77 additions & 5 deletions cli/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ declare namespace Cypress {
(task: 'firefox:force:gc'): Promise<void>
}

type BrowserName = 'electron' | 'chrome' | 'chromium' | 'firefox' | string
type BrowserName = 'electron' | 'chrome' | 'chromium' | 'firefox' | 'edge' | 'brave' | string

type BrowserChannel = 'stable' | 'canary' | 'beta' | 'dev' | 'nightly' | string

Expand Down Expand Up @@ -122,6 +122,8 @@ declare namespace Cypress {
clear: (keys?: string[]) => void
}

type IsBrowserMatcher = BrowserName | Partial<Browser>

/**
* Several libraries are bundled with Cypress by default.
*
Expand Down Expand Up @@ -335,11 +337,12 @@ declare namespace Cypress {
isCy(obj: any): obj is Chainable

/**
* Checks if you're running in the supplied browser family.
* e.g. isBrowser('Chrome') will be true for the browser 'Canary'
* @param name browser family name to check
* Returns true if currently running the supplied browser name or matcher object.
* @example isBrowser('chrome') will be true for the browser 'chrome:canary' and 'chrome:stable'
* @example isBrowser({ name: 'firefox' channel: 'dev' }) will be true only for the browser 'firefox:dev' (Firefox Developer Edition)
* @param matcher browser name or matcher object to check.
*/
isBrowser(name: string): boolean
isBrowser(matcher: IsBrowserMatcher): boolean

/**
* Internal options for "cy.log" used in custom commands.
Expand Down Expand Up @@ -2281,6 +2284,11 @@ declare namespace Cypress {
firefoxGcInterval: Nullable<number | { runMode: Nullable<number>, openMode: Nullable<number> }>
}

interface TestConfigOptions extends Partial<Pick<ConfigOptions, 'baseUrl' | 'defaultCommandTimeout' | 'animationDistanceThreshold' | 'waitForAnimations' | 'viewportHeight' | 'viewportWidth' | 'requestTimeout' | 'execTimeout' | 'env' | 'responseTimeout'>> {
// retries?: number
browser?: IsBrowserMatcher | IsBrowserMatcher[]
}

interface DebugOptions {
verbose: boolean
}
Expand Down Expand Up @@ -4662,3 +4670,67 @@ Cypress._ // => Lodash _
```
*/
declare const Cypress: Cypress.Cypress & EventEmitter

declare namespace Mocha {
interface TestFunction {
/**
* Describe a specification or test-case with the given `title` and callback `fn` acting
* as a thunk.
*
* - _Only available when invoked via the mocha CLI._
*/
(title: string, config: Cypress.TestConfigOptions, fn?: Func): Test

/**
* Describe a specification or test-case with the given `title` and callback `fn` acting
* as a thunk.
*
* - _Only available when invoked via the mocha CLI._
*/
(title: string, config: Cypress.TestConfigOptions, fn?: AsyncFunc): Test
}
interface ExclusiveTestFunction {
/**
* Describe a specification or test-case with the given `title` and callback `fn` acting
* as a thunk.
*
* - _Only available when invoked via the mocha CLI._
*/
(title: string, config: Cypress.TestConfigOptions, fn?: Func): Test

/**
* Describe a specification or test-case with the given `title` and callback `fn` acting
* as a thunk.
*
* - _Only available when invoked via the mocha CLI._
*/
(title: string, config: Cypress.TestConfigOptions, fn?: AsyncFunc): Test
}
interface PendingTestFunction {
/**
* Describe a specification or test-case with the given `title` and callback `fn` acting
* as a thunk.
*
* - _Only available when invoked via the mocha CLI._
*/
(title: string, config: Cypress.TestConfigOptions, fn?: Func): Test

/**
* Describe a specification or test-case with the given `title` and callback `fn` acting
* as a thunk.
*
* - _Only available when invoked via the mocha CLI._
*/
(title: string, config: Cypress.TestConfigOptions, fn?: AsyncFunc): Test
}

interface SuiteFunction {
/**
* [bdd, tdd] Describe a "suite" with the given `title` and callback `fn` containing
* nested suites.
*
* - _Only available when invoked via the mocha CLI._
*/
(title: string, config: Cypress.TestConfigOptions, fn: (this: Suite) => void): Suite
}
}
28 changes: 28 additions & 0 deletions cli/types/tests/cypress-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,31 @@ namespace CypressLocationTests {
cy.location('path') // $ExpectError
cy.location('pathname') // $ExpectType Chainable<string>
}

namespace CypressBrowserTests {
Cypress.isBrowser('chrome')// $ExpectType boolean
Cypress.isBrowser('firefox')// $ExpectType boolean
Cypress.isBrowser('edge')// $ExpectType boolean
Cypress.isBrowser('brave')// $ExpectType boolean
Cypress.isBrowser({channel: 'stable'})// $ExpectType boolean
Cypress.isBrowser({family: 'chromium'})// $ExpectType boolean
Cypress.isBrowser({name: 'chrome'})// $ExpectType boolean
Cypress.isBrowser({family: 'foo'}) // $ExpectError
Cypress.isBrowser() // $ExpectError
}

namespace CypressTestConfigTests {
it('test', {
browser: {name: 'firefox'}
}, () => {})
it('test', {
browser: [{name: 'firefox'}, {name: 'chrome'}]
}, () => {})
it('test', {
baseUrl: 'www.foobar.com',
browser: 'firefox'
}, () => {})
it('test', {
browser: {foo: 'bar'} // $ExpectError
}, () => {})
}
69 changes: 67 additions & 2 deletions packages/driver/src/cypress/mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,69 @@ const runnableResetTimeout = Runnable.prototype.resetTimeout
delete window.mocha
delete window.Mocha

function overrideMochaIt (specWindow) {
const _it = specWindow.it

function overrideIt (fn) {
specWindow.it = fn()
specWindow.it['only'] = fn('only')
specWindow.it['skip'] = fn('skip')
}

overrideIt(function (subFn) {
return function (...args) {
/**
* @type {Cypress.Cypress}
*/
const Cypress = specWindow.Cypress

function shouldRunBrowser (browserlist, browser) {
if (browserlist === null) {
return true
}

if (!_.isArray(browserlist)) {
browserlist = [browserlist]
}

return _.some(browserlist, Cypress.isBrowser)
}

const origIt = subFn ? _it[subFn] : _it

if (args.length > 2 && _.isObject(args[1])) {
const opts = _.defaults({}, args[1], {
browser: null,
})

const mochaArgs = [args[0], args[2]]

if (!shouldRunBrowser(opts.browser)) {
mochaArgs[0] = `[browser skip (${opts.browser})]${mochaArgs[0]}`

if (subFn === 'only') {
mochaArgs[1] = function () {
this.skip()
}

return origIt.apply(this, mochaArgs)
}

return _it['skip'].apply(this, mochaArgs)
}

const ret = origIt.apply(this, mochaArgs)

ret.testConfiguration = opts

return ret
}

return origIt.apply(this, args)
}
})
}

const ui = (specWindow, _mocha) => {
// Override mocha.ui so that the pre-require event is emitted
// with the iframe's `window` reference, rather than the parent's.
Expand All @@ -34,13 +97,15 @@ const ui = (specWindow, _mocha) => {
// such as describe, it, before, beforeEach, etc
this.suite.emit('pre-require', specWindow, null, this)

overrideMochaIt(specWindow)

return this
}

return _mocha.ui('bdd')
}

const set = (specWindow, _mocha) => {
const setMochaProps = (specWindow, _mocha) => {
// Mocha is usually defined in the spec when used normally
// in the browser or node, so we add it as a global
// for our users too
Expand All @@ -67,7 +132,7 @@ const globals = (specWindow, reporter) => {
})

// set mocha props on the specWindow
set(specWindow, _mocha)
setMochaProps(specWindow, _mocha)

// return the newly created mocha instance
return _mocha
Expand Down
2 changes: 1 addition & 1 deletion packages/driver/src/cypress/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const TEST_AFTER_RUN_EVENT = 'runner:test:after:run'

const ERROR_PROPS = 'message type name stack fileName lineNumber columnNumber host uncaught actual expected showDiff isPending'.split(' ')
const RUNNABLE_LOGS = 'routes agents commands'.split(' ')
const RUNNABLE_PROPS = 'id order title root hookName hookId err state failedFromHookId body speed type duration wallClockStartedAt wallClockDuration timings file'.split(' ')
const RUNNABLE_PROPS = 'id order title root hookName hookId err state failedFromHookId body speed type duration wallClockStartedAt wallClockDuration timings file testConfiguration'.split(' ')

// ## initial payload
// {
Expand Down
106 changes: 106 additions & 0 deletions packages/driver/test/cypress/integration/e2e/test-config.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* eslint-disable @cypress/dev/skip-comment,mocha/no-exclusive-tests */
/// <reference path="../../../../../../cli/types/index.d.ts" />
// @ts-check

const testState = {
ranFirefox: false,
ranChrome: false,
}

describe('per-test config', () => {
after(() => {
if (Cypress.browser.name === 'firefox') {
return expect(testState).deep.eq({
ranChrome: false,
ranFirefox: true,
})
}

if (Cypress.browser.name === 'chrome') {
return expect(testState).deep.eq({
ranChrome: true,
ranFirefox: false,
})
}

throw new Error('should have made assertion')
})

it('set various config values', {
defaultCommandTimeout: 200,
env: {
FOO_VALUE: 'foo',
},
}, () => {
expect(Cypress.config().defaultCommandTimeout).eq(200)
expect(Cypress.config('defaultCommandTimeout')).eq(200)
expect(Cypress.env('FOO_VALUE')).eq('foo')
})

it('does not leak various config values', {
}, () => {
expect(Cypress.config().defaultCommandTimeout).not.eq(200)
expect(Cypress.config('defaultCommandTimeout')).not.eq(200)
expect(Cypress.env('FOO_VALUE')).not.eq('foo')
})

it('can set viewport', {
viewportWidth: 400,
viewportHeight: 200,
}, () => {
expect(Cypress.config().viewportHeight).eq(200)
expect(Cypress.config().viewportWidth).eq(400)
})

it('can specify only run in chrome', {
browser: 'chrome',
}, () => {
testState.ranChrome = true
expect(Cypress.browser.name).eq('chrome')
})

it('can specify only run in firefox', {
browser: 'firefox',
}, () => {
testState.ranFirefox = true
expect(Cypress.browser.name).eq('firefox')
})

describe('in beforeEach', () => {
it('set various config values', {
defaultCommandTimeout: 200,
env: {
FOO_VALUE: 'foo',
},
}, () => {
expect(Cypress.config().defaultCommandTimeout).eq(200)
expect(Cypress.config('defaultCommandTimeout')).eq(200)
expect(Cypress.env('FOO_VALUE')).eq('foo')
})

beforeEach(() => {
expect(Cypress.config().defaultCommandTimeout).eq(200)
expect(Cypress.config('defaultCommandTimeout')).eq(200)
expect(Cypress.env('FOO_VALUE')).eq('foo')
})
})

describe('in afterEach', () => {
it('set various config values', {
defaultCommandTimeout: 200,
env: {
FOO_VALUE: 'foo',
},
}, () => {
expect(Cypress.config().defaultCommandTimeout).eq(200)
expect(Cypress.config('defaultCommandTimeout')).eq(200)
expect(Cypress.env('FOO_VALUE')).eq('foo')
})

afterEach(() => {
expect(Cypress.config().defaultCommandTimeout).eq(200)
expect(Cypress.config('defaultCommandTimeout')).eq(200)
expect(Cypress.env('FOO_VALUE')).eq('foo')
})
})
})
32 changes: 16 additions & 16 deletions packages/driver/test/cypress/support/defaults.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ $ = Cypress.$
## backup the original config
ORIG_CONFIG = _.clone(Cypress.config())

beforeEach ->
## restore it before each test
Cypress.config(ORIG_CONFIG)
# beforeEach ->
# ## restore it before each test
# Cypress.config(ORIG_CONFIG)

## always set that we're interactive so we
## get consistent passes and failures when running
## from CI and when running in GUI mode
Cypress.config("isInteractive", true)
## necessary or else snapshots will not be taken
## and we can't test them
Cypress.config("numTestsKeptInMemory", 1)
# ## always set that we're interactive so we
# ## get consistent passes and failures when running
# ## from CI and when running in GUI mode
# Cypress.config("isInteractive", true)
# ## necessary or else snapshots will not be taken
# ## and we can't test them
# Cypress.config("numTestsKeptInMemory", 1)

## remove all event listeners
## from the window
## this could fail if this window
## is a cross origin window
try
$(cy.state("window")).off()
# ## remove all event listeners
# ## from the window
# ## this could fail if this window
# ## is a cross origin window
# try
# $(cy.state("window")).off()
Loading

0 comments on commit bf8bc35

Please sign in to comment.