DEV Community

sam
sam

Posted on

Testcase setup in jest, resolved

I am trying to add a testcase to our app test suite.
it requires changing two of our files before the test and
restoring them after the test

so we have a helper, which provides global reusable functions.

start our app
get the web content from our app (we only have 1 page)

etc etc..

so I added two functions to be called before and after the test begins

but, altho the code works perfectly under nodejs,
under jest the files are not written.

const os = require("node:os");
const fs = require("node:fs");
const jsdom = require("jsdom");

const indexFile = __dirname +"/../../../index.html";
const cssFile = __dirname + "/../../../css/custom.css";
const sampleCss = [
    ".region.row3 {",
    " top: 0;",
    "}",
    ".region.row3.left {",
    " top: 100%;"
    ,"}"
    ];
var indexData = [];
var cssData = [];

exports.startApplication = async (configFilename, exec) => {
    jest.resetModules();
    if (global.app) {
        await this.stopApplication();
    }
    // Set config sample for use in test
    if (configFilename === "") {
        process.env.MM_CONFIG_FILE = "config/config.js";
    } else {
        process.env.MM_CONFIG_FILE = configFilename;
    }
    if (exec) exec;
    global.app = require("../../../js/app");

    return global.app.start();
};

exports.fixupIndex =  () => {

    indexData = fs.readFileSync(indexFile).toString();
    let workIndexLines = indexData.split(os.EOL);
    for (let l in workIndexLines) {
        if (workIndexLines[l].includes("region top right")) {
            console.log("found it")
            workIndexLines.splice(l, 0, "      <div class=\"region row3 left\"><div class=\"container\"></div></div>");
            break;
        }
    }
    fs.writeFileSync(indexFile, workIndexLines.join(os.EOL), { flush: true });  
    cssData = fs.readFileSync(cssFile).toString();
    console.log("css ="+cssData)
    fs.writeFileSync(cssFile, sampleCss.join(os.EOL), { flush: true });
};
Enter fullscreen mode Exit fullscreen mode

the actual testcase reads the content of the row3_left element
(this is a user extending our page template, and me trying to detect when they did that for other functions in our code that validate our template layout)

if I run
node tests/e2e/custom_region.js
it correctly modifies the files. so the paths are correct, the fs functions are correct and the file modifications are correct.
(I have a restore function which writes out the content read before the modify)

the testcase shown below calls

helper.fixupIndex()
helper.startApplication()
Enter fullscreen mode Exit fullscreen mode

so the files are not used until the startApplication() executes

I don't see any restrictions listed in the jest doc about local file access..
and all the testcase I see are actually USING the file contents in expect() or some other validation operation.. not as part of setup

we are executing these tests as part of a github workflow on pull request merge.. so I don't want to make a permanently modified copy of the files
testcase

const helpers = require("./helpers/global-setup"); // file contents above

helpers.fixupIndex();

describe("Position of modules", () => {
.
.
.
}
helpers.restoreIndex();
Enter fullscreen mode Exit fullscreen mode

the testcase works perfectly when the two files are modified in advance.

Top comments (1)

Collapse
 
rexxdad profile image
sam

SO, the answer was two fold

  1. use fs.promises.readFile/writeFile
  2. add the helper.fixupIndex()/restoreIndex() to the beforeAll/afterAll functions (else there was a timing race, the index file was modified AFTER the startApplication started..oops
describe("Custom Position of modules", () => {
    beforeAll(async () => {
        await helpers.fixupIndex();  //<-- fixup index.html/custom.css here
        await helpers.startApplication("tests/configs/customregions.js");
        await helpers.getDocument();
    });
    afterAll(async () => {
        await helpers.stopApplication();
        await helpers.restoreIndex(); // restore after app ended
    });
Enter fullscreen mode Exit fullscreen mode