Hello guys,
I finally got my first opportunity to show the potential of RF in the project I’m working on. It was a bit of work because the system only works in IE and at least here in Brazil, the courses are administered in Chrome and using extensions like TruePath. For me it was good, because I learned to get xpath, css selector and etc without the help of the extension.
That said, I ask for help from the community because I can’t automate the end of my test in a better way.
I read about cx_oracle, datadriver, I tried an oracle library but I can’t, I’m still a beginner.
Description: all my testing is done from a company registered in the system, so I automated this registration, but one of the last fields to be filled in is a code that I get from the bank (SQL Developer). I run a query that returns me about 1000 codes, I choose a random one, I go back to the system and insert that code in the field finalizing the company’s registration.
Solution:
Switch Window locator=MAIN
sleep 2s
Wait Until Element Is Visible name=YES - US
Input Text name=YES - US text=89550536120009227163 #code copied from bank
sleep 2s
Click Element xpath=//*[@src=‘…/images/next.gif’]
Help1: Would it be possible to make the RF go to the bank to randomly search for this code and then insert it in the field? Remembering that I don’t have advanced knowledge of RF.
Help2: If it is not possible by the bank, would it be possible to search for this code in a spreadsheet?
Thank you in advance for your attention and patience with the newbie.
You could start by looking to DataBaseLibrary to do a query to get the code (you mention bank but you mean DataBase).
The first thing you need to know is what kind of DataBase server you are using: Oracle, MySQL/MariaDB, Microsoft SQL Server. You will need the correct driver and the credentials to connect to it.
When you query the bank (SQL Database?) do you use the same machine as the test is executed on? do all the machines you are likely to run this test on have direct access to the bank with SQL Developer?
I ask this first question as previous places I worked only specific machines had access through the internal firewalls to access the database server.
Can the numbers from the bank be reused? or once used do they expire (this will depend on your application logic)
2.1. if they can’t be reused does the query you run returns about 1000 codes always return unused codes?
Once you know the answers to these 2 questions it’ll be easier to recommend some good solutions for you.
To answer the questions:
Sure that’s possible, DataBaseLibrary that @HelioGuilherme66 meintioned will let you do that.
Sure there are Libraries for reading spread sheets and csv files.
There are other options too,
For example: if your test machines don’t all have access to the bank server and the code can only be used once, the I would suggest TestDataTable as it will help you deal with the combination of both constraints. But if only one or neither are a constraint for you one of the other options is probably a better solution.
There is never one solution that is best for every situation, so I ask these questions to better understand your constraints.
Question 1: Yes, the same machine where I run the tests is the same as the SQL Developer. So just access the Database, run the query and get the code. They gave me the data and I configured the bases myself.
Question 2: Here I have a problem, when I use a code it does not have any markup that is in use or that is unavailable. If I try to register a new company and go to the database and run the query, this previously used code is returned as available among the other 1000 codes.
Doing a manual test, I solve this problem as follows: before starting a new registration, I go to the database, get a code, go to the application and check if there is already a company with that code. If this code is not associated with any company, an X message is displayed, then I start to register a new company, if the code is associated with a company, a Y message is displayed, then I go back to the database, get a new code and repeat the validation whether it already exists or not.
Solving this point of accessing the database and getting the code, in my head I have more or less the solution of how to automate the manual test that I mentioned above.
query database and get the list of codes (gets a python list from Query)
select a random code from the list
Get Length will give you the number of items in the list
This stackoverflow thread will shows a simple way to select a random item from a list, you could also just use the random.randint example from Evaluate and then select the item from the list using the random number as the index
check the code is used or not
run your test with the selected code
Now for some strategies for improving the reliability of your test:
These first 2 don’t require anything extra:
use a WHILE loop to keep selecting a code and checking the code until you get an unused code
rather than selecting at random, use a FOR loop to iterate over the list until you find an unused code
The problem with both those is over time as more and more tests are run they will take longer and longer to find a free code, if you reset the test environment database regularly this might not be an issue
This is where TestDataTable can help, first you’ll need a machine to run TestDataTable on, but as it’s requirements are pretty low as minimal vm or docker its enough. Once you have TestDataTable running you can try this approach
Create 2 robot files, one for the actual test you need to run and one as a data prep script
The data prep would do the following
query database and get a list of codes
use for loop to iterate the list of codes, for each code
check if code is used
if code is unused, send to TestDataTable, using the app name as the table and column name as unused_codes
the test would then do
get a value from TestDataTable from the unused_codes column (this will remove the code from TestDataTable so you don’t reuse it next time you run the test)
perform the test using the code from TestDataTable
The advantage of this approach is you only need to run the data prep script once and then you can run the test as many times as there are unused codes available in TestDataTable before you need to rerun the data prep script.
Wow, my brain was fried from so much information. Thanks a lot for the help.
As I am a very, very newbie with the Robot Framework, I tried to do it little by little and it still crashed.
I was able to get RF to look at my list of codes and select one at random.
As it worked, I tried to automate the part that checks if the code is in use or not but without success.
It looked like this:
Validate ICCID
Set Focus To Element name=selectById
Press Keys name=selectById i
sleep 2s
${ICCID}= Evaluate random.choice($ICCIDS) random
Set Suite Variable ${ICCID_OK} ${ICCID}
Input Text name=searchForId text=${ICCID}
sleep 2s
Set Focus To Element name=selectById
Press Keys name=selectById ARROW_DOWN
Set Focus To Element name=searchForId
Sleep 5s
Click Element name=imageField
Sleep 5s
${MSG2} Get Value name=message
IF ‘${MSG1}’ == ‘${MSG2}’
Create a Client
ELSE
Validate ICCID
END
This works for a code that is not in use, in the IF it enters the keyword Create a Customer and follows the test correctly… but if the code is in use, it gives an error in ${MSG2} Get Value name=message, because instead of the message there is actually a grid with company information.
Don’t mind the commands I used, it was the best I could get to make it work in IE.
It’s a bit hard to know what is going on here without seeing it, but what I suspect is if you are using Get Value to get the value of the option list, there was a value selected and you selected a second? if this is the case i’d expect that Get Value will return a list of values rather than a single string.
If my suspicions are correct that would explain IF ‘${MSG1}’ == ‘${MSG2}’ not working.
You could try something like this to find out:
${MSG2_Type}= Evaluate type(${MSG2})
Log To Console ${MSG2_Type}
and then something like this to handle it:
${is_string}= Evaluate isinstance(${MSG2}, str)
IF ${is_string}
IF ‘${MSG1}’ == ‘${MSG2}’
Create a Client
ELSE
Validate ICCID
END
ELSE
# do something else with the list, for loop around the if?
END
My intention of using Get Value in the MSG2 variable was to store the message stating that the code is not being used. In the IF I thought it would be possible to do something like… If it is visible, go to Create a Client and if it is not visible, go back to Validate ICCID.
I’m going to put more parts of the code here, but could I email you some prints to understand better?
*** Variables ***
${URL} http://brux0802:20060/docroot/login/login.jsp?logout=true
${USER} Test001
${PASSWORD} 123456
${BROWSER} ie
@{ICCIDS} 85550531110007430500 85550531110007430534 85550531110007430963
${MSG1} No Subscriber Data found!
*** Keywords ***
Open Browser
Open Browser browser=${BROWSER} options=ignore_zoom_level=True;attach_to_edge_chrome=True;edge_executable_path=“C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe”
Maximize Browser Window
Close the browser
Close All Browsers
Access the mobile page
Go To url=${URL}
Wait Until Page Contains Element id=CSM_login_title
Login to Mobile page
Input Text css:input[name=‘user’] text=${USER}
Input Text name=password text=${PASSWORD}
Click Button locator=loginBtn
sleep 2s
Wait Until Page Contains Element locator=OUT1t
Validate ICCID
Set Focus To Element name=selectById
Press Keys name=selectById i
sleep 2s
${ICCID}= Evaluate random.choice($ICCIDS) random
Set Suite Variable ${ICCID_OK} ${ICCID}
Input Text name=searchForId text=${ICCID}
sleep 2s
Set Focus To Element name=selectById
Press Keys name=selectById ARROW_DOWN
Set Focus To Element name=searchForId
Sleep 5s
Click Element name=imageField #
Sleep 5s
${MSG2} Get Value name=message
IF ‘${MSG1}’ == ‘${MSG2}’
Create a Client
ELSE
Validate ICCID
END
I just finished work so had a chance to look at you reply.
Something to note; when putting in robot code (or any other code) use the code blocks like this to preserve the white space as it’s really important in Robot Framework:
``` <insert code here>
```
I had a go at re-adding the whitespace, hopefully i got it right?:
*** Settings ***
Library SeleniumLibrary
library String
Library FakerLibrary locale=pt_BR
*** Variables ***
${URL} http://brux0802:20060/docroot/login/login.jsp?logout=true
${USER} Test001
${PASSWORD} 123456
${BROWSER} ie
@{ICCIDS} 85550531110007430500 85550531110007430534 85550531110007430963
${MSG1} No Subscriber Data found!
*** Keywords ***
Open Browser
Open Browser browser=${BROWSER} options=ignore_zoom_level=True;attach_to_edge_chrome=True;edge_executable_path=“C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe”
Maximize Browser Window
Close the browser
Close All Browsers
Access the mobile page
Go To url=${URL}
Wait Until Page Contains Element id=CSM_login_title
Login to Mobile page
Input Text css:input[name=‘user’] text=${USER}
Input Text name=password text=${PASSWORD}
Click Button locator=loginBtn
sleep 2s
Wait Until Page Contains Element locator=OUT1t
Validate ICCID
Set Focus To Element name=selectById
Press Keys name=selectById i
sleep 2s
${ICCID}= Evaluate random.choice($ICCIDS) random
Set Suite Variable ${ICCID_OK} ${ICCID}
Input Text name=searchForId text=${ICCID}
sleep 2s
Set Focus To Element name=selectById
Press Keys name=selectById ARROW_DOWN
Set Focus To Element name=searchForId
Sleep 5s
Click Element name=imageField #
Sleep 5s
${MSG2} Get Value name=message
IF ‘${MSG1}’ == ‘${MSG2}’
Create a Client
ELSE
Validate ICCID
END
A couple of things I noticed:
missing an =, not sure if this is causing your issue?
${MSG2} Get Value name=message
${MSG2}= Get Value name=message
Validate ICCID calls itself in the ELSE clause, was this the intention? there is a potential for an endless loop here
It’s not really clear from this what the issue is, as I mentioned previously if you change this
${MSG2} Get Value name=message
to this
${MSG2}= Get Value name=message
Log ${MSG2}
${MSG2_Type}= Evaluate type(${MSG2})
Log ${MSG2_Type}
Then you can see in the log what what was actually returned, then you can compare it to what was expected ${MSG1}
Some things to thing about:
What will happen if the same ICCID is selected twice?, once used can they be used again? with Validate ICCID configured as is, this could easily happen
is the element name=message a message bar? I ask because you previously mentioned “because instead of the message there is actually a grid with company information.”, can you reproduce this result manually in that message bar? You might have to skip a step to reproduce it but that might give a hint as to what’s happening with the script
I guess this is getting a bit long, but should give you plenty to try to start with,
Hi Dave,
Thank you very much for the great help he gave me.
I managed to get the IF/Else to work.
I had a doubt… when the test exits the IF executing the first keyword, everything goes well, however when it should execute the second keyword it gives an error. This I corrected by throwing it and the other keywords inside the IF. Getting like this:
IF ${MSG} == 1
Create a Client
Create an account
Create a Contract - OU
Add an Offer
Add a Subscriber
ELSE
Wait Until Page Contains text=Subscriber Name
sleep 2s
Click Element xpath=(//input[@name=‘radiobutton’])[2]
sleep 2s
sleep 2s
Click Element xpath=(//input[@name=‘radiobutton’])[1]
Press Keys name=selectById m
Set Focus To Element name=searchForId
Validate ICCID
END
I now have to work on the code list solution, because for each code used I wanted to make it leave the current list.
Thank you very much from the bottom of my heart for your help.