Different "Download" behaviour on web app on manual click and when clicked with Browser

Hello everyone! Hope you are doing well,

I would like ask for help on a peculiar behaviour I am getting on React web app.
Robot Framework + Browser is used, of course.

In essence, it’s a SPA form which populates bunch of data, at the end of which user can download a PDF version of the document. Now:

  1. When testing manually and selecting “Download” button, PDF is downloaded to selected download folder.
  2. When automation script touches the button, PDF is not downloaded.

As explained by a dev, when “Download” button is clicked, the following happens:

  • docGen API is hit
  • it returns base64 string
  • front-end magic is used to decode that base64 into PDF and save it to user machine

So, when “Download” is selected manually, all works well:

  • file gets downloaded to designated folder
  • if no default download folder is selected, an operating system “Save As” dialog will be displayed, so user can choose where to save the PDF.

This is a process that takes some 5-7 seconds (there is a nice spinner) and then the download icon appears showing a PDF is downloaded.

But, when robot script clicks the “Download” button:

  • spinner is spinning and after 5-7 seconds it stops
  • a file is seemingly downloaded, named by some id, with no extension
  • when test finishes, there is no file saved, it disappears
  • if that file is saved “forcifully” (long Sleep) and opened, it can be opened in PDF viewer, no content whatsoever, but with expected number of pages.
  • in Chrome downloads it shows as blob:{someId}, as Azure is used.

Looks like that file (with no extension) only lives during the test session. Am I missing something?
Seems like - FE code that decodes data to PDF is not executed when test is automated.
Sleep doesn’t help.
Adding downloadsPath didn’t help.

Any idea why this is happening? All help is very welcome as well as if you need more info. :slightly_smiling_face:
Why wouldn’t it be the same behaviour as when “Download” button clicked manually?

EDIT: Uh, once I layed this out, some ideas pop up.

  • since Browser is always incognito, that means tha OS “Save As” dialog will pop-up.
  • but setting downloadsPath, unfortunatelly, does not help (behaviour is the same)
  • and I never see the operating sistem “Save As” dialogue during test when starting any of the 3 engines (to maybe use RPA.Desktop to selelct “save” on the damned dialogue). Besides, how could I do it in CI/CD, on an agent, all headless…

The docs of New Browser says:

downloadsPath:
If specified, accepted downloads are downloaded into this folder. Otherwise, temporary folder is created and is deleted when browser is closed. Regarding file deletion, see the docs of Download and Promise To Wait For Download.

The docs of Promise To Wait For Download states:

With default filepath downloaded files are deleted when Context the download happened in is closed

saveAs:
Defines path where the file is saved persistently. File will also temporarily be saved in playwright context’s default download location. If empty, generated unique path (GUID) is used and file is deleted when the context is closed.

You should also use this keyword to actually get the files location. Please see the example as well.

Promise to Wait For Download

Hi René,

Thank you very much for your reply and for pointing this out.
Before trying this, I consulted one more experienced QA engineer I know and we got 2 workarounds:

1. A custom python conversion library to take downloaded content and spit it out in chosen format.

  • heavy on resources
  • supports both .pdf and .docx

class PdfConverterLibrary:
def init(self, *args, **kwargs):
print(f"Sample Library initialized with args: {args} and kwargs: {kwargs}")

def convertPdf(self,file_to_open, file_to_save):
    t= open(file_to_open, "rb")
    s=t.read()
    k=open(file_to_save, 'wb')
    k.write(s)

which is called in the test.

2. After some thinking, another, natively supported solution popped up, using OperatingSystem library.

  • light on resources

  • supports only .docx

    OperatingSystem.Empty Directory ${DIRECTORY_OF_WORKING}\Downloads\
    ${date} Get Current Date result_format=datetime
    ${date} Convert To String ${date}
    ${date} Replace String ${date} : -
    OperatingSystem.Wait Until Created ${DIRECTORY_OF_WORKING}\Downloads\* timeout=1 minute
    ${files} OperatingSystem.List Files In Directory ${DIRECTORY_OF_WORKING}\Downloads\
    ${binary} Get Binary File ${DIRECTORY_OF_WORKING}\Downloads\${files[0]}
    Create Binary File ${DIRECTORY_OF_WORKING}\DownloadedDocs\someFile${date}.docx ${binary}

3. Tried Promise To Wait for Download, as per your suggestion.
File gets downloaded but can’t be opened if it is .pdf. .docx works fine.

Test fails with this error (maybe we are missing something obvious, yet again):

EDIT: looks like it works without error without “timeout”. :man_shrugging:
.pdf still won’t open, though.