FOR Loop in Robot Framework failing to click through elements - robotframework

I'm trying to create a FOR Loop in Robot Framework that will click through a set of links on a page. Trying to avoid a string of "Click Element" lines and just make a loop out of it. I believe my base code is correct in the loop construction, but PyCharm is seeing the first line of the loop as its own keyword, which isn't right. It's not moving past that part. Any ideas here?
My variables are known, just stored off on another file.
Documentation Homepage
Library Zoomba.GUILibrary
Library Process
Resource ../../Pages/resource.robot
Suite Setup Browser Setup ${url}
*** Keywords ***
Menu Navigation
${list}= Create List ${TUAbout} ${TUAcademics} ${TUResearch}
:FOR ${item} IN #{list}
Wait For And Click Element ${item}
END
*** Test Cases ***
TC 001 Menu Navigation
Menu Navigation```

You need at least 2 spaces for the variables on the FOR line and FOR syntax has changed in more recent versions of RF so :FOR is deprecated syntax use just FOR e.g.
FOR ${item} IN #{list}
I believe that should be enough to fix the current error you're seeing

Related

Tosa puzzle with RobotFrameWork: read string text from a certain point till a certain point

The source is this obstacle: https://obstaclecourse.tricentis.com/Obstacles/87912
What I got this far is:
*** Settings ***
Library Browser
Library XML
Library Collections
Library String
Documentation BE FAST AUTOMATE
*** Variables ***
${links}= <isbn>
${rechts}= </isbn>
*** Test Cases ***
Execute a for loop only three times
Open Browser https://obstaclecourse.tricentis.com/Obstacles/87912
Click id=loadbooks
${alles}= Get Text id=books
This one is mentioned: 'hard'
The Get Text literally gets all the text which is fine, but from that point I have no clue how the get the isbn (from the specific, or even ... any)
A bit further thanks to this page: Parse XML only returns first element
*** Settings ***
Library Browser enable_presenter_mode=False
Library XML
Library Collections
Library String
Documentation BE FAST AUTOMATE
*** Variables ***
##{ROBOTS}= 1 2 3
${links}= <isbn>
${rechts}= </isbn>
*** Test Cases ***
Find the isbn
Open Browser https://obstaclecourse.tricentis.com/Obstacles/87912
sleep 5s
Click id=loadbooks
${alles}= Get Text id=books
${x}= Parse Xml ${alles}
${el_my_value}= XML.Get Element ${x} .//isbn
Log ${el_my_value}
${first_text}= Get Element Text ${el_my_value}
but now I still need the isbn corresponding to the correct title.
because the response is: Multiple elements (6) matching './/isbn' found.
I don't think I should post this as you are suppose to build the answer to the exercise, not google it...
Nevertheless, here it goes.
The data is hidden and if you carefully look into the html of the page you will see that after clicking the button "Load books" a javascript function is kicked that will set the value into the xml and into a variable.
After knowing this information is very simple to get the value that we want just using simple robot + selenium:
*** Settings ***
Library SeleniumLibrary
*** Test Cases ***
Insert Correct ISBN
Open Browser https://obstaclecourse.tricentis.com/Obstacles/87912 Chrome
Click Element id=loadbooks
${isbnValue} Execute Javascript return isbn
Input Text id=isbn ${isbnValue}

Joining 3 strings and using them to find element not working

I've a situation in my app where I need to click on file name from a /div table which will save the file name internally and gets displayed in a /div grid. Every time I run the automation, I need to click on a new file.
I don't have any problem in clicking the file to be saved.
But after the click, the app stores the file in a /div grid and I want to select the file that I added.
For this I used this approach:
I am storing the file name in a global variable ${g_ExtractedFileName}
For eg: XX_YY_Response_IdNum_48015_2020-07-27T12-18-44.334442.txt
My complete Xpath to the file is something like this
xpath://div[#role='row']//span[contains(text(),'XX_YY_Response_IdNum_48015_2020-07-27T12-18-44.334442.txt')]
For this I have the below:-
${attachedFileXpath1}= set variable xpath://div[#role='row']//span[contains(text(),'
${attachedFileXpath2}= set variable ${g_ExtractedFileName}
${attachedFileXpath3}= set variable ')]'
${attachedFileXpath}= set variable ${attachedFileXpath1}${attachedFileXpath2}${attachedFileXpath3}
click element ${attachedFileXpath}
This throws an error
SyntaxError: Failed to execute 'evaluate' on 'Document': The string
'//div[#role='row']//span[contains(text(),'XX_YY_Response_IdNum_48015_2020-07-27T12-18-44.334442.txt
')]'' is not a valid XPath expression.
When I don't use the variables and simply use (hard coded value for file name)
click element xpath://div[#role='row']//span[contains(text(),'XX_YY_Response_IdNum_48015_2020-07-27T12-18-44.334442.txt')]
It works correctly.
I also tried this but same error
${attachedFileXpath}= catenate ${attachedFileXpath1}${attachedFileXpath2}${attachedFileXpath3}
I am not sure when the 3 variables are concatenated, it cuts off the variable value to a new line causing this problem.
Any help is much appreciated.
The simplest approach is to simply use the replace functionality that is already present in Robot Framework variables. The below example will result in an Element not found error, but that is expected.
*** Settings ***
Library SeleniumLibrary
*** Variables ***
${g_ExtractedFileName} XX_YY_Response_IdNum_48015_2020-07-27T12-18-44.334442.txt
*** Test Cases ***
Use Global String in Locator
Open Browser https://google.com chrome
click element xpath://div[#role='row']//span[contains(text(),'${g_ExtractedFileName}')]
[Teardown] Close All Browsers
Simply create keyword which accept the file name as argument and returns complete valid xpath expression. It will be re-usable and elegant solution -
*** Test case ***
Select file saved in div grid
${attached_file_xpath}= GetAttachedFileXpath ${File_Name}
Click Element ${attached_file_xpath}
*** Keywords ***
GetAttachedFileXpath [Arguments] ${File_Name}
return from keyword xpath://div[#role='row']//span[contains(text(),'${File_Name}')]

How to create a incremental variable in a position of list on Robot Framework

I'm trying to do a test that lists all of the configuration files in a folder and performs one configuration at a time, but I don't know how to insert an incremental variable at the position of the list. In my code below, only the first file of the first position is loaded. Can anyone help a robot beginner?
${list} = List Files in Directory ${input_folder}
${lista} = Create List ${list}
${number_files} = BuiltIn.Get Length ${list}
:FOR ${i} IN ${lista}
Run Process python aster_scripts/setup_transform.py --input-yaml ${input_folder}${lista[0][0]}
Generate plan
END```
For using a list in a list content you need to use #
*** Settings ***
Library OperatingSystem
*** Test Cases ***
List Files
#{list}= List Directory ${EXECDIR}
FOR ${filename} IN #{list}
Log To Console ${filename}
END
It is also possible to use a list with $. As far as I can see it is not documented but ${list} is some kind of a "reference to list" Perl's style. It is not exactly like that but it helps me understand it. So with ${list} you can pass a list to a keyword as a scalar.

Iterate through variables in Robot Framework Click Element

As part of a Robot Framework test I would like to access multiple objects from my page with the same keyword. The xpath of the objects looks like this:
//div[#class='col-sm-4 ng-scope']//h1[#class='ng-binding'][contains(text(),'Bot1')]
//div[#class='col-sm-4 ng-scope']//h1[#class='ng-binding'][contains(text(),'Bot2')]
//div[#class='col-sm-4 ng-scope']//h1[#class='ng-binding'][contains(text(),'Botx')]
I've tried to set a list variable with the name of my test objects (elements)
*** Variables ***
#{TESTBOTS} = Bot1 Bot2 Botx
*** Keywords ***
Delete Bots
go to ${LANDINGURL}
Sleep 3s
Click Element //div[#class='col-sm-4 ng-scope']//h1[#class='ng-binding'][contains(text(), #{TESTBOTS})]
However, I get the following error:
FAIL Element with locator '//div[#class='col-sm-2 ng-scope']//h1[#class='ng-binding'][contains(text(),'${TESTBOTS')]' not found.
I'd really appreciate if you could point me to the right direction. Thanks!
The error message still does not seem to fit the snippet, I believe.
But anyway: with #{TESTBOTS} you unwrap the complete list. I would have expect an error like No element found with text 'Bot1 Bot2 Botx'
I think this should work iterating the list of testbots:
FOR ${testbot} IN #{TESTBOTS}
Click Element //div[#class='col-sm-4 ng-scope']//h1[#class='ng-binding'][contains(text(), ${testbot})]
END

How to loop on a table column?

Badly need your help. In Vehicle ID column, I would like to find a vehicle and once it finds it, it will click on it... How can I do that in Robot Framework? What approach should i be using?
For looping in table you can use xpath easily:
*** Test Cases ***
Stackoverflow Test
[Tags] #InDevelop
Go To https://www.w3schools.com/html/html_tables.asp
Wait Until Element Is Visible id=customers ${global_timeout}
:FOR ${index} IN RANGE 2 8
\ Wait Until Element Is Visible xpath=//*[#id="customers"]/tbody/tr[${index}]/td[1] ${global_timeout}
\ ${var} = Get Text xpath=//*[#id="customers"]/tbody/tr[${index}]/td[1]
\ Log ${var}
In order to click the correct element, you probably need to compare the variable content with your expected value. That can be done this way:
${areYouMyLine} = Run Keyword and Return Status Should Be Equal As Strings ${var} Island Trading
Run Keyword If ${areYouMyLine} Click Elementxpath=//*[#id="customers"]/tbody/tr[${index}]/td[1]
And also don't forget to Exit your For Loop since you found your element.
Exit For Loop
However this is not the best practice. You probably should go to your product team asking for some data attributes which will help you to find your line. Alternatively, if you know your table content, put it into a list and use For In Loop instead. Good stuff about loops can be found here: https://blog.codecentric.de/en/2013/05/robot-framework-tutorial-loops-conditional-execution-and-more/

Resources