feat: Added experimentalOriginDependencies to gate dependencies support within cy.origin (#24931)

* adding experimentalOriginDependencies flag

* update system tests
This commit is contained in:
Matt Schile
2022-12-01 14:40:05 -07:00
committed by GitHub
parent e8898d2f6b
commit 98efdf45b3
20 changed files with 228 additions and 9 deletions
+5
View File
@@ -3025,6 +3025,11 @@ declare namespace Cypress {
* @default false
*/
experimentalRunAllSpecs?: boolean
/**
* Enables support for require/import within cy.origin.
* @default false
*/
experimentalOriginDependencies?: boolean
}
/**
@@ -38,6 +38,7 @@ exports['config/src/index .getDefaultValues returns list of public config keys 1
'experimentalInteractiveRunEvents': false,
'experimentalRunAllSpecs': false,
'experimentalModifyObstructiveThirdPartyCode': false,
'experimentalOriginDependencies': false,
'experimentalSourceRewriting': false,
'experimentalSingleTabRunMode': false,
'experimentalStudio': false,
@@ -122,6 +123,7 @@ exports['config/src/index .getDefaultValues returns list of public config keys f
'experimentalInteractiveRunEvents': false,
'experimentalRunAllSpecs': false,
'experimentalModifyObstructiveThirdPartyCode': false,
'experimentalOriginDependencies': false,
'experimentalSourceRewriting': false,
'experimentalSingleTabRunMode': false,
'experimentalStudio': false,
@@ -202,6 +204,7 @@ exports['config/src/index .getPublicConfigKeys returns list of public config key
'experimentalInteractiveRunEvents',
'experimentalRunAllSpecs',
'experimentalModifyObstructiveThirdPartyCode',
'experimentalOriginDependencies',
'experimentalSourceRewriting',
'experimentalSingleTabRunMode',
'experimentalStudio',
+16 -3
View File
@@ -215,6 +215,11 @@ const driverConfigOptions: Array<DriverConfigOption> = [
validation: validate.isBoolean,
isExperimental: true,
requireRestartOnChange: 'server',
}, {
name: 'experimentalOriginDependencies',
defaultValue: false,
validation: validate.isBoolean,
isExperimental: true,
}, {
name: 'experimentalSourceRewriting',
defaultValue: false,
@@ -668,6 +673,12 @@ export const breakingRootOptions: Array<BreakingOption> = [
isWarning: false,
testingTypes: ['e2e'],
},
{
name: 'experimentalOriginDependencies',
errorKey: 'EXPERIMENTAL_ORIGIN_DEPENDENCIES_E2E_ONLY',
isWarning: false,
testingTypes: ['e2e'],
},
]
export const testingTypeBreakingOptions: { e2e: Array<BreakingOption>, component: Array<BreakingOption> } = {
@@ -676,7 +687,6 @@ export const testingTypeBreakingOptions: { e2e: Array<BreakingOption>, component
name: 'experimentalSingleTabRunMode',
errorKey: 'EXPERIMENTAL_SINGLE_TAB_RUN_MODE',
isWarning: false,
testingTypes: ['e2e'],
},
{
name: 'indexHtmlFile',
@@ -694,7 +704,6 @@ export const testingTypeBreakingOptions: { e2e: Array<BreakingOption>, component
name: 'experimentalStudio',
errorKey: 'EXPERIMENTAL_STUDIO_E2E_ONLY',
isWarning: false,
testingTypes: ['component'],
},
{
name: 'testIsolation',
@@ -705,7 +714,11 @@ export const testingTypeBreakingOptions: { e2e: Array<BreakingOption>, component
name: 'experimentalRunAllSpecs',
errorKey: 'EXPERIMENTAL_RUN_ALL_SPECS_E2E_ONLY',
isWarning: false,
testingTypes: ['component'],
},
{
name: 'experimentalOriginDependencies',
errorKey: 'EXPERIMENTAL_ORIGIN_DEPENDENCIES_E2E_ONLY',
isWarning: false,
},
],
}
@@ -1054,6 +1054,7 @@ describe('config/src/project/utils', () => {
experimentalModifyObstructiveThirdPartyCode: { value: false, from: 'default' },
experimentalFetchPolyfill: { value: false, from: 'default' },
experimentalInteractiveRunEvents: { value: false, from: 'default' },
experimentalOriginDependencies: { value: false, from: 'default' },
experimentalRunAllSpecs: { value: false, from: 'default' },
experimentalSingleTabRunMode: { value: false, from: 'default' },
experimentalStudio: { value: false, from: 'default' },
@@ -1148,6 +1149,7 @@ describe('config/src/project/utils', () => {
experimentalModifyObstructiveThirdPartyCode: { value: false, from: 'default' },
experimentalFetchPolyfill: { value: false, from: 'default' },
experimentalInteractiveRunEvents: { value: false, from: 'default' },
experimentalOriginDependencies: { value: false, from: 'default' },
experimentalRunAllSpecs: { value: false, from: 'default' },
experimentalSingleTabRunMode: { value: false, from: 'default' },
experimentalStudio: { value: false, from: 'default' },
+1
View File
@@ -18,6 +18,7 @@ export default defineConfig({
configFile: '../../mocha-reporter-config.json',
},
e2e: {
experimentalOriginDependencies: true,
setupNodeEvents: (on, config) => {
return require('./cypress/plugins')(on, config)
},
@@ -1218,7 +1218,7 @@ export default {
Variables must either be defined within the ${cmd('origin')} command or passed in using the args option.
Using \`require()\` or \`import()\` to include dependencies requires using the latest version of \`@cypress/webpack-preprocessor\`.`,
Using \`require()\` or \`import()\` to include dependencies requires enabling the \`experimentalOriginDependencies\` flag and using the latest version of \`@cypress/webpack-preprocessor\`.`,
},
callback_mixes_sync_and_async: {
message: stripIndent`\
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
<style>
body {
font-family: "Courier Prime", Courier, monospace;
padding: 0 1em;
line-height: 1.4;
color: #eee;
background-color: #111;
}
pre {
padding: 0 0;
margin: 0 0;
font-family: "Courier Prime", Courier, monospace;
}
body {
margin: 5px;
padding: 0;
overflow: hidden;
}
pre {
white-space: pre-wrap;
word-break: break-word;
-webkit-font-smoothing: antialiased;
}
</style>
</head>
<body><pre><span style="color:#e05561">The <span style="color:#e5e510">experimentalOriginDependencies<span style="color:#e05561"> experiment is currently only supported for End to End Testing and must be configured as an e2e testing type property: <span style="color:#de73ff">e2e.experimentalOriginDependencies<span style="color:#e05561">.<span style="color:#e6e6e6">
<span style="color:#e05561"><span style="color:#e6e6e6">
<span style="color:#e05561"><span style="color:#4ec4ff">{<span style="color:#e05561"><span style="color:#e6e6e6">
<span style="color:#e05561"><span style="color:#4ec4ff"> e2e: {<span style="color:#e05561"><span style="color:#e6e6e6">
<span style="color:#e05561"><span style="color:#4ec4ff"> experimentalOriginDependencies: true<span style="color:#e05561"><span style="color:#e6e6e6">
<span style="color:#e05561"><span style="color:#4ec4ff"> },<span style="color:#e05561"><span style="color:#e6e6e6">
<span style="color:#e05561"><span style="color:#4ec4ff">}<span style="color:#e05561"><span style="color:#e6e6e6"></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
</pre></body></html>
+13
View File
@@ -1142,6 +1142,19 @@ export const AllCypressErrors = {
If you have feedback about the experiment, please join the discussion here: http://on.cypress.io/run-all-specs`
},
EXPERIMENTAL_ORIGIN_DEPENDENCIES_E2E_ONLY: () => {
const code = errPartial`
{
e2e: {
experimentalOriginDependencies: true
},
}`
return errTemplate`\
The ${fmt.highlight(`experimentalOriginDependencies`)} experiment is currently only supported for End to End Testing and must be configured as an e2e testing type property: ${fmt.highlightSecondary(`e2e.experimentalOriginDependencies`)}.
${fmt.code(code)}`
},
FIREFOX_GC_INTERVAL_REMOVED: () => {
return errTemplate`\
The ${fmt.highlight(`firefoxGcInterval`)} configuration option was removed in ${fmt.cypressVersion(`8.0.0`)}. It was introduced to work around a bug in Firefox 79 and below.
@@ -1228,5 +1228,11 @@ describe('visual error templates', () => {
default: ['electron', ['env']],
}
},
EXPERIMENTAL_ORIGIN_DEPENDENCIES_E2E_ONLY: () => {
return {
default: [],
}
},
})
})
@@ -515,6 +515,10 @@
"experimentalRunAllSpecs": {
"name": "Run All Specs",
"description": "Enables the \"Run All Specs\" UI feature, allowing the execution of multiple specs sequentially."
},
"experimentalOriginDependencies": {
"name": "Origin Dependencies",
"description": "Enables support for `require`/`import` within `cy.origin`."
}
},
"device": {
+1
View File
@@ -789,6 +789,7 @@ enum ErrorTypeEnum {
ERROR_WRITING_FILE
EXPERIMENTAL_COMPONENT_TESTING_REMOVED
EXPERIMENTAL_NETWORK_STUBBING_REMOVED
EXPERIMENTAL_ORIGIN_DEPENDENCIES_E2E_ONLY
EXPERIMENTAL_RUN_ALL_SPECS_E2E_ONLY
EXPERIMENTAL_RUN_EVENTS_REMOVED
EXPERIMENTAL_SAMESITE_REMOVED
@@ -186,6 +186,43 @@ describe('experimentalRunAllSpecs', () => {
})
})
describe('experimentalOriginDependencies', () => {
it('is a valid config for e2e testing', () => {
cy.scaffoldProject('session-and-origin-e2e-specs')
cy.openProject('session-and-origin-e2e-specs')
cy.visitLaunchpad()
cy.skipWelcome()
cy.get('[data-cy-testingtype="e2e"]').click()
cy.findByTestId('launchpad-Choose a browser')
cy.get('h1').contains('Choose a browser')
})
it('is not a valid config for component testing', () => {
cy.scaffoldProject('session-and-origin-e2e-specs')
// TODO: remove config file from session-and-origin-e2e-specs project once the experimental flag is removed
cy.openProject('session-and-origin-e2e-specs', ['--config-file', 'cypress-invalid-component.config.js'])
cy.visitLaunchpad()
cy.skipWelcome()
cy.get('[data-cy-testingtype="component"]').click()
cy.findByTestId('error-header')
cy.contains('The experimentalOriginDependencies experiment is currently only supported for End to End Testing')
})
it('is not valid config when specified at root', () => {
cy.scaffoldProject('session-and-origin-e2e-specs')
// TODO: remove config file from session-and-origin-e2e-specs project once the experimental flag is removed
cy.openProject('session-and-origin-e2e-specs', ['--config-file', 'cypress-invalid-root.config.js'])
cy.visitLaunchpad()
cy.skipWelcome()
cy.get('[data-cy-testingtype="e2e"]').click()
cy.findByTestId('error-header')
cy.contains('The experimentalOriginDependencies experiment is currently only supported for End to End Testing')
})
})
describe('component testing dependency warnings', () => {
it('warns against outdated react and vite version', () => {
cy.scaffoldProject('component-testing-outdated-dependencies')
+2
View File
@@ -59,6 +59,7 @@ const _summaries: StringValues = {
experimentalStudio: 'Generate and save commands directly to your test suite by interacting with your app as an end user would.',
experimentalWebKitSupport: 'Adds support for testing in the WebKit browser engine used by Safari. See https://on.cypress.io/webkit-experiment for more information.',
experimentalRunAllSpecs: 'Enables the "Run All Specs" UI feature, allowing the execution of multiple specs sequentially',
experimentalOriginDependencies: 'Enables support for `require`/`import` within `cy.origin`',
}
/**
@@ -80,6 +81,7 @@ const _names: StringValues = {
experimentalStudio: 'Studio',
experimentalWebKitSupport: 'WebKit Support',
experimentalRunAllSpecs: 'Run All Specs',
experimentalOriginDependencies: 'Origin Dependencies',
}
/**
@@ -126,9 +126,13 @@ class RunPlugins {
.then((modifiedCfg) => {
debug('plugins file successfully loaded')
// specify which commands should (potentially) have their callbacks replaced. this is
// currently used by the webpack preprocessor. see its implementation for more details
global.__cypressCallbackReplacementCommands = ['origin']
// if the experimentalOriginDependencies flag is true, specify which
// commands should (potentially) have their callbacks replaced. this is
// currently used by the webpack preprocessor. see its implementation for
// more details
if (this._getExperimentalOriginDependenciesValue(initialConfig, modifiedCfg)) {
global.__cypressCallbackReplacementCommands = ['origin']
}
this.ipc.send('setupTestingType:reply', {
setupConfig: modifiedCfg,
@@ -147,6 +151,19 @@ class RunPlugins {
})
}
_getExperimentalOriginDependenciesValue (initialConfig, modifiedConfig) {
// prefer the modified value if it's specified
if (
typeof modifiedConfig === 'object'
&& typeof modifiedConfig.experimentalOriginDependencies === 'boolean'
) {
return modifiedConfig.experimentalOriginDependencies
}
// otherwise, use the initial value
return initialConfig.experimentalOriginDependencies
}
execute (event, ids, args = []) {
debug(`execute plugin event: ${event} (%o)`, ids)
@@ -277,6 +277,34 @@ describe.skip('lib/plugins/child/run_plugins', () => {
expect(global.__cypressCallbackReplacementCommands).to.deep.equal(['origin'])
})
it('defines global __cypressCallbackReplacementCommands if experimentalOriginDependencies: true', function () {
const setupNodeEventsFn = sinon.spy()
runPlugins.runSetupNodeEvents(setupNodeEventsFn)
const config = {
experimentalOriginDependencies: true,
}
this.ipc.on.withArgs('load:plugins').yield(config)
expect(global.__cypressCallbackReplacementCommands).to.deep.equal(['origin'])
})
it('does not define global __cypressCallbackReplacementCommands if experimentalOriginDependencies: false', function () {
const setupNodeEventsFn = sinon.spy()
runPlugins.runSetupNodeEvents(setupNodeEventsFn)
const config = {
experimentalOriginDependencies: false,
}
this.ipc.on.withArgs('load:plugins').yield(config)
expect(global.__cypressCallbackReplacementCommands).to.be.undefined
})
})
describe('on \'execute\' message', () => {
@@ -0,0 +1,8 @@
it('uses cy.origin() dependency handling', () => {
cy.visit('/primary_origin.html')
cy.get('a[data-cy="cross_origin_secondary_link"]').click()
cy.origin('foobar.com:4466', () => {
require('lodash')
})
})
@@ -0,0 +1,14 @@
module.exports = {
numTestsKeptInMemory: 0,
video: false,
e2e: {},
component: {
devServer () {
return {
port: 1234,
close: () => {},
}
},
experimentalOriginDependencies: true,
},
}
@@ -0,0 +1,6 @@
module.exports = {
numTestsKeptInMemory: 0,
video: false,
e2e: {},
experimentalOriginDependencies: true,
}
+16 -1
View File
@@ -14,6 +14,9 @@ const commonConfig = {
hosts: {
'*.foobar.com': '127.0.0.1',
},
e2e: {
experimentalOriginDependencies: true,
},
}
// TODO: This is probably more appropriate for a cy-in-cy test
@@ -54,7 +57,19 @@ describe('e2e cy.origin errors', () => {
async onRun (exec) {
const res = await exec()
expect(res.stdout).to.contain('Using `require()` or `import()` to include dependencies requires using the latest version of `@cypress/webpack-preprocessor`')
expect(res.stdout).to.contain('Using `require()` or `import()` to include dependencies requires enabling the `experimentalOriginDependencies` flag and using the latest version of `@cypress/webpack-preprocessor`')
},
})
systemTests.it('errors when the experimentalOriginDependencies flag is not set', {
browser: '!webkit', // TODO(webkit): results in "TypeError: expecting an array or an iterable object but got [object Null]"
spec: 'cy_origin_experimental_dependencies_error.cy.ts',
expectedExitCode: 1,
config: { ...commonConfig, e2e: { experimentalOriginDependencies: false } },
async onRun (exec) {
const res = await exec()
expect(res.stdout).to.contain('Using `require()` or `import()` to include dependencies requires enabling the `experimentalOriginDependencies` flag and using the latest version of `@cypress/webpack-preprocessor`')
},
})
})
@@ -3542,5 +3542,5 @@
"./tooling/v8-snapshot/cache/dev-darwin/snapshot-entry.js"
],
"deferredHashFile": "yarn.lock",
"deferredHash": "5f915e88ec6068dfce5f8adb2982fa045cdf3f27f34869c368443478e645b1e4"
"deferredHash": "8d8b606dabd3cc9e96c061293fa33f345f7bb2e66024b018d2edac2302b09f31"
}