I have to select one of the several values of type radio button using #FindBy.
Here is my html code that I need to automate.
I tried giving #FindBy(how=How.CSS,using= "[type='radio']" and value)
But I have to pass in the value dynamically. ie. Chose BlueSkies or Pangea airlines.What is the best way to write it.Will #FindBy return a list of WebElements and can I work on it like that. Please help.
<input type="radio" name="outFlight" value="Blue Skies Airlines$361$271$7:10"/>
</td>
<td class="data_left" align="LEFT" bgcolor="CCCCCC">
<font size="-1" face="ARIAL">
<b>Blue Skies Airlines 361</b>
</font>
</td>
<td class="data_center_mono" align="CENTER" valign="TOP" bgcolor="CCCCCC">
<font size="-1" face="ARIAL">7:10</font>
<br/>
</td>
<td class="data_center" align="CENTER" bgcolor="CCCCCC" nowrap="">
<font size="-1" face="ARIAL">non-stop</font>
</td>
</tr>
<tr>
<td class="data_verb_xcols" valign="top" bgcolor="#FFFFFF" colspan="4">
</tr>
<tr>
<td class="frame_action_xrows" rowspan="2" align="CENTER" bgcolor="#FFCC00" valign="CENTER">
<input type="radio" name="outFlight" value="Pangea Airlines$362$274$9:17"/>
</td>
<td class="data_left" align="LEFT" bgcolor="CCCCCC">
<font size="-1" face="ARIAL">
<b>Pangaea Airlines 362</b>
</font>
</td>
The value in #FindBy can't be dynamic. You can split it to two
#FindBy(how = How.CSS, using = "[value*='Blue Skies Airlines']")
private WebElement blueSkyesRadioButton;
#FindBy(how = How.CSS, using = "[value*='Pangea Airlines']")
private WebElement pangeaAirlinesRadioButton;
Or to insert them both to list and work with indexes
#FindBy(how = How.CSS, using = "[type='radio']")
private List<WebElement> radioButtons;
#FindBy(how = How.CSS, using = "[type='radio']")
private List<WebElement> radioButtons;
Some more explanation supporting the solution give by #Guy, you can write an method to select radio dynamically. For an example
public void selectRadio(String airlineName){
for(WebElement radio : radioButtons){
if(radio.getAttribute("value").contains(airlineName)
radio.click();
}
}
You can use iterator if you wish. You just need to call this method by page object passing the airlineName as an argument.
Related
<table class="table">
<tr>
<th>Name</th>
</tr>
<tr th:each="recipe : ${recipes}">
<td th:text="${recipe.Name}"></td>
<td>
<span th:each="recipe,iterStat : ${recipes}">
</span>
</td>
<td>
<a th:href="#{/recipe/food/{id}(id=${recipe.id})}">view</a>
</td>
</tr>
I am trying to click this link above, utilizing this controller
#RequestMapping(value="recipe/food/{id}", method = RequestMethod.POST)
public String viewRecipe(#PathVariable int id, Model model){
model.addAttribute("name", recipeDao.findOne(id));
model.addAttribute("recipeText", recipeDao.findOne(id));
return "Recipes/food" ;
}
to display a single item, based on its id here
<table class="table">
<tr>
<th>Name</th>
</tr>
<form method ="post" th:action="recipe/food/{id}" th:object=${recipe}">
<tr th:each="recipe : ${recipes}">
<td th:text="${recipe.name}">text</td>
<td th:text="${recipe.recipeText}">text</td>
</tr>
<span th:errors="*{recipeText}" class="error"></span>
</form>
however i only get a 404, but the url information is correct
When you click the link it will execute a GET-request, so try changing the method in the Controller to method = RequestMethod.GET or simply remove method = RequestMethod.POST.
Update:
The part of the food template that is in the third code snippet is looping over a list named recipes, but the Controller method isn't adding a list as an attribute to the model only "name" and "recipeText". What you want is probably the template to display the recipe that you clicked the link for? Something like <h4 th:text="${name}"></h4> <span th:text="${recipeText}" />
I am trying to locate a pesky button on my webpage. most of the other elements I can locate but this one is giving me a headache.
The html is:
<table class="d_FG" role="presentation">
<tbody>
<tr>
<tr id="z_t">
<td class="fct_w" colspan="2">
<div>
<input name="newAttachments_fsid" value="0" type="hidden">
<table id="z_u" class="dcs" role="presentation">
<tbody>
<tr style="border: none;">
<td colspan="3" style="padding-right:0">
<a id="z_v" class="vui-button d2l-button d2l_1_192_930" role="button" tabindex="0" aria-disabled="false">Add a File</a>
<a id="z_w" class="vui-button d2l-button d2l_1_193_372" role="button" tabindex="0" aria-disabled="false">Record Audio</a>
</td>
<td></td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
I am trying to locate the element:
<a id="z_v" class="vui-button d2l-button d2l_1_192_930" role="button" tabindex="0" aria-disabled="false">Add a File</a>
I have tried various methods such as:
public void add_attachment(){
driver.switchTo().defaultContent();
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
driver.findElement(By.id("z_v"))).click();
}
But just cant manage it. Always get the message it is not visible or another element would be clicked.
I tried using a javascript that scrolls down to the element but that didn't work. Any ideas to help me with would be greatly appreciated
Can you try some other workarounds like using Actions or javascriptExecutor as below,
WebElement btn = driver.findElement(By.id("z_v")));
Actions action = new Actions(driver);
action.click(btn).build.perform();
or
JavascriptExecutor js = (JavascriptExecutor)driver;
Js.executeScript("arguments[0].click()",btn);
I am trying Count total number of rows.
I need to count the different type of status available (Inactive,Active,Expired & Exhausted)
Current code is only fetching:
Count of rows
Text of Status and Name but I need only count written next to Status type.
It only fetch data from first page. Pages are populated based on the number transactions.
following is the code written:
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class counting {
public static void main(String[] args) {
String Status="Inactive";
//String NextPage="Inactive";
WebDriver driver= new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.navigate().to("http://Testsite/web");
driver.findElement(By.id("UserEntry")).sendKeys("00");
//Type Last Name
driver.findElement(By.id("Password")).sendKeys("Test");
// Click on Submit
driver.findElement(By.id("LoginButton")).click();
driver.findElement(By.linkText("Accounts"));
driver.findElement(By.linkText("Accounts")).click();
driver.findElement(By.xpath("html/body/form/div[3]/div/div[2]/table /tbody/tr/td[1]/div/ul/li[2]/a")).click();
List<WebElement> Account = driver.findElements(By.xpath("//table[#id='MainPlaceholder_AccountList']/tbody/tr/td[1]"));
List<WebElement> AccountStatus = driver.findElements(By.xpath("//table[#id='MainPlaceholder_AccountList']/tbody/tr/td[5]"));
System.out.println("Total Account- "+Account.size());
System.out.println("Total Status- "+AccountStatus.size());
Your code isn't fully formatted properly. I have used Appium (so it is selenium backend) for mobile tests and I am going to assume you could try to create a table that reaches to a certain point, and then rows that are composed of a certain className (or in your case I suppose a id value).
Ex:
table = (MobileElement) driver.findElement(By.xpath("//UIAApplication[1]/UIAWindow[2]/UIATableView[1]"));
rows = table.findElementsByClassName("UIATableCell");
The driver being a IOSDriver. Now this is how I locate certain elements for the iOS tests. But again, I am going to assume the logic is the same. Once you locate what you need, just populate your array with the objects.
Once you populate your array you could probably parse it to fit your needs.
for(int i=0;i<AccountStatus.size();i++){
if(AccountStatus.get(i).getText().equals(Status))
System.out.println(Account.get(i).getText()+" --- "+AccountStatus.get(i).getText());
}
}
}
HTML COde:
<table id="MainPlaceholder_AccountList" cellspacing="1" cellpadding="10" border="1" style="background-color:#888888;width:100%;font-size: 75%; padding: 5px;" rules="all">
<tbody>
<tr align="center" style="color:White;background-color:#232356;">
<th scope="col">Account Name</th>
<th scope="col">Number</th>
<th scope="col">Program</th>
<th scope="col">Site</th>
<th scope="col">Status</th>
<th scope="col">Edit</th>
<th scope="col">Delete</th>
</tr>
<tr style="background-color:White;">
<td class="capText" style="width:220px;">Last, First</td>
<td class="padIt" align="center" style="width:60px;">4563201</td>
<td class="capText" style="width:150px;"> </td>
<td class="padIt" style="width:115px;">local</td>
<td class="padIt" style="width:90px;">Active</td>
<td style="width:75px;">
<td style="width:75px;">
<td style="width:75px;">
<input id="MainPlaceholder_AccountList_EditAccount_0" type="submit" style="width:75px;" eid="550" value="Edit..." name="ctl00$MainPlaceholder$AccountList$ctl02$EditAccount">
</td>
<td style="width:75px;">
<input id="MainPlaceholder_AccountList_DeleteAccount_0" type="submit" style="width:75px;" eid="550" onclick="return confirm('Are you sure you want to delete the selected account?');" value="Delete" name="ctl00$MainPlaceholder$AccountList$ctl02$DeleteAccount">
</td>
td style="text-align: center">
<span id="MainPlaceholder_PageLabel" style="margin-right: 5px;">Page:</span>
<input id="MainPlaceholder_CurrentPage" type="text" style="width:40px;text-align: right" onclick="javascript:this.value="";" title="Type in a page number, then press the Enter key to go directly to that page." maxlength="5" value="1" name="ctl00$MainPlaceholder$CurrentPage">
<span id="MainPlaceholder_OfLabel" style="margin-left: 5px; margin-right: 5px;">of</span>
<span id="MainPlaceholder_TotalPages" style="margin-right: 5px;">21</span>
<input id="MainPlaceholder_LastButton" type="submit" style="height:24px;width:90px;" value="▼▼ Last" name="ctl00$MainPlaceholder$LastButton">
<input id="MainPlaceholder_NextButton" type="submit" style="height:24px;width:90px;" value="▼ Next" name="ctl00$MainPlaceholder$NextButton">
<input id="MainPlaceholder_PreviousButton" type="submit" style="height:24px;width:90px;" value="Previous ▲" name="ctl00$MainPlaceholder$PreviousButton">
<input id="MainPlaceholder_FirstButton" type="submit" style="height:24px;width:90px;" value="First ▲▲" name="ctl00$MainPlaceholder$FirstButton">
</td>
Code trials:
package modules;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.support.ui.Select;
public class PostUpdating {
public void Execute()
{
WebElement w = LaunchApplication.driver.findElement(By.id("whats-new"));
w.sendKeys("/C:/Users/Public/Pictures/Sample Pictures/Desert.jpg");
Select sel = new Select(LaunchApplication.driver.findElement(By.id("rtSelectPrivacy")));
sel.selectByVisibleText("Public");
Select sel1 = new Select(LaunchApplication.driver.findElement(By.id("whats-new-post-in")));
sel1.selectByVisibleText("My Profile");
LaunchApplication.driver.findElement(By.id("aw-whats-new-submit")).click();
}
}
The html
<div id="whats-new-textarea" style="position: relative;">
<textarea id="whats-new" class="bp-suggestions linkBox" rows="10" cols="50" name="whats-new" style="display: inline-block; height: 50px;"></textarea>
<div id="rtm-drop-files-title">Drop files here</div>
<div class="rtmp-url-scrapper-container">
<img class="rtmp-url-scrapper-loading" src="http://demo.rtcamp.com/rtmedia/wp-content/plugins/buddypress-media/app/assets/admin/img/boxspinner.gif">
<table id="rtmp-url-scrapper" style="display: none;">
<tbody>
<tr>
<td>
<table id="rtmp-url-scrapper-img-holder">
<tbody>
<tr>
<td style="height:100px; overflow:hidden;" colspan="2">
<div id="rtmp-url-scrapper-img">
<img src="">
</div>
</td>
</tr>
<tr>
<td id="" style="width:50%; text-align:right;">
<input id="rtmp-url-prevPicButton" type="button" value="<">
</td>
<td id="" style="width:50%; text-align:left;">
<input id="rtmp-url-nextPicButton" type="button" value=">">
</td>
</tr>
<tr>
<td colspan="2">
<div id="rtmp-url-scrapper-img-count"></div>
</td>
</tr>
</tbody>
</table>
</td>
<td>
I want to insert a image into my text box but when I use Sendkeys and gave the path from my computer but instead of sending the image it is sending the path only into my text box.Also there is a button in my webpage for uploading the picture but when I clicked on button windows dialoge box open. So selenium can't deal with Windows GUI.So Any help how to do this?
drv.find_element_by_id("IdOfInputTypeFile").send_keys(os.getcwd()+"/image.png")
To insert an image into the text box you need to send the filename along with the absolute path as a character sequence to the element inducing WebDriverWait for the elementToBeClickable() and you can use either of the following locator strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("textarea.bp-suggestions.linkBox#whats-new"))).sendKeys("/C:/Users/Public/Pictures/Sample Pictures/Desert.jpg");
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//textarea[#class='bp-suggestions linkBox' and #id='whats-new']"))).sendKeys("/C:/Users/Public/Pictures/Sample Pictures/Desert.jpg");
The event doesn't get fired in my controller. This is the code.
View:
<ui:repeat var="operation" value="#{trade.operationsSortList}">
<tr class="operations">
<th class="empty_cell"></th>
<td id="operation" class="operation_cell color">#{operation.operation}</td>
<td class="color">#{operation.time}</td>
<td class="color">#{operation.coment}</td>
<td class="color">
<h:form>
<h:selectBooleanCheckbox>
<f:ajax event="click" listener="#{controller.onDelete}" />
<f:attribute name="trade" value="#{trade}" />
</h:selectBooleanCheckbox>
</h:form>
</td>
</tr>
</ui:repeat>
Controller:
#ManagedBean
#RequestScoped
public class Controller
{
private ArrayList trades;
.....
.....
public void onDelete(AjaxBehaviorEvent event) {
Trade trade = (Trade) event.getComponent().getAttributes().get("trade");
}
}
Thanks in advance!
REDIT:
I got this working, but I still have problems because I have tables, so I need to wrap the tables in a form tag, so I enclose the whole view in a form tag. My goal is just to send to the server the clicked checkbox! The request is sent to the sever, but the listener doesn't get called. The javascript event gets called. This is the code:
VIEW:
<h:form>
<table id="trades">
<th class="image_cell"></th>
<th>Type</th>
<th>Portfolio</th>
<ui:repeat var="trade" value="#{controller.errorTrades}">
<tr class="trade error">
<td class="image_cell error"><h:graphicImage styleClass="expandable" url="resources/images/plus.png"></h:graphicImage></td>
<td id="type" class="error">#{trade.type}</td>
<td class="error">#{trade.portfolio}</td>
</tr>
<tr class="operations">
<td id="#{trade.murexId}" class="operation_row" colspan="4">
<table id="operations">
<tr class="header">
<th class="empty_cell"></th>
<th class="operation_cell">Operation</th>
<th>Time Transaction</th>
<th>Comment</th>
<th id="delete">Delete</th>
</tr>
<ui:repeat var="operation" value="#{trade.operationsSortList}">
<tr class="operation">
<th class="empty_cell"></th>
<td id="operation" class="operation_cell color">#{operation.operation}</td>
<td class="color">#{operation.time}</td>
<td class="color">#{operation.coment}</td>
<td class="color checkbox">
<h:selectBooleanCheckbox title="delete">
<f:ajax execute="#this" event="click" listener="#{controller.onDelete}" onevent="onDeleteProcess" />
<f:attribute name="murexId" value="#{trade.murexId}" />
<f:attribute name="operationId" value="#{operation.id}" />
</h:selectBooleanCheckbox>
</td>
</tr>
</ui:repeat>
</table>
</td>
</tr>
</ui:repeat>
</table>
</h:form>
CONTROLLER:
#ViewScoped
public class Controller
{
private ArrayList trades;
private ArrayList errorTrades = new ArrayList();
.......code
public boolean onDelete(AjaxBehaviorEvent event)
{
long murexId = 0;
BigDecimal operationId = null;
boolean result = false;
Trade trade;
Iterator itop;
Operation operation;
......code
return true;
}
}
It's pretty important for me to solve this issue.
Thanks!
Some comments on the way to a solution:
You have html table rows inside a ui:repeat. You should use a h:dataTable for this purpose.
The h:selectBooleanCheckbox has no value attribute. If you want to call an action method you should better use a h:commandLink or h:commandButton. Then you wouldn't need the f:attribute and could do something like this:
<h:commandLink value="Delete" action="#{controller.delete(trade)}"/>
And in your backing bean:
public void delete(Trade trade) {
// delete action
}
Furthermore you have one form for each row. Maybe there is another wrapping form around the table. This wouldn't be valid and would be the possible cause of unexpected behavior. If you are using ajax you simply could use only one form around the table and render/execute the parts you like.