Selenium cannot click menu-item from bootstrap dropdown - selenium

Actions action = new Actions(driver);
WebElement we = driver.findElement(By.xpath("//*[#id='ctl00_Sitemap1_HyperLink1']"));
action.moveToElement(we).build().perform();
WebElement tmpElement= driver.findElement(By.xpath("//*[#id='ctl00_Sitemap1_HyperLink1']"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", tmpElement);
List<WebElement> dd_list = driver.findElementsByXPath("//*[#id='masterNavigation']/ul/li[1]/ul/li");
for (WebElement ele : dd_list)
{
System.out.println("Values " + ele.getAttribute("innerHTML"));
if (ele.getAttribute("innerHTML").contains("Event Dashboard")) {
ele.click();
break;
}
}
}
Hi I am trying to Automate bootstrap drop-down menu. It's visibility is hidden by default.Once you hover mouse on it, its visibility property shows visible.I am able to click on drop-down , but after clicking on drop-down my selenium script is not selecting value from drop-down.
Error: Exception in thread "main"
org.openqa.selenium.ElementNotVisibleException: Cannot click on
element
HTML Code Snippet
<a class="ui-button-text-icons" id="ctl00_Sitemap1_HyperLink1" href="javascript:void(void);">
<span style="padding-right: 1.3em;">Dashboards</span>
<span class="ui-button-icon-secondary ui-icon ui-icon-triangle-1-s"></span>
</a>
<ul style="visibility: hidden;">
<li class="first featureGranted">
Classic Dashboard
</li>
</ul>

Few things
You don't need to traverse though all li elements to find your desire element you can do it with Xpath
I have no Idea why you are using JavaScript to click first Element, but unless click method provided by Selenium is not working I would suggest not to use JavaScript Click
Error suggests that element is not visible, it could be due to multiple reasons. You could wait using Explicit wait until element is visible as mentioned below. it might resolve your issue
Code
Actions action = new Actions(driver);
WebElement we = driver.findElement(By.xpath("//*[#id='ctl00_Sitemap1_HyperLink1']"));
action.moveToElement(we).build().perform();
WebElement tmpElement= driver.findElement(By.xpath("//*[#id='ctl00_Sitemap1_HyperLink1']"));
JavascriptExecutor js = (JavascriptExecutor) driver;
// I have no idea why you are clicking using JavaScript
js.executeScript("arguments[0].click();", tmpElement);
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement eventDashboardMenu = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//li[contains(text(),'Event Dashboard')]")));
eventDashboardMenu.click();

Related

msg no such element: Unable to locate element:

HTML:
"Add to cart" object
<button class="button spin-button prod-ProductCTA--primary button--primary" data-automation-id="button" data-tl-id="ProductPrimaryCTA-cta_add_to_cart_button" type="button"><span class="button-wrapper"><span class="spin-button-children">Add to cart</span></span></button>
"Get in stock alert" object
<button class="button spin-button prod-ProductCTA--primary button--primary" data-automation-id="button" data-tl-id="cta_oos_button" aria-expanded="false" aria-label="get in stock alert" role="button" tabindex="0" type="button"><span class="button-wrapper"><span class="spin-button-children">Get in-stock alert</span></span></button>
I do not want to click "Add to cart". I just want to store locator info in WebElement "addToCart". Because objects have very identical properties, I chose this unique property "data-tl-id" but did not work.
Web Driver
WebElement addToCart = driver.findElement(By.xpath("//button[#data-tl-id='ProductPrimaryCTA-cta_add_to_cart_button']"));
Below worked for me but both above objects have the same class name so i cant use the class name.
WebElement addToCart = driver.findElement(By.xpath("//span[#class='button-wrapper']"));
I also tried below ways but none worked for me.
WebElement addToCart = driver.findElement(By.xpath("//span[text()='Add to cart'"));
WebElement addToCart = driver.findElement(By.xpath("//span[contains(#text,'Add to cart')]"));
I get error "No such element: Unable to locate element: ". How to locate the "Add to cart" object?
Your xpath is wrong WebElement addToCart = driver.findElement(By.xpath("//span[text()='Add to cart'"));
Try below solution
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement webElement = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[text()='Add to cart']")));
System.out.println("Printing "+webElement.getText());
Or you can also try xpath with contains
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement webElement = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[contains(text(),'Add to cart')]")));
System.out.println("Printing "+webElement.getText());
since this xpath worked for you,
WebElement addToCart = driver.findElement(By.xpath("//span[#class='button-wrapper']"));
Use this to uniquely identify WebElement
driver.findElement(By.xpath("//button[contains(#data-tl-id,'cart')]/span[#class='button-wrapper']"))
you can also use this xpath
//span[contains(text(),'Add to cart')]

Selenium webdriver wait doesn't seem to work in case of overlay

There is an overlay ( a grey color translucent screen ) that comes up when ever one clicks Login button and it stays for few seconds. Because of this, selenium web driver isn't able to find the elements as this overlay kinds of hides them for a while or at least that is what looks to me. How can I handle this? I don't find Thread.sleep to be an efficient way here.
I tried -
public void login(){
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.invisibilityOfElementLocated((By.id("ajax-overlay"))));
wait.until(ExpectedConditions.elementToBeClickable((By.id("okbutton))));
driver.findElement(By.id("username)).sendKeys("admin");
driver.findElement(By.id("password")).sendKeys("admin123");
driver.findElement(By.id("okbutton")).click();
wait.until(ExpectedConditions.invisibilityOfElementLocated((By.id("ajax-overlay"))));
}
but nothing seems to work and I still get error -
org.openqa.selenium.WebDriverException: unknown error: Element <button id="loginDialog:okButton" name="loginDialog:okButton" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only ui-panel-titlebar-icon synchronous" onclick="PrimeFaces.ab({source:'loginDialog:okButton',process:'loginDialog:okButton loginDialog:username loginDialog:password loginDialog:okButton',update:'startingCashFocus loginDialog:dialogFocus loginDialog:lblPassword loginDialog:lblUsername loginDialog:messages',oncomplete:function(xhr,status,args){handleLoginAttempt(xhr, status, args, loginWidget, null); ;}});return false;" tabindex="1" type="submit" role="button" aria-disabled="false">...</button> is not clickable at point (931, 250). Other element would receive the click: <div id="ajax-overlay" class="ui-blockui ui-widget-overlay ui-helper-hidden eternal" style="display: block;"></div>
Also, there is no way to find out the overlay id and thankfully, selenium gave it in its error details.
Try to click element with one of the following method, which will solve this Exception :
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.id('okbutton'))).click().perform();
OR
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", driver.findElement(By.id('okbutton')));

NoSuchElementException: no such element: Unable to locate element:while identifying draggable and droppable element

I am actually new to selenium. I am trying to do drag and drop operation on a demo website : http://jqueryui.com/droppable/ (Here go to demo-->Droppable).
Following is my html source :
<div id="draggable" class="ui-widget-content ui-draggable ui-draggable-handle" style="position: relative;">
<p>Drag me to my target</p>
</div>
Following is my code block :
WebElement drag=dr.findElement(By.xpath("//*[#id='draggable']"));
wait.until(ExpectedConditions.elementToBeClickable(drag));
WebElement drop=dr.findElement(By.xpath("//*[#id='droppable']"));
wait.until(ExpectedConditions.elementToBeClickable(drop));
//act.moveToElement(drop).build().perform();
act.dragAndDrop(drag, drop).build().perform();
The element to drag and the element to drop are within an <iframe>. So you have to switch to the intended frame first then locate the draggable and droppable elements and perform dragAndDrop() as follows :
Here is the complete code snippet :
System.setProperty("webdriver.gecko.driver", "C:\\path\\to\\geckodriver.exe");
WebDriver driver=new FirefoxDriver();
driver.get("http://jqueryui.com/droppable/");
driver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);
driver.switchTo().frame(driver.findElement(By.xpath("//iframe[#class='demo-frame']")));
WebElement from = driver.findElement(By.id("draggable"));
WebElement to = driver.findElement(By.id("droppable"));
new Actions(driver).dragAndDrop(from, to).build().perform();
System.out.println("Drag and Drop Completed");
driver.quit();
The problem is that the drag & drop elements are located within an iframe. You need to switch to the iframe with class='demo-frame'
Once you switch to the iframe, you can then locate and interact with your element.

NoSuchElementException: Unable to locate element uisng selenium web-driver

Here i am trying to click a button using css selector find method.But its unable to locate the element. So i tried giving the time also but still its unable to click the element
Code sample -->
WebDriverWait waitr = new WebDriverWait(driver, 10);
WebElement element = waitr.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#userTable > tbody > tr:nth-child(3) > td.sorting_1 > div > a")));
element.click();
My HTML body Looks as follows
<a data-toggle="dropdown" class="mainAnchor" aria-expanded="false">CA05
<span class="caret" style="margin-left:5px;"><span> </span></span></a>
If i use Thread.sleep(1000); instead of wait it works fine but i don't want to use Thread.sleep.Please help me to solve this issue
To click on the element with text as CA05 you can use the following line of code :
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.cssSelector("a.mainAnchor[data-toggle=dropdown]"))).click();
Hi you can use a fluentwait like the following below.
static Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(elementWaitTime, SECONDS)
.pollingEvery(2,SECONDS)
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver aDriver) {
driver= aDriver;
element.click();
return aDriver.findElement(cssSelector("#userTab a.mainAnchor"));
}
});

I would like to click on New Contact button from web page for my selenium script

I would like to click on a "New Contact" button for my selenium script. I have tried:
driver.findElement(By.id("btn-group.contact_list-menu-contact_add")).click();
And by xpath as well, but it is not working. How could I get this working?
<div class="btn-group left">
<a id="contact_list-menu-contact_add" class="Button btn-contactadd primary SaveItem" href="javascript:">New Contact</a>
</div>
You are searching by an incorrect id value, use contact_list-menu-contact_add instead:
driver.findElement(By.id("contact_list-menu-contact_add")).click();
Or, by a CSS selector:
driver.findElement(By.cssSelector(".btn-group .btn-contactadd")).click();
driver.findElement(By.cssSelector(".btn-group #contact_list-menu-contact_add")).click();
driver.findElement(By.cssSelector("#contact_list-menu-contact_add")).click();
Or, by a link text:
driver.findElement(By.linkText("New Contact")).click();
If the target element is inside an iframe, you would need to switch into the context of the frame before searching for the element. Assuming that your frame has contactURL id, this is how to switch to it:
driver.switchTo().frame("contactURL");
If you are getting NoSuchElementException as you have mentioned in the comment, There are may be two reason :-
May be when you are going to find element, it would not be present on the DOM, So you should implement WebDriverWait to wait until element visible and clickable as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement el = wait.until(ExpectedConditions.elementToBeClickable(By.id("contact_list-menu-contact_add")));
el.click();
May be this element is inside any frame or iframe. If it is, you need to switch that frame or iframe before finding the element as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("contactURL"));
WebElement el = wait.until(ExpectedConditions.elementToBeClickable(By.id("contact_list-menu-contact_add")));
el.click();
Edited :- As I see from your provided HTML this button is inside <div id="btn-new-group" class="btn-group-actions left" style="display: none;"> which is set to be invisible, that's why you are not able to find button. You should make it visible first then try to find as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("contactURL"));
WebElement invisibleDiv = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("btn-new-group")));
//Now make it visible first
((JavascriptExecutor)driver).executeScript("arguments[0].style.display = 'block';", invisibleDiv);
//Now find contact button
WebElement el = wait.until(ExpectedConditions.elementToBeClickable(By.id("contact_list-menu-contact_add")));
el.click();
Hope it helps...:)