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();
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 had taken the xPath as below but I am not able to get the value 145666 when I try to print.
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[contains(#class,'mat-content')]//div[#id='demandTrackingID']")));
Now iam getting the below Expception :
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.xpath: //span[contains(#class,'mat-content')]//div[#id='TrackID']
Note: This Html Element is a Non Visible Element I need to inspect the panel and get this element as there is no field for this Element
HTML:
<div _ngcontent-wbh-c179="" id="TrackID" class="disp-none">14566 </div>
Please try this:
WebElement trackid= driver.findElement(By.xpath("//span[contains(#class,'mat-content')]//div[#id='TrackID']"));
System.out.println("getid:"+ trackid.getText());
You will possible need to add an explicit wait before that to make element fully loaded before retrieving it's content
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[contains(#class,'mat-content')]//div[#id='TrackID']")));
WebElement trackid= driver.findElement(By.xpath("//span[contains(#class,'mat-content')]//div[#id='TrackID']"));
System.out.println("getid:"+ trackid.getText());
id is ID not id
so use this :
WebElement trackid= driver.findElement(By.id("TrackID"));
System.out.println("getid:"+ trackid.getText());
The element that contains the text you want has an ID, TrackID, not to be confused with the "ID" text on the page. You can use that to locate the element more easily than the XPath you are currently using. Once you have the element, you can use WebDriverWait to wait for the element to contain text. Code is below.
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until((ExpectedCondition<Boolean>) d -> d.findElement(By.id("TrackID")).getText().length() != 0);
Given the class class="disp-none" on the element, I'm guessing that the element might not be visible. If this is the case, you'll have to use JavaScript to get the invisible text. Selenium was designed to only interact with visible elements and will throw an exception if you try to interact with elements that are not visible.
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until((ExpectedCondition<Boolean>) d -> d.findElement(By.id("TrackID")).getText().length() != 0);
WebElement element = driver.findElement(By.id("TrackID"));
String trackID = (JavascriptExecutor)driver.executeScript("return arguments[0].text", element);
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);
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.
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")));