i want to automate a website using playwright, the scenario is;
page.get_by_role("heading", name="Success")
page.get_by_role("heading", name="id have multiple account")
page.get_by_role("heading", name="id unregistred")
i try this code
with sync_playwright() as p: browser = p.chromium.launch(headless=False) page = browser.new_page() page.goto('https://example/login') page.get_by_placeholder("username").fill("my_username") page.get_by_placeholder("password").fill("my_password") page.get_by_role("button", name="submit").click() for i in array_of_dicts: page.get_by_placeholder('input id').fill(i['id']) page.get_by_test_id("btnSubmit").click() time.sleep(2) success= page.get_by_role("heading", name="Success").is_visible() type = page.locator("span").filter(has_text="id have multiple account").is_visible() unregistred = page.get_by_role("heading", name="id unregistred").is_visible() if(success): print("success") elif(type): print("type") elif(unregistred): print("unregistred") else: print("unknown") page.goto('https://example.com/verify_id') browser.close()
its works but when i remove the time.sleep(2), it print unknown, its like playwright doesnt wait until one of the element is visible.
time.sleep(2)
unknown
and if i try this
with sync_playwright() as p: browser = p.chromium.launch(headless=False) page = browser.new_page() page.goto('https://example/login') page.get_by_placeholder("username").fill("my_username") page.get_by_placeholder("password").fill("my_password") page.get_by_role("button", name="submit").click() for i in array_of_dicts: page.get_by_placeholder('input id').fill(i['id']) page.get_by_test_id("btnSubmit").click() if(page.wait_for_selector('#success', state='visible') or page.wait_for_selector('#type', state='visible')): print('success') else: print('unknown') page.goto('https://example.com/verify_id') browser.close()
its wait and execute print("success") if the id is directing to success page, but when the id is suppose to show modal dialog of page.wait_for_selector('#type', state='visible') its like the code stop and waiting inside if page.wait_for_selector('#success', state='visible') until it timeout and show error without it check page.wait_for_selector('#type', state='visible')
print("success")
page.wait_for_selector('#type', state='visible')
if page.wait_for_selector('#success', state='visible')
what i want is to check multiple element, if one of the element return true it stop waiting and execute the next code without using time.sleep(2) or fixed pause. is that posible?
Yes, you can achieve this by using the Promise.any method provided by Playwright to wait for multiple conditions and proceed as soon as any one of them resolves.
Promise.any
Here’s an example using Promise.any:
from playwright.sync_api import sync_playwright, TimeoutError with sync_playwright() as p: browser = p.chromium.launch(headless=False) page = browser.new_page() page.goto('https://example/login') page.get_by_placeholder("username").fill("my_username") page.get_by_placeholder("password").fill("my_password") page.get_by_role("button", name="submit").click() for i in array_of_dicts: page.get_by_placeholder('input id').fill(i['id']) page.get_by_test_id("btnSubmit").click() try: success = page.wait_for_selector('#success', state='visible') print('Success:', success.text_content()) except TimeoutError: pass # Continue to the next step try: type_modal = page.wait_for_selector('#type', state='visible') print('Type Modal:', type_modal.text_content()) except TimeoutError: pass # Continue to the next step try: unregistered_modal = page.wait_for_selector('#unregistered', state='visible') print('Unregistered Modal:', unregistered_modal.text_content()) except TimeoutError: print('Unknown') # All conditions failed page.goto('https://example.com/verify_id') browser.close()
In this code:
TimeoutError
print
try
Unknown
Remember to adjust the selectors ('#success', '#type', '#unregistered') based on the actual HTML structure of the pages.
'#success'
'#type'
'#unregistered'
Yes, it’s possible to achieve this without using fixed pauses or time.sleep by using the Race class in Playwright. The Race class allows you to wait for the first event to occur among multiple conditions. Here’s how you can modify your code to use Race:
time.sleep
Race
from playwright.sync_api import sync_playwright, Race with sync_playwright() as p: browser = p.chromium.launch(headless=False) page = browser.new_page() page.goto('https://example/login') page.get_by_placeholder("username").fill("my_username") page.get_by_placeholder("password").fill("my_password") page.get_by_role("button", name="submit").click() for i in array_of_dicts: page.get_by_placeholder('input id').fill(i['id']) page.get_by_test_id("btnSubmit").click() race = Race(page.wait_for_selector('#success', state='visible'), page.wait_for_selector('#type', state='visible'), timeout=5000) # Specify a timeout in milliseconds winner = race.wait() if winner: if winner == '#success': print('success') elif winner == '#type': print('type') else: print('unknown') page.goto('https://example.com/verify_id') browser.close()
In this example, Race is used to wait for the first condition to be met among the success and type elements. The winner variable will contain the selector of the first condition that is met. You can then check which condition was met and proceed accordingly.
winner
Make sure to adjust the selectors ('#success', '#type', etc.) based on the actual structure of your web page.