Selenium Access options for input drop-down list - java

I have an input control that acts as a read-only drop-down list (Svelte is framework behind it). How do I get a list of the drop-down options using Selenium and Java please? I have tried the select option:
Select allOptions = new Select(webDriver.getWebDriver().findElement(By.xpath(xpath)));
I got exceptions saying that you cannot select on an input. Because the control is read-only you can't type into it to enter values.
<input readonly="true" autocapitalize="none" autocomplete="off" autocorrect="off" spellcheck="false" tabindex="0" type="text" aria-autocomplete="list" id="select-instances" placeholder="Select an instance" class="svelte-abcd" style="">
I have researched answers here, for example this one. You don't get list tags from Svelte. Any suggestions or help would be greatly appreciated.

I would try with sendKeys combination (you can experiment with ArrowDown, Tab, Enter) and then if it is not working for you - with JavaScript. You can set the text and then trigger onchange event if needed.
document.getElementById("select-instances").value = "My value";
or set the placeholder
document.getElementById("select-instances").setAttribute('placeholder','My value');
Reference:
What is JavaScriptExecutor in Selenium?

Open DevTools -> Sources
Click on the input -> Press F8 to stop JS execution in the browser
Inspect dropdown option -> Write down the xpath
public List<string> GetOptionsText(IWebDriver driver)
{
string parentInputXpath = "inputXpath";
string optionXpath = "optionXpath";
List<string> optionsText = new List<string>();
driver.FindElement(By.XPath(parentInputXpath)).Click();
options = driver.FindElement(By.XPath(parentInputXpath)).FindElements(By.XPath(optionXpath)).ToList();
if (options.Count == 0)
throw new NoSuchElementException("Dropdown options not found");
foreach (var option in options)
{
optionsText.Add(option.Text);
}
return optionsText;
}
P.S: It would be also good to add implicit/explicit waits here.

If Possible can you share pic of html code of the dropdown element
Select allOptions = new
Select(webDriver.getWebDriver().findElement(By.xpath(xpath)));
List<WebElement> elements = allOptions.getOptions();
List<String> options = new LinkedList<String();
for(WebElement el: elements)
{
options.Add(el.getText());
}

although I'm not a expert in selenium but just try to solve this problem. I create a index.html file to get the options from the dropdown menu. I only create a drop down menu in this index.html files its code is this:-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="row">
<span class="label">Select Text</span>
<span class="box"><input readonly="true" autocapitalize="none" autocomplete="off" autocorrect="off" spellcheck="false" tabindex="0" type="text" aria-autocomplete="list" id="datatext" placeholder="Select an instance" class="datatext" >
<select class="contentselect"
id="contentselect">
<option></option>
<option value="one">test1</option>
<option value="two">test2</option>
<option value="two">test3</option>
<option value="two">test4</option>
<option value="two">test5</option>
<option value="two">test6</option>
</select></span>
</div>
<script>
textfield = document.getElementById("datatext");
contentselect = document.getElementById("contentselect");
contentselect.onchange = function () {
var text = contentselect.options[contentselect.selectedIndex].value
if (text != "") {
textfield.value += text;
}
}
</script>
</body>
</html>
Then I create a java file to read all the options from the index.html. Java code looks like:-
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\Goal Projects\\Webnovel API\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://127.0.0.1:5500/index.html");
Select allOptions = new Select(driver.findElement(By.xpath("//select[#id='contentselect']")));
List<WebElement> elements = allOptions.getOptions();
List<String> options = new ArrayList<String>();
for (WebElement element : elements) {
options.add(element.getText());
}
for (String s : options) System.out.println(s);
}
Result Output is like this:-
I think you are using wrong xpath you are using input xpath but you should use selection path.
I hope this will help you, Thanks for reading.

Related

Jsoup css selector "not", not return anything

I'm trying to ignore an item and not parse it on Jsoup
But css selector "not", not working !!
I don't understand what is wrong ??
my code:
MangaList list = new MangaList();
Document document = getPage("https://3asq.org/");
MangaInfo manga;
for (Element o : document.select("div.page-item-detail:not(.item-thumb#manga-item-5520)")) {
manga = new MangaInfo();
manga.name = o.select("h3").first().select("a").last().text();
manga.path = o.select("a").first().attr("href");
try {
manga.preview = o.select("img").first().attr("src");
} catch (Exception e) {
manga.preview = "";
}
list.add(manga);
}
return list;
html code:
<div class="col-12 col-md-6 badge-pos-1">
<div class="page-item-detail manga">
<div id="manga-item-5520" class="item-thumb hover-details c-image-hover" data-post-id="5520">
<a href="https://3asq.org/manga/gosu/" title="Gosu">
<img width="110" height="150" src="https://3asq.org/wp-content/uploads/2020/03/IMG_4497-110x150.jpg" srcset="https://3asq.org/wp-content/uploads/2020/03/IMG_4497-110x150.jpg 110w, https://3asq.org/wp-content/uploads/2020/03/IMG_4497-175x238.jpg 175w" sizes="(max-width: 110px) 100vw, 110px" class="img-responsive" style="" alt="IMG_4497"/> </a>
</div>
<div class="item-summary">
<div class="post-title font-title">
<h3 class="h5">
<span class="manga-title-badges custom noal-manga">Noal-Manga</span> Gosu
</h3>
If I debug your code and extract the HTML for:
System.out.println(document.select("div.page-item-detail").get(0)) (hint use the expression evaluator in IntelliJ IDEA (Alt+F8 - for in-session, real-time debugging)
I get:
<div class="page-item-detail manga">
<div id="manga-item-2003" class="item-thumb hover-details c-image-hover" data-post-id="2003">
<a href="http...
...
</div>
</div>
</div>
It looks like you want to extract the next div tag down with class containing item-thumb ... but only if the id isn't manga-item-5520.
So here's what I did to remove that one item
document.select("div.page-item-detail div[class*=item-thumb][id!=manga-item-5520]")
Result size: 19
With the element included:
document.select("div.page-item-detail div[class*=item-thumb]")
Result size: 20
You can also try the following if you want to remain based at the outer div tag rather than the inner div tag.
document.select("div.page-item-detail:has(div[class*=item-thumb][id!=manga-item-5520])")

How to send dropdown value to servlet NOT the option text

I have dropdown with options and the values. I can get the option value by the dropdown name in servlet but how can i get the dropdown "value" in servlet. In screenshot, temporarily i concatenated the with options but i want to store value in variable in servlet.
Please help:
HTML:
<input type="text" name="taxiDropdown" id= "taxiDropdown" placeholder="Search taxi...">
</div>
<div class="scrolling menu">
<%
List eList = (ArrayList) session.getAttribute("taxiInfo");
%>
<%
for (int i = 0; i < eList.size(); i++) {
%>
<div class="item" data-value="<%=((TaxiInfo) eList.get(i)).getID()%>">
<div class="ui green empty circular label"></div>
<%=((TaxiInfo) eList.get(i)).getTaxiPlate() +" "+ ((TaxiInfo) eList.get(i)).getID() %>
</div>
<%
}
%>
</div>
</div>
Servlet:
String val = request.getParameter("taxiDropdown");
(in "val", I want to store the value of the dropdown not the option text)
In JSP you should have something like that:
<form method="post">
<select name="taxiDropdown" id="taxiDropdown">
<%
List<TaxiInfo> eList = (List<TaxiInfo>) request.getAttribute("taxiInfo");
for (TaxiInfo taxiInfo : eList) {
%>
<option name="<%=taxiInfo.getTaxiPlate()%>" value="<%=taxiInfo.getID()%>"><%=taxiInfo.getTaxiPlate()%></option>
<%
}
%>
</select>
<input type="submit" />
</form>
Then in controller/servlet you will receive the id of TaxiInfo:
String val = request.getParameter("taxiDropdown");
System.out.println(val);
Or in your case you should set a hidden input with javascript with desired value.
added this code in html:
Move value of the dropdown selection to hidden textbox
<script type='text/javascript'>
$(function() {
$('#driverdp').change(function() { <-- this is my dropdown -->
var x = $(this).val();
$('#driverid').val(x); <-- this is my textbox -->
});
});
</script>
Servlet:
get the value of hidden text in servlet
String text= request.getParameter("driverId");
hope it will help someone

How to open documents in html(inside iframe or div) by passing document path

I have a requirement in my application like,I need to open files(pdf,docx,pptx..)with in html(embedding into div or iframe) by passing document paths(urls) on click of a button.
I have tried opening the documents outside the application and its working,But I am stuck on hw to approach the above problem.
Thanks.
You can have a iframe inside a div and o0pen the document in that iframe element as follows:
<div>
<iframe src="" id="iframeRight" style="width:600px; height:500px;" frameborder="0">
</iframe>
</div>
In the controller, on click of button you can assign the base64 string of the document to iframe src as follows:
document.getElementById("iframeRight").src = base64String;
Just ensure that the base64 string has the metadata attached to it like for pdf it must start as:
data:application/pdf;base64,
PFB a demo program that lets user select the document and displays the same in the iframe. Copy paste in notepad and run this as html file. Select a doc less than 5 mb in size.
<!DOCTYPE html>
<html>
<body>
<input type="file" id="file-uploadUC" />
<iframe src="demo_iframe.htm" id="ifrm" height="200" width="300"></iframe>
<script>
document.getElementById("file-uploadUC").addEventListener("change", rdfile);
function rdfile() {
extn = '';
FileContentBase64 = '';
FileName = '';
if (this.files && this.files[0]) {
if (this.files[0].size <= 5347738) {
var FR = new FileReader();
FileName = this.files[0].name;
extn = FileName.split(".").pop();
FR.onload = function (e) {
FileContentBase64 = e.target.result;
document.getElementById("ifrm").src = FileContentBase64;
};
FR.readAsDataURL(this.files[0]);
}
else {
}
}
else {
}
}
</script>
</body>
</html>

Selenium driver - select the desired li item in the list

In a list of 8 Elements I would select the one that contains the search text in children div. I need this because the elements of the list changes order every time. Here I would like to select the one that contains the text "TITLE TO LISTEN". How do I scroll through the list and select the wish li?
Thanks in advance
Here one li:
...
<li id="3636863298979137009" class="clearfix" data-size="1" data-fixed="1" data-side="r">
<div class="userContentWrapper">
<div class="jki">
<span class="userContent">
TITLE TO LISTEN
</div>
<div class="TimelineUFI uiContainer">
<form id="u_0_b0" class="able_item collapsed_s autoexpand_mode" onsubmit="return window.Event && E" action="/ajax/ufi/modify.php" method="post" >
<input type="hidden" value="1" name="data_only_response" autocomplete="off">
<div class="TimelineFeedbackHeader">
<a class="ction_link" role="button" title="Journal" data-ft="{"tn":"J","type":25}" rel="dialog" href="/ajax/" tabindex="0" rip-style-bordercolor-backup="" style="" rip-style-borderstyle-backup="" >LISTEN</a>
</div>
</form>
</div>
</div>
</li>
</ol>
</div>
...
I tried this code, but it don't work because the elements ids change each time.
driver.findElement(By.xpath("//li[8]/div[2]/div/div[2]/form/div/div/span[2]/a")).click();
For example:
If text contain "TEXT TO LISTEN": li[3]/div[2]/div/div/div[2]/div/div/span
Link "listen" i want to click : li[3]/div[2]/div/div[2]/form/div/div/span[2]/a
here is number 3, but the order may change. I would first like to get that number and then click on the right link
Use this
driver.findElement(By.xpath("//li[contains(text(), 'Your text goes here')]"))
EDIT: just realised it's very old ques and you might have got ans by now, so for others who are looking for answer to this question.
You could get list of all li elements, and then search for specified text
for(int i=0; i< listOfLiElements.Count, i++){
if(listOfLiElements[i].FindElement(By.ClassName("userContent")).Text == "TITLE TO LISTEN")
{
correctElement = listOfLiElements[i].FindElement(By.TagName("a"));
i =listOfLiElements.Count;
}
}
Well, then just iterate through for each and ask if the current element has the right text inside it.
List<Element> listOfLiTags = driver.findElement(By.Id("yourUlId")).findElements(By.TagName("li"));
for(Element li : listOfLiTags) {
String text = li.getElement(By.ClassName("userContent").getText();
if(text.equals("TITLE TO LISTEN") {
//do whatever you want and don't forget break
break;
}
}
Note that this is much more easier with CssSelector API.
List<Element> listOfSpans = driver.findElements(
By.CssSelector("ul[id=yourId] li span[class=userContent]");
Now just iterate and ask for the right text:)
You can try this :
public void ClickLink()
{
WebElement ol =driver.findElement(By.id("ol"));
List<WebElement> lis=ol.findElements(By.tagName("li"));
ArrayList<String> listFromGUI=new ArrayList<>();
for(int i=0;i<lis.size();i++)
{
WebElement li=ol.findElement(By.xpath("//ol[#id='ol']/li["+(i+1)+"]/div[2]/div/div/div[2]/div/div/span"));
if(li.getText().trim().equals("TEXT TO LISTEN"))
{
WebElement link=ol.findElement(By.xpath("//ol[#id='ol']/li["+(i+1)+"]/div[2]/div/div[2]/form/div/div/span[2]/a"));
if(link.getText().trim().equals("LISTEN"))
{
link.click();
break;
}
}
}
}

How to run a child window java script function in parent window after changing the url in the parent window?

I want to execute the java script function of a child window on parent window, Even after changing the URL in the parent window.
I tried like below:
**Parent.html:**
<html>
<head>
<title>Parent window document</title>
</head>
<body>
<script type="text/Javascript">
function openChildWindow()
{
var s_url = "child.html";
var s_name = "ChildWindowDocument";
var s_specs = "resizable=yes,scrollbars=yes,toolbar=0,status=0";
var childWnd = window.open(s_url, s_name, s_specs);
var div = childWnd.document.getElementById("child_wnd_doc_div_id");
div.innerHTML = "Hello from parent wnd dddsfds";
}
</script>
<input type="button" value="Open child window document" name="sss" onclick="openChildWindow()" />
<div>Click me: nothing will happen.</div>
<div id="aaa" class="yourclass">
<p>This is a paragraph with a <span>span</span> where the paragraph's container has the class. Click the span or the paragraph and see what happens.</p>
This sentence is directly in the div with the class rather than in child element.
</div>
<div>Nothing for this div.</div>
<a>dsfsd</a>
</body>
</html>
**child.html:**
<html>
<head>
<title>Parent window document</title>
<script>
opener.document.body.onclick = function(e) {
var sender = (e && e.target) || (window.parent.event && window.parent.event.srcElement);
document.getElementById("id").value=sender.tagName;
}
</script>
</head>
<body>
<div id="child_wnd_doc_div_id">child window</div>
ID: <input type="text" id="id"/><br/>
Name: <input type="text" id="id"/><br/>
Xpath: <input type="text" id="id"/><br/>
CSS: <input type="text" id="id"/><br/>
</body>
</html>
Clearly, my concept is: I want to execute the child window function after changing the url in the parent window.
The only way I see:
observe the unload-event of the opener. When it fires, try(after a short timeout) to reassign the onclick-function(and also the onunlad-function).
Of course this will only work when both documents are placed under the same domain.

Categories

Resources