I am centralizing all particular XPath strings to a resource file and importing the variables in that resource file in my test suite (robot framework). This way, they can be maintained in one place and I can use variable names that make the robot file readable. Is that something that is good practice?
Sometimes I want to pass an argument to the variable, to make it more dynamic. However, the value of the variable contains and XPath, which sometimes has //div[path...etc][text()='MyString'].
Question: In the robot file, how to pass an argument ('MyString') to the Click Element method that is using a variable?
It is certainly a good practice to separate your UI objects technical reference from your test logic. Typically this pattern is called an object store, but other names are used as well.
As for the method of separation, I'd recommend using a YAML variable file over a resource file for static values and including them using the command line argument robot --variablefile MyVariables.yaml MyRobotFile.robot
over including a resource file in your test script. This has the added advantage that if you want to switch out your object store because of a different software release then this doesn't require a test script change.
In the event that your variable content changes depending upon some value known when starting robot, then Python Variable Class is a good approach. This is a Python function or Python class that takes an argument and you can use Python to go to a database, file, or use internal logic to determine which variables need to be returned and what value they should hold.
As for adding variable pieces to an xpath without ending up with a lot of specific specialised keywords, I use Custom Locator Strategy functionality from the SeleniumLibrary library. This allows me to use the normal keywords without any additional keywords in the test logic itself.
In the below example a custom locator abc=
is created and can be used instead of xpath=
for any standard SeleniumLibrary keyword. In this case I use a Dictionary as the Locator object store to hold the ID's and refer to them using a unique name. Note that the abc=
is stripped from the value in the ${criteria}
argument.
*** Variables ***
&{locators}
... myCustomId1=//*[@id='12234']
... myCustomId2=//*[@id='23455']
*** Test Cases ***
Test Case
Add Location Strategy abc Custom Locator Strategy
Page Should Contain Element abc=myCustomId1
*** Keywords ***
Custom Locator Strategy
[Arguments] ${browser} ${criteria} ${tag} ${constraints}
${WebElement}= Get Webelement xpath=${locators['${criteria}']}
[Return] ${WebElement}