How to ignore the fail case and continues to next value - selenium

I am looping values from an Excel file by using ${txnExcel} to search and compare the value. But sometimes ${txnExcel} is doesn't exist in the system. In that case I want to ignore the fail (as there is no need to compare value) and continue to the next ${txnExcel} by skipping the error.
open excel ${PATH_EXCEL}
${exp_row_count} get row count Sheet1
:For ${i} in range 1 ${exp_row_count}
\ ${excel_index} evaluate ${i}+1
\ ${txnExcel} Read Cell Data By Name Sheet1 B${excel_index}
\ ${ServiceTypeExcel} Read Cell Data By Name Sheet1 C${excel_index}
\ ${TransferAmountExcelOrigin} Read Cell Data By Name Sheet1 D${excel_index}
\ ${CurrencyExcel} Read Cell Data By Name Sheet1 E${excel_index}
\ ${TransferAmountExcel} set variable ${TransferAmountExcelOrigin} ${CurrencyExcel}
#=======================================================================================
\ input text name=id_or_tsn ${txnExcel}
\ click button name=Submit
\ wait until element is visible xpath=/html/body/div[2]/div[2]/div/div/div/div[1]/div[2] 5s
#===========================Compare Transaction Element================================================
\ ${txnCompare} get text xpath=/html/body/div[2]/div[2]/div/div/div/div[1]/div[2]
\ ${ServiceTypeCompare} get text xpath=/html/body/div[2]/div[2]/div/div/div/div[3]/div[2]/span
\ ${TransferAmountCompare} get text xpath=/html/body/div[2]/div[2]/div/div/div/div[5]/div[2]/span
\ ${CurrencyCompare} get text xpath=/html/body/div[2]/div[2]/div/div/div/div[4]/div[2]
\ should be equal as strings ${txnExcel} ${txnCompare} invalid TXN comparison[${i}]
\ should be equal as strings ${ServiceTypeExcel} ${ServiceTypeCompare} invalid ServiceType comparison[${i}]
\ should be equal as strings ${TransferAmountExcel} ${TransferAmountCompare} invalid Transfer Amount comparison[${i}]
\ should be equal as strings ${CurrencyExcel} ${CurrencyCompare} invalid Currency comparison[${i}]
#============================End Compare Transaction Element====================================================

The way I understood your question was that you cycle through items fetched from Excel. Sometimes the item in Excel does not exist in the application. If that is the case, then skip the checks for that item and fetch the next item from excel.
As correctly referenced by #pankaj mishra, the keyword Run Keyword and Ignore Error should be used. This keyword outputs 2 values (this is why you see 2 variables before it). The first one contains the status and the second one the actual value.
This is then used by the keyword Continue For Loop which breaks off this cycle when the keyword returned an error (FAIL). All the checks that followed (represented by the logging step) are then skipped.
*** Test Cases ***
TC
#{list} Create List ${3} ${6} ${15} ${21}
Log To Console \n
:FOR ${id} IN #{list}
\ ${status} ${result}
\ ... Run Keyword And Ignore Error Mock Element Exists ${id}
\
\ Continue For Loop If '${status}' == 'FAIL'
\ Log To Console No Failure for ${id}
*** Keywords ***
Mock Element Exists
[Arguments] ${id}
&{dic} Create Dictionary 3=1 6=2 18=6 21=7
[Return] ${dic['${id}']}

You can put a if condition on your code when dealing with ${txnExcel} .
Just check as below in your desired language.Below code is just a logic. Write it in your desired language.
if(${txnExcel} != NULL){
// put your compare code inside this if statement.
}

you can use Run keyword and ignore error or Run Keyword And Continue On Failure.
details about these keywords can be found from
http://robotframework.org/robotframework/latest/libraries/BuiltIn.html
also there is a good example about these keywords here
How to ignore Get Table Text from Cell, if xpath of cell not match
in your code , your can use below line
\ ${status} ${result}
\ ... Run Keyword And Ignore Error input text name=id_or_tsn ${txnExcel}
\ Continue For Loop If '${status}' == 'FAIL'
and one more time in last to skip error for ${txnexcel}
Run Keyword And Continue On Failure Should Be Equal As Strings
${txnExcel} ${txnCompare} invalid TXN comparison[${i}]
Even if the value or variable ${txnExcel} is not provided , it will continue to next KW.

Here the solution that work for me now .
open excel ${PATH_EXCEL}
${exp_row_count} get row count Sheet1
:For ${i} in range 1 ${exp_row_count}
\ ${excel_index} evaluate ${i}+1
\ ${txnExcel} Read Cell Data By Name Sheet1 B${excel_index}
\ ${ServiceTypeExcel} Read Cell Data By Name Sheet1 C${excel_index}
\ ${TransferAmountExcelOrigin} Read Cell Data By Name Sheet1 D${excel_index}
\ ${CurrencyExcel} Read Cell Data By Name Sheet1 E${excel_index}
\ ${TransferAmountExcel} set variable ${TransferAmountExcelOrigin} ${CurrencyExcel}
#=======================================================================================
\ input text name=id_or_tsn ${txnExcel}
\ click button name=Submit
\ ${found_txn} run keyword and return status wait until element is visible xpath=/html/body/div[2]/div[2]/div/div/div/div[1]/div[2] 5s
\ ${error_message} run keyword unless ${found_txn} get text xpath=/html/body/div[2]/div[2]
\ run keyword and continue on failure element should be visible xpath=/html/body/div[2]/div[2]/div/div/div/div[1]/div[2]
\ run keyword unless ${found_txn} continue for loop
#===========================Compare Transaction Element================================================
\ ${txnCompare} get text xpath=/html/body/div[2]/div[2]/div/div/div/div[1]/div[2]
\ ${ServiceTypeCompare} get text xpath=/html/body/div[2]/div[2]/div/div/div/div[3]/div[2]/span
\ ${TransferAmountCompare} get text xpath=/html/body/div[2]/div[2]/div/div/div/div[5]/div[2]/span
\ ${CurrencyCompare} get text xpath=/html/body/div[2]/div[2]/div/div/div/div[4]/div[2]
\ should be equal as strings ${txnExcel} ${txnCompare} invalid TXN comparison[${i}]
\ should be equal as strings ${ServiceTypeExcel} ${ServiceTypeCompare} invalid ServiceType comparison[${i}]
\ should be equal as strings ${TransferAmountExcel} ${TransferAmountCompare} invalid Transfer Amount comparison[${i}]
\ should be equal as strings ${CurrencyExcel} ${CurrencyCompare} invalid Currency comparison[${i}]

Related

Robot Framework: How do I direct my test results to an external file?

I have a functioning Robot Framework test that searches for identified elements in a list and then logs their presence or absence to the console. This has been working just fine for me so far. But now I need that console output directed to a file.
I have used the LOG keyword, I've used LOG MANY keyword and I've tried to also use APPEND TO FILE to get this done. I'm wondering at this point if my issue is the list/search logic itself. I can have individual commands logged or appended no problem. Even looking at the generated log.html file, only those basic log commands show up. Not the console output. Here's the keyword in question. And just to note, the search logic is sound. My problem is how to LOG what normally shows in the console to a file.
***Test Keyword***
Log "TEST MENU ----"
${StaList}= Create List test1 test2 test3 test4 test5 test6
FOR ${a} IN #{StaList}
${p}= Run Keyword And Return Status Page Should Contain Element xpath=//*
[contains(text(), "${a}")]
Run Keyword If ${p} Log "(${a}) X" ELSE Log "(${a}) "
END
When I run this with "Log To Console", this is what I get. A running list showing me if an element is present (with X) or absent (without X).
"TEST MENU ----
"(test1) X"
"(test2) "
"(test3) X"
This works fine if its just me running it. But I need this output sent to a text file to deliver to my team. I've been at this for a while now and need some help. Anybody have any ideas? Thanks so much!
Log to Console, does just that. It shows in Console but not in log.html.
What you want is to duplicate your step to APPEND TO FILE, so you have in Console and in the file.
You need to add \n or ${ENTER} to your output strings.
EDIT: Here is a fully working example:
*** Settings ***
Suite Setup Create and Open Page
Suite Teardown Close All Browsers
Library SeleniumLibrary
Library OperatingSystem
*** Test Cases ***
Example Test
Verify Elements
*** Keywords ***
Verify Elements
Log To Console "TEST MENU ----"\n
Create File test_menu.txt TEST MENU ----\n
${StaList}= Create List test1 test2 test3 test4 test5 test6
FOR ${a} IN #{StaList}
${p}= Run Keyword And Return Status Page Should Contain Element xpath=//*[contains(text(), "${a}")]
Run Keyword If ${p} Log To Console "(${a}) X"\n
... ELSE Log To Console "(${a}) "\n
Run Keyword If ${p} Append To File test_menu.txt (${a}) X\n
... ELSE Append To File test_menu.txt (${a}) \n
END
Log The result is test_menu.txt html=True
Create and Open Page
Create File my_mock.html
Append To File my_mock.html <HTML>\n \ \ \ <BODY>\n \ \ \ \ \ \ \ <p>test2</p>\n \ \ \ \ \ \ \ <p>test4</p>\n \ \ \ \ \ \ \ <p>test5</p>\n \ \ \ </BODY>\n</HTML>
Open Browser file://${CURDIR}/my_mock.html
You should replace Run Keyword If by IF/ELSE/END blocks.

Nextflow multiple inputs with different number of files

I'm trying to input two channels. However, the seacr_res_ch2 has 4 files, bigwig_ch3 has 5 files which contain a control and 4 samples. So I was trying to run the following process to compute the peak center.
When I ran this process I have got this error: unexpected EOF while looking for matching `"'
process compute_matrix_peak_center {
input:
set val(sample_id), file(seacr_bed) from seacr_res_ch2
set val(sample_id), file(bigwig) from bigwig_ch3
output:
set val(sample_id), file("${sample_id}.peak_centered.mat.gz") into peak_center_ch
script:
"""
"computeMatrix reference-point \
-S ${bigwig} \
-R ${seacr_bed} \
-a 1000 \
-b 1000 \
-o ${sample_id}.peak_centered.mat.gz \
--referencePoint center \
-p 10
"""
}
Likely the input files are not file objects. Try replacing the file in the declaration with path, eg:
input:
set val(sample_id), path(seacr_bed) from seacr_res_ch2
set val(sample_id), path(bigwig) from bigwig_ch3
Check the documentation for details https://www.nextflow.io/docs/latest/process.html#input-of-type-path
Your input block declares twice a value called sample_id. There's no guarantee that these values will be the same if the value is derived from two (or more) channels. One value will simply clobber the other(s). You'll need to join() these channels first:
input:
set val(sample_id), file(seacr_bed), file(bigwig) from seacr_res_ch2.join(bigwig_ch3)

In Finding Broken links script ( using Selenium Robot Framework) -In Get Request URL's are going twice by appending

I am not sure what's wrong in the below Get Request, when i run the script in Get Request link appended.
Issue :
GET Request : url=http://127.0.0.1:5000//http://127.0.0.1:5000/index.html
Please see the below code and the Report screenshot.
I am stuck here! Really appreciate for the help.
${url3} http://127.0.0.1:5000/
${BROWSER} chrome
*** Test Cases ***
BrokenLinksTest-ForPracticeSelenium-2ndPage
Open Browser ${url3} ${BROWSER}
Maximize Browser Window
VerifyAllLinksOn2ndPage
Close Browser
*** Keywords ***
VerifyAllLinksOn2ndPage
Comment Count Number Of Links on the Page
${AllLinksCount}= get element count xpath://a
Comment Log links count
Log ${AllLinksCount}
Comment Create a list to store link texts
#{LinkItems} Create List
Comment Loop through all links and store links value that has length more than 1 character
: FOR ${INDEX} IN RANGE 1 ${AllLinksCount}-1
\ Log ${INDEX}
\ ${link_text}= Get Text xpath=(//a)[${INDEX}] #<-- for what ? -->
\ ${href}= Get Element Attribute xpath=(//a)[${INDEX}] href
\ Log ${link_text}
\ log to console ("The link text is "${link_text}" & href is "${href}" ${INDEX})
\ ${linklength} Get Length ${link_text} #<-- you are checking text not href ? -->
\ Run Keyword If ${linklength}>1 Append To List ${LinkItems} ${href}
Log Many ${LinkItems}
Remove Values From List ${LinkItems} javascript:void(0) #<-- don't forget checking content on list -->
${linkitems_length} Get Length ${LinkItems}
Log Many ${LinkItems}
#{errors_msg} Create List
Create Session secondpage http://127.0.0.1:5000/
:FOR ${INDEX} IN RANGE ${linkitems_length}
\ Log Many ${LinkItems[${INDEX}]}
\ ${ret} get request secondpage ${LinkItems[${INDEX}]}
\ log to console ${ret}
\ log ${ret}
\ ${code} Run Keyword And Return Status Should Be Equal As Strings ${ret.status_code} 200
#\ log to console "Gonna link" ${LinkItems[${INDEX}]}
# \ click link ${LinkItems[${INDEX}]}
#\ Capture Page Screenshot
#\ Click Link link=${LinkItems[${INDEX}]}
\ Run Keyword Unless ${code} Append To List ${errors_msg} error :${LinkItems[${INDEX}]} | ${ret.status_code}
${check} Run Keyword And Return Status Lists Should Be Equal ${errors_msg} ${EMPTY}
Run Keyword Unless ${check} Fail Link \ assertion Failed with msg:\n#{errors_msg}
Sleep 1
Ok, the "problem" is with these two lines:
Create Session secondpage http://127.0.0.1:5000/
and:
${ret} get request secondpage ${LinkItems[${INDEX}]}
As your screens show, your list of items (#{LinkItems}) already contains full url links, e.g.: http://127.0.0.1:5000/index.html but the Create Session keyword adds another http://127.0.0.1:5000/ in front of each list item.
Think about it as BASE_URL set up by Create Session keyword and an endpoint, e.g. /index.html. Create Session and Get Request are used together, the former setting up BASE_URL, the latter the endpoint part of the URL. You can see the documentation for the Create Session keyword, it explains its second parameter:
url Base url of the server
To solve this, you'd need to store in #{LinkItems} only everything after last / (it seems so in your case), so for example only /index.html or /shop.html

Export test results to excel using Robot Framework and Excellibrary

I'm new to Robotframework and I've been trying to export the result of my test to excel, but I couldn't get the correct loop for writing the data to excel.
the logic works that every time the element is present in the page, it will be log to the console. But at the same time, I want it to be written in excel.
With the current code, it's only failing, it couldn't recognize ${my_data}
I just put ..... to represent the codes that are not mentioned.
*** Test Cases ***
Check data of the web
Open browser ${url} chrome
: FOR ${url} IN #{url_list}
\ Go To ${url}
\ ${searched_script} = Get Source
\ Run Keyword And Continue On Failure Should Contain ${searched_script} ${sample}
\ Log to Console ${url}
\ #{site_data} = Get WebElements
\ Loop data #{site_data}
\ Push all result to excel
Close Browser
*** Keywords ***
Loop data
[Arguments] #{site_data}
: FOR ${site_data} IN #{site_data}
\ Log ${site_data}
\ ${my_data}= Get Element Attribute ${site_data} my_data_sample
\ Continue For Loop If $my_data is None
\ Run Keyword And Continue on Failure Should Contain ${my_data} hello_world
\ Log To Console ${my_data}
Push all result to excel
Create excel document doc_id=docname
Write excel rows 1 0 #{my_data} sheet #my_data here is not passing the data from the loop
Save Excel Document test.xlsx
the problem in your example is that the variable is local to your test case, not to the test suite.
you need to add the following command to promote the value to test suite
Set Suite Variable ${my_data}

Expected list-like value, got string

I have written a keyword which calls a sub-keyword. Now the sub keyword is returning two values which I am trying to store it in an array assigned to main keyword. When I log to console the returned values, it gives an error message saying - Expected list-like value, got string
I have tried the below workarounds(failed):
1. Attempt1:
#{Items1} Run keyword if '${INACTIVEStateCount}'!='0' INACTIVE OTOID selector ${StateCount}
Log To console Values are ${Items1}
2. Attempt2:
#{Items1} Run keyword if '${INACTIVEStateCount}'!='0' INACTIVE OTOID selector ${StateCount}
${Items2} Create List #{Items1}
Log To console Values are ${Items2}
Main keyword:
#{Items1} Run keyword if '${INACTIVEStateCount}'!='0' INACTIVE OTOID selector ${StateCount}
${Items2} Create List #{Items1}
Log To console Values are ${Items2}
SubKeyword:
INACTIVE OTOID selector
[Documentation] Used to select Inactive OTOIDs
[Arguments] ${StateCount} ${LocatorWaitTime}=${defaultWait time}
:FOR ${INDEX} IN RANGE 1 ${StateCount}
\ ${Check}= Run keyword and return status Page should contain element xpath=//*#id='lookupFiberDetailsResult']/table/tbody/tr[${INDEX}]/td[4][text()='INACTIVE']
\ ${OTO_IDStatus} Run keyword if '${Check}'=='True' Get Text xpath=//*[#id='lookupFiberDetailsResult']/table/tbody/tr[${INDEX}]/td[4][text()='INACTIVE']
\ Log to Console Loop${INDEX} - OTOID:${OTO_IDStatus}
\ ${OTO_ID} Run keyword if '${OTO_IDStatus}'!='None' Get Text xpath=//*[#id='lookupFiberDetailsResult']/table/tbody/tr[${INDEX}]/td[2]
\ ${LineIdentifier} Run keyword if '${OTO_IDStatus}'!='None' Get Text xpath=//*[#id='lookupFiberDetailsResult']/table/tbody/tr[${INDEX}]/td[1]
\ Run keyword if '${OTO_IDStatus}'!='None' Log to Console OTOID is: ${OTO_ID}
\ Run keyword if '${OTO_IDStatus}'!='None' Log to Console OTOID is: ${LineIdentifier}
\ Run Keyword If '${OTO_IDStatus}'!='None' [Return] ${OTO_ID}
\ Run Keyword If '${OTO_IDStatus}'!='None' [Return] ${LineIdentifier}
\ Exit For Loop if '${OTO_IDStatus}'!='None'
What I intend to achieve:
I am making the sub-keyword return two values: OTOID and LineIdentifier and store it in an array. And then use these two values separately for further use.
Actual:
When I log to console the values stored in array then I get an error saying:
Expected list-like value, got string
The issue is that you are trying to store the return values from the sub keyword as an array/list but returning strings from it.
*** Keywords ***
Main keyword
${OTO_ID} ${LineIdentifier} Run keyword if '${INACTIVEStateCount}'!='0' INACTIVE OTOID selector ${StateCount}
INACTIVE OTOID selector
Return From Keyword If '${OTO_IDStatus}'!='None' ${OTO_ID} ${LineIdentifier}
This will return the values ${OTO_ID} and ${LineIdentifier} as individual variables and not arrays.
Please note that I've ignored the other steps in the sub keyword just to make the answer simpler.
The line(s) that needs to be replaced:
Run Keyword If '${OTO_IDStatus}'!='None' [Return] ${OTO_ID}
Run Keyword If '${OTO_IDStatus}'!='None' [Return] ${LineIdentifier}
Update:
If you want to strictly return the values as list, use below code
*** Keywords ***
Main keyword
${Identifiers} Run keyword if '${INACTIVEStateCount}'!='0' INACTIVE OTOID selector ${StateCount}
INACTIVE OTOID selector
${Identifiers} Create List
.
<Your FOR loop here>
.
\ Run Keyword If '${OTO_IDStatus}'!='None' Append to List ${identifiers} ${OTO_ID} ${LineIdentifier}
Exit For Loop If '${OTO_IDStatus}'!='None'
Return From Keyword If '${OTO_IDStatus}'!='None' ${Identifiers}
Reference : Robot User guide