Search code examples
testingautomated-testse2e-testingtestcafemonkeypatching

Monkey patch Testcafe


I'm trying to monkey patch Testcafe in the following manner:

  1. Add custom methods available in all tests
t.patch.typeText = async (selector, txt, opts) => {
  await t.click(selector);
  await t.typeText(selector, txt, opts);
}
/* This didn't work */
  1. Run custom code on every page load.
await t.click(Selector('a[href="/no_thing"]');
await t.onPageLoaded(someCustomFunction())

Didn't find much online googling these, any pointers would be helpful.


Solution

  • The test controller instance (t) is different in each test, so you cannot patch it this way.

    Regarding the two scenarios you have described, try the following approaches:

    Scenario 1

    Create helper functions with actions you need to reuse. You can define helpers in a separate file and then import this file to the tests whenever you need these functions:

    helpers.js  

    import { t } from 'testcafe';
    
    export async function type(selector, txt, opts) => {
        await t
            .click(selector)
            .typeText(selector, txt, opts);
    }
    

    test.js  

    import { Selector } from 'testcafe';
    import { type } from './helpers.js';
       
    fixture `My Fixture`
        .page `https://devexpress.github.io/testcafe/example/`;
     
    test('My Test', async t => {
        await type(Selector('#element'), 'text', { replace: true });
    });
    

    Please also note that the t.typeText action clicks the target input before it types text. You shouldn't need a separate click action to focus the input.

    For more information about helper functions, see Create Helpers.

    We have plans to support custom actions that would better address your use case in the future releases. See this GitHub issue for details.

    Scenario 2

    TestCafe can inject custom scripts into every page visited during the test run, test or fixture. These scripts are injected into the <head> tag and executed in a usual manner.

    Create a file with the scripts you need to inject:

    script.js  

    window.addEventListener('DOMContentLoaded', function () {
        // this code runs on each page when it is loaded
    });
    

    Then inject these scripts with one of the following methods:

    Command line interface  

    testcafe chrome test.js --client-scripts script.js
    

    Programming interface  

    runner.clientScripts('script.js');
    

    Configuration file  

    {
        "clientScripts": "script.js"
    }
    

    For more information about script injection, see Inject Scripts into Tested Pages.