1

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.

5
  • Can you provide a minimal reproducible example? Most of this stuff is undefined, not reproducible, and probably not relevant to the top level question you seem to be asking. I haven't tried it, but can't you use a test.use() for a particular describe block and set a particular sloMo value in that? There's never a need for defining function delay(ms: number) {, just import {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.
    – ggorlen
    Commented Jul 2 at 20:35
  • What do you need in particular? I described that I need to reduce the execution pace for only one test inside a describe-block. As I mentioned as a comment after await tab.locator.click() the system needs time to load data correctly. I added test.use({launchOptions: {slowMo: 500}}) but got the failure Cannot use({ launchOptions }) in a describe group....Make it top-level in the test file....
    – Klim Bim
    Commented Jul 3 at 6:47
  • I need a minimal reproducible example :-). Your question is coherent but then there's a bunch of unrunnable random functions without context. I don't see why the question can't be elaborated with a simple, complete example. But OK, that answers my speculation--thanks for trying it. It may not be possible to do this.
    – ggorlen
    Commented Jul 3 at 6:55
  • @ggorlen I hope the update 2 example explains it better.
    – Klim Bim
    Commented Jul 4 at 14:36
  • OK, thanks. So you really have a bug, but I still don't have a site you're automating or a complete, runnable test file, so I can't help you solve it, other than to say that your proposed solution is an XY problem--slowing things down (basically timeouts) is not the way to resolve this sort of bug. Picking a proper ordering and waiting for the necessary conditions in the UI is. You probably need to wait for a predicate after await table.nth(1).click() that determines when it's safe to click the button.
    – ggorlen
    Commented Jul 4 at 14:46

0