mirror of
https://github.com/cypress-io/cypress.git
synced 2026-05-19 22:59:16 -05:00
fix: Remove default esModuleInterop option from ts-node and preprocessor (#8143)
* make tests preprocessor agnostic * update eslintignore * put back deps needed for e2e test * remove obselete snapshot it was replaced by 1_typescript_support_spec.ts.js * switch from browserify to webpack preprocessor * cmon github * fix/update tests * bump preprocessor and update snapshots * update snapshots * bump preprocessor to gain json support * fix e2e tests with webpack-originated errors * bump preprocessor version, fix node globals * update snapshot * remove support for ? in file path * bump preprocessor version * bump preprocessor again * bump preprocessor * bump preprocessor * update snapshots * bump preprocessor version * bump preprocessor, quiet the paths plugin * add test verifying tsconfig paths work * refactor registering ts-node * separate spec/support file typescript tests from plugins file typescript tests * fix unit tests * fix: Remove esModuleInterop default from ts-node (#7808) * Remove esModuleInterop from ts-node. * Add e2e test. * Fix test. Change test name. Add comment. * Fix test snapshot name. * update snapshotting Co-authored-by: Chris Breiding <chrisbreiding@gmail.com> * clean up e2e project * bump preprocessor to 1.3.2, which removes esModuleInterop default value * improve esmoduleinterop e2e tests * change spec file * bump batteries-included preprocessor and install latest webpack preprocessor beside it * update snapshots * put back snapshot * update snapshot * update snapshot Co-authored-by: Kukhyeon Heo <sainthkh@naver.com> Co-authored-by: Brian Mann <brian.mann86@gmail.com>
This commit is contained in:
+1
-1
@@ -26,7 +26,7 @@ packages/server/lib/scaffold/plugins/index.js
|
||||
packages/server/lib/scaffold/support/index.js
|
||||
packages/server/lib/scaffold/support/commands.js
|
||||
packages/server/test/support/fixtures/projects/e2e/cypress/integration/stdout_exit_early_failing_spec.js
|
||||
packages/server/test/support/fixtures/projects/e2e/cypress/integration/typescript_failing_spec.ts
|
||||
packages/server/test/support/fixtures/projects/e2e/cypress/integration/typescript_syntax_error_spec.ts
|
||||
|
||||
**/.projects
|
||||
**/*.d.ts
|
||||
|
||||
+12
-28
@@ -1,4 +1,4 @@
|
||||
exports['e2e typescript spec passes 1'] = `
|
||||
exports['e2e typescript in spec and support file spec passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
@@ -62,7 +62,7 @@ exports['e2e typescript spec passes 1'] = `
|
||||
|
||||
`
|
||||
|
||||
exports['e2e typescript spec fails 1'] = `
|
||||
exports['e2e typescript in spec and support file spec fails with syntax error 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
@@ -71,23 +71,23 @@ exports['e2e typescript spec fails 1'] = `
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Cypress: 1.2.3 │
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 1 found (typescript_failing_spec.ts) │
|
||||
│ Searched: cypress/integration/typescript_failing_spec.ts │
|
||||
│ Specs: 1 found (typescript_syntax_error_spec.ts) │
|
||||
│ Searched: cypress/integration/typescript_syntax_error_spec.ts │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: typescript_failing_spec.ts (1 of 1)
|
||||
Running: typescript_syntax_error_spec.ts (1 of 1)
|
||||
|
||||
Oops...we found an error preparing this test file:
|
||||
|
||||
/foo/bar/.projects/e2e/cypress/integration/typescript_failing_spec.ts
|
||||
/foo/bar/.projects/e2e/cypress/integration/typescript_syntax_error_spec.ts
|
||||
|
||||
The error was:
|
||||
|
||||
Error: Webpack Compilation Error
|
||||
./cypress/integration/typescript_failing_spec.tsXX:XX
|
||||
./cypress/integration/typescript_syntax_error_spec.tsXX:XX
|
||||
Module parse failed: Unexpected token (4:19)
|
||||
File was processed with these loaders:
|
||||
* ../../../../node_modules/@cypress/webpack-batteries-included-preprocessor/node_modules/ts-loader/index.js
|
||||
@@ -115,14 +115,15 @@ Fix the error in your code and re-run your tests.
|
||||
│ Screenshots: 0 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Spec Ran: typescript_failing_spec.ts │
|
||||
│ Spec Ran: typescript_syntax_error_spec.ts │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
(Video)
|
||||
|
||||
- Started processing: Compressing to 32 CRF
|
||||
- Finished processing: /XXX/XXX/XXX/cypress/videos/typescript_failing_spec.ts.mp4 (X second)
|
||||
- Finished processing: /XXX/XXX/XXX/cypress/videos/typescript_syntax_error_spec.ts (X second)
|
||||
.mp4
|
||||
|
||||
|
||||
====================================================================================================
|
||||
@@ -132,14 +133,14 @@ Fix the error in your code and re-run your tests.
|
||||
|
||||
Spec Tests Passing Failing Pending Skipped
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ✖ typescript_failing_spec.ts XX:XX - - 1 - - │
|
||||
│ ✖ typescript_syntax_error_spec.ts XX:XX - - 1 - - │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
✖ 1 of 1 failed (100%) XX:XX - - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e typescript project passes 1'] = `
|
||||
exports['e2e typescript in spec and support file project passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
@@ -227,20 +228,3 @@ exports['e2e typescript project passes 1'] = `
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['typescript with tsconfig run'] = `
|
||||
(Run Finished)
|
||||
|
||||
|
||||
Spec Tests Passing Failing Pending Skipped
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ✔ app_spec.ts XX:XX 1 1 - - - │
|
||||
├────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ ✔ js-spec.js XX:XX 2 2 - - - │
|
||||
├────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ ✔ math.ts XX:XX - - - - - │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
✔ All specs passed! XX:XX 3 3 - - -
|
||||
|
||||
|
||||
`
|
||||
@@ -4,15 +4,13 @@
|
||||
const _ = require('lodash')
|
||||
const debug = require('debug')('cypress:server:plugins:child')
|
||||
const Promise = require('bluebird')
|
||||
const tsnode = require('ts-node')
|
||||
const resolve = require('resolve')
|
||||
|
||||
const errors = require('../../errors')
|
||||
const preprocessor = require('./preprocessor')
|
||||
const task = require('./task')
|
||||
const util = require('../util')
|
||||
const validateEvent = require('./validate_event')
|
||||
const tsNodeOptions = require('../../util/ts-node-options')
|
||||
const { registerTsNode } = require('../../util/ts-node')
|
||||
|
||||
const ARRAY_METHODS = ['concat', 'push', 'unshift', 'slice', 'pop', 'shift', 'slice', 'splice', 'filter', 'map', 'forEach', 'reduce', 'reverse', 'splice', 'includes']
|
||||
|
||||
@@ -183,21 +181,7 @@ module.exports = (ipc, pluginsFile, projectRoot) => {
|
||||
})
|
||||
|
||||
if (!tsRegistered) {
|
||||
try {
|
||||
const tsPath = resolve.sync('typescript', {
|
||||
basedir: projectRoot,
|
||||
})
|
||||
|
||||
const tsOptions = tsNodeOptions.getTsNodeOptions(tsPath)
|
||||
|
||||
debug('typescript path: %s', tsPath)
|
||||
debug('registering plugins TS with options %o', tsOptions)
|
||||
|
||||
tsnode.register(tsOptions)
|
||||
} catch (e) {
|
||||
debug(`typescript doesn't exist. ts-node setup failed.`)
|
||||
debug('error message: %s', e.message)
|
||||
}
|
||||
registerTsNode(projectRoot)
|
||||
|
||||
// ensure typescript is only registered once
|
||||
tsRegistered = true
|
||||
|
||||
@@ -6,8 +6,6 @@ const Promise = require('bluebird')
|
||||
const commitInfo = require('@cypress/commit-info')
|
||||
const la = require('lazy-ass')
|
||||
const check = require('check-more-types')
|
||||
const tsnode = require('ts-node')
|
||||
const resolve = require('resolve')
|
||||
const scaffoldDebug = require('debug')('cypress:server:scaffold')
|
||||
const debug = require('debug')('cypress:server:project')
|
||||
const cwd = require('./cwd')
|
||||
@@ -31,7 +29,7 @@ const keys = require('./util/keys')
|
||||
const settings = require('./util/settings')
|
||||
const specsUtil = require('./util/specs')
|
||||
const { escapeFilenameInUrl } = require('./util/escape_filename')
|
||||
const tsNodeOptions = require('./util/ts-node-options')
|
||||
const { registerTsNode } = require('./util/ts-node')
|
||||
|
||||
const localCwd = cwd()
|
||||
|
||||
@@ -103,21 +101,7 @@ class Project extends EE {
|
||||
return scaffold.plugins(path.dirname(cfg.pluginsFile), cfg)
|
||||
}
|
||||
}).then((cfg) => {
|
||||
try {
|
||||
const tsPath = resolve.sync('typescript', {
|
||||
basedir: this.projectRoot,
|
||||
})
|
||||
|
||||
const tsOptions = tsNodeOptions.getTsNodeOptions(tsPath)
|
||||
|
||||
debug('typescript path: %s', tsPath)
|
||||
debug('registering project TS with options %o', tsOptions)
|
||||
|
||||
tsnode.register(tsOptions)
|
||||
} catch (e) {
|
||||
debug(`typescript doesn't exist. ts-node setup failed.`)
|
||||
debug('error message %s', e.message)
|
||||
}
|
||||
registerTsNode(this.projectRoot)
|
||||
|
||||
return cfg
|
||||
}).then((cfg) => {
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// returns options for ts-node registration
|
||||
// https://github.com/TypeStrong/ts-node
|
||||
const _ = require('lodash')
|
||||
|
||||
/**
|
||||
* Default ts - node options.We want to output CommonJS modules.
|
||||
* And we want to run fast - thus transpile only mode (no type checking)
|
||||
*/
|
||||
const tsOptions = {
|
||||
transpileOnly: true,
|
||||
compilerOptions: {
|
||||
module: 'CommonJS',
|
||||
esModuleInterop: true,
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns combined object with ts-node options.
|
||||
* @param {string} tsPath Path to TypeScript
|
||||
*/
|
||||
function getTsNodeOptions (tsPath) {
|
||||
const merged = _.cloneDeep(tsOptions)
|
||||
|
||||
merged.compiler = tsPath
|
||||
|
||||
return merged
|
||||
}
|
||||
|
||||
module.exports = { getTsNodeOptions }
|
||||
@@ -0,0 +1,34 @@
|
||||
const debug = require('debug')('cypress:server:ts-node')
|
||||
const tsnode = require('ts-node')
|
||||
const resolve = require('resolve')
|
||||
|
||||
const getTsNodeOptions = (tsPath) => {
|
||||
return {
|
||||
compiler: tsPath, // use the user's installed typescript
|
||||
compilerOptions: {
|
||||
module: 'CommonJS',
|
||||
},
|
||||
transpileOnly: true, // transpile only (no type-check) for speed
|
||||
}
|
||||
}
|
||||
|
||||
const registerTsNode = (projectRoot) => {
|
||||
try {
|
||||
const tsPath = resolve.sync('typescript', {
|
||||
basedir: projectRoot,
|
||||
})
|
||||
const tsOptions = getTsNodeOptions(tsPath)
|
||||
|
||||
debug('typescript path: %s', tsPath)
|
||||
debug('registering project TS with options %o', tsOptions)
|
||||
|
||||
tsnode.register(tsOptions)
|
||||
} catch (err) {
|
||||
debug(`typescript doesn't exist. ts-node setup failed.`)
|
||||
debug('error message: %s', err.message)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
registerTsNode,
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import e2e from '../support/helpers/e2e'
|
||||
import Fixtures from '../support/helpers/fixtures'
|
||||
|
||||
describe('e2e typescript in plugins file', function () {
|
||||
e2e.setup()
|
||||
|
||||
it('handles tsconfig with module other than commonjs', function () {
|
||||
return e2e.exec(this, {
|
||||
project: Fixtures.projectPath('ts-proj-with-module-esnext'),
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/7575
|
||||
it('defaults to esModuleInterop: false', function () {
|
||||
return e2e.exec(this, {
|
||||
project: Fixtures.projectPath('ts-proj'),
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/7575
|
||||
it('allows esModuleInterop to be overridden with true via tsconfig.json', function () {
|
||||
return e2e.exec(this, {
|
||||
project: Fixtures.projectPath('ts-proj-esmoduleinterop-true'),
|
||||
})
|
||||
})
|
||||
})
|
||||
+3
-20
@@ -1,9 +1,7 @@
|
||||
import snapshot from 'snap-shot-it'
|
||||
|
||||
import e2e from '../support/helpers/e2e'
|
||||
import Fixtures from '../support/helpers/fixtures'
|
||||
|
||||
describe('e2e typescript', function () {
|
||||
describe('e2e typescript in spec and support file', function () {
|
||||
e2e.setup()
|
||||
|
||||
it('spec passes', function () {
|
||||
@@ -13,9 +11,9 @@ describe('e2e typescript', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('spec fails', function () {
|
||||
it('spec fails with syntax error', function () {
|
||||
return e2e.exec(this, {
|
||||
spec: 'typescript_failing_spec.ts',
|
||||
spec: 'typescript_syntax_error_spec.ts',
|
||||
snapshot: true,
|
||||
expectedExitCode: 1,
|
||||
onStdout: e2e.normalizeWebpackErrors,
|
||||
@@ -36,19 +34,4 @@ describe('e2e typescript', function () {
|
||||
project: Fixtures.projectPath('ts-proj-with-paths'),
|
||||
})
|
||||
})
|
||||
|
||||
it('handles tsconfig with module other than commonjs', function () {
|
||||
const projPath = Fixtures.projectPath('ts-proj-with-own-tsconfig')
|
||||
|
||||
return e2e.exec(this, {
|
||||
project: projPath,
|
||||
config: {
|
||||
video: false,
|
||||
},
|
||||
}).then((result) => {
|
||||
const runSummary = e2e.leaveRunFinishedTable(e2e.normalizeStdout(result.stdout))
|
||||
|
||||
snapshot('typescript with tsconfig run', runSummary)
|
||||
})
|
||||
})
|
||||
})
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"supportFile": false
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
it('passes', () => {
|
||||
expect(true).to.be.true
|
||||
})
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
exports.export1 = 'export1'
|
||||
|
||||
exports.export2 = 'export2'
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import commonjsExports from './commonjs-export'
|
||||
|
||||
if (commonjsExports.export1 !== 'export1' || commonjsExports.export2 !== 'export2') {
|
||||
throw new Error('Imported values do not match exported values')
|
||||
}
|
||||
|
||||
// Default Cypress plugin function
|
||||
export default (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => {
|
||||
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"supportFolder": false
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
describe('uses task that is in typescript plugins file', () => {
|
||||
it('calls task', () => {
|
||||
cy.task('hello', 'TS').should('equal', 'Hello, TS!')
|
||||
})
|
||||
})
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export const asyncGreeting = async (greeting: string) => {
|
||||
return Promise.resolve(`Hello, ${greeting}!`)
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import { add } from './math'
|
||||
|
||||
it('is true', () => {
|
||||
expect(add(1, 2)).to.eq(3)
|
||||
})
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
import { add } from './math'
|
||||
|
||||
describe('JS spec', () => {
|
||||
it('adds 2 and 2 together', () => {
|
||||
expect(add(2, 2)).to.equal(4)
|
||||
})
|
||||
|
||||
it('calls task', () => {
|
||||
cy.task('hello', 'TS').should('equal', 'Hello, TS!')
|
||||
})
|
||||
})
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
export const add = (a: number, b: number) => {
|
||||
return a + b
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
export const asyncGreeting = async (greeting) => {
|
||||
return Promise.resolve(`Hello, ${greeting}!`)
|
||||
}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"project": "packages/server/test/support/fixtures/projects/ts-proj-with-own-tsconfig/tsconfig.json"
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/no-misused-promises": "error"
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
// Copied an example command from https://on.cypress.io/custom-commands
|
||||
Cypress.Commands.add('clickLink', (label: string | number | RegExp) => {
|
||||
cy.get('a').contains(label).click()
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/7510
|
||||
// The code below fails when @typescript-eslint/no-misused-promises is error
|
||||
// and the return type of function in Cypress.Commands.add doesn't support Chainable.
|
||||
Cypress.Commands.add('dataCy', (value) => {
|
||||
return cy.get(`[data-cy=${value}]`)
|
||||
})
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
// ***********************************************************
|
||||
// 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')
|
||||
@@ -1,5 +1,6 @@
|
||||
import { add } from './math'
|
||||
|
||||
it('is true', () => {
|
||||
// @ts-ignore
|
||||
expect(add(1, 2)).to.eq(3)
|
||||
})
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = () => {}
|
||||
@@ -1,17 +1,13 @@
|
||||
// Copied an example from https://docs.cypress.io/api/plugins/browser-launch-api.html#Use-fake-video-for-webcam-testing
|
||||
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import fn from './commonjs-export-function'
|
||||
|
||||
// if esModuleInterop is forced to be true, this will error // with 'fn is
|
||||
// not a function'. instead, we allow the tsconfig.json to determine the value
|
||||
// of esModuleInterop
|
||||
fn()
|
||||
|
||||
// Default Cypress plugin function
|
||||
export default (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => {
|
||||
on('before:browser:launch', (browser, launchOptions) => {
|
||||
if (browser.family === 'chromium' && browser.name !== 'electron') {
|
||||
// Mac/Linux
|
||||
//launchOptions.args.push('--use-file-for-fake-video-capture=cypress/fixtures/my-video.y4m')
|
||||
|
||||
// Windows
|
||||
// launchOptions.args.push('--use-file-for-fake-video-capture=c:\\path\\to\\video\\my-video.y4m')
|
||||
}
|
||||
|
||||
return launchOptions
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1856,7 +1856,7 @@ describe('lib/config', () => {
|
||||
})
|
||||
|
||||
it('sets the pluginsFile to index.ts if it exists', () => {
|
||||
const projectRoot = path.join(process.cwd(), 'test/support/fixtures/projects/ts-proj')
|
||||
const projectRoot = path.join(process.cwd(), 'test/support/fixtures/projects/ts-proj-with-module-esnext')
|
||||
|
||||
const obj = {
|
||||
projectRoot,
|
||||
@@ -1873,7 +1873,7 @@ describe('lib/config', () => {
|
||||
})
|
||||
|
||||
it('sets the pluginsFile to index.ts if it exists (without ts require hook)', () => {
|
||||
const projectRoot = path.join(process.cwd(), 'test/support/fixtures/projects/ts-proj')
|
||||
const projectRoot = path.join(process.cwd(), 'test/support/fixtures/projects/ts-proj-with-module-esnext')
|
||||
const pluginsFolder = `${projectRoot}/cypress/plugins`
|
||||
const pluginsFilename = `${pluginsFolder}/index.ts`
|
||||
|
||||
|
||||
@@ -354,7 +354,6 @@ This option will not have an effect in Some-other-name. Tests that rely on web s
|
||||
compiler: projTsPath,
|
||||
compilerOptions: {
|
||||
module: 'CommonJS',
|
||||
esModuleInterop: true,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user