I am trying to get the id of an element which starts with 'u_' and ends with '_5' and in between data changes alphabetically.So, sometimes i see 'u_d_5' and sometime 'u_6_5' . In that case, how would get the dynamic id?
I know there are some methods like starts-with or ends-with but they aren't working at all for me. Could anyone please suggest me some idea in this?
code snippet:
WebElement cls=ff.findElement(By.xpath("//*[#id='u_6_5']"));
whole code:
String s=System.getProperty("user.dir");
System.setProperty("webdriver.chrome.driver", s+"\\ChromeDriver\\chromedriver.exe");
ChromeDriver ff=new ChromeDriver();
try{
ff.manage().window().maximize();
ReadfrmExcel rd=new ReadfrmExcel();//reading data
String[][] readata=rd.excelRead();
for(int i=1; i<readata.length; i++)
{
ff.get("http://www.facebook.com");
Thread.sleep(1000);
ff.findElementByXPath("//*[#id='email']").sendKeys(readata[i][0]);
ff.findElementByXPath("//*[#id='pass']").sendKeys(readata[i][1]);
ff.findElement(By.id("u_0_v")).click();
System.out.println("Waiting for element to appear");
Thread.sleep(3000);
WebElement element=ff.findElement(By.id("userNavigationLabel"));
element.click();
System.out.println("Clicked drop down");
//ff.findElementByXPath("//*[#id='userNavigationLabel']").click();
System.out.println("sleeping 5 secs");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WebElement cls=ff.findElement(By.xpath("//*[starts-with(#id,'u_') and ends-with(#id, '_5']"));
boolean vis=cls.isDisplayed();
System.out.println(vis);
Thread.sleep(8000);
System.out.println("Sleeping 8 secs");
cls.click();
System.out.println("After clicking");
System.out.println("Successfully logged out!!");
//ff.close();
ff.close();
}
}
catch(Exception e){
System.out.println(e);
}
you can use xpath's starts-with and ends-with methods:
WebElement cls=ff.findElement(By.xpath("//*[starts-with(#id,'u_') and ends-with(#id, '_5')]"));
if this is not working, your browser might only support xpath 1.0 (see this answer for details) -> then you can only use starts-with
WebElement cls=ff.findElement(By.xpath("//*[starts-with(#id,'u_')]"));
if you definitely need to check the end of the id, then you can try the following xpath instead:
//*[starts-with(#id, 'u_') and substring(#id, string-length(#id) - 1) = '_5']
I have tried to get all ids, which i have to use.
First get the tag name in which your id attribute has been defined.
java.util.List links = ff.findElements(By.tagName("span"));
ArrayList arrList = new ArrayList();
for (int i = 0;i < links.size();i++){
if(links.get(i).getAttribute("id").startsWith("u_") &&
links.get(i).getAttribute("id").endsWith("_5")){
arrList.add(links.get(i).getAttribute("id"));
}
}
Now you will find all the ids which are starts with "u_" and ends with"_5".
System.out.println("arrList elements : "+arrList);
Related
I am trying to get all drop downs from a web page and select a value from them in one go.
I have attached a code snippet which gets all the dropdowns which are bootstrapped and under tag on the web page.
I want to access children of each ul tag which are under li tag and click on any of those children.
I am attaching the screen shot taken from web site.
It always says element not interactable eventhough it is clikable element.
Please help.
Application screenshot
Code:
List<WebElement> dropDowns = webDriver.findElements(By.xpath("//ul[contains(#class,'dropdown')]"));
try{Thread.sleep(5000);}catch (Exception e){};
for(WebElement webElement : dropDowns){
try{
List<WebElement> elementList = webElement.findElements(By.xpath("//ul[contains(#class,'dropdown')]//li"));
for (int i = 0 ; i < elementList.size();i++){
elementList.get(i).click();
Thread.sleep(3000);
}
}
catch (Exception e){
System.out.println("-----------Error----------");
continue ;
}
}
try{Thread.sleep(10000);}
catch (Exception e){}
webDriver.quit();
}
I see below issues in your code.
You are trying to use the webElement from dropDowns list which will through stale element exception if you use webElement in the for loop.
Your code will perform the operation on the first operation on the first dropdwn all the times as you are not getting the downdown based on the index.
you mentioned you want to select an item in the list but you are clicking on the each item in the dropdown.
Please try with the below logic.
int dropDowns = webDriver.findElements(By.xpath("//ul[contains(#class,'dropdown')]")).size();
try{Thread.sleep(5000);}catch (Exception e){};
JavascriptExecutor js = (JavascriptExecutor) webDriver;
for(int dropdownIndex =0; dropdownIndex < dropDowns; dropdownIndex++){
WebElement dropdown = webDriver.findElements(By.xpath("//ul[contains(#class,'dropdown')]")).get(dropdownIndex);
try{
List<WebElement> elementList = dropdown.findElements(By.xpath(".//li"));
for (int i = 0 ; i < elementList.size();i++){ // not sure if you really want to click each item in the dropdown, hence not modified this part.
WebElement item = elementList.get(i);
js.executeScript("arugments[0].click()",item);
Thread.sleep(3000);
}
}
catch (Exception e){
System.out.println("-----------Error----------");
continue ;
}
}
Long story short - I have a button that doesn't have ID's and has a compound class( So selenium hates it / cant find it). So I use the XPath selector for it that works great
driver.findElement(By.xpath("//input[#value='Continue to Payment']")).click()
But the button changes depending on the language being used.
So at the moment, I have
if (driver.findElement(By.xpath("//input[#value='Continue to Payment']")).isDisplayed()){
driver.findElement(By.xpath("//input[#value='Continue to Payment']")).click();
}
else if (driver.findElement(By.xpath("//input[#value='Paiement']")).isDisplayed()){
driver.findElement(By.xpath("//input[#value='Paiement']")).click();
}
else if ( same thing as above but for another language)
But when Selenium errors out after going through the first if statement with:
no such element: Unable to locate element:{"method":"xpath","selector":"//a[contains(text(),'Checkout')]"}
I know the element is not there.. so I dont want it to do anything & move on to the next if else statement.
What am I missing here?
try {
if (driver.findElement(By.xpath("//input[#value='Continue to Payment']")).isDisplayed()){
driver.findElement(By.xpath("//input[#value='Continue to Payment']")).click();
}
else if (driver.findElement(By.xpath("//input[#value='Paiement']")).isDisplayed()){
driver.findElement(By.xpath("//input[#value='Paiement']")).click();
}
else
System.out.println("Button not found");
} catch(NoSuchElementException | StaleElementReferenceException e) {
System.out.println("Impossible to click the pop-up. Reason: " + e.toString());
}
Try above solution, Hopefully it will work for you. In your example wrong code has been written for else if (driver.findElement(By.xpath("//input[#value='Paiement']")).isDisplayed).
You can use separate short methods to achieve expected results and log errors.
public WebElement getElement(WebDriver driver, String XPATH, int timeoutInSeconds){
WebElement elem = null;
try{
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
elem = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(XPATH));
} catch (Exception e){
// log or print error.
}
return elem;
}
You can then call it like
WebElement e = getElement(driver, "//input[#value='Continue to Payment']", 10);
if (e != null) {
e.click();
} else {
e = getElement(driver, "//input[#value='Paiement']", 5);
if (e != null) {
e.click();
} /// and so on....
}
This way you can adjust the wait time for each element and also not fall into errors if any one element is missing because of language.
I am scraping fixtures of one website and then using another website to check each team's form. The issue I am having is that not all teams exist on the form website and I am getting a NoSuchElementException for the teams whose xPath clearing doesn't exist on the URL not found page. I am trying to catch the exception but the program still breaks.
I have added a try catch but it doesn't solve my problem, the program breaks as soon as it arrives as a non-found team.
for(int i = 0; i < fixtures.getAwayTeams().size(); i++)
{
driver.navigate().to(FORMURL.concat( (fixtures.getAwayTeams().get(i)).replace( ' ', '+' )));
for (int j = 1; j < 11; j++) {
String xPath = FORMXPATHONE.concat( String.valueOf( j ) ).concat(FORMXPATHTWO);
try {
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xPath)));
forms = driver.findElementsByXPath( xPath );
} catch(NoSuchElementException | StaleElementReferenceException e) {
awayTeamForm.add("No Form for Team");
}
for (WebElement languageElement : forms) {
ArrayList <String> wld = new ArrayList<String>();
wld.add( languageElement.getText() );
String listedForm = String.join(",", wld );
awayTeamForm.add(listedForm);
}
}
}
}
Caused by: org.openqa.selenium.NoSuchElementException: Unable to locate element: //*[#id="results"]/table/tbody/tr[1]/td[6]
You can check that the element is present on the page or not by first fetching the element list and then checking the size of that list, if its greater than 0 then the element is present else the element is not present on the page. By this you don't need to catch the exception as well.
You can do it like:
List<WebElement> elementList = driver.findElements(By.xpath("xPath"));
if(elementList.size()>0){
// Element is present
}
else{
// Element is not present
}
Your try-catch statement looks fine. Which means, the issue has to be somewhere else.
You are using selenium, which means there are two Exceptions called NoSuchElementException available. Check your imports. Most likely the problem you have is, that you do import java.util.NoSuchElementException instead of org.openqa.selenium.NoSuchElementException
Try catch the whole loop body and debug to see if you are catching the right exception and on the right line.
Are you sure that only
forms = driver.findElementsByXPath( xPath );
can raise the exception?
try this :
try {
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xPath)));
forms = driver.findElementsByXPath( xPath );
} catch(NoSuchElementException | StaleElementReferenceException | TimeoutException e) {
awayTeamForm.add("No Form for Team");
}
public void privateCohortCreation() {
if(webElements.newCohortElm.isDisplayed()) {
SeleniumUtils.click(getDriver(),webElements.createCohortSelectionFromMenu);
webElements.cohortname.sendKeys("private_cohort_test");
SeleniumUtils.click(getDriver(),webElements.createCohortButton);
}
else {
doApply();
}
}
I want that if the element is displayed then perform the task else call doApply() method. But this is giving an exception
"no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/app-root/div/app-container/app-indv301/app-global-filters/div/ul/li[3]/app-cohort/div/div/app-status/div"} (Session info: chrome=70.0.3538.77)"
You can use findElements() to check whether the element is on the webpage.
findElements() - returns empty list if there is no element with given locator
findElement() - throws NoSuchElementException if element is not on the page
Try below code:
List<WebElement> elements = driver.findElements(By.locator);
if(!elements.isEmpty()) {
if(elements.get(0).isDisplayed()) {
elements.get(0).click();
}
else {
// element not visible
}
}else{
// here mention code if element not present
}
Recommendation : Use relative xpath instead of absolute xpath. or try CSS selector instead.
Try using try catch instead of if else.
try {
if (webElements.newCohortElm.isDisplayed()) {
doApply();
}
}
catch (Exception e){
SeleniumUtils.click(getDriver(), webElements.createCohortSelectionFromMenu);
webElements.cohortname.sendKeys("private_cohort_test");
SeleniumUtils.click(getDriver(), webElements.createCohortButton);
}
I'm trying to find the size of the page numbers present in a page.
d.get("http://www.moneycontrol.com/stocks/advice/display_more.php");
java.util.List<WebElement> list = d.findElements(By.xpath("//div[#class='gray2_11']/a"));
int u=list.size();
System.out.println(u);
I tried the above code , but it prints the size as "0"
Any suggestions ??
You have to get back the element into visible mode.
Then call the list element. I am adding here the complete code.
driver.get("http://www.moneycontrol.com/stocks/advice/display_more.php");
String scrollElementIntoMiddle = "var viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);"
+ "var elementTop = arguments[0].getBoundingClientRect().top;"
+ "window.scrollBy(0, elementTop-(viewPortHeight/2));";
((JavascriptExecutor) driver).executeScript(scrollElementIntoMiddle, driver.findElement(By.className("nextBtn")));
//((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", ele);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
java.util.List<WebElement> list = driver.findElements(By.xpath("//div[#class='gray2_11']/a"));
int u=list.size();
System.out.println(u);
Only to print the size of the page numbers present in the page you can use the following code block :
d.get("http://www.moneycontrol.com/stocks/advice/display_more.php");
System.out.println(d.findElements(By.xpath("//div[#class='gray2_11']//a")).size());
Console Output :
11
Update :
The reason you are still getting 0 elements is because you haven't upgraded your browser to latest Firefox Quantum version and latest GeckoDriver binary so try adding WebDriverWait as follows :
System.setProperty("webdriver.gecko.driver", "C:\\path\\to\\geckodriver.exe");
WebDriver d = new FirefoxDriver();
d.get("http://www.moneycontrol.com/stocks/advice/display_more.php");
System.out.println(new WebDriverWait(d, 20).until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath("//div[#class='gray2_11']//a"))).size());