cypress: After Spec API TypeScript Code breaks the config.ts file - [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"
Current behavior
If I use the code from the snippet here for TypeScript it breaks the project:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /Users/george/Documents/core-cypress/cypress.config.ts
at new NodeError (node:internal/errors:372:5)
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:76:11)
at defaultGetFormat (node:internal/modules/esm/get_format:118:38)
at defaultLoad (node:internal/modules/esm/load:21:20)
at ESMLoader.load (node:internal/modules/esm/loader:407:26)
at ESMLoader.moduleProvider (node:internal/modules/esm/loader:326:22)
at new ModuleJob (node:internal/modules/esm/module_job:66:26)
at ESMLoader.#createModuleJob (node:internal/modules/esm/loader:345:17)
at ESMLoader.getModuleJob (node:internal/modules/esm/loader:304:34)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
at async importModuleDynamicallyWrapper (node:internal/vm/module:437:15)
at async loadFile (/Users/george/Library/Caches/Cypress/10.3.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/child/run_require_async_child.js:106:14)
at async EventEmitter.<anonymous> (/Users/george/Library/Caches/Cypress/10.3.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/child/run_require_async_child.js:116:32)
Even just this line breaks the project:
const del = require('del')
Desired behavior
I can run my tests and the videos are deleted if test passed.
Test code to reproduce
/* eslint @typescript-eslint/no-var-requires: "off" */
import { defineConfig } from "cypress";
import { checkGmail, CheckGmailParam } from "../core-cypress/cypress/plugins/checkGmail";
import * as path from "path";
const del = require('del')
export default defineConfig({
e2e: {
async setupNodeEvents(on, config) {
const version = config.env.version || 'development'
const configFile = await import(path.join(
config.projectRoot,
'cypress/config',
`${version}.json`
));
config.projectId = "5jgpns"
config.baseUrl = configFile.baseUrl
config.env = configFile.env
config.defaultCommandTimeout = 10000
config.chromeWebSecurity = false
on("task", {
async checkGmail(args: CheckGmailParam) {
return await checkGmail(args);
},
});
on('after:spec', (spec, results) => {
if (results && results.stats.failures === 0 && results.video) {
// `del()` returns a promise, so it's important to return it to ensure
// deleting the video is finished before moving on
return del(results.video)
}
})
return config
},
reporter: 'mochawesome'
},
});
Cypress Version
10.1.0
Other
Current snippet also isn’t 100% TypeScript/Eslint friendly because uses require instead of import and has unused parameter. Something like this should work right?
import { deleteAsync } from 'del'
on('after:spec', async (_spec, results) => {
if (results && results.stats.failures === 0 && results.video) {
// `del()` returns a promise, so it's important to return it to ensure
// deleting the video is finished before moving on
await deleteAsync(results.video)
}
})
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 3
- Comments: 53 (37 by maintainers)
Run any test with the above config file or just the module import in config file, super easy to reproduce.
esbuildworks pretty well for our projects, although to supportrequire()and friends, you need a custombannerconfigurationOh, I’m sorry, I think you are right - I didn’t realize this was the issue with the
mtsdiscussion. I prematurely closed it. I agree, we should make sure we are in a good place with the whole ESM / CJS / TS loading.We can track specific progress for
cypress.config.mtshere: https://github.com/cypress-io/cypress/issues/24962@karlhorky Sorry, this issue seems to have gotten incorrectly marked and not routed to the correct team and thus looked abandoned. I will reopen and route.
Thanks for the detailed reply. Let me spend a bit of time reading and researching this.
My main concern with adding any kind of Cypress-specific flag/hint is that the same flag/hint should be possible with ts-node (and whatever toolchain the user has in their project). As long as said hint is present (eg, the
mtsincypress.config.mts) Cypress will run all the code through ts-node with the configuration/hints presented by the user and work as it would without Cypress.I think the first two are the most viable. I am not sure if we need to modify Cypress to do the first, do we? This should be doable in ts-node/userland. Or, we might need an additional hint here.
For
mts, we should definitely do this, I created: https://github.com/cypress-io/cypress/issues/24962. We will look formts, usets-node/esm, and letts-nodedo the rest.As for a new command line flag, I think we need to consider carefully what it would actually do - would we ultimately we would just do some additional conditions here (similar to your first option) https://github.com/cypress-io/cypress/blob/e3435b6fba05480765769974d829e69cf1e42ca0/packages/data-context/src/data/ProjectConfigIpc.ts#L273-L310?
I can try to setup a small reproduction repo.
I have tried 16.15.0, 16.17.1 and 16.18.1. All have the same error. Even an update to cypress 10.11 doesn’t change anything.
I get this error:
Line 25 starts here:
Also why does Cypress recommend
delmodule? Wouldn’t built infsmodule work?