Hi there, I have a suite of tests that are largely independent of each other, so I use the worker parallelism.
Unfortunately, a small subset needs access to on-disk files for upload tests. When these tests run at the same time, they end up interfering with each other and causing failures.
Does Playwright have a mutex/lock object that can block access to a resource on a worker level until they are released?
This thread is trying to answer question "Does Playwright have a mutex/lock object that can block access to a resource on a worker level until they are released?"
https://playwright.dev/docs/api/class-test#test-step there are discouraged methods in these docs for having tests run in parallel conditionally
Run a simple server to manage such test. I haven't done this before, but a server (not handling request in parallel) can solve your problem. Server can hold the lock/mutex in its own process, and you can block your tests by polling the server from worker process. Setting timeouts for such test cases would be the next problem. ๐
We can create a websocket server to manage the global state, and lock/unlock the state in the test. For easy use, I have integrated it into a custom reporter.
import { test } from '@playwright/test';
import { useState } from 'monocart-reporter';
test('example test 1', async ({ browserName }) => {
const state = useState({
timeout: 10 * 1000
});
// lock
await state.send('lock');
console.log(`[${browserName}][test 1] get list`);
const list = await state.get('list');
console.log(`[${browserName}][test 1] receive list`, list);
list.push(`${browserName} 1`);
console.log(`[${browserName}][test 1] set list`, list);
await state.set('list', list);
// unlock
await state.send('unlock');
});
// playwright.config.js
import { devices } from '@playwright/test';
let locking = false;
const waitingList = [];
const lockHandler = () => {
if (locking) {
return new Promise((resolve) => {
waitingList.push(resolve);
});
}
locking = true;
};
const unlockHandler = () => {
if (waitingList.length) {
const next = waitingList.shift();
next();
locking = true;
} else {
locking = false;
}
};
export default {
projects: [
{
name: 'chromium',
use: devices['Desktop Chrome']
},
{
name: 'firefox',
use: devices['Desktop Firefox']
}
],
reporter: [
['dot'],
['monocart-reporter', {
state: {
data: {
list: [1, 2, 3]
},
onReceive: (action) => {
if (action === 'lock') {
return lockHandler();
}
return unlockHandler();
}
}
}]
]
};
example: https://github.com/cenfun/monocart-reporter-test/tree/main/tests/global-state
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].