Fetching Relative Attributes by Xpath - java

In the dropdown list below, Im trying to select and echo the results of the data-balance attributes assigned to the data-store attribute labeled "Depot Spot" using xpath. I tried the following xpath  but its only showing the text results of the first "Depot Spot" option. What am i missing?
<div class="modal-content">
<div class="modal-header"><button class="close dialog-close" type="button" aria-hidden="true">×</button>
<h4 class="modal-title"></h4>
<p> </p>
<p> //select[#name='giftcard']/option[#data-store='Depot Spot'][#data-balance]</p>
<p> </p>
<p> Result im getting= Depot Spot<span class="message">: 6010 ($34.25)</span></p>
<p> </p>
<p> </p>
But the results should be Depot Spot $34.25
Depot Spot $91.60
Depot Spot $9.46
</div>
<div class="modal-body"><form><input name="action" type="hidden" value="orderAssignGiftcard" />
<input name="orderId" type="hidden" value="139903" />
<div class="text-center">
<p> </p>
</div>
<hr />
<div class="form-group"> </div>
<div class="form-group"><label>Gift Cards</label><select class="form-control giftcard-selector" name="giftcard">
<option value="81695" data-store="Depot Spot" data-number="6010" data-pin="3591" data-balance="34.25">Depot Spot: 9808 ($34.25)</option>
<option value="81651" data-store="Sunnys" data-number="06074" data-pin="0939" data-balance="8.31001">Sunnys: 9808 ($8.31)</option>
<option value="81693" data-store="Marvies" data-number="10162" data-pin="5399" data-balance="53.67">Marvies: 5399 ($53.67)</option>
<option value="81694" data-store="HappyOnes" data-number="10162" data-pin="7011" data-balance="59.95">HappyOnes: 7011 ($59.95)</option>
<option value="81648" data-store="Depot Spot" data-number="3487" data-pin="7120" data-balance="91.6">Depot Spot: 3487 ($91.60)</option>
<option value="81636" data-store="Depot Spot" data-number="03371" data-pin="7231" data-balance="9.46">Depot Spot: 03371 ($9.46)</option>
</select></div>
</form>
<div> </div>
</div>
<div class="modal-footer"> </div>
</div>

You don't need such complicated xpath. This should make the job as well. You can collect data-store and data-balance values to separate lists if you wish.
List<String> results = new ArrayList<String>();
WebElement dropdown = driver.findElement(By.Name("giftcard"));
dropdown.click(); // to make the options visible
List<WebElement> options = dropdown.findElements(By.TagName("option"));
for (WebElement option: options) {
String dataStore = option.getAttribute("data-store");
String dataBalance = option.getAttribute("data-balance");
results.add(dataStore + "\\$" + dataBalance);
}

To select the option with text as Depot Spot: 9808 ($34.25) from the dropdown you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following Locator Strategies:
Using cssSelector and selectByVisibleText():
new Select(new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("select.form-control.giftcard-selector[name='giftcard']")))).selectByVisibleText("Depot Spot: 9808 ($34.25)");
Using xpath and selectByValue():
new Select(new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//select[#class='form-control giftcard-selector' and #name='giftcard']")))).selectByVisibleText("Depot Spot: 9808 ($34.25)");
Further, to print print the value of the data-balance attributes assigned to the data-store value or innerText starting with Depot Spot you can use Java8's stream() and map() you can use the following solution:
Using cssSelector and data-store attribute:
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("select.form-control.giftcard-selector[name='giftcard'] option[data-store='Depot Spot']"))).stream().map(element->element.getAttribute("data-balance")).collect(Collectors.toList()));
Using xpath and text Depot Spot::
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//select[#class='form-control giftcard-selector' and #name='giftcard']//option[starts-with(., 'Depot Spot')]"))).stream().map(element->element.getAttribute("data-balance")).collect(Collectors.toList()));

Related

Select menu element with Selenium

I would like to select an element of a dropdown menu using Selenium in a Java application.
I tried several times using Select, List < WebElement > etc... with no success.
The html of the webpage is this:
<div class="margin-top_2">
<span class="right_column_2">
<div id="f1:idSelectTipoDoc" class="ui-selectonemenu ui-widget ui-state-default ui-corner-all ui-helper-clearfix" style="vertical-align: middle; width: 198px;">
<div class="ui-helper-hidden-accessible">
<select id="f1:idSelectTipoDoc_input" name="f1:idSelectTipoDoc_input" style="vertical-align:middle">
<option value="">Select a fruit</option><option value="A">Apple</option>
<option value="T">Tangerine</option></select>
</div>
<input type="text" name="f1:idSelectTipoDoc_editableInput" class="ui-selectonemenu-label ui-inputfield ui-corner-all" tabindex="-1" style="cursor: pointer; width: 182px;">
<div class="ui-selectonemenu-trigger ui-state-default ui-corner-right"><span class="ui-icon ui-icon-triangle-1-s"></span></div></div></span>
</div>
This was my last try but the element in dropdown menu was not selected:
//open the dropdown menu
WebElement tipo1 = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id=\"f1:idSelectTipoDoc\"]/div[2]")));
tipo1.click();
// select the Apple line
WebElement tipo2 = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id=\"f1:idSelectTipoDoc\"]")));
Select elem = new Select(tipo2);
elem.selectByVisibleText("Apple");
Anyone know why it is not working? Thanks
your locator is wrong, you are using locator for div element and not select. use:
WebElement tipo2 = new WebDriverWait(driver, Duration.ofSeconds(5)).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//select[#id=\"f1:idSelectTipoDoc_input\"]")));
Select elem = new Select(tipo2);
elem.selectByVisibleText("Apple");

How to get the tagName of an element with no identifier or css classes using Selenium and Java

Using selenium how do I fetch a html tags element, the html tag does not have any unique identifiers, below is the html code:
<form data-v-48e2f75a="">
<header data-v-48e2f75a="">
<h4 data-v-48e2f75a="">via email</h4>
</header>
<div data-v-48e2f75a="" class="form-wrap">
<div data-v-cccee08c="" data-v-48e2f75a="" class="input-wrap email-input" type="email">
<label data-v-cccee08c="">
<div data-v-cccee08c="" class="input-inner-wrap has-icon">
<!--The below input tag is one of the tags I need to fetch-->
<input data-v-cccee08c="" placeholder=" " type="email"> <i data-v-cccee08c="" class="input-label-icon icon-envelope-o"></i> <span data-v-cccee08c="" class="input-label">Your E-mail</span> <!---->
</div>
<!----> <!----> <!---->
</label>
</div>
<div data-v-cccee08c="" data-v-48e2f75a="" class="input-wrap password-input" type="password">
<label data-v-cccee08c="">
<div data-v-cccee08c="" class="input-inner-wrap has-icon">
<input data-v-cccee08c="" placeholder=" " type="password"> <i data-v-cccee08c="" class="input-label-icon icon-unlock"></i> <span data-v-cccee08c="" class="input-label">Your Password</span> <!---->
</div>
<!----> <!----> <!---->
</label>
</div>
</div>
<p data-v-48e2f75a="" class="secondary-utilities forgot-password"><span data-v-48e2f75a="">Forgot password?</span></p>
<footer data-v-48e2f75a="" class="form-footer">
<div data-v-48e2f75a="" class="secondary-utilities registration">
<p data-v-48e2f75a="">Don't have an account?</p>
<span data-v-48e2f75a="">Sign up new account</span>
</div>
<button data-v-48e2f75a="" class="app-button rose-button min-width">Sign in</button>
</footer>
</form>
How I have been trying to get the element / things I've tried:
public static boolean login(WebDriver browser, String email, String password){
List<WebElement> elements = browser.findElements(By.xpath("//input[#type='email' or #type='password']"));
System.out.println();
for (WebElement element : elements){
System.out.println(element.getTagName());
System.out.println(element.toString());
}
return false;
}
however the above method keeps returning null, below are some of the other methods I've tried:
List<WebElement> elements = browser.findElements(By.id("input[type='email']"));
List<WebElement> elements = browser.findElements(By.cssSelector("*[type='email']"));
List<WebElement> elements = browser.findElements(By.cssSelector("*[type='email']"));
The tag is surrounded by some dividers...
As the elements are React elements as well as <input> elements to extract the <tagName> of the element using Selenium, you have to induce WebDriverWait for the visibilityOfElementLocated() and you can use either of the following Locator Strategies:
Using css-selectors and the type attribute of the <input>:
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("//[type='email'][placeholder]"))).getTagName());
Using xpath and the text Your E-mail of the <span>:
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[text()='Your E-mail']//preceding::*[#type='email' and #placeholder]"))).getTagName());
Should it be like this?
List<WebElement> elements = browser.findElements(By.xpath("//input[#type='email']"));
Instead of:
List<WebElement> elements = browser.findElements(By.id("input[type='email']"));
Because your element has no "id" attribute, you can't find it by By.id.
Try this:
WebElement emailElement = driver.findElement(By.xpath("//input[#type='email']"));
WebElement passwordElement = driver.findElement(By.xpath("//input[#type='password']"));
Or if you want to get a list of elements, use this:
driver.findElements(By.xpath("//input[#type='email']|//input[#type='password']"))

Selenium Select not working on <select> element

I have the task to click on element in the droplist, using exactly Select class.
So I have the HTML block:
<div id="_desktop_currency_selector">
<div class="currency-selector dropdown js-dropdown open">
<span>Валюта:</span>
<span class="expand-more _gray-darker hidden-sm-down" data-toggle="dropdown">UAH ₴</span>
<a data-target="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" class="hidden-sm-down">
<i class="material-icons expand-more"></i>
</a>
<ul class="dropdown-menu hidden-sm-down" aria-labelledby="dLabel" style="display: block;">
<li>
<a title="Евро" rel="nofollow" href="http://prestashop-automation.qatestlab.com.ua/ru/?SubmitCurrency=1&id_currency=2" class="dropdown-item">EUR €</a>
</li>
<li class="current">
<a title="Украинская гривна" rel="nofollow" href="http://prestashop-automation.qatestlab.com.ua/ru/?SubmitCurrency=1&id_currency=1" class="dropdown-item">UAH ₴</a>
</li>
<li>
<a title="Доллар США" rel="nofollow" href="http://prestashop-automation.qatestlab.com.ua/ru/?SubmitCurrency=1&id_currency=3" class="dropdown-item">USD $</a>
</li>
</ul>
<select class="link hidden-md-up">
<option value="http://prestashop-automation.qatestlab.com.ua/ru/?SubmitCurrency=1&id_currency=2">EUR €</option>
<option value="http://prestashop-automation.qatestlab.com.ua/ru/?SubmitCurrency=1&id_currency=1" selected="selected">UAH ₴</option>
<option value="http://prestashop-automation.qatestlab.com.ua/ru/?SubmitCurrency=1&id_currency=3">USD $</option>
</select>
</div>
</div>
In follow attempt, I have
org.openqa.selenium.TimeoutException: Expected condition failed:
waiting for element to be clickable: By.xpath:
//*[#id='_desktop_currency_selector']//select (tried for 30 second(s)
with 500 MILLISECONDS interval)
click(currencyDropListBtn);
WebElement dropListBtn = driver.findElement(By.xpath("//*[#id='_desktop_currency_selector']//i"));
waitToBeClickable(dropListBtn);
dropListBtn.click();
WebElement dropListElement = driver.findElement(By.xpath("//*[#id='_desktop_currency_selector']//select"));
waitToBeClickable(dropListElement);
Select select = new Select(dropListElement);
select.selectByIndex(1);
It will be work in the follow way:
WebElement dropListBtn = driver.findElement(By.xpath("//*[#id='_desktop_currency_selector']//i"));
waitToBeClickable(dropListBtn);
dropListBtn.click();
WebElement dropListElement = driver.findElement(By.xpath("//a[#title='Евро']"));
waitToBeClickable(dropListElement);
click(dropListElement);
But I need to use exactly Select class.
How to correctly select the droplist element via Select?
Normally for select element, you do not need to click the option inside it.
You can just set the value of the select element with value of the option you want to select.
I post a utility function that I use a lot.
set_value("//select[#class='link hidden-md-up']",'http://prestashop-automation.qatestlab.com.ua/ru/?SubmitCurrency=1&id_currency=3','value')
def set_value(xpath, val, field):
script = """(function()
{
node = document.evaluate("%s", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (node==null)
return '';
node.%s='%s';
return 'ok';
})()"""%(xpath,field,val)
driver.execute_script(script)

Trouble selecting option in display: none dropdown Selenium

I dont ask this question lightly, but it proving to be more problematic than I thought. I have trawled through google looking at possible solutions but it seems I just cannot select a specific option from a dropdown list.
If anyone can give me a pointer or a solution it would be very welcome as I am pulling my hair out trying to get this to work.
Here is the html:
<div id="main-content" class="col-xs-12">
<div class="row">
<div
class="form-horizontal col-sm-6 col-sm-offset-3 col-md-4 col-md-offset-4">
<div class="col-xs-12">
<h1>Please sign in</h1>
<div class="form-group form-group-sm">
<div class="form-group">
<div class="form-group">
<div class="form-group" data-bind="visible:loginExternal"
style="display: none;">
<div class="form-group">
<span class="k-widget k-dropdown k-header" style="width: 100%;"
unselectable="on" role="listbox" aria-haspopup="true"
aria-expanded="false" tabindex="0" aria-owns=""
aria-disabled="false" aria-readonly="false" aria-busy="false">
<span class="k-dropdown-wrap k-state-default"
unselectable="on"> <span class="k-input"
unselectable="on">Please select ...</span> <span
class="k-select" unselectable="on"> <span
class="k-icon k-i-arrow-s" unselectable="on">select</span>
</span>
</span> <select data-role="dropdownlist" data-text-field="display"
data-option-label="Please select ..."
style="width: 100%; display: none;"
data-value-primitive="true" data-value-field="irn"
data-bind="source: locations, value: selectedLocation">
<option value="822">Alexandra</option>
<option value="800">Ridge</option>
<option value="896">Ture</option>
<option value="899">Grove</option>
<option value="824">Lea</option>
<option value="825">Mount</option>
<option value="894">Cliffe</option>
<option value="788">Bank</option>
<option value="826">Ponga</option>
<option value="259">Post</option>
</select>
</span>
</div>
<div class="form-group">
<span class="k-widget k-dropdown k-header" style="width: 100%;"
unselectable="on" role="listbox" aria-haspopup="true"
aria-expanded="false" aria-owns="loginSubLoc_listbox"
aria-disabled="true" aria-readonly="false" aria-busy="false"
aria-activedescendant="loginSubLoc_option_selected"> <span
class="k-dropdown-wrap k-state-disabled" unselectable="on">
<span class="k-input" unselectable="on"></span> <span
class="k-select" unselectable="on"> <span
class="k-icon k-i-arrow-s" unselectable="on">select</span>
</span>
</span> <select id="loginSubLoc" data-role="dropdownlist"
data-text-field="display"
data-option-label="Please select ..."
style="width: 100%; display: none;"
data-value-primitive="true" data-value-field="irn"
data-bind="source: sublocations, value: selectedsubLocation, enabled: isSublocationEnabled"
disabled="disabled">
<option value="">Please select ...</option>
<option value="0" selected="selected"></option>
</select>
</span>
</div>
<div class="form-group">
<button id="submit" class="btn btn-lg btn-primary btn-block"
type="button" data-bind="click: btnLoginClicked">Login</button>
</div>
I have tried the following:
WebElement element = driver.findElement(By.cssSelector("div>span>select[data-bind='source: locations, value: selectedLocation']"));
Select dropdown = new Select(element);
driver.findElement(By.cssSelector("div.form-group>span>span.k-dropdown-wrap.k-state-default>span.k-input")).click();
dropdown.selectByValue("822");
I get an error: element not visible: Element is not currently visible and may not be manipulated
I also tried the following:
driver.findElement(By.cssSelector(".k-input")).click();
List<WebElement> popupdd = driver.findElements(By.cssSelector("div>span>select[data-bind='source: locations, value: selectedLocation']>option"));
driver.switchTo().activeElement();
int noOptions = popupdd.size();
System.out.println("Total options = " + noOptions);
if (noOptions > 0) {
for (WebElement e : popupdd) {
System.out.println(e.getAttribute("textContent"));
if (e.getAttribute("textContent").contains(location)) {
System.out.println("Trying to click on : " + location);
e.click();
Thread.sleep(500);
break;
} else {
System.out.println("counld find the entry: " + location);
}
}
}
It prints out correctly the option values but cannot click onthe option I want. I get an error: org.openqa.selenium.ElementNotVisibleException: element not visible
Very frustrating. Not sure how to mover forward wit this one.
Any help would be greatly appreciated as I am presently relying on the Robot class to manipulate the dropdown and want to avoid this method.
1st way: it is not the problem to click any element using the same js. As you know how to get any option the last actions remaning is to perform a click. This should work for you:
WebElement hiddenWebElement =driver.findElement(By(..selector of the element....));
((JavascriptExecutor)driver).executeScript("arguments[0].click()",hiddenWebElement);
2nd way:
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x = $(\'#subElement\');");
stringBuilder.append("x.click();");
js.executeScript(stringBuilder.toString());
3rd way: using actions builder, advanced user actions API.
WebElement mnEle;
WebElement sbEle;
mnEle = driver.findElement(By.Id("mnEle")).click();
sbEle = driver.findElement(By.Id("sbEle")).click();
Actions builder = new Actions(driver);
// Move cursor to the Main Menu Element
builder.moveToElement(mnEle).Perform();
// Giving 5 Secs for submenu to be displayed
Thread.sleep(5000L);
// Clicking on the Hidden SubMenu
driver.findElement(By.Id("sbEle")).click();
Hope this will help you :)
Here is the Answer to your Question:
As per your Question, to select the option <option value="822">Alexandra</option> you can consider trying the following piece of code:
WebElement select_dropdownlist = driver.findElement(By.xpath("//*[#data-role='dropdownlist' and #data-text-field='display']"));
Select dropdownlist = new Select(select_dropdownlist);
dropdownlist.selectByVisibleText("Alexandra");
OR
WebElement select_dropdownlist = driver.findElement(By.xpath("//*[#data-role='dropdownlist' and #data-option-label='Please select ...']"));
Select dropdownlist = new Select(select_dropdownlist);
dropdownlist.selectByValue("822");
Let me know if this Answers your Question.

How to get input value by using class?

I am using the code below
WebElement inputele = driver.findElement(By.className("class_name"));
String inputeleval = inputele.getAttribute("value");
System.out.println(inputeleval);
but the value is empty. The HTML is below.
<div id="main">
<div id="hiddenresult">
<div class="tech-blog-list">
<label for="Question">1st Question</label>
<input id="txt60" class="form-control" type="text" value="sddf sd sdfsdf sdf sdfsdf sdfsdfsd fsd" />
</div>
</div>
<div class="pagination_main pull-left">
<div id="Pagination">
<div class="pagination">
<a class="previous" onclick="PreviousBtnClickEvent();" href="javascript:void(0)">Previous</a>
<a id="pg59" class="ep" onclick="PaginationBtnClickEvent(this);" href="javascript:void(0)" name="Textbox">1</a>
<a id="pg41" class="ep" onclick="PaginationBtnClickEvent(this);" href="javascript:void(0)" name="Textbox">2</a>
<a id="pg40" class="ep" onclick="PaginationBtnClickEvent(this);" href="javascript:void(0)" name="Textarea">3</a>
<a id="pg60" class="ep current" onclick="PaginationBtnClickEvent(this);" href="javascript:void(0)" name="Textbox">4</a>
</div>
</div>
</div>
</div>
Try using WebDriverWait to wait until element fully loaded on page and visible as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement inputele= wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("class_name")));
String inputeleval = inputele.getAttribute("value");
System.out.println(inputeleval);
Note :-By.className("class_name") will give that element which class attribute equal to class_name. Make sure which element you want to locate is unique element with class attribute equal to class_name otherwise wise it will give first element with condition true.
Hope it will work..:)
Looks like your code is pretty close but you have the wrong class name? In your code above, you had "class_name" instead of "form-control". I'm assuming that was some sample code and not the actual code you are using? There is only one INPUT in the HTML and the code below should work. It also has an ID so that should be more specific in case there are more than one INPUTs on the page.
WebElement inputele= driver.findElement(By.className("form-control"));
String inputeleval = inputele.getAttribute("value");
System.out.println(inputeleval);

Categories