I'm working on implementing a test that reads a list of files from a given directory. The list is then checked against a Map
object that uses filenames as keys. If a match is found I want to execute some tests, if not skip the file and move on to the next one.
I have the test working if I just grab one object from the Map but it fails when I try to loop. I want to run tests by looping over multiple files.
It only seems to be a problem if I have async calls in my tests. Using a completely synchronous loop I can get it to run just fine. Here is an example of the synchronous loop (I realize this is a very contrived example but it works as expected):
describe('a test', () => {
const list = ['a', 'b', 'c'];
const test = (x) => {
describe(`should run ${x}`, () => {
beforeAll(async () => {
console.log('beforeAll');
});
beforeEach(async () => {
console.log('beforeEach');
});
for(let i = 0; i < 2; i++) {
it(`should log iteration ${i}`, async () => {
console.log(x, i);
expect(i).toBeTruthy();
});
}
});
}
for (let i = 0; i < list.length; i++) {
test(list[i]);
}
});
The output from the above snippet suggests that it runs just fine:
This same pattern does not work if it is asynchronous though. In fact, the nested describe in test
isn't even running as far as I can tell. I logged the project
variable to the console so I could see that it was getting called but the logging in...
statement in the beforeAll
isn't getting executed at all. It seems like it's just skipping right over it. How do I make this work with async/await
?
describe('Import Project', () => {
const _page = new PageFactory();
const utils = new Utils();
const projPath = browser.params.projPath;
let projectGuid: string;
const test = (project) => {
describe(`importing ${project.name}`, () => {
beforeAll(async () => {
console.log('logging in...'); //not getting executed for some reason
await _page.loginPage.login(browser.params.username, browser.params.password);
// import
await _page.projectsPage.importProject(projectPath + project.filename)
.withImportType(project.importType)
.withProjectName(project.projectName)
.inEnvironment(project.environment)
.import();
projectGuid = await utils.extractGuid();
});
afterEach(async () => {
await _page.designerPage.navigateTo(projectGuid);
});
for(let i = 0; i < project.operations.length; i++) {
const operation = project.operations[i];
it(`should run ${operation.name} successfully`, async () => {
await runOperation(operation.name);
const status = await _page.operationLogsPage.getStatus(operation.outcomeTarget);
expect(status).toEqual(operation.expectedStatus);
});
}
});
}
utils.getProjects().then(projects => {
// projects is a string[] of filenames
// that are returned using fs.readdir()
for (let i = 0; i < projects.length; i++) {
const myProject = projectMap.get(projects[i]);
if (myProject) {
test(myProject);
}
}
});
});
The output from this is just Executed 0 of 0 specs SUCCESS in 0.003 sec.
I don't understand how this would be any different than manually writing out all these nested describe blocks. If I wrote each one out it would work just fine but for some reason in a loop it doesn't want to work. Any ideas?