0

I'm trying to implement conditional code in playwright inside of page object. It depends on if element is found on page or not. The problem is - returned value is always the same, no matter if element is present or not. Here is my code:

    this.pagePlaceholder = page.locator('.s-wrapper.s-wrapper_placeholder');


  async clearUpPage() {
    const placeholdersNumber = await this.pagePlaceholder.count();
    console.log(placeholdersNumber);

      
        if (placeholdersNumber < 1) {
          await this.mainSection.hover({
            position: {
              x: 200,
              y: 150,
            },
          });
    
          await this.page.click('.section-options__btn._del:visible');
          await expect(this.pagePlaceholder).toBeVisible();
        }
      }

So the problem is - count() always returns 0, even if element of that class is present on that page. I also tried solutions with "if (this.pagePlaceholder)" and "if (this.pagePlaceholder.isVisible())" and those also return same value no matter what. If I use 'waitForSelector" inside "if" - it throws timeout error if selector is not found, so test is failed instead of case being skipped.

2 Answers 2

1

So I managed to find a solution on Playwright's github. The solution is - to use separate "delay" function like that:

import { delay } from './utils';

 async clearUpPage() {
    await delay(5000, null);

    const placeholdersNumber = await this.pagePlaceholder.count();
    console.log(placeholdersNumber);

    if (placeholdersNumber < 1) {...}
}

delay() function is imported from the file utils.ts:

export function delay<T>(milliseconds: number, value: T): Promise<T> {
    return new Promise(function(resolve) { 
        setTimeout(resolve.bind(null, value), milliseconds)
    });
}

Original answer

Note that milliseconds value matters. Value from original answer (2000) didn't help in my case.

Sign up to request clarification or add additional context in comments.

2 Comments

Playwright provides a page.waitForTimeout() function that can be used for waiting.
@Greener that also works. Thanks! Too bad that more elegant approach doesn't work. As tests with "timeout" are flaky :(
0

Try adding a

await this.pagePlaceholder.waitFor({ state: "visible" });

Before you perform the count, I suspect that the screen is still loading when you try to count it (its not there).

Failing that you might want to enable trace recording and look at that!.

5 Comments

It solves the counting problem. But it throws error if element can't be found on the page - (locator.waitFor: Timeout 20000ms exceeded. --waiting for selector ".s-wrapper.s-wrapper_placeholder" to be visible). And I already tried to use it inside if () check, but playwright doesn't allow that.
Is "pagePlaceholder" always shown on the page or is it optional?
It's optional. Thats why I need to use "if" statement :)
const shown = await this.pagePlaceholder.isVisible({timeout: 20000}); Will let you see if its currently shown or not
Not sure why, but as I stated in original post - it always returns same value (false in this case, and true for "isHidden"), even if element is clearly visible. I tried to await for "this.page.waitForLoadState()" before running your code - same results.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.