Joining 3 strings and using them to find element not working - robotframework

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}')]

Related

Robotframework : file_1.robot needs to update a variable in file_2.robot

I tried using the Set Global Variable keyword but I am not sure if I am doing this correct. I was hoping to make 2 files have access to this variable. Here is my variables section. I am using VS code with Robot plugin for syntax highlighting. The error show when I run this
is:
Invalid variable name 'Set Global Variable'.robotcode.diagnostics(ModelError)
*** Variables ***
Set Global Variable ${VERBOSE} 0
${SERIAL_PORT} None
Is there a special library I need to import to use Set Global Variable?
My use case is that I have 2 robot files both of them need to know if Verbose mode is enabled. I pass verbose to file_1.robot file via command line, I was hoping I could also pass the verbose variable to a Resource file_2.robot, but I am unable to do this because
in my second file there is no "command line argument to pass in to it"
Is there a way from file_1.robot I can set/update a variable in file_2.robot ?
For file one i can do this via command line, but for file 2 I was hoping something like this would exist:
Resource ../resources/Serial.robot -v Verbose:0
(in this case Serial.robot is the infamous file 2 )
To make things even simpler I dont need Verbose in File 1 , i Just need it to pass it on to the resource file somehow
Set Global Variable is a keyword that could be used inside test cases or custom keywords. What you need is to define variable (link to documentation).
I pass verbose to file_1.robot file via command line, I was hoping I could also pass the verbose variable to a Resource file_2.robot, but I am unable to do this because in my second file there is no "command line argument to pass in to it"
Nope, you are passing global variable visible from everywhere. Take a look at documentation about scopes and priorities for variables.
If you want to define once and use in multiple places you could create file with common variables and import in both files. Example:
Here you define:
# BaseVariables.robot
*** Variables ***
${VERBOSE} 0
And use:
# file_1.robot
*** Settings ***
Resource BaseVariables.robot
and in second file
# file_2.robot
*** Settings ***
Resource BaseVariables.robot

FOR Loop in Robot Framework failing to click through elements

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

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}

Possibility to modify 1 or 2 arguments from multiple list of arguments in keyword during creation test case in robotframework

I am curious if it's possible to modify some default argument when I try using following keyword during test case creation. See example below.
*** Keywords ***
Open URL With Custom Parameters
[Arguments] ${fe}=example.lan ${be}=https://example.be.lan ${reminderInterval}=5 ${licence}=default ${flowId}=7349 ${name}=example ${cur}=EUR ${lang}=en
... ${browser}=chrome
Open Browser https://${fe}/${name}/debug_index.html?&appsrv=${be}&currency=${cur}&lang=${lang}&reminderInterval=${reminderInterval}&fullscreen=yes&license=${licence} ${browser}
I would like to modify only 2 dedicated arguments e.g. Below doesn't work
*** Test Cases ***
Open browser and do sth
Open URL With Custom Parameters ${name}=development ${be}=https://goodday.com`
If is possible to change default argument from keyword in different order where is set it in keyword?
I would like to avoid adding all remains parameter to change only 1 or 2 arguments like below:
*** Test Cases ***
Open browser and do sth
Open URL With Custom Parameters ${fe}=https://development ${be}=https://goodday3421.com
....
Yes, it's possible, just don't use the ${} around the arguments' names when calling the keyword:
Open URL With Custom Parameters fe=https://development be=https://goodday3421.com

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

Resources