I am working with a globalSetup
function which seeds dependent data for my test suite.
What I want is to be able to skip this global setup based on some flag, options, or other config, while developing tests. The setup goes:
globalSetup
beforeAll
hook which copies this data to run tests againstafterAll
hook which deletes the newly copied dataglobalTeardown
which deletes the source dataSo, ideally, I would be able to run step 1 once, repeat steps 2 and 3 over and over again as I iterate on a test, and then run step 4 once I'm finished. I don't want to have to recreate the source data over and over again, because that process is much slower than simply copying it in.
Anybody have any thoughts or know any strategies to achieve this? I am using typescript node.
This thread is trying to answer question "How can I conditionally skip a global setup function in my test suite to avoid recreating source data repeatedly?"
Instead of running globalSetup through playwright.config.ts, you can set up your global setup as a project dependency: https://playwright.dev/docs/test-global-setup-teardown#option-1-project-dependencies.
Hi, you can add an environment variable for that. You'll need dotenv
npm package to read env file with your credentials and this setting (because commit credentials is a bad practice). During the development process you can change the value as you want. Btw, in code this value will be available with process.env.YOUR_ENV_NAME
.
Very much possible. I too use the a similar setup where in I store all the storage state files in a particular directory say "local_files". Now in further parts of my script we can check by code if this directory exists or not to run particular set of code. In my case I run login steps only if no storage state is present
Ok, after some refining, this is the solution I arrived at:
const dbSetup = async (): Promise<() => Promise<void>> => {
const setupFileExists = fs.existsSync("tmp/setup.json");
if (process.env.CI || !setupFileExists) {
console.info("Setting up source data");
const { environmentInfo, cleanup } = await runMySeedingFunction();
process.env.TEST_ENVIRONMENT_INFO = JSON.stringify(environmentInfo);
if (process.env.CI) return cleanup;
try {
fs.mkdirSync("tmp");
} catch (error) {
console.info("tmp folder already exists");
}
await fsPromise.writeFile("tmp/setup.json", JSON.stringify(environmentInfo));
}
if (setupFileExists) {
console.info("Using existing setup.json");
const environmentInfo = await fsPromise.readFile("tmp/setup.json", "utf-8");
process.env.TEST_ENVIRONMENT_INFO = environmentInfo;
console.info("Skipping db setup");
}
return noOpCleanup;
};
async function noOpCleanup() {
console.info("Teardown not required");
}
Function is called from playwright.config.ts
:
export default defineConfig({
testDir: "./src/e2e",
globalSetup: require.resolve("./src/e2e/global-setup"),
// ....
// ...
})
setup.json
file with info about seeded dataWell, usually environment variable is an input to your program so I don't fully understand why you're saving some data into it programatically
process.env.TEST_ENVIRONMENT_INFO = JSON.stringify(environmentInfo);
If you seed the data from JSON file you can easily access this file in your tests. I'd suggest you to refactor the code a bit because as for me it's hard to understand and read.
return noOpCleanup;
I also didn't understand this line
But I'm glad it works.
Using an environment variable is suggested in the documentation so I followed that.
Agree the noOpCleanup is a bit confusing, but playwright will call the function returned from your global setup function as the cleanup. In the case of wanting to save the seeded data, there should be no cleanup action, so I wanted to be super clear that no action was taken during cleanup. I could probably remove the thing entirely, but at my company log every single thing, so I think I will keep it.
Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email [email protected].