I have a dynamically created list of car types, generated on a page.
I want to be able to locate the element by text string , and click on the checkbox next to it (double clicking on the text will produce the same result)
I am currently using :
//select car makes
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.xpath("//div[#id='MakesList']/label[2]/i"))).doubleClick().build().perform();
But this is very flaky.. doesn't always select the option i want.
So i am trying to get string "ALFA ROMEO":
action.moveToElement(driver.findElement(By.xpath("//label[contains(.,' ALFA ROMEO ')]"))).doubleClick().build().perform();
But i doesn't select the option.
Here is the html :
<label class="c-option c-option-search--right u-px u-py-sm u-bb u-m-0 ng-binding ng-scope" ng-repeat="item in label.buckets" ng-class="{ 'u-bg-faded u-text-muted u-disabled' : sc.doc_count[label.id + item.key] == 0 }"><input type="checkbox" name="capMakeName" value="alfaromeo" checklist-value="item" ng-model="checked" class="ng-scope ng-pristine ng-untouched ng-valid" checklist-model="sc.searchCriteria.selected.makes">
<i class="c-option__checkbox"></i> ALFA ROMEO <span class="u-text-muted u-text-80 ng-binding">(9)</span>
</label>
Any pointers appreciated.
In your html there are:
<input type="checkbox" name="capMakeName" value="alfaromeo"
If your final goal is to click the checkbox, you could use these infos in order to do that:
driver.findElement(By.xpath("//input[#name='capMakeName' and #value='alfaromeo']")).click();
You could first check if elements are visible (or perhaps wait for them to load),
driver.findElements( By.xpath("//input[#name='capMakeName' and #value='alfaromeo']" ).size() != 0
You could try getting all the checkboxes as a list, then clicking on the one with the text you want
public void clickCheckBoxWithText(String text){
List<WebElement> checkboxes= driver.findElements(By.cssSelector("input[type='checkbox']"));
for(WebElement checkbox:checkboxes){
if(checkbox.getText().equals(text)) {
checkbox.click();
break;
}
}
}
Related
I am having hard time with identifying if radio option No is selected or not using Selenium Java. Below is the screenshot of the radio options on the web page.
Here is the raw HTML code. Since it is missing pseudo elements I attached screenshot of it as well.
<div id="ButtonOptions" class="sample prop_group">
<label class="vdl-radio">
<input id="radio_K371FCY2UbrpgcP3RE6VC" type="radio" class="vdl-radio__input" tabindex="0" aria-disabled="false" value="true">
<label for="radio_K371FCY2UbrpgcP3RE6VC">Yes</label>
</label>
<label class="vdl-radio">
<input id="radio_4XLAugQMgEwzm3e2quk5y" type="radio" class="vdl-radio__input" tabindex="0" aria-disabled="false" value="false" checked="">
<label for="radio_4XLAugQMgEwzm3e2quk5y">No</label>
</label>
</div>
Below is the screenshot of HTML code that has pseudo element ::after (highlighted below) gets dynamically loaded when No option is selected.
I created below Java method that executes JavaScript that I am expecting to return whole label for tag. It is currently printing out null. However, when I execute the script used below in Chrome browser console, it identifies the entire label tag including ::before and ::after pseudo elements.
public String whichRadioOptionIsSelected(){
String tag = "";
List<WebElement> radioOptions = findElementsByXpath(".//div[#id='ButtonOptions']/label");
//Iterate thru both radio options and execute the JavaScript.
for(int i = 1; i <= radioOptions.size(); i++) {
String script = "return document.querySelector('div#ButtonOptions > label:nth-of-type("+i+") label', null);";
JavascriptExecutor js = (JavascriptExecutor) driver;
tag = (String) js.executeScript(script);
System.out.println(tag);
}
return tag;
}
}
To validate if the radiobutton with text as No is selected or not you can use the following xpath based Locator Strategy:
Using preceding:
try {
driver.findElement(By.xpath("//div[#id='ButtonOptions']//label[#class='vdl-radio']//label[text()='No']//preceding::input[#checked]"));
System.out.println("No option is selected");
}
catch(NoSuchElementException e) {
System.out.println("No option isn't selected");
}
Using preceding-sibling:
try {
driver.findElement(By.xpath("//div[#id='ButtonOptions']//label[#class='vdl-radio']//label[text()='No']//preceding-sibling::input[#checked]"));
System.out.println("No option is selected");
}
catch(NoSuchElementException e) {
System.out.println("No option isn't selected");
}
Reference
You can find a detailed discussion on pseudo-element in:
How locate the pseudo-element ::before using Selenium Python
i am trying to display two "text text-pass" from html in chrome browser to my print console, apparently, it did not work, any advise please?
my browser html code
<a href="/abc/123" class="active">
<div class="sidebar-text">
<span class="text text-pass"> </span> </a>
<a href="/abc/1234" class="active">
<div class="sidebar-text">
<span class="text text-pass"> </span> </a>
My code
String 123= driver.findElement(By.xpath("//*[#id="js-app"]/div/div/div[2]/div[1]/div/div/ul/li[5]/a")).getText();
System.out.println(123);
String 1234= driver.findElement(By.xpath("//*[#id="js-app"]/div/div/div[2]/div[1]/div/div/ul/li[5]/a")).getText();
System.out.println(1234);
You can use .findElements to get multiple elements with the same pattern, it will return a list collection.
UPDATE
Refers to your comment, you need put the string into a list again and check with the Collection.contains() method:
List<String> results = new ArrayList<>();
List<WebElement> elements = driver.findElements(By.xpath("//div[#class='sidebar-text']//span"));
for(WebElement element: elements) {
String attr = element.getAttribute("class");
results.add(attr);
System.out.println(attr);
}
if(results.contains("text text-fail")) {
System.out.println("this is list contains 'text text-fail'");
}
Try this Code :
String pass = driver.findElement(By.xpath("//*[#class='sidebar-text']/span")).getAttribute("class");
System.out.println(pass);
How my web application works:
My web application loads a div with radio button input elements after conditions in the form above are changed. The form above will allow the manager to select a date and time. The div below will load with all the employees available at that date and time. I give this div the id "EmployeeListBox". Everytime conditions change in the form above the EmployeeListBox gets radio buttons injected using jquery's append method.
Okay so that's the idea of how my web application works. What I am trying to do is click the first radio button in the div EmployeeListBox after the form gets changed, using selenium web driver for Firefox in java. This is the line that I need to fix:
`driver.findElement(By.xpath("//[#id="EmployeeCell"]/span[2]/input")).click();`
When I run this xpath I recive this error:
Exception processing script - Element not found in the cache - perhaps the page has changed since it was looked up.
I guess the xpaths I have tried do not work because the elements are dynamically loaded.
Here is the JS code that loads the EmployeeListBox.
AvialableStaff = JSON.parse( data );
var MSG = "";
$('#EmployeeListBox').empty();
/*for each employee in AvialableStaff load the #CreateShiftLifeOfEmployees Select option*/
var eico = 0;
for ( var Staff in AvialableStaff )
{
var ID = AvialableStaff[Staff]["employeeID"];
var name = AvialableStaff[Staff]["Firstname"]+" "+ AvialableStaff[Staff]["Lastname"];
MSG += "<div id = \"EmployeeCell\">";
MSG += "<span class = \"MakeLeft\" id = \"EI"+eico+"\" > "+name+" </span>";
MSG += "<span class = \"MakeRight\"><input type = \"radio\" name=\"ChooseStaff\" value = \""+ID+"\" class = \"CSTAFFradioButtons\" /> </span>";
MSG += "</div>";
eico++;
}
$('#EmployeeListBox').append( MSG );
Here is my EmployeeListBox without the employee cells:
<p>Select an available employee</p>
<div id = "CSEmployeeList" >
<div id = "StaffAvaileP"> <h3> Staff Available</h3> </div>
<div id = "EmployeeListBox">
<!-- Radio Buttons go here -->
</div>
</div>
This is what the employee box looks like after the form has been changed and employee radio buttons have been inserted:
<div id="EmployeeListBox">
<div id="EmployeeCell">
<span class="MakeLeft" id="EI0"> Person One </span>
<span class="MakeRight">
<input type="radio" name="ChooseStaff" value="9" class="CSTAFFradioButtons">
</span>
</div>
<div id="EmployeeCell">
<span class="MakeLeft" id="EI1"> Person Two </span>
<span class="MakeRight">
<input type="radio" name="ChooseStaff" value="10" class="CSTAFFradioButtons">
</span>
</div>
<div id="EmployeeCell">
<span class="MakeLeft" id="EI2"> Person Three </span>
<span class="MakeRight">
<input type="radio" name="ChooseStaff" value="11" class="CSTAFFradioButtons">
</span>
</div>
</div><!--End of EmployeeListBox -->
Here is my java method which runs the test:
/** Method testCreateShifts
* purpose: Loads shifts with realistic shift data like the
* real life Saturday schedule.
*/
public static void testCreateShifts()
{
driver.get(theurl);
String createshiftPage = "https://***/index.php?/CreateAShift";
driver.get(createshiftPage);
new Select(driver.findElement(By.id("Day"))).selectByVisibleText("11");
new Select(driver.findElement(By.id("StartTime"))).selectByVisibleText("8:30am");
new Select(driver.findElement(By.id("EndTime"))).selectByVisibleText("2:00pm");
driver.findElement(By.id("Instructor")).click();
/*TODO: Currently trying to click on first employee in employee list box*/
driver.findElement(By.xpath("//*[#id=\"EmployeeCell\"]/span[2]/input")).click();
driver.findElement(By.id("CreateShiftSubmit")).click();
}/*End of Method testCreateShifts*/
So using selenium in java how do I click first radio button that is in the list after the EmployeeListBox gets reloaded by jquery?
I found out what was wrong. I needed to give my webapplication time to load.
I told my java test to wait 1 second with this line.
try {Thread.sleep(2000);}catch (InterruptedException ex) { }
I have a web page contains 2 list boxes left & Right with transfer arrows.
I need to select an item from left and click on arrow so that it will move to rigtside list box.
I did my code like below, but it is not working.
List<WebElement> li = driver.findElements(By.xpath(".//*[#id='availableClients']/div/ul"));
for (WebElement lit : li)
{
System.out.println(lit.getText());
if (lit.getText().equalsIgnoreCase("CHKD"))
{
lit.click();
break;
}
}
HTML SOURCE
<div id="availableClients" class="left"> <label for="Available_Clients">Available Clients</label> <div class="list-swap-left"> <span style="width:0"/> <ul class="list-swap-list ui-sortable" title="Select the client to have access to this help link"> <li id="1" class="">abc</li> <li id="22" class="">CHKD</li> <li id="83" class="">Peg</li> <li id="95" class="">Sale</li>
Finally i myself got the solution:
// To Select the Item from List Box
WebElement xps = driver.findElement(By.xpath(xpath));
List<WebElement> sli = xps.findElements(By.tagName("li"));
for (int i = 0; i < sli.size(); i++)
{
if (sli.get(i).getText().equalsIgnoreCase(Itemtext))
{
sli.get(i).click();
break;
}
else{System.out.println("Item not fount in the list");}
}
//Click on Arrow Icon outside the List box to move the Item
driver.findElement(By.cssSelector("i.icn.cir-fwd")).click();
I'm testing an application and in the application there is a table containing checkboxes (3 rows, x columns). Below is the html for part of this table (1row). I'm trying to click on the text of one of these items to either select or deselect a checkbox based on the text. So for example, I want to click on the text 'Text next to checkbox for nr 8' in order to select that textbox. However, I don't want to go there via a hard xpath using code like /table/tbody/tr[2]/td[2]/div/span)[2] but based on the text. I'm trying code like the ones below but they don't seem to work:
driver.findElement(By.xpath("(//*[#class='settingsPanelTD' and text()='Text next to checkbox for nr 8']")).click();
driver.findElement(By.xpath("(//*[#class='settingswidgetTitle' and text()='Text next to checkbox for nr 8']")).click();
driver.findElement(By.xpath("(//*[#class='settingswidgets' and text()='Text next to checkbox for nr 8']")).click();
I would like to create a string for the final xpath so you only have to change the text you'd like to click to change the test, something like:
String text = "Text next to checkbox for nr 8"; /** variable text based on what you want to click */
String locator = "//*[#class='settingswidgets' and text()='";
String xpathitem = locator + text + "']";
driver.findElement(By.xpath(xpathitem)).click();
This is the HTML:
<td class="settingsPanelTD" width="33%">
<div class="settingwidgetsTitle">
<input id="widgetsettings8" class="settingwidgets" type="checkbox" alt="2">
<span>Text next to checkbox for nr 8</span>
<a class="AddWidget" href="#"></a>
</div>
</td>
<td class="settingsPanelTD" width="33%">
<div class="settingwidgetsTitle">
<input id="widgetsettings9" class="settingwidgets" type="checkbox" alt="2">
<span>Text next to checkbox for nr 9</span>
<a class="AddWidget" href="#"></a>
</div>
</td>
<td class="settingsPanelTD" width="33%">
<div class="settingwidgetsTitle">
<input id="widgetsettings9" class="settingwidgets" type="checkbox" alt="2">
<span>Text next to checkbox for nr 10</span>
<a class="AddWidget" href="#"></a>
</div>
</td>
I'm using eclipse, Selenium and Java.
The XPaths you are using are incorrect. The third XPath you are using is closest to the correct solution:
//*[#class='settingswidgets' and text()='Text next to checkbox for nr 8']
In plain English, your XPath means - look for any element in the document with a class="settingswidgets" and text equal to Text next to checkbox for nr 8. Unfortunately, no such element exists.
One potential XPath you could use is:
//span[text()="Text next to checkbox for nr 8"]
This searches for any span element with the appropriate text.
You could then use:
String text = "Text next to checkbox for nr 8";
String locator = "//span[text()='";
String xpathitem = locator + text + "']";
driver.findElement(By.xpath(xpathitem)).click();
This should generate the desired click.
I don't have enough reputation to add comment
but in case you are unable to select option by clicking Span tag you need to click on input tag
ArrayList<WebElement> al=new ArrayList<WebElement>();
driver.findElements(By.className("settingwidgetsTitle"));
for(int i=0;i<al.size();i++){
if(driver.findElement(By.xpath(".//div[#class='settingwidgetsTitle']/span")).getText().equals("Option to Select")){
driver.findElement(By.xpath(".//div[#class='settingwidgetsTitle']["+i+"]
/input").click());
break;
}}