Search code examples
typescriptplaywrightplaywright-test

Wait for the presence of either of two locators in Playwright Typescript using Promise.race()


I am new to Typescript world exploring Playwright for Test Automation. There is a case where, some loading happens and I get either of 2 element - Validated, Failed. In Selenium, I prefer to go with WebDriverWait and stop the loop at once any one element appears. In Typescript, I learnt that we could use something like Promise.race() but I couldn't make it work. Here's my code:

public waitForFinalStatus = async (): Promise<Boolean> => {     
    const [failed, validated] = await Promise.race([
        this.locFailed().waitFor({ timeout: 120000 }).then(() => "Failed"),
        this.locValidated().waitFor({ timeout: 120000 }).then(() => "Passed")
    ]);

    return validated === "Passed";
}

Both failed, validated statuses are getting values like "E", "C" which I couldn't comprehend. I thought that, when its passed, value "Passed" would be passed and the other one would have undefined.

I have one more question here. Lets say, the Validated element appeared. After the wait time of 120 seconds, waitFor on locFailed would fail which should throw error, isn't it? Without proper try catch won't it affect the program flow? In case of Selenium Java, this is handled internally WebDriverWait by ignoring NotFoundException so that the exception thrown by element not being available is handled. As far as I understood, waitFor just throw error if element is not found within the specified conditions and throws error if not found. A bit of info on this concept would be enlightening.


Solution

  • hardkoded's answer probably fits your particular problem better, but in general you should know that Promise.race returns a Promise that resolves to a single value, not an array. In your case, Promise.race would resolve to either "Failed" or "Passed". With the array assignment, you are simply getting the first two characters of the returned string.

    See, for example, MDN's documentation for Promise.race.

    After the wait time of 120 seconds, waitFor on locFailed would fail which should throw error, isn't it? Without proper try catch won't it affect the program flow?

    Promise.race attaches success and error callbacks to all promises you pass it, meaning, if those promises reject, that is not an unhandled promise rejection and therefore will not lead to an error or process exit.

    If, for example, locValidated().waitFor() resolves, then the Promise returned by Promise.race will resolve with "Passed". If later, locFailed().waitFor() rejects, nothing will happen.