So there's a nice keyword in RFW which is:
Table Cell Should Contain,
But now It should check the tabletext against a regexp. but it doesn't seem to work that way, because it says,
text not found
*** Variables
${pattern2} ^[0-9]{1}[0-9]{1}
Table Cell Should Contain xpath=//div[#id='components_block']/table 2 6 ${pattern2}
this doesn't work: either i guess:
Table Cell Should Contain xpath=//div[#id='components_block']/table 2 6 regexp:^[0-9]{1}[0-9]{1}
Regretfully, no, in Robot Framework you cannot chain keywords - to use the output of one directly as an input for another. You have to have intermediate/temp variables for that.
For the case here, you want to see does a table cell has text, matching a specific regular expression. As the keyword Table Cell Should Contain does not support regexp in the looked-for argument, but only normal strings, you can't use it.
Break down this verification in 2 steps - first get the text in the cell (in a temp variable), and then see does it match the regular expression with the Should Match Regexp keyword:
*** Variables ***
${pattern2} ^[0-9]{1}[0-9]{1}
*** Testcases ***
A case
${temp variable}= Get Text xpath=locator_that_will_return_the_specific_cell
# alternatively, you can use this keyword - if the table is an actual <table> element in the html
# ${temp variable}= Get Text xpath=locator_that_will_return_the_table 2 5
# now having the text in the cell, see does it match the regexp
Should Match Regexp ${temp variable} ${pattern2}
As to what are the values of "locator_that_will_return_the_specific_cell" and "locator_that_will_return_the_table" - I can't tell you; nor anyone else, without a sample of the HTML.
I found I direct match/hit to the table location like so: xptah=//tr[1]/td[4]
then I could do this:
${gettext} Get Text xpath=//tr[1]/td[4]
Should Match Regexp ${gettext} ^[0-9]{1}[.]{1}[0-9]{1}[0-9]{1}
Related
I want to extract information from downloaded html-Code. The html-Code is given as a string. The required information is stored inbetween specific html-expressions. For example, if I want to have every headline in the string, I have to search for "H1>" and "/H1>" and the text between these html expressions.
So far, I used substr(), but I had to calculate the position of "H1>" and "/H1>" first.
htmlcode = " some html code <H1>headline</H1> some other code <H1>headline2</H1> "
startposition = c(21,55) # calculated with gregexpr
stopposition = c(28, 63) # calculated with gregexpr
substr(htmlcode, startposition[1], stopposition[1])
substr(htmlcode, startposition[2], stopposition[2])
The output is correct, but to calculate every single start and stopposition is a lot of work. Instead I search for a similar function like substr (), where you can use start and stop words instead of the position. For example like this:
function(htmlcode, startword = "H1>", stopword = "/H1>")
I'd agree that using a package built for html processing is probably the best way to handle the example you give. However, one potential way to sub-string a string based on character values would be to do the following.
Step 1: Define a simple function to return to position of a character in a string, in this example I am only using fixed character strings.
strpos_fixed=function(string,char){
a<-gregexpr(char,string,fixed=T)
b<-a[[1]][1:length(a[[1]])]
return(b)
}
Step 2: Define your new sub-string function using the strpos_fixed() function you just defined
char_substr<-function(string,start,stop){
x<-strpos_fixed(string,start)+nchar(start)
y<-strpos_fixed(string,stop)-1
z<-cbind(x,y)
apply(z,1,function(x){substr(string,x[1],x[2])})
}
Step 3: Test
htmlcode = " some html code <H1>headline</H1> some other code <H1>headline2</H1> "
htmlcode2 = " some html code <H1>baa dee ya</H1> some other code <H1>say do you remember?</H1>"
htmlcode3<- "<x>baa dee ya</x> skdjalhgfjafha <x>dancing in september</x>"
char_substr(htmlcode,"<H1>","</H1>")
char_substr(htmlcode2,"<H1>","</H1>")
char_substr(htmlcode3,"<x>","</x>")
You have two options here. First, use a package that has been developed explicitly for the parsing of HTML structures, e.g., rvest. There are a number of tutorials online.
Second, for edge cases where you may need to extract from strings that are not necessarily well-formatted HTML you should use regular expressions. One of the simpler implementations for this comes from stringr::str_match:
# 1. the parenthesis define regex groups
# 2. ".*?" means any character, non-greedy
# 3. so together we are matching the expression <H1>some text or characters of any length</H1>
str_match(htmlcode, "(<H1>)(.*?)(</H1>)")
This will yield a matrix where the columns are (in order) the fully matched string followed by each independent regex group we specified. You would just want to pull the second group in this case if you want whatever text is between the <H1> tags (3rd column).
so there is a website: https://www.guruwatch.nl/Aandelen/Default.aspx
I click the element 'koop' and then I want to verify that the value in the top is bigger then 10
id="ctl00_ctl00_ContentPlaceHolder1_RightContent_ListAandelen_repAandelen_ctl01_lblCountBuy"
what is the fastest way to do this?
i used
Element Text Should Be ctl00_ctl00_ContentPlaceHolder1_RightContent_ListAandelen_repAandelen_ctl01_lblCountBuy 24
but that is for the exact match, i just want to verify the integer is bigger then 10.
there is also an
Should Be Equal As Integers first second
builtin
but not a
Should Be Bigger As Integer
Should be Smaller As Integer
p.s. why are those not builtin? is it so strange to use this?
There are plenty of ways of checking if one value is larger than another with the * If keywords that can be found in the BuiltIn Library. Below is an example of how you can craft the larger than keyword:
*** Test Cases ***
Test Positive
${value} Set Variable 24
Should Be Larger Than ${value} 1
Test Negative
${value} Set Variable 24
Run Keyword And Expect Error * Should Be Larger Than ${value} 100
*** Keywords ***
Should Be Larger Than
[Arguments] ${value_1} ${value_2}
Run Keyword If ${value_1} <= ${value_2}
... Fail The value ${value_1} is not larger than ${value_2}
In order to do this, you need to find the xpath locator first. Since the xpath is quite long so, I just assign it to a variable as below.
${top_position_xpath}= set variable //span[#id='ctl00_ctl00_ContentPlaceHolder1_RightContent_ListAandelen_repAandelen_ctl01_lblCountBuy'
${get_number}= GET TEXT xpath=${top_position_xpath} ## --> This is xpath locator for that top column
${check}= SHOULD BE TRUE ${get_number} > 10 # --> The current test will fail if the result is false..
Okay, so I summarize the steps I use above here:
Get the xpath locator for the specific column that you want to verify.
Use the GET TEXT keyword to get the exact output (number) of that column.
Verify using the SHOULD BE TRUE keyword. This keyword is sufficient to verify the condition.
But just to highlight, that if you use the SHOULD BE TRUE keyword as above, the test will fail immediately, so a good approach is to use with keyword RUN AND RETURN STATUS and assign a variable to tell either the condition is true or false, so that you can proceed with your next code or statements..
${result}= RUN KEYWORD AND RETURN STATUS SHOULD BE TRUE ${get_number} > 10 #
Before I read the messages I solved it myself this way:
Should Match Regexp ctl00_ctl00_ContentPlaceHolder1_RightContent_ListAandelen_repAandelen_ctl01_lblCountBuy [0-9]{1}[0-9]{1}
How Can we use value returned from one keyword as input argument to other keyword directly (without assigning return value to variable)
Currently I am maintaining all Web Elements or Variable names and corresponding xpath in an Excel Sheet. I get XPath using keyword read_xpath by passing web element/variable name as argument.
I store the xpath in separate variable then make use of it for other or Next line keyword. Since I need to use a variable for each XPath access, i am trying to find out, whether is there any way to directly use one keyword output as input to other keyword without assigning it to variable.
The main purpose of storing XPath in Excel sheet is to avoid multiple test cases change with single Element XPath change, making just single change on Excel Sheet should be sufficient.
For Example:
read_xpath reads values from a Excel sheet, Excel sheet has two columns, one variable name and second one is xpath. Function read_xpath(element) takes variable name as input and gives back xpath.
xlread.py file looks like xlread.py code Excel Sheet look like Excel sheet
sample.robot file looks as below
${login_user_textctrl}= read_xpath username_textctrl
clear element text ${login_user_textctrl}
Input text ${login_user_textctrl} admin
Now let us check how I used read_xpath keyword in my robot file
I called Keyword read_xpath with argument username_texctrl, which returns xpath for username text Control which is stored in variable ${login_user_textctrl}. Now Input Text ${login_user_textctrl} admin works fine.
For below code
clear element text read_xpath username_textctrl
I am getting, clear element text requires 1 argument but two arguments provided, is there any way i can use the the value returned from Keyword(read_xpath) as input to other keyword directly, without assigning it to any variable?
Thanks in advance.
Separating your locators from your robot code through an Object Repository is often done when the locators are reused a lot. An alternative implementation paradigm is to use the Page Object Model. An example of such an implementation can be found in the Robotframework-PageObjectLibrary.
In case you still prefer the Object Repository approach, then using the Selenium2Library keyword Add Location Strategy might be of interest to you. Below is a working example which uses a YAML file as it's OR to fetch the search input box and search button from Google.
ObjectRepo.yaml
OR:
searchbox: '//input[#id="lst-ib"]'
searchbutton: '//button[#id="_fZl"]'
Robot Script
*** Settings ***
Library Selenium2Library
Variables ObjectRepo.yaml
*** Test Cases ***
Yaml Object Repository
[Setup] Add Location Strategy yro Yaml Locator Strategy
Open Browser http://www.google.com Chrome
Input Text yro=searchbox Robot Framework
Click Element yro=searchbutton
Sleep 3s
[Teardown] Close All Browsers
*** Keywords ***
Yaml Locator Strategy
[Arguments] ${browser} ${criteria} ${tag} ${constraints}
${xpath}= Set Variable ${OR.${criteria}}
${retVal}= Get Webelement xpath=${xpath}
[Return] ${retVal}
As you can see the abstraction through a custom locator keyword allows for clearner code and not require you to fetch into a variable for later reuse.
You can use Evaluate to call python functions directly. Example:
${my element to clear}= Evaluate read_xpath("username_textctrl") xlread
See the documentation here
(Note: Example is untested and you should check if xlread is in PYTHONPATH, or found at test run time)
So I have two possible valid values for Should Be Equal As Strings.
Is there a way to do something like
Should Be Equal As Strings
... Create create|update
Doesn't necessarily need to be using that specific keyword but I want to be able to accept one of the other
You can use Should match regexp
Here's an example:
*** Variables ***
${action1} create
${action2} update
${action3} delete
*** Test Cases ***
Example
Should match regexp ${action1} create|update
Should match regexp ${action2} create|update
Run keyword and expect error 'delete' does not match 'create|update'
... Should match regexp ${action3} create|update
I Have multiple records in table like below. Each record holds mutiple entries separated by #.
record1 - 123.45.56:ABCD:789:E # 1011.1213.1415:FGHI:1617:J #
record2 - 123.45.56:ABCD:1617:E # 1011.1213.1415:FGHI:12345:J #
I need to pass an argument to a different project/service which builds an sql query and send the output to me.
Now if I send an argument like below, it gives me wrong output
123.45.56:*:1617
This recognizes both record1 and record 2 as proper output because of wildcard char. But as per my requirement only record2 is proper as record1 has 123.45.56 in one entry and 1617 in a different entry.
Is there a way to construct an expression that says the like condition to ignore such invalid entries.
Please note that I cant change the query as I am not constructing it. The only way for me is to tweak the expression that I can send as argument.
You need to restrict the pattern you match to be specic enough such that it only matches the first record and not the second one.
You can try:
SELECT *
FROM yourTable
WHERE col LIKE '123.45.56:' AND col LIKE '1617:J #'