Rayrun
← Back to Discord Forum

[Solved] Ideas on how to create a file, and then add test case for every entry?

Hi guys, I'm creating visual comparison cases for react storybook, I'm making a request with playwright that returns the urls for different components, after the I want to navigate to those urls and compare the screenshots, however it'll be better if this is done dynamically. generating the file:

test('Generate paths', async ({ request }) => { // It's long, but it basically writes an array to the elementPaths // It's working, because I can verify that the file changes after the run });

example on the file: export const elementPaths = [ 'ui-alert--error', 'ui-avatar--initials', ]

and with the test I wan't to do: elementPaths.forEach(async (element) => { test(Visual compare ${element}, async ({ page }) => { await page.goto(/iframe.html?id=${element}); await expect(page).toHaveScreenshot(${element}.png); await actOnElement(page.locator('//*[@id="storybook-root"]//*').first()); await expect(page).toHaveScreenshot(${element}-after.png); }); });

The problem is that 'elementPaths' should be dynamic, and whatever I've tried, playwright doesn't like to take the new values. What I've tryed:

  • Adding it in beforeAll
  • Adding it as a project dependency to the compare project.

Any ideas are welcome (kind a lost my temper with this 🙂 ) ... It'll probably work if file update is a whole other project, but seems ugly like that

This thread is trying to answer question "How can I create a file with dynamic entries and add a test case for each entry using Playwright for visual comparison in React Storybook?"

13 replies

@oci1458 this may help you

First create a separate file (for e.g paths.js) that exports a function to generate the dynamic elementPaths array

`export async function generateElementPaths() { const elementPaths = await makeRequestsAndGetUrls();

return elementPaths; }`

Second; in your test file, import the generateElementPaths function from paths.js and call it in the beforeAll hook

`import { generateElementPaths } from './paths';

let elementPaths;

beforeAll(async () => { elementPaths = await generateElementPaths(); });`

Third; modify your test to iterate over the dynamically generated elementPaths array

elementPaths.forEach(async (element) => { test(Visual compare ${element}, async ({ page }) => { await page.goto(/iframe.html?id=${element}); await expect(page).toHaveScreenshot(${element}.png); await actOnElement(page.locator('//*[@id="storybook-root"]//*').first()); await expect(page).toHaveScreenshot(${element}-after.png); }); });

@yusufozt.: Thanks for the help. However, playwright dislikes that even more, when done like this, it 'thinks' that the array is empty and cannot iterate over it, I'm sure there is something small that I'm missing

Thanks for the help. However, playwright dislikes that even more, when done like this, it 'thinks' that the array is empty and cannot iterate over it, I'm sure there is something small that I'm missing

The elementPaths is pretty much the stories.json file you get adding features: { buildStoriesJson: true}} to your main.js Storybook configuration.

You can require and parse it synchronously to parameterize the tests.

Or does it work if you do the following in a single test file:

  1. Run a test that generates the elementPaths
  2. Do the elementPaths. forEach(...) maybe in a describe(...) setting the "children" tests to run in parallel

So that 1 and 2 run synchronously, rather than in parallel

@p01___: Did not know about the option to have `stories.json` file generated it's same as `elementPaths`, will give it a try and update this response. About running them in sync, wasn't working, seems like playwright parses the files before the execution starts probably for safety reasons, which I do get, however I don't get why it wasn't working when I used the generation of elementPaths in a different project and set is a dependency to the original one.

Did not know about the option to have stories.json file generated it's same as elementPaths, will give it a try and update this response.
About running them in sync, wasn't working, seems like playwright parses the files before the execution starts probably for safety reasons, which I do get, however I don't get why it wasn't working when I used the generation of elementPaths in a different project and set is a dependency to the original one.

Ok in case somebody gets to this problem, because of this change https://github.com/microsoft/playwright/issues/12018 , such dynamic case creation is not possible, thus if the case data comes from an api(like in my example) this should be called 'before' executing tests. Also thanks Mathieu 'p01' Henri , for pointing out the stories.json, this solution also worked!

[Solved] Ideas on how to create a file, and then add test case for every entry?

TwitterGitHubLinkedIn
AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

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 luc@ray.run.