DevExpress / testcafe

A Node.js tool to automate end-to-end web testing.
https://testcafe.io
MIT License
9.78k stars 661 forks source link

userVariables are not available in global hooks #8195

Closed JakubMaz closed 1 month ago

JakubMaz commented 1 month ago

What is your Scenario?

I want to set project config which is unique in every test run, by creating new environment instance before tests run. It will contains for expample, base url to web page, api url e.t.c. I will use it in a lot of files, with tests, hooks e.t.c, so it should be available everywhere. In global hooks I want tu use this project config to send some requests to api.

What is the Current behavior?

userVariables are available every where apart from global hooks. In global hooks it's returns null

What is the Expected behavior?

userVariables should be available in global hooks to set additional data in userVariables, which will be usefull in tests/local tests hooks

What is your TestCafe test code?

In runner.js I pass this config to userVariables by:

import createTestCafe from 'testcafe';
import { setConfig } from './setConfig.js';

(async () => {
    // create new environment instance
    const newConfig = { // In real life it's getting from api
        apiUrl: 'http://localhost:3000',
        baseUrl: 'http://localhost:3001',
        baseUrl2: 'http://localhost:3002',
    };

    const options = {
        hostname: 'localhost',
        port1:    1337,
        port2:    1338,
        userVariables: { newConfig }
    };

    const testcafe = await createTestCafe(options);
    const runner = testcafe.createRunner()
    const failedTests = await runner
        .src('./tests/test.js')
        .browsers('chrome')
        .run({ 
            disableNativeAutomation: true,
            hooks: {
                testRun: {
                    before: () => {
                        setConfig(newConfig)
                    }
                },
            }
        });

    console.log(failedTests);

    await testcafe.close();
})();

setConfig.js

import testcafe from 'testcafe';
const { userVariables } = testcafe;

export const setConfig = () => {
    //send some request to userVariables.apiUrl
    userVariables.additionalData = 'test' //data from request
}

Steps to Reproduce

  1. Create testcafe runner createTestCafe
  2. Pass userVariables there
  3. Set new data in userVariables by global hooks

TestCafe version

3.6.0

Node.js version

18.17.0

Command-line arguments

node runner.js

Other

Found this bug by trying to resolve this problem: https://stackoverflow.com/questions/78476786/dynamic-data-are-not-available-in-test-files-testcafe-3-6-0

PavelMor25 commented 1 month ago

Hello @JakubMaz,

The issue is that userVariables in your case is part of the TestCafe object you created. Therefore, when you import it in setConfig.js, you cannot access it. You can create a closure for userVariables in yoursetConfig function to be able to modify it in global hooks.

setConfig.js


export const setConfig = (userVariables) => {
    return (config) => {
        userVariables.config = config;
    }
}

runner.js

import createTestCafe from 'testcafe';
import { setConfig } from './setConfig.js';

(async () => {
    // create new environment instance
    const newConfig = { // In real life it's getting from api
        apiUrl: 'http://localhost:3000',
        baseUrl: 'http://localhost:3001',
        baseUrl2: 'http://localhost:3002',
    };

    const options = {
        hostname: 'localhost',
        port1:    1337,
        port2:    1338,
        userVariables: { newConfig }
    };

    const testcafe = await createTestCafe(options);

   const setNewConfig = setConfig(testcafe.configuration._options.userVariables.value);

    const runner = testcafe.createRunner()
    const failedTests = await runner
        .src('./tests/test.js')
        .browsers('chrome')
        .run({ 
            disableNativeAutomation: true,
            hooks: {
                testRun: {
                    before: () => {
                        setNewConfig(newConfig)
                    }
                },
            }
        });

    console.log(failedTests);

    await testcafe.close();
})();

However, testcafe.configuration._options.userVariables.value is not part of the public API and can be changed at any time. Please use it with caution.

Please let us know your results.

JakubMaz commented 1 month ago

This resolved me problem. However, it would be nice to have a supported solution. Can you upgrade this ticket type to an improvement?

PavelMor25 commented 1 month ago

We have other priorities at the moment, and this usage scenario is not popular enough among our users. Thus, we can't rise its priority. If there is more demand for this feature in the future, we will reconsider this task.

Thank you for your understanding.