Testcafe: declare var test on global scope issue

Created on 14 Jun 2017  ·  30Comments  ·  Source: DevExpress/testcafe

Great to see TypeScript definition files with the package.
Unfortunately, we're having issues in a project that also uses Mocha. Both libraries have a test declaration on global scope, so TypeScript is throwing the following error:

Error TS2403: Subsequent variable declarations must have the same type.  Variable 'test' must be of type 'TestFn', but here has type 'ITestDefinition'.

In testcafe package:
declare var test: TestFn;

In @types/mocha
declare var test: Mocha.ITestDefinition;

It's global scope all over again.
I would prefer to import test from the Testcafe package. Or is there some other solution to this?

Auto-locked question

Most helpful comment

having the same issue with jest and #testcafe -> both expose test as global type

All 30 comments

@jvanoostveen Can you just filter out mocha tests from TestCafe source files?

The error is raised during bundling, TypeScript will load all the definitions it can find (or so it seems).
During the bundling, neither TestCafe or Mocha code should be touched or loaded.
There are in the bundled code, no references to either mocha typings or testcafe typings. So I'm quite puzzled on why this error even is an issue, the typings are irrelevant at this point.

Did I get it right: you are bundling production code and during compilation of the production code you get complains from TS compiler about mocha and TestCafe tests?

Yes, except, I get the compiler error not on the tests, but on the definition files.

Do you require/import TestCafe or mocha in your production files?

Hey Guys, I'm encountering the same issue while using mocha and testcafe in the same project. I'm evaluating testcafe for end to end testing and have @types/mocha in my project. Any ideas on how to resolve this?

I haven't found a way around this, and as we're also evaluating, I've for now downgraded to v0.15. But that one has issues already fixed in the newer ones...

The problem is that both mocha and testcafe are polluting the global scope (I'm guessing this is for good reasons). In such first glance, I would dump mocha and live with testcafe, while bringing a mocha replacement. Then again, I have no idea what are your project concerns and why you use mocha.

polluting the global scope, looks like we're back in the early days of javascript...
I would rather have it that only core JS is on the global scope, all else can be imported.

Use both of Mocha & TestCafe, would like to have some viable workaround.

I guess you can use two tsconfig.json files: one for E2E tests and the second one for mocha tests.

tsconfig.testcafe.json
tsconfig.mocha.json

Each config will filter the appropriate files.
Then you will run the appropriate tests using -p Typescript compiler parameter.
https://www.typescriptlang.org/docs/handbook/compiler-options.html

Can someone share their setup? I still don't understand how both mocha and testcafe tests are mixed up and why they simultaneously compiled by TS and what production code bundling has to do with it all.

The typescript compiler loads all types from node_modules/@types by default. So if you have Mocha included in your project it will load their definition file as well. It seems that the TestCafe CLI doesn't load the tsconfig.json from the root of the project (or any tsconfig.json at all). If this were the case we could use the typeRoots or types compilerOptions in tsconfig.json to only include the specific typings we would need for the TestCafe tests.

When I change the src/compiler/test-file/formats/typescript.js to only load node and testcafe types, I can get the project/tests to run.

    static _getTypescriptOptions () {
        // NOTE: lazy load the compiler
        var ts = require('typescript');

        return {
            allowJs:         true,
            pretty:          true,
            inlineSourceMap: true,
            noEmit:          true,
            noImplicitAny:   false,
            module:          ts.ModuleKind.CommonJS,
            target:          'ES6',
            lib:             ['lib.es6.d.ts'],
+           types:           ['node', 'testcafe'],
            baseUrl:         __dirname,
            paths:           { testcafe: ['../../../../ts-defs/index.d.ts'] }
        };
    }

But those types might not be enough for all cases, so loading and parsing of the tsconfig.json corresponding to the tests is still the better way to go.

I also noticed a new TypeScript program is created for each file, this might not be the fastest way...

I also noticed a new TypeScript program is created for each file, this might not be the fastest way...

We are investigating it in context of the #1591

having the same issue with jest and #testcafe -> both expose test as global type

Hi everyone!

Let's determine the problem and try to solve it.
I've created an example for it: https://github.com/AlexanderMoskovkin/testcafe-mocha-example
This is a project with mocha and testcafe included as a devDependencies.

As I understand you have a problem when you build your project, when TypeScript compiles the sources.
To reproduce it I've created the tsconfig.json and added test script into the package.json. It runs TypeScript compiler.

Take a look at my tsconfig.json.
There is no need to compile TestCafe tests separately since TestCafe complies them itself before test run. So, I added a path to TestCafe tests to the exclude section.
Take a look at the types field:

  • when I remove it TypeScript should work according its default behavior ( https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types). In this case npm test command works properly (TypeScript compiles unit tests succesfully);
  • when I set "types": ["mocha"] it uses the mocha typedefs only and it works properly too;
  • the only way to reproduce the issue on my side is adding "types": ["mocha", "testcafe"]. But as I mentioned before there is no need to compile TestCafe tests separately.

So, is something configured in the other way in your projects? Maybe I missed something? Feel free to create a Pull Request in my example repo to show your case.

/cc @jvanoostveen, @qballer, @vasyas, @peterwestendorp, @Hotell, @oukayuka, everyone

I still have to check our situation, I am unable to access the source code (🏖), maybe @peterwestendorp can check, but when – in your example – I add the e2e directory to the included sources, then it will not compile.

{
    "include": [
        "unit/**/*.ts",
        "e2e/**/*.ts"
    ]
}
$ npx tsc
e2e/test.ts(1,26): error TS2307: Cannot find module 'testcafe'.
e2e/test.ts(3,1): error TS2304: Cannot find name 'fixture'.
e2e/test.ts(7,13): error TS2339: Property 'wait' does not exist on type 'MochaDone'.

So it is hard to compare, because it might also be the case that the definition file is not found anyway, if so changing "types" will not affect anything.
In the last error, it uses the Mocha definitions. But this might be related to something else, it is hard to debug these definition things...
Changing the version to 0.16.2 has the seem results.

When the e2e directory is excluded in the tsconfig.json, I also notice some editors have problems when figuring out how to deal with the TypeScript.

Anyway, it doesn't seem that these issues are related to the original issue, where the compilation in TestCafe was causing the mocha definition conflict...

So, back to the _original_ case, running the TypeScript tests with TestCafe, when I add this to the package.json and run it:
"e2e": "node_modules/.bin/testcafe chrome e2e/"

$ npm run e2e

> [email protected] e2e /testcafe-mocha-example
> testcafe chrome e2e/

ERROR Cannot prepare tests due to an error.

Error: TypeScript compilation failed.
/testcafe-mocha-example/node_modules/@types/mocha/index.d.ts (42, 13): Subsequent variable declarations must have the same type.  Variable 'test' must be of type 'TestFn', but here has type 'ITestDefinition'.

So it is not about compiling the _rest_ of the code, but running the TestCafe files written in TypeScript. Did you manage to have those working with the example?

heyo folks!

check this:

thanks for starting to resolve this @AlexanderMoskovkin , your solution is kinda sub-optimal.

Providing types in tsconfig === explicitly naming libraries, that you wanna use for type checking, which can be super annoying, in projects with lot's of 3rd party libraries -> If types is specified, only packages listed will be included.,

Even if we did that, there is still issue with testcafe handling of TSC, which I described in my PR

PS: also I've created "issue" here https://github.com/Microsoft/TypeScript/issues/17663

I'd really like to use both jest and testcafe and typescript, and the currently problem regarding duplicate types (aka @types/jest/index.d.ts (23, 13): Subsequent variable declarations must have the same type. Variable 'test' must be of type 'TestFn', but here has type 'It') is a show stopper.

I think it would be helpful if testcafe could use a local test directory tsconfig.json that would allow specifying types.

@mike-packetwerk

is a show stopper.

there is absolutely none :) you can see my PR's and description. Also folks from TS confirmed that my solution is "the only possible/best one" --> https://twitter.com/martin_hotell/status/894627899688574977

Although as I've mentioned in my comments zilion times, those solutions won't work for testcafe because it doesn't consume users tsconfig, but that's not a showstopper, you can use my solution and define npm script like this : "e2e": "tsc && testcafe chrome ts-out/e2e"

what is ts-out ? -> "outDir": "ts-out", TS compiler setting in tsconfig

quick fix is straightforward in testcafe's codebase

https://github.com/DevExpress/testcafe/blob/master/src/compiler/test-file/formats/typescript.js#L14

just adding skipLibCheck: true will do the trick until testcafe wont support users tsconfig

@Hotell Ah, ok, I'll try your tsc && ... trick tomorrow. I can imagine it will work. Thanks.

Guys, thanks a lot for your investigations and clarifications, now the problem is clear for me.

For now I suppose we can use the following solutions to resolve the problems:
1) For the TypeScript compilation of the whole project - it can be resolved by tsconfig.json options:

  • skipLibCheck: true. It allows to ignore the variable declarations must have the same type error;
  • specifying types if it's suitable for the project (it can be super annoying, in projects with lot's of 3rd party libraries);
  • excluding TestCafe tests path since TestCafe compiles the tests before running.

2) For running .ts tests via TestCafe - we can use the solution proposed by @Hotell, add the skipLibCheck: true option in our sources (it should fix the original issue, and we can publish it in the next minor version soon).

Meanwhile we will think about more fundamental solutions (like taking into account tsconfig.json in the project or something else)

@Hotell FYI, pre-compiling with tsc and my custom tsconfig.json worked a dream. Thanks again.

// testcafe/tsconfig.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../dist/testcafe",
    "module": "es2015",
    "target": "es2017",
    "baseUrl": "",
    "types": [
      "testcafe",
      "node"
    ]
  }
}

@mike-packetwerk cheers mate!

I ran into the same issue and solved it by monkey-patching the tsconfig for testcafe:

const TypeScriptTestFileCompiler = require('testcafe/lib/compiler/test-file/formats/typescript');

const _getTypescriptOptions = TypeScriptTestFileCompiler._getTypescriptOptions;

TypeScriptTestFileCompiler._getTypescriptOptions = () => {
    const config = _getTypescriptOptions();
    config.skipLibCheck = true;

    return config;
}

I hope this helps someone till this is fixed.

@draconisNoctis thanks for the info. The fix is on the way. We're going to release a minor version with it at the start of the next week.

I have latest 0.20.1 and still getting a subsequent variable declaration error as well as :

ERROR in /Volumes/Workspace/Projects/wirecash-client/node_modules/testcafe/ts-defs/index.d.ts (1594,6): error TS1036: Statements are not allowed in ambient contexts.

This thread has been automatically locked since it is closed and there has not been any recent activity. Please open a new issue for related bugs or feature requests. We recommend you ask TestCafe API, usage and configuration inquiries on StackOverflow.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

inikulin picture inikulin  ·  3Comments

chebum picture chebum  ·  3Comments

fnlctrl picture fnlctrl  ·  3Comments

madroneropaulo picture madroneropaulo  ·  3Comments

AndreyBelym picture AndreyBelym  ·  3Comments