Webdriver does not select a drop down lsi items - java

I got an error org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with. How can i solve it?

It could mean that your element visibility is set to hidden. Or it could also mean that the element is not currently in view and have to be scrolled into view.

If it's not visible while the WebDriver is looking to interact with the drop down then:
1st-) You should increase the implicit wait time, until any controller appears in the UI:
public Accesor(WebDriver driver,String url){
this.driver = driver;
this.driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.get(url);
}
2nd-)Try waiting until that specific element appears (but i wouldnt recommend that):
WebElement cBoxOverlay = wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("cboxOverlay"))));
3rd-) If it's a real bug of the application and the UI does not show the dropdown you are looking for that is suppose to be there then try handling those kind of exceptions by taking a screenshot of the screen and trying with the next testcase or testsuite:
public void takePicture(){
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
try {
FileUtils.copyFile(scrFile, new File("c:\\tmp\\"+ getClass().getName().substring("com.automation.testsuite.".lastIndexOf(".")+1) + ""+new Date().toString().substring(0,10) +".png"));
} catch (IOException e) {
e.printStackTrace();
}

Related

Stale Element Reference appears when navigating back to a page, how to write a neat code

I am automating in Java Selenium, without using Page Factory.
I have an Add Candidate Button element that is clicked in two tests. One is straightforward, after entering InviteToCompany page I click this button and proceed. However, another requires me to go past InviteToCompany page, but then use Go Back Arrow to go back to 'InviteToCompany' page and click Add Candidate Button again. This is when StaleElementReferenceException appears.
I have written such a piece of code to deal with this issue, however I am wondering, if there is a cleaner and neater way, than catching exception for second test, to proceed.
public InviteToCompanyPO clickAddCandidateBtn() {
try {
getClickableElement(addCandidateBtn).click();
} catch (StaleElementReferenceException e) {
log.warn("StaleElementReferenceException caught, retrying...", e);
getClickableElement(addCandidateBtn).click();
}
return new InviteToCompanyPO(driver);
}
Before I had to write second test (the one causing staleness), this method simply looked like this:
public InviteToCompanyPO clickAddCandidateBtn() {
getClickableElement(addCandidateBtn).click();
return new InviteToCompanyPO(driver);
}
I tried writing something like this:
public InviteToCompanyPO clickAddCandidateBtn() {
wait
.ignoring(StaleElementReferenceException.class)
.until(ExpectedConditions.elementToBeClickable(addCandidateBtn))
.click();
return new InviteToCompanyPO(driver);
}
but it doesn't work.
I guess you are using a page factory?
Anyway, when you back to the InviteToCompany page and need to click Add Candidate Button again you will need to get that element again.
I mean to pass the locator or By of that element and get the WebElement object again with driver.findElement() method.
This causes by the fact that WebElement is actually a reference (pointer) to the actual Web Element on the page. And when you navigating from the page to other page the references to the objects on the previous page becoming invalid, Stale. When you open the previous page again it is rendered again, so you need to get the references (pointers) to elements on that page again.
Cleaner way You can use a Webdriver wait Like this to click
public void refreshedClick(By by){
new WebDriverWait(driver, timeout)
.ignoring(StaleElementReferenceException.class)
.until(new Predicate<WebDriver>() {
#Override
public boolean apply(#Nullable WebDriver driver) {
driver.findElement(by).click();
return true;
}
});
}
Java 8
public void refreshedClick(By by){
new WebDriverWait(driver, timeout)
.ignoring(StaleElementReferenceException.class)
.until((WebDriver d) -> {
d.findElement(by).click();
return true;
});
}

Alternative to thread.sleep() - amazon selenium webdriver add to cart ignore insurance dialog

I am trying to avoid using Thread.sleep() but without it, No Thanks button on insurance dialog doesn't get clicked
Steps:
Search product on amazon.com
Click on product title
On product details click on add to cart
Click on No thanks button on buy insurance dialog
Item gets added to cart.
I have tried following to replace thread.sleep();
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);
wait.until(ExpectedConditions.elementToBeClickable(By.id("add-to-cart-button"))).click();
try {
Thread.sleep(2000);
if (insurancePopUpDialog.isDisplayed()) {
wait.until(ExpectedConditions.elementToBeClickable(insuranceNoThanksButton));
new Actions(driver).moveToElement(insuranceNoThanksButton).click().build().perform();
wait.until(ExpectedConditions.or(
ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id=\"huc-v2-order-row-items-msg\"]")),
ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id=\"huc-v2-order-row-confirm-text\"]")),
ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id=\"attachDisplayAddBaseAlert\"]/div/h4"))
));
}
} catch (Exception e) {
e.printStackTrace();
}
Tried implicit wait
Avoid passing pre-declared WebElement to ExpectedConditions function as it should be readily available for WebDriver on browser. Try below inside if condition:-
wait.until(ExpectedConditions.elementToBeClickable(By.xpath(<xpath for weblement insuranceNoThanksButton >)));
Later, you can declare WebElement insuranceNoThanksButton for further operations.
If above doesn't work, try with javascript click:-
((JavascriptExecutor)driver).executeScript("arguments[0].click();", insuranceNoThanksButton);

Why isn't my click event not working in Selenium?

When clickevent is fired, I want it to redirect/open new page in same tab. The new tab would be '/Waiting', however even after click event is fired, it stays in the same page. While doing manually by going to browser's localhost, it works though. Also, even after 10 secs, it doesn't load.
#Test
public void firstPlayerConnection() {
try {
driver.get(uiPath);
WebElement startGame = driver.findElement(By.id("startGame"));
startGame.click();
WebElement gif = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("loading")));
assertEquals("/Waiting", driver.getCurrentUrl());
} finally {
driver.quit();
}
}
Provide wait explicitly, & if it still does not work then try to use submit() in place of click().
If I'm not mistaken the NoSuchElement exception must be on the startGame.Click() command. To avoid this exception you have to (explicit) wait till this element is clickable.
WebElement startGame = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.elementToBeClickable(By.id("startGame")));

Customwait - Check element is visible/disappear with selenium webdriver (element is in the DOM, but not visible)

I would like to implement a custom wait method which should wait till a loading popup is visible.
This loading popup has its own id = "wait". I use this custom expectedConditions (from Stackoverflow) to check it:
public static ExpectedCondition<Boolean> absenceOfElementLocated(
final WebElement element) {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
try {
element.isDisplayed();
return false;
} catch (NoSuchElementException e) {
return true;
} catch (StaleElementReferenceException e) {
return true;
}
}
#Override
public String toString() {
return "element to not being present: " + element.getText();
}
};
}
My script pass on when the loading still visible and I do not know why.
Thanks!
Use ExpectedConditions#invisibilityOfElementLocated(By locator)
You can also use negation -> ExpectedConditions#not(ExpectedCondition condition)
A basic example:
Go to this page: Primefaces - dropdown
There is Submit button on this page, if you click on this button, then Selected message will appear on the screen, then this message will dissapear after a few seconds.
So we will wait in our code for the following events:
the button appears and is clickeable (it cannot be clicked until it is not clickeable)
the message appears and is visible
the message disappears an is not visible
WebDriver driver = new ChromeDriver();
try {
driver.get("https://www.primefaces.org/showcase/ui/ajax/dropdown.xhtml");
final By buttonSubmit = By.xpath("//button[ *[ text() = 'Submit' ]]");
final By message = By.xpath("//span[ text() = 'Selected' ]");
WebDriverWait wait = new WebDriverWait(driver, 50);
long time = System.currentTimeMillis();
wait.until(ExpectedConditions.elementToBeClickable(buttonSubmit)).click();
System.out.println(String.format("Button clicked after %d miliseconds", System.currentTimeMillis() - time));
wait.until(ExpectedConditions.visibilityOfElementLocated(message));
System.out.println(String.format("The message appeared after %d miliseconds", System.currentTimeMillis() - time));
// wait.until(ExpectedConditions.invisibilityOfElementLocated(message));
wait.until(ExpectedConditions.not(ExpectedConditions.visibilityOfElementLocated(message)));
System.out.println(String.format("The message dissapeared after %d miliseconds", System.currentTimeMillis() - time));
} finally {
driver.quit();
}
And a result is:
Starting ChromeDriver 2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f) on port 15827
.....
.....
.....
Button clicked after 153 miliseconds
The message appeared after 791 miliseconds
The message dissapeared after 6924 miliseconds
It's hard to tell why your code isn't working without more of the code. You do have some logic errors in your custom wait but you don't need that custom wait because ExpectedConditions already has visibility and invisibility covered.
Use this to wait for the popup to appear
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.id("wait")));
Use this to wait for the popup to disappear
new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.id("wait")));
There are times when a popup is just a container for dynamically loaded content. In these cases, you might wait for the frame of the popup to appear but the contents of the frame are not quite loaded yet so if you try to interact with them, you will get errors. In those cases you will need to wait for an element inside the container to be visible.
Same thing for when a dialog is closing. I've had experiences where I've waited for the dialog container to close but the grey overlay is still up blocking clicks, etc. In those cases I had to wait for the overlay to become invisible.
I would suggest that you spend some time familiarizing yourself with the available methods of ExpectedConditions and save yourself having to write custom waits for things that already exist and don't need to be debugged/tested.

Close random 'PopUps'

I have created WebDriver tests which run for the same duration.
Some of the tests lest say ‘PopupX’ will appear at 30 seconds.
On some of the test ‘PopupX’ will appear at 60 Seconds
On some of the test ‘PopupX’ will appear at 35 Seconds
You understand the id.
The popup always has a unique Id being the ‘X’ to close the application and even different popups have the same ‘X’ close option.
Does anyone know of a way to constantly search and close ‘A form of continuous polling’ which will close the popup if it was to appear at anytime in any of the test cases?
I know the following method listed below works and can successfully close the popup:
public void closeGiveawayPopup() throws InterruptedException {
WebDriverWait wait = new WebDriverWait(driver, 10);
try {
List<WebElement> elements = wait
.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector(".close")));
for (WebElement element : elements) {
if (element.isDisplayed()) {
element.click();
Thread.sleep(1000);
wait.until(ExpectedConditions.invisibilityOfAllElements(elements));
Thread.sleep(2000);
}
}
} catch (Exception e) {
throw (e);
}
I have tried to add the following method below in the TestNG 'BeforeMethod' annotation but the url dosnt even load:
public void closeGiveawayPopup() throws Exception {
try {
List<WebElement> elements = getDriver().findElements(By.cssSelector(".close"));
for (WebElement element : elements) {
if (element.isDisplayed()) {
element.click();
}
}
} catch (Exception e) {
throw (e);
}
}
Details of the popup have been listed below:
I don't think you are doing anything wrong Phil. #BeforeMethod annotation is the way to go. The only thing that needs improving is to include (if you don't have it already) a #BeforeClass annotation for your browser startup/shutdown respectively. Perhaps, this is why 'the browser does not even open' as you mention in your description above. So something like this:
#BeforeClass
public void initialSetup(String browser){
Webdriver driver = new browser ();
driver.get("https://www.buyagift.co.uk/");
}
#BeforeMethod
public void closeGiveAwayPopup(){
//same as your code
}
#Test(priority=1)
public void makeSureIarrivedOnTheHomePage(){
titleGrabbed = driver.getTitle().toString();
titleExpected = "Experience Days and Gifts from Buyagift";
Assert.assertEquals(titleGrabbed ,titleExpected )
}
#Test(priority=2)
public void clickLoginButton(){
//more actions
}
#AfterClass
public void shutDown(){
driver.quit();
}
The only way I can think of in order to have this 'continuous polling' effect that you are after is to make your #Test really really small (1 step at a time). This way hopefully you can achieve the desired effect. So don't bundle a lot of WebDriver actions under 1 #Test as you are increasing the risk of a pop-up appearing in the meantime.
The only thing that puzzles me is your comment 'the url does not even load'. Are you sure you are grabbing the actual pop-up and not closing the whole window?
If that is the case, or if the above does not work for you, try using Xpath instead of CSS. From your screenshot you need to expand both div[#id='competition_inner_ and outer details'] and find the close button somewhere (probably you are looking for an < input >, < i > or < button > tag, then I will be able to help you more and give you the full Xpath so you can try for yourself.
So something like this:
driver.findElement(By.xpath("//div[#id='competiton_giveaway_popup']//button[#id='close']"));
PS. Another thing that came to mind, double check that you are using actual Testng annotations instead of Junit as it is easy to get confused and misclick sometimes when importing from IDE (I'm looking at you Eclipse!). So you can delete the #BeforeMethod annotation and write it again making sure it points to Testng.
PS2. On your step#9 you have missed the
WebDriverWait wait = new WebDriverWait(driver, 10);
line. I hope this is not the one giving you trouble, please double check and let me know.
Best of luck!

Categories