Search code examples
javascriptplaywrightplaywright-test

How do I properly run individual Playwright tests from a dynamic array of built urls?


I have a Puppeteer CICD project where I use the NodeEnvironment to proceed to our test harness website, pull down the current list of custom xml tests from the dropdown element our QA team uses and then dynamically constructs an array of 1200+ URLs from this. Then I was using this.global to use as a reference array where I would then use clustering to run these in parallel.

I'm having problems wrapping my head around the proper way to get this list populated and then run the tests in parallel. The parameterized test option seems to be close to what I want, but I need a way to populate the dynamic array of urls before I jump to the for loop and it seems that the array is not populated yet and it is trying to run through the for loop and execute tests, even when using a promise.

I know I could probably hack something to get things working, but I would much rather know the proper expected way of doing this that allows me to take advantage of the parallelization playwright provides.

I am currently looking into worker fixtures or sharding to see if it provides me a way of achieving this, but the problem is if each worker goes to the website to populate the array then they will all have the 1200 test cases, which doesn't help either. I'm open to any ideas here, but an important thing to state is that I want each url to have its own test as each test has a series of get requests which I need to capture and perform comparisons against the query params.

A drastically minimized example of what I currently have is below:

dynamic.spec.js

//The object that contains the 1200+ urls that needs to be built at the start
let globalUrlObj;

test.beforeAll( async () => {
  globalUrlObj = await setupUrlList(); //<-- This method goes to website and builds list
});

// Because globalUrlObj was not waited on above in beforeAll, it is undefined at this point and the execution comes back stating that there are no tests to run

if (globalUrlObj && globalUrlObj[config.baseKey] !== undefined) {
  for (const testUrlObj of globalUrlObj[config.baseKey]){
    test(`Testing with url ${testUrlObj.url}`, async () => {
       // Perform my analysis
       // ...
    });
  }
}

Solution

  • First thing first. You do not need before all as far as I can see. How it will work in a paralel execution if have before all, every worker that exists will run before all (you do not need that, you need it only once). So just put the code outside of it.

    Choose a regular for loop for execution and add i (iterator) that will make your test unique. If this does not help you please write what kind of error you face.