I am trying to return a value from a keyword to my test case, but I am getting error
Variable 'xxx' not found.
This is my code.
*** Keywords ***
Click Dispatched check box from Status
${dispatchOptionPresent}= run keyword and return status click element ${selectDispatchedCheckbox_xpath}
set global variable ${g_dispatchOptionPresent} ${dispatchOptionPresent}
run keyword if '${dispatchOptionPresent}' == 'False' NoDispatchedStatusFoundforSelection
... ELSE Set Test Message *HTML* Applied <b>'Dispatched'</b> status filter
click element xpath://body
sleep 2
NoDispatchedStatusFoundforSelection
Fail 'Dispatched' status option not found...
[Return] ${g_dispatchOptionPresent}
*** Test Cases ***
Click 'Dispatched' check box for Status
[Tags] Filter-From Date/Status for LOA
[Documentation] Test to select 'Dispatched' check box for Status
${dispatchStatusFound}= Click Dispatched check box from Status
set global variable ${g_dispatchStatusFound} ${dispatchStatusFound}
pass execution if '${g_dispatchStatusFound}' == 'False' *HTML* <b>'Dispatch'</b> status found for selection!!!
For some reason, the test case is not seeing the returned value from the keyword section.
I checked for any formatting issues also, but no luck.
A similar scenario in one of my another test case works correctly with [Return]
But this one throws me :
Variable '${g_dispatchStatusFound}' not found.
Any help is much appreciated.
Thank you.
Related
I struck in one problem in which I want to store Value returned from 1st keyword in variable during initial run and then using that variable in another keywords without running the 1st keyword again .
I tried below code but not able to resolve the issue.
Create Account Post Request
${response}= call post request ${headers2} ${base_url} ${base_url_account} ${account_data}
log ${response}
Should Be True ${response.status_code} == 201
${account_id} get value from json ${response.json()} id
log ${account_id}
RETURN ${account_id}
Get Network ID --> [While running this keyword Create Account Post Request will run again which updates the account ID which I don't want]
${acc}= Create Account Post Request --> [During this It will run Create Account Post Request again which I don't want]
log ${acc}
My questions are :
How to use account_ID in any keywords without running the first
keyword again and again ?
How to use return value from 1st keyword in any other keywords? [Condition, I don't want to run 1st keyword again to get the return value]
Below scenario is expected :
1st Keyword ran
1st Keyword return some value
Store value in some variable
Use returned value anywhere in the suite file, in any keyword within the suite, in any test case .
Declare a blank variable
*** Variables ***
${account_id}
Add an IF condition in the keyword to run only if the account id is blank, else return the global variable. This way the function steps will be executed only once throughout the suite.
Create Account Post Request
IF "${account_id}" == "" --> ${account_id} should be in inverted commas "${account_id}".
${response}= call post request ${headers2} ${base_url} ${base_url_account} ${account_data}
log ${response}
Should Be True ${response.status_code} == 201
${account_id} get value from json ${response.json()} id
log ${account_id}
Set Suite Variable ${account_id}
END
[RETURN] ${account_id}
How do I find out if a variable has been defined in my Robot Framework script? I am doing API testing, not UI testing. I have a complex set up and tear-down sequence and, since I am interacting with multiple computers through the script, it is important to know the current state if a fatal error has occurred. I could track what I have done with some complex set of meta variables or a variable tracking list, but I would prefer to query if a particular variable has been defined and if so take the appropriate tear-down steps.
A simplified version is something like:
*** Test Cases ***
Check monitor
${monitored}= Connect to Monitor ${Monitor IP Address} ${User name} ${password}
${peer connected}= Connect to Monitor ${Peer IP Address} ${User name} ${password}
Get Information from Monitor ${IP Address}
Send Info to Peer ${buffer1}
Report back to Monitor ${Monitor IP Address}
We are assuming that the tear-down closes the connections. I want to close any connections that are open, but if I failed to open the peer connection I will close the monitor connection and fail on closing the monitor connection.
I am trying to determine if ${peer connected} is defined. Can I look into Robot Framework's variable storage to see if it is there (in that dictionary?)?
You can call Get Variables to get a dictionary of all variables, then check whether the variable you're interested in is in the dictionary.
*** Test cases ***
Example
${foo}= set variable hello, world
${variables}= Get variables
Should be true "\${foo}" in $variables
Should not be true "\${bar}" in $variables
There a pretty straightforward approach - the built-in keyword Get Variable Value returns python's None (by default) if there is no such variable defined:
${the var}= Get Variable Value ${peer connected}
${is set}= Set Variable If """${the var}""" != 'None' ${True} ${False}
I am fine with this approach. In case the variable is not defined, the test case does not fail....
${variables} Get variables
${status} Run Keyword And Return Status Evaluate $new_table in $variables
${new_table} Set variable if ${status}==${FALSE} new_tbl ${new_table}
Also possible is:
${variables} Get Variables
IF "\${dataPluginVersion}" in "${variables}"
No Operation
ELSE
${dataPluginVersion} Set Variable 0
END
Or:
${variables} Get Variables
IF not "\${dataPluginVersion}" in "${variables}"
${dataPluginVersion} Set Variable 0
END
A shorter way:
OEM-T01-99-Test-variables
[Tags] TEST
Variable Should Not Exist \${TESTDEVICE_SSH_CONNECTION}
Variable Should Exist \${TEST_NAME}
This method is more readable and less verbose than using "Get Variables" keyword, IMHO
Reference: Robotframework built-in keywords
I would like to use value from keyword 1 to keyword 2. Tried searching on net but i could not able to solve it.
Verify that apps are listed
wait until element is visible ${AppMenuGrid} ${Timeout} "Apps NOT listed. Step execution failed"
log "Apps listed"
${APPSCOUNT} = GET ELEMENT COUNT ${AppMenuGrid}
log "Number of apps loaded are ${APPSCOUNT}"
[Return] ${APPSCOUNT}
Click on Refresh button
wait until element is visible ${Refresh} ${Timeout} "Refresh button is not visible"
click element ${Refresh}
log "click on refresh button successful"
Verify that same apps are listed
wait until element is visible ${AppMenuGrid} ${Timeout} "Apps list not refreshed. Step execution failed"
log "Apps list refreshed"
${APPSRECOUNT} = GET ELEMENT COUNT ${AppMenuGrid}
${Count} = verify that apps are listed ${APPSCOUNT}
log "Number of apps before refresh ${Count}"
log "Number of apps after refresh ${APPSRECOUNT}"
run keyword if "${APPSRECOUNT}" == "${Count}" log "Number of apps matching after refresh"
... ELSE fail "All apps not loaded after refresh"
I want to use AppsCount value (ex .10) from keyword "Verify that apps are listed" into "Verify that same apps are listed" keyword. But in the 2nd keyword, APPSCOUNT value is always blank.
Change the keyword Verify that same apps are listed to accept arguments:
Verify that same apps are listed
[Arguments] ${expected appscount}
# the rest of its code
And then, in the case where it's used, pass the value from the first keyword:
A case
${the count}= Verify that apps are listed
Verify that same apps are listed ${the count}
I agree with Todor Minakov's approach, to share the value via return clauses. Here is another approach:
Robot Framework (as described in the User Guide) has notion of variable scope: Local (Keyword) level, Test case level, Test suite level and Global. By default, the variables defined in the keywords have local scope.
To share the value of the variable between two keywords, just add a test case scope to the variable, like this:
Verify that apps are listed
wait until element is visible ${AppMenuGrid} ${Timeout} "Apps NOT listed. Step execution failed"
log "Apps listed"
${APPSCOUNT} = GET ELEMENT COUNT ${AppMenuGrid}
Set Test Variable ${APPSCOUNT}
Then, you can call ${APPSCOUNT} inside any other keyword in the same test case and it will have the stored value.
i tried the following and it worked.
In the test case file, i added a variables with the same name ${APPSCOUNT} and set the variables to the keyword like below,
Verify that apps are listed ${APPSCOUNT}
After this i can see value from keyword 1 in keyword 2.
Is this the correct approach?
I have a simple Robot Framework script
*** Settings ***
Documentation Simple Amazon.in demo
Library SeleniumLibrary
*** Variables ***
${MESSAGE} Hello, World
*** Test Cases ***
User must sign in to check out
[Documentation] This is some basic info about the test
[Tags] Smoke
Open Browser http://www.amazon.in chrome
Input text id=twotabsearchtextbox Ferrari 458
Click Button xpath=//div[#class='nav-search-submit nav-sprite']/input[#class='nav-input' and 1]
Wait until page Contains results for "Ferrari 458"
Click Link css=#result_0 a.s-access-detail-page
Wait until Page Contains Back to search results for "Ferrari 458"
Click Button id=add-to-cart-button
Wait Until Page Contains 1 item added to Cart
But whenever chrome reaches Click Link css=#result_0 a.s-access-detail-page it opens a new tab, and my robot script fails. How can I rectify it. Please help
You can use the select window keyword and Get Window Titles keyword to navigate between them Get Window Titles keyword will return a list of titles the last index in that list is the new tab that has been opened, to access it from the list you can do the following ${Tabs[1]} (as in this code there is only 2 values in the list)
*** Settings ***
Documentation Simple Amazon.in demo
Library SeleniumLibrary
*** Variables ***
${MESSAGE} Hello, World
*** Test Cases ***
User must sign in to check out
[Documentation] This is some basic info about the test
[Tags] Smoke
Open Browser http://www.amazon.in chrome
Input text id=twotabsearchtextbox Ferrari 458
Click Button xpath=//div[#class='nav-search-submit nav-sprite']/input[#class='nav-input' and 1]
Wait until page Contains results for "Ferrari 458"
Click Link css=#result_0 a.s-access-detail-page
${Tabs} = Get Window Titles
select window title=${Tabs[1]}
Wait until Page Contains Back to search results for "Ferrari 458"
Click Button id=add-to-cart-button
# Wait Until Page Contains 1 item added to Cart
Wait Until Page Contains Added to Cart
Results:
==============================================================================
Amazon :: Simple Amazon.in demo
==============================================================================
User must sign in to check out :: This is some basic info about th...
DevTools listening on ws://127.0.0.1:29864/devtools/browser/75b8be3c-6e76-474f-b391-d340fb322895
User must sign in to check out :: This is some basic info about th... | PASS |
------------------------------------------------------------------------------
Amazon :: Simple Amazon.in demo | PASS |
1 critical test, 1 passed, 0 failed
1 test total, 1 passed, 0 failed
==============================================================================
Output: C:\development\robot-scripts\sssss\output.xml
Log: C:\development\robot-scripts\sssss\log.html
Report: C:\development\robot-scripts\sssss\report.html
I changed the last line of your code as it wasn't a valid text. See the comment in the code.
I am trying to utilize a global variable that I set by passing it in as an argument to a keyword but it is not working for some reason. Here's the code:
*** Variables ***
${ENV} qa
${MOBILE} 0
${BROWSER} Chrome
${DELAY} 0
${VALID USER} username
${VALID PASSWORD} 123456
&{SERVER} qa=https://${PREFIX}.qa.myapp.com
... staging=https://${PREFIX}.staging.myapp.com
... prod=https://${PREFIX}.myapp.com
${LOGIN URL} ${SERVER.${ENV}}/
${WELCOME URL} ${SERVER.${ENV}}/Profile
*** Keywords ***
Begin Web Test
[Arguments] ${pf}
[Tags] Critical
Set Global Variable ${PREFIX} ${pf}
Open Browser ${LOGIN URL} ${BROWSER}
Run Keyword If ${MOBILE} == 1
... Set Window Size 50 800
... ELSE Maximize Browser Window
Set Selenium Speed ${DELAY}
Login Page Should Be Open
Input Text username ${VALID USER}
Input Text password ${VALID PASSWORD}
Click Button btn_login
Location Should Be ${WELCOME URL}
Page Should Contain Update Profile
When I run this I receive an error:
[ ERROR ] Error in file '/path/to/Common.robot': Setting variable '&{SERVER}' failed: Variable '${PREFIX}' not found.
Could someone explain why this doesn't work?
The variables in the *** Variables *** section are static, and only set once prior to the start of the first test. You cannot expect the variables to automatically update when you change the value of ${PREFIX}.
One solution would be to move the setting of the variables into a keyword that you can call either after defining the global variable, or by passing in the value of ${PREFIX}.