Search code examples
node.jsautomated-testsintegration-testinge2e-testingtestcafe

TestCafe: import tests from another file into the current fixture


I have a file tests.js that contains some test(...) definitions. I want to reuse these tests across multiple fixtures, preferably without making any modifications to the original code.

So I wrote a main.js that defines a fixture and imports tests.js, thereby "assembling" a test suite. (In case that works, I could write different driver files with different fixtures, importing the same tests.js from within each.)

However, I'm getting a test is not defined error when trying to execute main.js:

C:\Windows\Temp\dummy>testcafe chrome main.js --debug-on-fail
ERROR Cannot prepare tests due to an error.

ReferenceError: test is not defined
    at Object.<anonymous> (C:\Windows\Temp\dummy\tests.js:1:1)
    at Object.<anonymous> (C:\Windows\Temp\dummy\main.js:7:1)

Type "testcafe -h" for help.

Minimal sample:

// tests.js

test('wait', async t => {
    await t.wait(1);
});


// main.js

fixture `here goes the name`
    .page("http://localhost:3000")
    .beforeEach(async t => {
        // do stuff
    });

import "./tests";

/*
trick testcafe to scan the file;
based on https://github.com/DevExpress/testcafe/issues/2889#issuecomment-423859785

test();
*/

I already tried:

  • removing the block comment hack (test();) - which gives ERROR No tests to run. Either the test files contain no tests or the filter function is too restrictive.
  • moving the tests.js import to the top - still gives test is not defined
  • importing testcafe from within main.js and tests.js - same error

Is there a way to make the test function "visible" to other files imported by the testcafe entrypoint file? Or will I actually need to modify my tests.js file in order to get this working? Maybe by adding the test definitions into a method, and invoking it from within main.js - as in the original code sample of this issue?


Solution

  • TestCafe doesn't allow calling fixture and test functions outside the test scope. You can wrap your tests from the tests.js file in a function and call this function in the main.js file:

    // tests.js
    export default function () {
       test('Test 1', () => {});
       test('Test 2', () => {});
       test('Test 3', () => {});
    }
    
    // main.js
    import defineTests from './tests';
    
    defineTests();
    

    See also: Organize Tests