Skip to content

Commit

Permalink
Merge branch 'develop' into retry-flake
Browse files Browse the repository at this point in the history
  • Loading branch information
flotwig committed Oct 26, 2022
2 parents 0e99559 + 928315d commit 1ec4b6d
Show file tree
Hide file tree
Showing 192 changed files with 5,581 additions and 2,619 deletions.
3 changes: 2 additions & 1 deletion .vscode/cspell.json
Expand Up @@ -37,6 +37,7 @@
"topnav",
"unconfigured",
"unplugin",
"unref",
"unrunnable",
"unstaged",
"urql",
Expand All @@ -48,4 +49,4 @@
],
"ignoreWords": [],
"import": []
}
}
38 changes: 26 additions & 12 deletions cli/types/cypress.d.ts
Expand Up @@ -641,12 +641,6 @@ declare namespace Cypress {
*/
off: Actions

/**
* Used to import dependencies within the cy.origin() callback
* @see https://on.cypress.io/origin
*/
require: (id: string) => any

/**
* Trigger action
* @private
Expand Down Expand Up @@ -1095,7 +1089,7 @@ declare namespace Cypress {
*
* @see https://on.cypress.io/session
*/
session(id: string | object, setup?: () => void, options?: SessionOptions): Chainable<null>
session(id: string | object, setup: () => void, options?: SessionOptions): Chainable<null>

/**
* Get the window.document of the page that is currently active.
Expand Down Expand Up @@ -2814,12 +2808,32 @@ declare namespace Cypress {
*/
supportFile: string | false
/**
* The test isolation level applied to ensure a clean slate between tests.
* - legacy - resets/clears aliases, intercepts, clock, viewport, cookies, and local storage before each test.
* - strict - applies all resets/clears from legacy, plus clears the page by visiting 'about:blank' to ensure clean app state before each test.
* @default "legacy", however, when experimentalSessionAndOrigin=true, the default is "strict"
* The test isolation ensures a clean browser context between tests. This option is only available when
* `experimentalSessionAndOrigin=true`.
*
* Cypress will always reset/clear aliases, intercepts, clock, and viewport before each test
* to ensure a clean test slate; i.e. this configuration only impacts the browser context.
*
* Note: the [`cy.session()`](https://on.cypress.io/session) command will inherent this value to determine whether
* or not the page is cleared when the command executes. This command is only available in end-to-end testing.
*
* - on - The page is cleared before each test. Cookies, local storage and session storage in all domains are cleared
* before each test. The `cy.session()` command will also clear the page and current browser context when creating
* or restoring the browser session.
* - off - The current browser state will persist between tests. The page does not clear before the test and cookies, local
* storage and session storage will be available in the next test. The `cy.session()` command will only clear the
* current browser context when creating or restoring the browser session - the current page will not clear.
*
* Tradeoffs:
* Turning test isolation off may improve performance of end-to-end tests, however, previous tests could impact the
* browser state of the next test and cause inconsistency when using .only(). Be mindful to write isolated tests when
* test isolation is off. If a test in the suite impacts the state of other tests and it were to fail, you could see
* misleading errors in later tests which makes debugging clunky. See the [documentation](https://on.cypress.io/test-isolation)
* for more information.
*
* @default null, when experimentalSessionAndOrigin=false. The default is 'on' when experimentalSessionAndOrigin=true.
*/
testIsolation: 'legacy' | 'strict'
testIsolation: null | 'on' | 'off'
/**
* Path to folder where videos will be saved after a headless or CI run
* @default "cypress/videos"
Expand Down
2 changes: 1 addition & 1 deletion cli/types/tests/cypress-tests.ts
Expand Up @@ -922,7 +922,6 @@ namespace CypressTaskTests {
}

namespace CypressSessionsTests {
cy.session('user')
cy.session('user', () => {})
cy.session({ name: 'bob' }, () => {})
cy.session('user', () => {}, {})
Expand All @@ -931,6 +930,7 @@ namespace CypressSessionsTests {
})

cy.session() // $ExpectError
cy.session('user') // $ExpectError
cy.session(null) // $ExpectError
cy.session('user', () => {}, {
validate: { foo: true } // $ExpectError
Expand Down
7 changes: 4 additions & 3 deletions graphql-codegen.yml
Expand Up @@ -18,7 +18,7 @@ vueOperations: &vueOperations
- 'typescript-operations'
- 'typed-document-node':
# Intentionally specified under typed-document-node rather than top level config,
# becuase we don't want it flattening the types for the operations
# because we don't want it flattening the types for the operations
flattenGeneratedTypes: true

vueTesting: &vueTesting
Expand Down Expand Up @@ -122,9 +122,10 @@ generates:
'./packages/app/src/generated/graphql-test.ts':
documents:
- './packages/app/src/**/*.{vue,ts,tsx,js,jsx}'
- './packages/frontend-shared/src/**/*.{vue,ts,tsx,js,jsx}'
- './packages/frontend-shared/src/gql-components/**/*.{vue,ts,tsx,js,jsx}'
<<: *vueTesting

'./packages/frontend-shared/src/generated/graphql-test.ts':
documents: './packages/frontend-shared/src/gql-components/**/*.{vue,ts,tsx,js,jsx}'
documents:
- './packages/frontend-shared/src/gql-components/**/*.{vue,ts,tsx,js,jsx}'
<<: *vueTesting
6 changes: 6 additions & 0 deletions npm/grep/CHANGELOG.md
@@ -0,0 +1,6 @@
# [@cypress/grep-v3.1.0](https://github.com/cypress-io/cypress/compare/@cypress/grep-v3.0.3...@cypress/grep-v3.1.0) (2022-10-21)


### Features

* **grep:** move cypress-grep to @cypress/grep ([#23887](https://github.com/cypress-io/cypress/issues/23887)) ([d422aad](https://github.com/cypress-io/cypress/commit/d422aadfa10e5aaac17ed0e4dd5e18a73d821490))
7 changes: 7 additions & 0 deletions npm/webpack-dev-server/CHANGELOG.md
@@ -1,3 +1,10 @@
# [@cypress/webpack-dev-server-v2.4.1](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v2.4.0...@cypress/webpack-dev-server-v2.4.1) (2022-10-19)


### Bug Fixes

* clean up inconsistencies in UI between sentence case and title case ([#23681](https://github.com/cypress-io/cypress/issues/23681)) ([f73aef5](https://github.com/cypress-io/cypress/commit/f73aef54b041fe08d939b52e5c6fe1d133502051))

# [@cypress/webpack-dev-server-v2.4.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v2.3.0...@cypress/webpack-dev-server-v2.4.0) (2022-10-13)


Expand Down
7 changes: 7 additions & 0 deletions npm/webpack-preprocessor/CHANGELOG.md
@@ -1,3 +1,10 @@
# [@cypress/webpack-preprocessor-v5.15.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-preprocessor-v5.14.0...@cypress/webpack-preprocessor-v5.15.0) (2022-10-19)


### Features

* Enable requiring cy.origin dependencies with require() and import() ([#24294](https://github.com/cypress-io/cypress/issues/24294)) ([1b29ce7](https://github.com/cypress-io/cypress/commit/1b29ce74aafa0bc5015a93cb618b7fbda243e07a))

# [@cypress/webpack-preprocessor-v5.14.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-preprocessor-v5.13.1...@cypress/webpack-preprocessor-v5.14.0) (2022-10-04)


Expand Down
4 changes: 2 additions & 2 deletions npm/webpack-preprocessor/index.ts
Expand Up @@ -341,8 +341,8 @@ const preprocessor: WebpackPreprocessor = (options: PreprocessorOptions = {}): F
bundles[filePath].deferreds.length = 0
}

// the cross-origin-callback-loader extracts any cy.origin() callback
// functions that contains Cypress.require() and stores their sources
// the cross-origin-callback-loader extracts any cross-origin callback
// functions that require dependencies and stores their sources
// in the CrossOriginCallbackStore. it saves the callbacks per source
// files, since that's the context it has. here we need to unfurl
// what dependencies the input source file has so we can know which
Expand Down
Expand Up @@ -68,7 +68,7 @@ interface CompileOptions {
}

// the cross-origin-callback-loader extracts any cy.origin() callback functions
// that contains Cypress.require() and stores their sources in the
// that includes dependencies and stores their sources in the
// CrossOriginCallbackStore. this sends those sources through webpack again
// to process any dependencies and create bundles for each callback function
export const compileCrossOriginCallbackFiles = (files: CrossOriginCallbackStoreFile[], options: CompileOptions): Promise<void> => {
Expand Down
52 changes: 20 additions & 32 deletions npm/webpack-preprocessor/lib/cross-origin-callback-loader.ts
Expand Up @@ -12,21 +12,13 @@ import utils from './utils'

const debug = Debug('cypress:webpack')

// this loader makes supporting dependencies within the cy.origin() callbacks
// possible. it does this by doing the following:
// - extracting callback(s)
// - the callback(s) is/are kept in memory and then run back through webpack
// this loader makes supporting dependencies within cross-origin callbacks
// possible. if there are no dependencies (e.g. no requires/imports), it's a
// noop. otherwise: it does this by doing the following:
// - extracts the callbacks
// - the callbacks are kept in memory and then run back through webpack
// once the initial file compilation is complete
// - users use Cypress.require() in their test code instead of require().
// this is because we don't want require()s nested within the callback
// to be processed in the initial compilation. this both improves
// performance and prevents errors (when the dependency has ES import
// statements, babel will error because they're not top-level since
// the require is not top-level)
// - replacing Cypress.require() with require()
// - this allows the require()s to be processed normally during the
// compilation of the callback itself.
// - replacing the callback(s) with object(s)
// - replaces the callbacks with objects
// - this object references the file the callback will be output to by
// its own compilation. this allows the runtime to get the file and
// run it in its origin's context.
Expand Down Expand Up @@ -77,9 +69,9 @@ export default function (source: string, map, meta, store = crossOriginCallbackS

const lastArg = _.last(path.get('arguments'))

// the user could try an invalid signature for cy.origin() where the
// last argument is not a function. in this case, we'll return the
// unmodified code and it will be a runtime validation error
// the user could try an invalid signature where the last argument is
// not a function. in this case, we'll return the unmodified code and
// it will be a runtime validation error
if (
!lastArg || (
!lastArg.isArrowFunctionExpression()
Expand All @@ -89,21 +81,17 @@ export default function (source: string, map, meta, store = crossOriginCallbackS
return
}

// replace instances of Cypress.require('dep') with require('dep')
// determine if there are any requires/imports within the callback
lastArg.traverse({
CallExpression (path) {
const callee = path.get('callee') as NodePath<t.MemberExpression>

// e.g. const dep = Cypress.require('../path/to/dep')
if (callee.matchesPattern('Cypress.require')) {
if (
// e.g. const dep = require('../path/to/dep')
// @ts-ignore
path.node.callee.name === 'require'
// e.g. const dep = await import('../path/to/dep')
|| path.node.callee.type as string === 'Import'
) {
hasDependencies = true

path.replaceWith(
t.callExpression(
callee.node.property as t.Expression, // 'require'
path.get('arguments').map((arg) => arg.node), // ['../path/to/dep']
),
)
}
},
}, this)
Expand Down Expand Up @@ -150,7 +138,7 @@ export default function (source: string, map, meta, store = crossOriginCallbackS
// replaces callback function with object referencing the extracted
// function's callback name and output file path in the form
// { callbackName: <callbackName>, outputFilePath: <outputFilePath> }
// this is used at runtime when cy.origin() is run to execute the bundle
// this is used at runtime when the command is run to execute the bundle
// generated for the extracted callback function
lastArg.replaceWith(
t.objectExpression([
Expand All @@ -167,7 +155,7 @@ export default function (source: string, map, meta, store = crossOriginCallbackS
},
})

// if we found Cypress.require()s, re-generate the code from the AST
// if we found requires/imports, re-generate the code from the AST
if (hasDependencies) {
debug('callback with modified source')

Expand All @@ -183,6 +171,6 @@ export default function (source: string, map, meta, store = crossOriginCallbackS
}

debug('callback with original source')
// if no Cypress.require()s were found, callback with the original source/map
// if no requires/imports were found, callback with the original source/map
this.callback(null, source, map)
}
Expand Up @@ -61,7 +61,7 @@ describe('./lib/cross-origin-callback-loader', () => {
expect(store.addFile).not.to.be.called
})

it('is a noop when cy.origin() callback does not contain Cypress.require()', () => {
it('is a noop when cy.origin() callback does not contain require() or import()', () => {
const source = `it('test', () => {
cy.origin('http://www.foobar.com:3500', () => {})
})`
Expand Down Expand Up @@ -90,11 +90,30 @@ describe('./lib/cross-origin-callback-loader', () => {
sinon.stub(utils, 'tmpdir').returns('/path/to/tmp')
})

it('replaces cy.origin() callback with an object', () => {
it('replaces cy.origin() callback with an object when using require()', () => {
const { resultingSource, resultingMap } = callLoader(stripIndent`
it('test', () => {
cy.origin('http://www.foobar.com:3500', () => {
Cypress.require('../support/utils')
require('../support/utils')
})
})`)

expect(resultingSource).to.equal(stripIndent`
it('test', () => {
cy.origin('http://www.foobar.com:3500', {
"callbackName": "__cypressCrossOriginCallback",
"outputFilePath": "/path/to/tmp/cross-origin-cb-abc123.js"
});
});`)

expect(resultingMap).to.be.undefined
})

it('replaces cy.origin() callback with an object when using import()', () => {
const { resultingSource, resultingMap } = callLoader(stripIndent`
it('test', () => {
cy.origin('http://www.foobar.com:3500', async () => {
await import('../support/utils')
})
})`)

Expand All @@ -113,7 +132,7 @@ describe('./lib/cross-origin-callback-loader', () => {
const { resultingSource, resultingMap } = callLoader(stripIndent`
it('test', () => {
cy.other('http://www.foobar.com:3500', () => {
Cypress.require('../support/utils')
require('../support/utils')
})
})`,
['other'])
Expand All @@ -129,11 +148,11 @@ describe('./lib/cross-origin-callback-loader', () => {
expect(resultingMap).to.be.undefined
})

it('adds the file to the store, replacing Cypress.require() with require()', () => {
it('adds the file to the store, replacing require() with require()', () => {
const { store } = callLoader(
`it('test', () => {
cy.origin('http://www.foobar.com:3500', () => {
Cypress.require('../support/utils')
require('../support/utils')
})
})`,
)
Expand All @@ -149,7 +168,7 @@ describe('./lib/cross-origin-callback-loader', () => {
const { store } = callLoader(
`it('test', () => {
cy.origin('http://www.foobar.com:3500', function () {
Cypress.require('../support/utils')
require('../support/utils')
})
})`,
)
Expand All @@ -164,7 +183,7 @@ describe('./lib/cross-origin-callback-loader', () => {
const { store } = callLoader(
`it('test', () => {
cy.origin('http://www.foobar.com:3500', () => {
Cypress.require('../support/utils')
require('../support/utils')
})
})`,
)
Expand All @@ -179,7 +198,7 @@ describe('./lib/cross-origin-callback-loader', () => {
const { store } = callLoader(
`it('test', () => {
cy.origin('http://www.foobar.com:3500', () => {
const utils = Cypress.require('../support/utils')
const utils = require('../support/utils')
utils.foo()
})
})`,
Expand All @@ -193,13 +212,13 @@ describe('./lib/cross-origin-callback-loader', () => {
}`)
})

it('works with multiple Cypress.require()s', () => {
it('works with multiple require()s', () => {
const { store } = callLoader(
`it('test', () => {
cy.origin('http://www.foobar.com:3500', () => {
Cypress.require('../support/commands')
const utils = Cypress.require('../support/utils')
const _ = Cypress.require('lodash')
require('../support/commands')
const utils = require('../support/utils')
const _ = require('lodash')
})
})`,
)
Expand All @@ -220,7 +239,7 @@ describe('./lib/cross-origin-callback-loader', () => {
cy
.wrap({})
.origin('http://www.foobar.com:3500', () => {
Cypress.require('../support/commands')
require('../support/commands')
})
})`,
)
Expand All @@ -236,7 +255,7 @@ describe('./lib/cross-origin-callback-loader', () => {
`it('test', () => {
cy.origin('http://www.foobar.com:3500', () => {
const someVar = 'someValue'
const result = Cypress.require('./fn')(someVar)
const result = require('./fn')(someVar)
expect(result).to.equal('mutated someVar')
})
})`,
Expand All @@ -256,7 +275,7 @@ describe('./lib/cross-origin-callback-loader', () => {
const { store } = callLoader(
`it('test', () => {
cy.origin('http://www.foobar.com:3500', { args: { foo: 'foo'}}, ({ foo }) => {
const result = Cypress.require('./fn')(foo)
const result = require('./fn')(foo)
expect(result).to.equal('mutated someVar')
})
})`,
Expand Down

5 comments on commit 1ec4b6d

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1ec4b6d Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.11.1/linux-x64/retry-flake-1ec4b6d9018e5723a6ede0518d6d9f17813ca7d9/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1ec4b6d Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.11.1/linux-arm64/retry-flake-1ec4b6d9018e5723a6ede0518d6d9f17813ca7d9/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1ec4b6d Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.11.1/darwin-x64/retry-flake-1ec4b6d9018e5723a6ede0518d6d9f17813ca7d9/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1ec4b6d Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.11.1/win32-x64/retry-flake-1ec4b6d9018e5723a6ede0518d6d9f17813ca7d9/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1ec4b6d Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.11.1/darwin-arm64/retry-flake-1ec4b6d9018e5723a6ede0518d6d9f17813ca7d9/cypress.tgz

Please sign in to comment.