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/
Related
I am currently trying to pass a keyword and its arguments as a List to an another keyword, which then runs it, like this.
Keyword That Runs:
[Arguments] #{keyword_to_run_with_parameters}
Run Keyword #{keyword_to_run_with_parameters}
For demo I created a parameter in the following way to test it:
#{to_analyze}= Create List Should Be Equal ${True} ${True}
Which gave me the following:
No keyword with name 'keyword_to_run_with_parameters = ['Should Be Equal', True, True]' found.
I have tried creating the list in different ways, but this was the only one that worked. I also tried running it with ${keyword_to_run_with_parameters}, but did not run.
I tried to search StackOverflow for any suggestion, but did not find appropriate ones.
Edit:
I am working with GUI and I want to create a new Keyword which takes screenshots when a non-selinium keyword fails. This is currently not working, because I cannot handle the list as a container for keywords and their arguments. A solution could be to only call this function if the keyword already failed, but I'm curious about other approaches.
Capture Screenshot On Failure
[Documentation] Captures screenshot on failure of a keyword, then fails the test with custom message if any is given.
... Needed because RobotFramework/Selinium only takes screenshot if a RobotFramework/Selinium command fails.
... param: keywords: #{keywords}= Create List Keyword Arguments
[Arguments] ${failmessage}=Basic feedback for failiure. Picture is above. #{keywords}
${good} = Run Keyword And Return Status #{keywords}
Run Keyword If not ${good} Run Keywords
... Capture Page Screenshot
... AND Fail ${failmessage}
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
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
I have a webpage with a combobox to sort a list by Price, Name,... The list is in many pages, so I need to get all elements first and after, I will sort by and check if the elements are correct. Right?
I am trying to do it and navigate for all pages and get all elements. But it is only taking the elements in first page. I am totally new in Robot framework.
Does anyone have a suggestion how I can do it?
${name_list_actual} Create List
${cnt_pages}= Get Element Count //div[#class='container index-new-p']/div/nav[#class='text-center']/ul/li/*
Log To Console ${cnt_pages}
:FOR ${n} IN RANGE 1 ${cnt_pages}
\ Click link //div[#class='container index-new-p']/div/nav/ul/li[${n}]/a
\ ${cnt}= Get Element Count //*[#class="title"]/*
:FOR ${i} IN RANGE 1 ${cnt}
\ ${get_names} Get Element Attribute //table[#class='result-table']/tbody/tr[${i}]/td/div/div[2]/div/a text
\ Append To List ${name_list_actual} ${get_names}
${get_names}= Select All From List //table[#class='result-table']/tbody/tr[${i}]/td/div/div[2]/div/a
\ Log To Console ${name_list_actual}
\ Continue For Loop
Thanks so much
First and foremost, by your code sample's indent it looks like you're doing nested for loops - an outer one for the changing the pages, and an inner that'll get the text in each row. The thing is - Robot Framework doesn't support nested for loops - see the documentation.
What happened on execution is the first loop (the pagination) ran with just two statements and finished:
\ Click link //div[#class='container index-new-p']/div/nav/ul/li[${n}]/a
\ ${cnt}= Get Element Count //*[#class="title"]/*
Then all the rest were executed as part of the second.
A solution would be to have a keyword "Get All Values In The Table" that'll hold the inner loop, and call it in the current outer, which will paginate.
Another issue - you're using IN RANGE, passing 1 as start and ${cnt} as end; if it had value of 4, you probably expect the tracking variable to get all values from 1 to 4.
Yet range works with the first argument inclusive, and up to - but not getting to - the second argument; thus it covers the range 1 to 3. To salvage that, you'd need to set the upper bound to cnt+1, e.g. ${cnt + 1}.
Minor stuff:
You have a statement that's within the loop block, but not prefixed with \:
${get_names}= Select All From List //table[#class='result-table']/tbody/tr[${i}]/td/div/div[2]/div/a
I'm surprised it didn't give you a syntax error - it effectively breaks the loop, and the framework should complain the next lines are prefixed as if in a loop, but one is not started.
-
When you are changing the pages by the click, you are not making sure the UI has loaded the data for the new page. If this happens through ajax calls, you may very well be working with the previous page's data, thinking it is the new one - the selenium click returns control very fast, and the operands for getting the text are running - while the UI still waits for the new data and is displaying the previous one.
-
In RF version 3.1 the loop syntax is different - the block members are not prefixed with \, and it's closed with an END statement.
I'd suggest to migrate to it - a) the current one is going to be eventually deprecated, and b) in the new one the nesting would have been marked as syntax error (you're starting a new loop without END-ing the running one), instead of silently passing with unexpected behavior.
I have 3 test cases which will test the same functionality. It will use same keywords as shown below.
Instead of writing three different test cases "test-1151,test-2125,test-2126", I want to write one test case separated with colons as shown below. But robot should treat this as three seperate test case and it should show pass/fail test case count accordingly.
test.robot:
*** Settings ***
Library lib.test
*** Variables ***
*** Keywords ***
*** Test Cases ***
test-1151:test-2125:test-2126
[Documentation] test_sample
[Tags] sanity
Install Adobe software
Launch the app
If I run the above robot file, robot is taking "test-1151:test-2125:test-2126" as one test case. How to tell robot to treat this as three different test cases (separated with colon)?
Why don't you turn the detail of the test case into a keyword? Then write three test cases that call the keyword?
This might be an alternative option for you:
http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#data-driven-style
Basically have one test template which would be the same, maybe have some arguments for parameters that will change based on test cases. You can then have many test cases doing exactly the same or slightly different things in a short and concise notation.
It's unclear what your real goals are. It seems that you want to see three items in the report, "test-1151", "test-2125", and "test-2126", but that you actually only want to run that test once.
I'm guessing that those names correspond to either a test plan or an item in a ticketing system of some sort.
My recommendation is to use tags to tag your test. You can give the test any name you want, and then give it tags for the names you want to see in the report. Once the test runs, the report can give you statistics based on tag.
For example:
test-1151:test-2125:test-2126
[Documentation] test_sample
[Tags] sanity test-1151 test-2125 test-2126
Install Adobe software
Launch the app
To answer your specific question of whether you can have this one test reported three times, the answer is "no". It will show up in the logs and report as a single test. However, the report also includes test status by tag, so you will see one item in the report for each tag.