Total noob here. I’ve been assigned a critical business project that involves visiting a website, navigating to a report, starting the generation of the report, then waiting for a download link to become available.
I’ve gotten to the point where I can start the report generation, but to start the download, I have to watch a div with a mat-table in it. The requirement is to always get the first mat-row right after the mat-header-row, then watch the contents of that first mat-row and wait until a Download link shows up.
Every Get Element or Get Elements I try claims the mat-row or mat-rows are not in the domain. I am wondering:
Can Browser Get Element detect Angular+Flex mat-row elements?
It’s probably a resounding no, but I’d like to confirm before I take alternate routes, none of which are good options.
I’m pretty sure my boss won’t let me post the code, but I’ll ask for permission. For now, I’ll copy and paste as little as possible so as to not get in trouble.
I confirm that the locator you provided does work with the example website you linked to–thanks very much for that!
However, this might be the real source of my problem…
In the example website, the tr tags look like this:
That is to say, there is no tr tag, every row is a mat-row tag…
I don’t even understand how the web browser (FireFox) knows to render a mat-row tag.
(I just noticed this key difference when examining the source code of the website you provided that works and comparing it to the source code of the site I have to work with that doesn’t work. Thanks again for providing the example.)
Ah! I didn’t see that! (I used Take Screenshot of just the element, and from just a partial screenshot it wasn’t clear to me that it was choosing the first row of the second table.)
I will give your selector a try in my production code and get back to you with the results…
*** Settings ***
Library Browser
*** Test Cases ***
Test 5
New Browser chromium headless=false
New Context
New Page https://material.angular.io/components/table/examples
Scroll To Element :nth-match(mat-table,1) > mat-row:nth-of-type(1)
Highlight Elements :nth-match(mat-table,1) > mat-row:nth-of-type(1)
Sleep 5s
b) Taking the locator from your first post, I was able to get my production code to take a screenshot of the first mat-row in the table, exactly what I need to target and later manipulate!
Follow up on this issue.
I have noticed that SOMETIMES the Get Element is able to target the mat-row element in my production code and sometimes it is not able to.
It appears to be that the mat-table doesn’t show up fast enough sometimes. In those cases, then it unsurprisingly produces the “element not found in the DOM” error. I guess I’ll have to figure out how to make Browser wait until the mat-table shows up. I had thought that Get Element would wait long enough before giving up…
This is a lucky coincidence with a different task I face: I have to watch this first mat-row and wait for a report to be generated in the background, followed by a Download link being added to the mat-row. I then have to click that exact Download link. So, I have to wait anyway, and a lot longer than just for the mat-table to show up in the DOM–the report generation might take 60s or more.
Yes, that’s what’s makes this weird.
I had gotten used to Get Element waiting for the element to show up in the DOM, but this time, Get Element gives up almost instantly and marks the test as failed seemingly without trying.
Also, all this time, I have had Set Browser Timeout 60. This 60-second timeout has been in full effect in prior failures but in this case, it never waits more than 1 or 2 full seconds before failing.
Perhaps this is a bug, since it does not observe the timeout.
It was for the first mat-row (which is why I thought Browser couldn’t even detect mat-row elements at first). My belief at the time was that: “hey, Browser Get Element will wait long enough for the first mat-row to show up, the Set Browser Timeout is plenty long, therefore the instant failure must be due to an inability to recognize mat-row tags.”
I have not even gotten to the point where I’m waiting for the Download link to be added to the first mat-row, so no idea how that will go yet… It definitely will take a long time for our larger reports (much longer than the Set Browser Timeout of 60 seconds). I figured I would have to study the Wait For keywords and pick the right one to use.
I will give “Wait for Elements State” a try first (I have no idea which Wait For is for what use case or how to use any of them. All I know right now is that my current setup of VSCode with the two Robocorp extensions and Browser v. 17.x does not recognize any of the Wait For [something] keywords, it only recognizes “Wait For”). Others have given me advice on using Browser 18.x, which does have all the extra Wait For [something]s.
I suggest using the RobotCode extension, because the Robocorp extensions are no longer mantained and offer no support voor Robot Framework 7. And I also suggest upgrading to the latest Browser Libray version.
You can also first wait for the page to be fully loaded, aka no more exchange on the network, then wait the element.
If the reports need more than 1 minute to be sent to the UI, RF will wait for all the report to be loaded, then will wait for the element to be visible.
We definitely need a very long time for this report to download–the end user recorded a video of it and had to stop recording in the middle so as to keep the video file small! I think it ended up being 10 to 15 total minutes for the report to be created in the backend. Downloading the actual report is fairly quick–the files are not huge. It just takes a long time to run the SQL queries to create the reports.
I told them and my manager that it might not be possible to wait that long, that Robot Framework might exceed the timeout and give up.
I will try Wait For Load State first, then the other Wait For …s. In the worst case, we can split the task into two separate Robot runs: one to start the download and record the timestamp shown in the Downloads mat-table, another to come and get the correct download later based on the exact timestamp.
Hi,
As said before by Falcon, you can define your own timeout using [Set Browser Timeout]
It can be 15 minutes or longer like 20 mn…
Just follow the example on the RF documentation to restore the default timeout:
${old_timeout} = Set Browser Timeout 20m
… your stuff …
Set Browser Timeout ${old_timeout}
You can also use ‘sleep’ in a loop with a limit (to avoid infinite loop) but it is less elegant…
If you do not want to have a script which waits a long time (because it run in ci and you do not want to pay a lot for just wait time), you can separate as you’ve described but this will be more complex to manage (some reports, need to store the information in a temporary file, …).
Regards
Olivier