Closed opasno closed 5 years ago
I'm not sure we can do this, since the whole point of global{Setup,Teardown}
is that it runs before we create a runtime (which is what contains our require
which passes stuff through the transforms).
@cpojer thoughts on this?
I think we should transform it if we can, but I’m not sure right now what code changes that would entail. It may make sense to split the transformer into a separate package, something I wanted to do for a while.
Is there a workaround here? I'd like to be able to load some support code in globalSetup that uses ES6 modules and I'd prefer to not have to rewrite all of it back to requires/exports.
No current workaround that I know of, sorry. PR welcome here, though 🙂
@glasser I'm currently working around this issue by using babel-register
and babel-pollyfill
at the top of my jest.config.js
.
yarn add babel-register babel-pollyfil
const { readFileSync } = require('fs')
const babelConfig = JSON.parse(readFileSync('./.babelrc', 'utf8'))
require('babel-register')(babelConfig)
require('babel-polyfill')
const { join } = require('path')
const ROOT = process.cwd()
// const TESTS = join(ROOT, '__tests__')
const JEST_ENV = join(ROOT, '__jest_env__')
module.exports = {
verbose: true,
transform: {
'^.+\\.jsx?$': 'babel-jest'
},
globalSetup: join(JEST_ENV, 'setup.js'),
globalTeardown: join(JEST_ENV, 'teardown.js'),
testEnvironment: join(JEST_ENV, 'server-environment.js')
}
@opasno You seem to be using typescript, so try this method. In my case, I could easily solve the problem. I do not know if this method is useful in all cases, but I did the following things.
register
code that you are using (e.g. like babel/register, ts-node/registercode will be like this:
__tests__/globalSetup.js
, db/index.ts
require("ts-node/register");
const {db} = require("../db");
module.exports = async function () {
return db.setup();
};
Note that entire setup/teardown codes will be executed in non-jest environment, so all modules and objects related to Jest can not be referred while setup/teardown. However, It is enough to do setup/teardown.
Is anybody working on a PR for this already? Just encountered this issue and took me awhile to realise what was happening and track down this issue. At the very least, maybe the docs could be updated to indicate that transforms will not take place on globalSetup
due to it being outside a jest
runtime.
If anyone runs into this, you can trivially work around by performing these two steps.
Specify in jest.json:
"globalSetup": "<rootDir>/test_setup/global_setup_hook.js"
Create a .js file 'global_setup_hook.js' and invoke your typescript code from there:
require("ts-node/register");
// If you want to reference other typescript modules, do it via require: const my_typescript_module = require('my_typescript_module');
module.exports = async function () { // Call your initialization methods here. await my_typescript_module.Initialize(); return null; };
This assumes that you have "ts-node": "^5.0.1" in your package.json. No changes required in jest or ts-jest for this to work.
If anyone is working on a PR for this, keep in mind that testEnvironment files are not transpiled either.
Is this the same with setupTestFrameworkScriptFile? It is not transpiled?
@tachang Most likely. It would be extremely easy to test, why don't you do that yourself?
@WillAvudim your solution works greatly :) I have shortened it to a two-liner file:
setup_hook.js:
require("ts-node/register");
module.exports = require('./setup').default;
This works, because I have the setup file declared with default export function:
setup.ts:
import { anything } from 'you-want';
export default async function() {
// do all the setup you want in TypeScript
}
I hope someone finds this useful.
@tachang setupTestFrameworkScriptFile
should work as it's required through the runtime: https://github.com/facebook/jest/blob/b60f44a9829b51bc4bc387dbef8d7d37de3cc7e6/packages/jest-jasmine2/src/index.js#L129-L131 & https://github.com/facebook/jest/blob/b60f44a9829b51bc4bc387dbef8d7d37de3cc7e6/packages/jest-circus/src/legacy_code_todo_rewrite/jest_adapter.js#L76-L78
I'm still not sure how to solve this. One thing is to transpile the setup file itself (that can be done pretty easily), but to also transpile files required from it forces us to implement require
or hook into node's own require
. The first is difficult since it's part of jest-runtime
which is not created yet. The second since we should use something like https://www.npmjs.com/package/pirates (which is what babel-register uses) which feels... invasive. Might be the correct solution though.
Anybody wanna create a PoC using https://www.npmjs.com/package/pirates?
We could also print a pretty error if we get a syntax error saying we don't transform. That's probably better than what we have now
Should we always bail if there's a syntax error in the global setup, or should we respect bail flag in the config?
would love to see this. I am using both babel and typescript, and not being able to use es6 for some global setup in test files in a centralized manner kind of sucks. is another workaround just importing the function in the tests you need as well? not as convenient but it would be transpiled right?
@SimenB What is the approach we decided to go with?
I amended @WillAvudim example to support tsconfig-paths
yarn add --dev tsconfig-paths
require("ts-node/register");
require('tsconfig-paths/register');
// If you want to reference other typescript modules, do it via require:
const my_typescript_module = require('my_typescript_module');
module.exports = async function () {
// Call your initialization methods here.
await my_typescript_module.Initialize();
return null;
};
I don't use typescript, is there another solution?
@shai32, you can do the same with @babel/register
and @babel/polyfill
:
require('@babel/register');
require('@babel/polyfill');
module.exports = require('./setup').default;
@ezze I tried that, but I am using yarn workspace, and it doesn't work with yarn workspace (shared packages are not compiled because they are in node_moduels)
I don't understand why setupTestFrameworkScriptFile is transformed but globalSetup is not.
This is available in Jest 24
Are https://jestjs.io/docs/en/configuration.html#modulenamemapper-object-string-string concidered if using global setup with typescript
No, jest does not control the resolution algorithm in this case
@glasser I'm currently working around this issue by using
babel-register
andbabel-pollyfill
at the top of myjest.config.js
.yarn add babel-register babel-pollyfil
const { readFileSync } = require('fs') const babelConfig = JSON.parse(readFileSync('./.babelrc', 'utf8')) require('babel-register')(babelConfig) require('babel-polyfill') const { join } = require('path') const ROOT = process.cwd() // const TESTS = join(ROOT, '__tests__') const JEST_ENV = join(ROOT, '__jest_env__') module.exports = { verbose: true, transform: { '^.+\\.jsx?$': 'babel-jest' }, globalSetup: join(JEST_ENV, 'setup.js'), globalTeardown: join(JEST_ENV, 'teardown.js'), testEnvironment: join(JEST_ENV, 'server-environment.js') }
Small typo here on your yarn commands.
yarn add babel-register babel-polyfill
Based on @AlvSovereign and @sourcec0de work, adding
const { readFileSync } = require('fs');
const babelConfig = require('./babel.config.js');
require('@babel/register')(babelConfig);
in your jest.config.js worked for me
No need for workarounds, the feature has been implemented
You said it was implemented in jest 24, but we are using jest 24.8.0 and if I don't do that, it does not work. Am i missing something?
Also, in the documentation, this is still present:
Note: While code transformation is applied to the linked setup-file, Jest will not transform any code in node_modules. This is due to the need to load the actual transformers (e.g. babel or typescript) to perform transformation.
Transforming node_modules
is not the same as Make "globalSetup" and "globalTeardown" work together with "transform"
, which is what this issue is about.
EDIT: We also transform everything not ignore via transformIgnorePatterns
since 24.6: #8143. It should have updated the docs, though
Thanks. Indeed these 2 subjects got mixed in this issue, that's why I replied in it, sorry.
I was not able to make it work using transformIgnorePatterns: []
. I'll try some other things and if I can't find a solution, maybe I'll open a new issue.
Variable added to global in global{Setup,Teardown} cannot be used in test cases?
I add a key to global
in globalSetup file, but i cannot get it from my test cases.
And it seems that, there're two different globals, the first one is instanceof NodeJS.Global, howere the second one is Window.
// globalSetup.ts
module.exports = async () => {
(global as any).aaa = 111;
}
// testcase.test.ts
console.log('>>global', typeof global, (global as any).aaa);
@vifird that is correct, each test runs in its own sandboxed environment.
@jeysal So is there a way to add global settings? except "globals" field in jest's configuration.
Correct. We might add a way to send variables from globalSetup
to tests (there are some issues about it, but I'm currently on mobile) but that's not in place yet
@SimenB
i still can't use the import
statement like import vue from 'vue'
in the file which globalSetup
point to
i have an error on my terminal without any extra information
Determining test suites to run...
SyntaxError: Unexpected identifier
Did i missing something ? And what are u meaning about "This is available in Jest 24" ? i thought i don't need to config anything and i can have such feature
below is my jest.config.js
module.exports = {
globalSetup: './tests/unit/run-once-before-all-files.js',
moduleFileExtensions: [
'js',
'jsx',
'json',
'vue'
],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
'^.+\\.jsx?$': 'babel-jest'
},
transformIgnorePatterns: [
'/node_modules/',
'/public/',
'/__mocks__/',
'/api/',
'/src/assets/',
'tests/e2e/'
],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
snapshotSerializers: [
'jest-serializer-vue'
],
testMatch: [
'**/tests/unit/**/*.test.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
testURL: 'http://localhost/',
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname'
],
'setupFiles': ['jest-canvas-mock']
}
using Jest 24.9 and had to require('ts-node/register)
to get it working too. I don't understand how this is available in Jest 24
I can confirm this is not working in 24.9. As a matter of fact, it only works up to 24.1 for me.
Related: #9041
Please open up new issues (with reproductions) if you have a regression to report - this old issue is not the place for it
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.
Do you want to request a feature or report a bug? Feature
What is the current behavior? Modules defined in
globalSetup
andglobalTeardown
are not being transformed as defined intransform
configuration entry.What is the expected behavior? Modules should be transformed.
Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.
jest 22.0.4 ts-jest 22.0.0 node 8.9.2 npm 5.5.1 OS Windows 10