Reputation: 2210
I came across a scenario where I'm getting race conditions even with workers = 1
if testing with multiple browsers.
Firefox and Chrome work fine but it's the WebKit that's failing/passing at random.
Consider a record to be inserted via a form following a delete. All 3 browsers will be inserting and deleting a record in sequence but I feel browsers (webkit is the one) are jumping ahead in parallel instead of in a sequence. username
is the primary key.
await page.goto("http://localhost:4173/");
// insert
const random = Math.random();
await page.locator('input[id="first"]').fill('John');
await page.locator('input[id="last"]').fill('Doe');
await page.locator('input[id="username"]').fill('johndoe' + random);
await page.waitForFunction(() => {
const button = document.querySelector('#form button.primary');
return button && !button.disabled;
});
await page.locator('#form button.primary').click();
// delete
await page.getByText('johndoe' + random).click();
await page.locator('#list footer button[id="delete"]').click();
Consider if we remove the random part; then for all 3 browsers (maybe just webkit), this becomes a single shared record that they are racing to insert and delete.
If you assign a random number, then essentially each browser works to insert and delete it's own individual record, and the unit test passes reliably.
For the time being, I solved it using a random number joining with the username but I feel there has to be a better solution.
Playwright config
workers: process.env.CI ? 1 : undefined,
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
]
Upvotes: 5
Views: 268
Reputation: 3418
Welcome to the cross-browser test automation, this is how it works here ;)
At least for WebKit. Before it was much worse, with IE and specific driver for it.
What you can do:
test("Example", async ({ browserName }) => {
if (browserName === "webkit") {
// Do something specific for WebKit
}
});
await page.waitForFunction(() => {
const button = document.querySelector('#form button.primary');
return button && !button.disabled;
});
await page.locator('#form button.primary').click();
In your example, it's not needed. PW click ensures that the button exists and is enabled before the click - see https://playwright.dev/docs/api/class-locator#locator-click.
It is still not clear why you need random - but if you need browser unique value try user_${browserName}
await page.getByText(`johndoe_${browserName}`).click();
Upvotes: 5