I would like to slow down the test execution of test step. I´m testing a container which has two tabs and each tab has different table with data. When I click on a tab, it takes time until data is loaded. Due to the race issue, PlayWright is too fast in headless mode and still has data of the previous tab although the next tab has been clicked and is open. I cannot rely on table´s data because it always different therefore an expect()
will not solve the issue.
I used slowMo: 500
in playwright.config.ts
and everything behaved as expected. However, it slows down every test that I don´t want to. I would like to reduce the execution speed for only one particular test. I added await browser.browserType().launch({slowMo: 500})
which doesn´t work. I wouldn´t like to add a timeout or pause the execution if possible.
test.spec.ts
import {test} from "../../../fixtures/catalog_management/sub_atr/pax_cargo_compatibilities";
test.describe('Pax Cargo Compatibilities', () => {
test('has items', async ({login, pax_cargo_compatibilities, action_toolbar}) => {
for (const tab of [pax_cargo_compatibilities.tab_requestor, pax_cargo_compatibilities.tab_provider]) {
await test.step(`${await tab.innerText()}`, async () => {
//this test doesn´t need to be slow
await tab.locator.click()
await action_toolbar.button_insert.click()
await pax_cargo_compatibilities.verify_properties()
await pax_cargo_compatibilities.dialog.getByTitle('Close').click()
})
}
.....many more tests
test('delete entity',async ({login, browser, pax_cargo_compatibilities, action_toolbar, form_buttons, validation, get_content_of_cell_of_tables_row}) => {
await browser.browserType().launch({slowMo: 500}) // does not work
for (const tab of [{'locator': pax_cargo_compatibilities.tab_requestor, 'tid': 'requestorTable'}, {'locator': pax_cargo_compatibilities.tab_provider, 'tid': 'providerTable'}]) {
await test.step(`${await tab.locator.innerText()}`, async () => {
await tab.locator.click() //this part needs time to load data correctly
let tab_table_data = pax_cargo_compatibilities.table.filter({has: pax_cargo_compatibilities.page.getByTestId(RegExp(`id=${tab.tid}`))})
console.log(await get_content_of_cell_of_tables_row(tab_table_data, [0,7]))
// console.log(await (pax_cargo_compatibilities.table).allTextContents())
// console.log('############################################################################')
})
}
)}
fixture
import {test as base} from '../base_fixture_catalog_management';
import {PaxCargoCompatibilities} from "../../../pom/catalog_management/sub_atr/pax_cargo_compatibilities";
import {get_content_of_cell_of_tables_row, login} from "../../../lib/shortcut";
import { Locator } from '@playwright/test';
/**
* Fixture of Pax Cargo Compatibilities which is an extension of 'base_fixture_catalog_management'
*/
export const test = base.extend<{ pax_cargo_compatibilities: PaxCargoCompatibilities, login: any , get_content_of_cell_of_tables_row: any}>({
pax_cargo_compatibilities: async ({page, catalog_management}, use) => {
await catalog_management.pax_cargo_compatibility.click()
await use(new PaxCargoCompatibilities(page));
}, login: async ({page}, use) => {
await login(page, process.env.EURALL)
await use(login)
}, get_content_of_cell_of_tables_row: async ({}: any, use: (arg0: (table: Locator, columns: number[]) => Promise<string[]>) => any) => {
await use(get_content_of_cell_of_tables_row)
}
})
export {expect} from '@playwright/test';
Does somebody have an idea or experience?
update
What I have implemented but I´m not satisfied, is
function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
@ggorlen: I removed it and tried your proposal import {setTimeout} from "node:timers/promises"
and it helps but I guess it is not how I suppose to do it?
update 2
Here is a easy minimal example
test.describe('My race issue', () => {
test('update entity', async ({page}) => {
//button is disabled as long as nothing is selected at table_of_content
let button_update = page.getByRole('button', {name: 'Update'})
let table_of_content = page.locator(".z-listbox-body").locator("tr[id]")
let input_title = page.(getByTestId(/Row-Idspace-Textbox/)
await table.nth(1).click()
await button_update.click()
await input_title.fill('test')
}
)}
So the problem is, in my code selecting a table´s row is more complex. However, the part await button_update.click()
is faster finished then await table.nth(1).click()
, therefore I get a test timeout and cannot perform input_title.fill('test')
because button_update.click()
didn´t open the form. I would like to only slow down the test('update entity...')
because the other tests I have run as expected.
test.use()
for a particular describe block and set a particularsloMo
value in that? There's never a need for definingfunction delay(ms: number) {
, justimport {setTimeout} from "node:timers/promises"
instead of reinventing the wheel. And that doesn't really do sloMo in any case, since sloMo affects all operations, not just a single timeout.describe
-block. As I mentioned as a comment afterawait tab.locator.click()
the system needs time to load data correctly. I addedtest.use({launchOptions: {slowMo: 500}})
but got the failureCannot use({ launchOptions }) in a describe group....Make it top-level in the test file....
await table.nth(1).click()
that determines when it's safe to click the button.