I try to get variable ${var_Master} from a txt file and put it in to into list box and ${ValSub} is working fine, but I got error on var ${var_Master}:
**InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified (Session info: chrome=64.0.3282.167)
(Driver info: chromedriver=2.34.522940
(1a76f96f66e3ca7b8e57d503b4dd3bccfba87af1),platform=Windows NT
10.0.14393 x86_64)
With the below code example:
${var_sub} Get File ../resources/var_sub.txt
#{list} Split To Lines ${var_sub}
${var_Master} Get File ../resources/var_master.txt
:FOR ${line} IN #{list}
\ ${ValSub}= Get Variable Value ${line}
\ sleep 1s
\ select from list by value name=merchant_id ${ValSub}
\ select from list by value name=master_marchant_id ${var_Master}
In Robot Framework there is no need to create custom import routine to create variables as there is a standard keyword for it: Import Variables (Documentation).
In the below example I'm using a file in the YAML markup language which allows for the creation of specific Python and Robot variable types like lists, dictionaries and scalars in human readable format. It is also possible to import a python file declaring the objects as well.
In this example I've created a mock scalar variable master and a mock list variable list to prove that looping is possible and mocked the Select From List By Value as a custom keyword.
vars.yaml
master: master value
list:
- item 1
- item 2
- item 3
example.robot
*** Test Cases ***
TC1
Import Variables ${EXECDIR}/vars.yaml
:FOR ${line} IN #{list}
\ sleep 1s
\ select from list by value name=master_marchant_id ${master}
\ select from list by value name=merchant_id ${line}
*** Keywords ***
Select From List By Value
[Arguments] ${locator} ${value}
Log Selecting "${value}" from "${locator}" element.
I use this method to solve my problem
${var_master} Get File ../resources/var_master.txt
#{list} Split To Lines ${var_master}
:FOR ${lineb} IN #{list}
\ ${ValMas}= Get Variable Value ${lineb}
${var_sub} Get File ../resources/var_sub.txt
#{list} Split To Lines ${var_sub}
:FOR ${line} IN #{list}
\ ${ValSub}= Get Variable Value ${line}
\ sleep 1s
\ select from list by value name=master_marchant_id ${ValMas}
\ select from list by value name=merchant_id ${ValSub}
Related
I am trying the below steps but it throws an error: '${dut1_lmepid_${i}}' no keyword found.
If I use anything like ${temp_var} in place of ${dut1_lmepid_${i}} it works fine though.
: For ${i} IN RANGE 1 2
\ ${var} = Set Variable dut1_lmepid_${i}
\ ${dut1_lmepid_${i}}= Run Keyword get-local-ac-id me${i}
It is possible to do this using a second step using the keyword Set Global Variable:
*** Test Cases ***
Test Item
:For ${i} IN RANGE 1 5
\ ${value} = Run Keyword get-local-ac-id me ${i}
\ Set Global Variable ${dut1_lmepid_${i}} ${value}
No Operation
*** Keywords ***
get-local-ac-id
[Arguments] ${arg}
[Return] value ${arg}
This is currently not possible with Robot. You can use "variables inside variables" to resolve the values of variables (see the documentation on this topic) but not to resolve/set the name of the variable itself.
I am trying to get all the text from a class or xpath, iterate over it and put it in a list.
Tried below code but keep getting this error:
No keyword with name 'Append To List' found.
${xpath}= Set Variable //label[#class='required']
${count}= Get Element Count ${xpath}
${names}= Create List
:FOR ${i} IN RANGE 1 ${count} + 1
\ ${name}= Get Text xpath=(${xpath})[${i}]
\ Append To List ${names} ${name}
\ Log To Console ${names}
Other solution that i tried .getting same error for the below code as well.
#{locators}= Get Webelements ${requiredDocuments}
#{result}= Create List
: FOR ${locator} IN #{locators}
\ ${name}= Get Text ${locator}
\ Log ${name}
\ Append To List ${result} ${name}
Log ${result}
You need to import the standard library Collections in order to use the keyword Append To List. To import the library, declare it in the settings of your test case, for example like this:
*** Settings ***
Library Collections
I was getting this with the BuiltIn Library. Turns out, I had only once space between the command and the keyword. Once I added two spaces, my keyword was recognized. It doesn't look like that is your problem but it resolves this error and for me, spacing was my problem.
I would like to look for a particular message in a constantly updating file. I used Wait Until Keyword Succeeds with my own keyword to search the file and it works fine.
*** Test Cases ***
${lineCount} MyKeywordToGetLineCountToStartSearch ${filename}
Wait Until Keyword Succeeds 10s 2s KeywordToLookForTheMessage ${filename} ${linecount} ${message}
*** Keywords ***
KeywordToLookForTheMessage
[Arguments] ${filename} ${linecount} ${message}
Run tail -n +${linecount} ${filename} > ${locationdir}/${newfile}
${filecontent} Get File ${locationdir}/${newfile}
#{lines} Split To Lines ${filecontent}
${result_list} Create List
: FOR ${line} IN #{lines}
\ ${state} ${msg} Run Keyword And Ignore Error Should Contain ${line} ${message}
\ Run Keyword If '${state}' == 'PASS' Append To List ${result_list} ${line}
Should not be empty ${result_list}
Now what I'm missing is ,
With each iteration I need the line count to be updated so that I don't look through the same lines again .
While doing that, I would also want to retain the original line count value for further in the testcase.
How can I do that ?
This kind of complex logic should be implemented in test library using Python, not trying to use lower level keywords provided by existing libraries.
Code 1 works but its partially hardcoded to get al city information , i am looking to display all key value pair at same time.
*** Test Cases ***
Code1
#get json file
${json_data}= Get file detail.json
#get dictionaries under list
${data}= evaluate json.loads($json_data) json
${alladdress}= get from dictionary ${data} alladdress
${addresslist}= get from dictionary ${alladdress} addresslist
# loop over dictionaries under list. I wanted to use loop FOR ${address} in ${addresslist.keys()} but for some reason its not working so i use this code to display key value pair
: FOR ${address} in #{addresslist}
\ ${city} = Get From Dictionary ${address} city
\ ${key}= set variable ${address.keys()}
\ ${listkey}= get from list ${key} 0
# since i know list 0 is city but its kind of hardcoded
\ log to console ${listkey}, ${city}
# i am trying to display key value pair using below code but it displays error #{address.keys()}' failed: Variable '${address}' not found.
Code2
#get json file
${json_data}= Get file detail.json
${data}= evaluate json.loads($json_data) json
${alladdress}= get from dictionary ${data} alladdress
${addresslist}= get from dictionary ${alladdress} addresslist
# loop over list which contents dictionary object.
:FOR ${address} IN #{addresslist}
\ Loop over address #{address}
Loop over items
[Arguments] #{address}
:FOR ${key} IN #{address.keys()}
\ ${value}= Get From Dictionary ${address} ${key}
# here i get error #{address.keys()}' failed: Variable '${address}' not
found.
\ log to console ${key},${value}
Here is Json File
{"class": {"id": 0,"name": "David"},"alladdress": {"count": 3,"addresslist": [{"houseno": 1,"streetno": 5,"streetname": "tesla","city": "ABC","state": "AA","country": "UK","zip": 85555},{"houseno": 2,"streetno": 6,"streetname": "honda","city": "PQR","state": "BB","country": "IN", "zip": 5252}]}}
In the code you have this comment:
# loop over dictionaries under list. I wanted to use loop FOR ${address}
# in ${addresslist.keys()} but for some reason its not working so i use
# this code to display key value pair
The reason :FOR ${address} IN ${addresslist.keys()} doesn't work is because ${addresslist} is a list, not a dictionary. Lists don't have keys.
You need to loop over every address in ${addresslist}, and then within that loop you can call a keyword to print the key/value pairs of each element in the list.
Here is a complete working example:
*** Settings ***
Library OperatingSystem
Library Collections
*** Keywords ***
Log dictionary
[Description] log key/value pairs from dictionary to the console
[Arguments] ${dict}
log to console \n----
:FOR ${key} IN #{dict.keys()}
\ ${value}= get from dictionary ${dict} ${key}
\ log to console ${key} => ${value}
*** Test Cases ***
Code1
${json_data}= Get file detail.json
${data}= evaluate json.loads($json_data) json
${alladdress}= get from dictionary ${data} alladdress
#{addresslist}= get from dictionary ${alladdress} addresslist
:FOR ${address} in #{addresslist}
\ log dictionary ${address}
I have text file which has list of lists like below.
**sample.txt Text file content **:
[["Sanjay", "Bangalore", "100"], ["Akshay", "Pune", "101"], ["Pranay", "Delhi", "102"]]
Requirement:
I have to iterate over each list in he above list and assign each item in list to variable.
Test Case
${FILECONTENT}= Get File sample.txt
Log to console ${FILECONTENT}
: FOR ${ELEMENT} IN ${FILECONTENT}
\ ${NAME}= ${ELEMENT}[0]
\ ${CITY}= ${ELEMENT}[1]
\ ${ID}= ${ELEMENT}[2]
\ Log to console ${ELEMENT}
Log to console For loop is over
I am not able to loop over content as its not treating content as list of lists.
Can any one help how to achieve this.
The example code you provided has a few issues. First, and foremost is that you need to convert the string to a list-in-list construction. Then you need to correctly iterate over it and lastly assign variables in the right way.
As there isn't a native keyword to allow for instant string to list-in-list conversion I created a custom keyword library for it and stored it as List.py in the same folder as your robot script:
import ast
class List(object):
ROBOT_LIBRARY_VERSION = 1.0
def __init__(self):
pass
def ConvertToListFromString(self, ListString):
x = ast.literal_eval(ListString)
return x
This library can then be utilized to create the functionality in robot:
*** Settings ***
Library OperatingSystem
Library List
*** Test Cases ***
Sample
${FILECONTENT}= Get File sample.txt
#{list} Convert To List From String ${FILECONTENT}
Log to Console ${EMPTY}
: FOR ${ELEMENT} IN #{list}
\ ${NAME} Set Variable ${ELEMENT[0]}
\ ${CITY} Set Variable ${ELEMENT[1]}
\ ${ID} Set Variable ${ELEMENT[2]}
\
\ Log to console Name=${NAME}, City=${CITY}, Id=${ID}
This then results into:
Command: C:\Python27\python.exe -m robot.run -P C:\Eclipse\Workspace\ExternalList
-s ExternalList.ExternalList C:\Eclipse\Workspace\ExternalList
Suite Executor: Robot Framework 3.0 (Python 2.7.9 on win32)
==============================================================================
ExternalList
==============================================================================
ExternalList.ExternalList
==============================================================================
Sample
Name=Sanjay, City=Bangalore, Id=100
Name=Akshay, City=Pune, Id=101
Name=Pranay, City=Delhi, Id=102
| PASS |
------------------------------------------------------------------------------
ExternalList.ExternalList | PASS |
1 critical test, 1 passed, 0 failed
1 test total, 1 passed, 0 failed
==============================================================================
ExternalList | PASS |
1 critical test, 1 passed, 0 failed
1 test total, 1 passed, 0 failed
==============================================================================
Output: C:\Eclipse\Workspace\ExternalList\output.xml
Log: C:\Eclipse\Workspace\ExternalList\log.html
Report: C:\Eclipse\Workspace\ExternalList\report.html
It should be noted that reading files an converting them to code poses some security risks that need to be mitigated. The above code is therefore not Production ready.
If the data is valid JSON, you can convert the data to JSON and then iterate over the values very easily:
${FILECONTENT}= Get File sample.txt
${JSON}= evaluate json.loads($FILECONTENT) json
:FOR ${ELEMENT} IN #{JSON}
\ ${NAME} Set Variable ${ELEMENT[0]}
\ ${CITY} Set Variable ${ELEMENT[1]}
\ ${ID} Set Variable ${ELEMENT[2]}
\ Log to console element: ${ELEMENT}
Note: the other statements in your FOR loop are incorrect. To set new variables you must call the Set Variable keyword. That is why I changed them in the example code.