10

I'm using Playwright to upload a file and download the result. When the inputfiles are large, and it takes a long time to process I get a timeout from playwright; it takes to long for the button "Download" to appear.

    raise exception
playwright._impl._api_types.TimeoutError: Timeout 30000.0ms exceeded while waiting for event "download"
=========================== logs ===========================
waiting for event "download"
============================================================

How can I let playwright wait longer on that specific event?

with page.expect_download() as download_info:
    page.locator("text=Download").click()
    #todo: wait longer?
download = download_info.value
# expect(page).to_have_url("http://localhost:8080/swagger/#/NER/post_ner")
path = download.path()
suggested_filename = file_out
download.save_as(suggested_filename)

5 Answers 5

8

If you know that the click will take a while, you can set a timeout:

page.locator("text=Download").click(timeout=60000)
Sign up to request clarification or add additional context in comments.

5 Comments

Adding on, remember that the timeout is in ms.
I tried this: age.locator("text=Download").click(timeout=120000), but it's ignored. I get the same error message: playwright._impl._api_types.TimeoutError: Timeout 30000.0ms exceeded while waiting for event "download" This worked: page.set_default_timeout(timeout=120000)
I don't think the timeout here applies to the action triggered by the click, only the wait until the click can be fired on a visible element.
@ggorlen I had to double-check that it the source code and the timeout also applies to the navigation as well.
I also checked that it's mentioned in the docs @ggorlen :) "When all steps combined have not finished during the specified timeout, this method throws a TimeoutError. Passing zero timeout disables this." "all steps combined"
2

Not sure if this will help, but I have used the code below successfully many times:

with page.expect_download(timeout=0) as download_info:

Setting timeout=0 causes it to wait for as long as it takes to download.

3 Comments

Timeout of 0 is excessive. If an action doesn't work in a few hours or days at the very most, it's best to fail with a clear error message rather than block forever.
@ggorlen Based on how fast file will be downloaded... Like if site gives you small speed, timeout=0 can be used.
I don't think there are any files that take forever to download. Surely, after a few hours or days, you should give up and avoid an effective infinite loop so you can debug the script with a clear error or retry the action. I'm just repeating my above comment, though. Something like, say, timeout=86400000 (24 hours) is far prefereable to 0 in my view.
0

Doc says you are going the right way

# Wait for the download process to complete and save the downloaded file somewhere
download.save_as("/path/to/save/at/" + download.suggested_filename)

But, looks like your button misclicked (is locator valid?) or some network event missed. So, play around expect(page.locator("text=Download")).to_be_enabled(timeout=100_000) first, then try to wrap something like that using network devTool:

with (
    page.expect_response(**/swagger/#/NER/post_ner) as response_info,
    page.expect_download() as download_info
):
    # 1. make sure you are on the right page
    page.goto(/navigate/to/download/view)
    response = response_info.value
    assert response.ok
    # 2. wait for button to enabled
    expect(page.locator("text=Download")).to_be_enabled()
    page.locator("text=Download").click()
 
download = download_info.value
path = download.path()
suggested_filename = file_out
download.save_as(suggested_filename)

Comments

0

You can increase the timeout for a specific event by passing a custom timeout value to the expect_download context. By default, Playwright uses 30 seconds as the timeout. If your processing takes longer, you can extend it.

with page.expect_download(timeout=60000) as download_info:
page.locator("text=Download").click()
download = download_info.value
path = download.path()
suggested_filename = file_out
download.save_as(suggested_filename)

Setting a timeout on the click() method only affects how long Playwright waits for the click action to complete. However, your issue is with waiting for the download event to occur after clicking the button. That's why it's better to extend the timeout on the expect_download() context.

I hope that you find my advice useful. Have a nice day!

Comments

-1

You can also set the timeout to 0 if your not concerned with it taking too long. Though this can lead to it potentially taking hours...or never end if it gets stuck loading. A timeout of some value other than 0 is probably best practice.

page.locator("text=Download").click(timeout=0)

1 Comment

I tried that, was also ignored. Thanks for your reply.

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.