I am running Selenium Web-driver using JAVA and facing an issue with auto-suggest input text field. When I enter a String "books" in the text field, an option would show up. Then I want to click or select the input populated on the auto suggest menu.
Below is the code:
WebDriver driver = new FirefoxDriver();
driver.get("http://www.amazon.com/");
driver.findElement(By.id("twotabsearchtextbox")).sendKeys("books");
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("gwcswTooltip")));
List<WebElement> findElements = driver.findElements((By.id("gwcswTooltip").name("books on")));
for (WebElement webElement : findElements)
{
System.out.println(webElement.getText());
}
You need to just pick the right locator.
Add the following line
List<WebElement> findElements = driver.findElements((By.xpath("//div[#id='srch_sggst']/div")));
instead of
List<WebElement> findElements = driver.findElements((By.id("gwcswTooltip").name("books on")));
Related
While trying to get the menu list, I'm getting this error message:
Exception in thread "main" org.openqa.selenium.support.ui.UnexpectedTagNameException: Element should have been "select" but was "a".
Here below is the code:
public static void main(String[] args) {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver", "D:\\selenium files\\chromedriver_win32_new\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.tutorialspoint.com/tutor_connect/index.php");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
WebElement ele = driver.findElement(By.xpath("//*[#id=\"logo-menu\"]/div/div[1]/div/a"));
Select s = new Select(ele);
//getting list of menu
List <WebElement> op = s.getOptions();
int size = op.size();
for(int i =0; i<size ; i++){
String options = op.get(i).getText();
System.out.println(options);
}
}
}
That is because the element you are trying to cast is a link tag and not a select tag.
You need to give the Xpath or CSS of the correct Select element and then cast it from WebElement into a Select ojbect.
In the example you are using there is not real selector, you first need to click on the buttons that says "Categories" and later take the options that appear:
WebElement button = driver.findElementByCSS("div[class='mui-dropdown']");
button.click();
WebElement SelectObj = driver.findElementByCSS("ul[class*='mui--is-open']");
Select s = new Select(SelectObj);
The desired element is not a <select> element but a <ul> element. Once you click on the <a> element then only the classname mui--is-open is appended to the desired <ul> element.
Solution
So to get the contents of the dropdown menu you need to induce WebDriverWait for the visibilityOfAllElementsLocatedBy() and you can use Java8 stream() and map() and you can use either of the following Locator Strategies:
Using cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("a.mui-btn.mui-btn--primary.categories"))).click();
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("ul.mui-dropdown__menu.cat-menu.mui--is-open a"))).stream().map(element->element.getText()).collect(Collectors.toList()));
Using xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='mui-btn mui-btn--primary categories']"))).click();
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//ul[#class='mui-dropdown__menu cat-menu mui--is-open']//a"))).stream().map(element->element.getText()).collect(Collectors.toList()));
References
You can find a couple of relevant detailed discussions in:
How to extract the text iterating specific rows within a table using XPath with Selenium and Java
How to extract the dynamic values of the id attributes of the table elements using Selenium and Java
How to print runs scored by a batsmen in a scoreboard format webelements through CSS selector using Selenium and Java
I am trying to learn selenium to find elements and I could not clicking the "Edit"buttons and Im trying the get the size of the rows of the table.
Here is my code:
System.setProperty("webdriver.chrome.driver","C:\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
String baseUrl = "https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/PopupEditing/Angular/Light/";
driver.get(baseUrl);
driver.manage().window().maximize();
TimeUnit.SECONDS.sleep(5);
List<WebElement> we = driver.findElements(By.linkText("Edit")); System.out.println(we.size());
we.get(1).click();
Here is the link that I am working:
https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/PopupEditing/Angular/Light/
driver = new ChromeDriver();
driver.get("https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/PopupEditing/Angular/Light/");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
WebElement frame = wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("demoFrame"))));
driver.switchTo().frame(frame);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("[class=\"dx-link dx-link-edit\"]"))).click();
Use webdriver wait and switchTo frame, you have to switch to iframe first to interacte elements inside the iframe.
once you finish , if you want to interact with elements outside iframe then you have to switch out of it first.
driver.switchTo().defaultContent();
//rest of your code
The element is present inside an iframe and you need to switch iframe first and then you will be able to interact with element.
To overcome synchronization issue you need to induce WebDriverWait() and wait for frameToBeAvailableAndSwitchToIt() and following locator.
To get the link details induce WebDriverWait() and wait for visibilityOfAllElementsLocatedBy() and following locator.
WebDriver driver = new ChromeDriver();
String baseUrl = "https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/PopupEditing/Angular/Light/";
driver.get(baseUrl);
driver.manage().window().maximize();
new WebDiverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("demoFrame")));
List<WebElement> we =new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.linkText("Edit")));
System.out.println(we.size());
we.get(1).click();
This is the html code for the button in the pop up ( pop up has a lead gen form) -
<button id="getCoupon" class="fetch" data-bind="click: submitForm" type="submit">Fetch Coupon</button>
This is the script which I have written in JAVA in Eclipse. I am able to fill the name, Email and Phone number but I'm not able to click on the button -
driver.findElement(By.id("getCoupon")).click();
As per the comment and URL, you have shared :
You can try with this code :
public class Pawan {
static WebDriver driver ;
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\user**\\Downloads\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://vets.cm.qa.preview.vca.webstagesite.com/free-first-exam");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("input[value='/santa-monica']~div.select-btn"))).click();
wait.until(ExpectedConditions.elementToBeClickable(By.id("fName"))).sendKeys("Pawan");
wait.until(ExpectedConditions.elementToBeClickable(By.id("lName"))).sendKeys("Sharma");
wait.until(ExpectedConditions.elementToBeClickable(By.id("email"))).sendKeys("ps12#gmail.com");
wait.until(ExpectedConditions.elementToBeClickable(By.id("zip"))).sendKeys("90404");
wait.until(ExpectedConditions.elementToBeClickable(By.id("phone"))).sendKeys("9697989900");
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollBy(0,100)", "");
wait.until(ExpectedConditions.elementToBeClickable(By.id("getCoupon"))).click();
}
}
As per your HTML code, your id is : "getCoupon",
whereas in code you mentioned id as : "getCouponFetch". Please correct and it should work. Code -
driver.findElement(By.id("getCoupon")).click();
If selenium click don't work, use below Java Script click code :
WebElement element = driver.findElement(By.id("getCoupon")); JavascriptExecutor executor = (JavascriptExecutor)driver; executor.executeScript("arguments[0].click();", element);
Firstly, what kind of error did you get??
Try using implicit wait if your getting "NoSuchElementException" like below:
driver.manage().timeOuts().implicitlywait(30,TimeUnit.SECONDS);
Then try using the below way to locate that button:
driver.findElementByXpath("text()[contains(.,'Fetch Coupon')]").click();
As per the HTML you have shared to click() on the button you have to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.fetch#getCoupon"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='fetch' and #id='getCoupon'][contains(.,'Fetch Coupon')]"))).click();
Update
As an alternative you can use the executeScript() method to invoke the click() as follows:
Using cssSelector:
WebElement fetch_coupon = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.fetch#getCoupon")));
((JavascriptExecutor)driver).executeScript("arguments[0].click();", fetch_coupon);
Using xpath:
WebElement fetch_coupon = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='fetch' and #id='getCoupon'][contains(.,'Fetch Coupon')]")));
((JavascriptExecutor)driver).executeScript("arguments[0].click();", fetch_coupon);
I am trying to click on dropdown value to select city in from field in Make my trip http://www.makemytrip.com/. But getting Stale element reference exception. Ids are getting changed on page load.
Tried below code:
driver.findElement(By.xpath(".//*[#id='hp-widget__sfrom']")).clear();
driver.findElement(By.xpath(".//*[#id='ui-id-1']"));
driver.findElement(By.xpath(".//*[#id='hp-widget__sfrom']")).click();
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeSelected(driver.findElement(By.xpath(".//*[#class='ui-menu-item'][2]"))));
To click on a dropdown value e.g. Mumbai you can use the following solution:
Code Block:
driver.get("https://www.makemytrip.com/")
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#class='input_fromto checkSpecialCharacters ui-autocomplete-input' and #id='hp-widget__sfrom']"))).click();
List<WebElement> myList = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//li[#class='ui-menu-item'][starts-with(#id,'ui-id-')]//span[#class='autoCompleteItem__label']")));
for (WebElement element:myList)
if(element.getText().contains("Mumbai"));
element.click();
Browser Snapshot:
You can use this working code:
WebDriver driver = new ChromeDriver();
driver.get("https://www.makemytrip.com/");
driver.findElement(By.xpath(".//*[#id='hp-widget__sfrom']")).clear();
driver.findElement(By.xpath(".//*[#id='hp-widget__sfrom']")).click();
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[#class='ui-menu-item'][2]/div/p[1]/span[1]"))).click();
I have fixed the xPath of dropdown list element. Always try to specify the exact element yo want to interact with. For example if you want to click on button, try to find <span> or <button> tag, for a link <a> tag and for input fields <input> tag.
You can try this code :
I do not see any use of xpath in this scenario. I have converted some of the xpath to either css selector or id. and have kept only one. Though I have not faced any stale element reference.
System.setProperty("webdriver.chrome.driver", "D:\\Automation\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
WebDriverWait wait = new WebDriverWait(driver, 30);
driver.get("https://www.makemytrip.com/");
WebElement from = wait.until(ExpectedConditions.elementToBeClickable(By.id("hp-widget__sfrom")));
from.click();
from.clear();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("ul[class*='ui-widget-content hp-widget__sfrom']")));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//li[contains(#aria-label,'Top Cities : Mumbai, India ')]"))).click();
The below code works fine for me and it is parameterized as well, it works for any input value without changing the xpath. In this example, I took mumbai as test data.
driver.get("https://www.makemytrip.com/");
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
driver.findElement(By.xpath("//input[contains(#id,'hp-widget__sfrom')]")).clear();
driver.findElement(By.xpath("//input[contains(#id,'hp-widget__sfrom')]")).click();
driver.findElement(By.xpath("//input[contains(#id,'hp-widget__sfrom')]")).sendKeys("Mumbai");
Thread.sleep(2000);
WebDriverWait wait = new WebDriverWait(driver, 30);
By option = By.xpath("//div[#class='autoCompleteItem']/p/span[contains(text(),'Mumbai')]");
wait.until(ExpectedConditions.elementToBeClickable(option));
driver.findElement(option).click();
private void next() {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.reddit.com/r/pics/");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
WebElement element = driver.findElement(By
.xpath("//span[contains(.,'next')]"));
element.click();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
System.out.println(driver.getCurrentUrl());
is this code correct, all that happens when next is clicked is the focus scrolls down the page to the button
Your xpath selector is wrong.
Change it to:
WebElement element = driver.findElement(By
.xpath("//a[contains(text(),'next')]"));
or even better (in case one of the topic links contains the text "next") use:
WebElement element = driver.findElement(By
.xpath("//span[#class='nextprev']/a[contains(text(), 'next')]"));
This will ensure that the a element that is picked up is within the correct span at the bottom of the page and make your test less brittle.
The xpath = //span[contains(.,'next')] used in your code, locates span with contents view more : next › ,but you need to click only on next ›.i.e., you need to click on the anchor tag which contains next ›.
The below code will solve the issue.
WebDriver driver = new FirefoxDriver();
driver.get("http://www.reddit.com/r/pics/");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
WebElement element = driver.findElement(By
.linkText("next ›"));
element.click();
System.out.println(driver.getCurrentUrl());
It is always better to avoid xpath and use other locators like linkText or partialLinkText in this case.