Issues in clicking element - java

I am using java selenium for saving web data if any changes made.
Web page contains two buttons 'Confirm' and 'Cancel'. If i made any changes in web page, both 'confirm' and 'cancel' buttons will be visible at the time i can click confirm button by using below code .
WebElement confirm =wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Confirm')]")));
confirm.click();
If there is no changes in web page , Confirm button will get disabled(grayed) at the time i want to click Cancel button Automatically.
I have tried with below code , it is not working. Please help on this.
try
{
WebElement confirm = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Confirm')]")));
confirm.click();
}
catch (ElementNotVisibleException exception)
{
WebElement cancel = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Cancel')]")));
cancel.click();
}

Why do you want to complicate things? Keep it simple.
WebElement confirm = driver.findElement(By.id("<your confirm button id>"));
WebElement cancel= driver.findElement(By.id("<your cancel id>"));
if(confirm.isEnabled())
{
confirm.click();
}
else
{
cancel.click();
}
You may also try with confirm.isDisplayed();

You can try catching the exception when click on 'Confirm' button fails and as part of exception handling you can click on 'Cancel' button in following way:
try {
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Confirm')]")));
driver.findElement(By.xpath("//button[contains(text(), 'Confirm')]")).click();
} catch (Exception we) {
System.out.println("'Confirm' button is not clickable, hence trying to click on 'Cancel' button");
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Cancel')]")));
driver.findElement(By.xpath("//button[contains(text(), 'Cancel')]")).click();
}
UPDATE 1:
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//button[contains(text(), 'Confirm')]")));
WebElement confirmButton = driver.findElement(By.xpath("//button[contains(text(), 'Confirm')]"));
if (confirmButton.isEnabled())
confirmButton.click();
else
driver.findElement(By.xpath("//button[contains(text(), 'Cancel')]")).click();
Let me know, whether it works for you.

Related

How to handle browser notification popup which is without any elements?

How to press the OK button as per the image.
I can switch to this window. but it is not loaded till i click ok, so there is no any elements.
Alert handle does't helped too.
Autoit cannot detect this pop up message too.
disable-notifications cant help too.
Any ideas?
Two screeshots is added.
Firefox snapshot:
Chrome Snapshot:
p.companieGenreal.sActivities().click();
driver.switchTo().defaultContent();
String parent = driver.getWindowHandle();
p.companieGenreal.sAddNew().click();
p.companieGenreal.sAddJobOrder().click();
p.companieGenreal.sContract().click();
swithToChildWindow(parent);
driver.switchTo().alert().accept();
To treat it as an alert try this:
Alert a = driver.switchTo().alert();
a.confirm();
If it can be closed with Escape key, send Escape keypress like this (or ENTER if it closes when Enter is hit):
Actions action = new Actions(driver);
action.sendKeys(Keys.ESCAPE);
beforeunload
The beforeunload event is fired when the window, the document and its resources are about to be unloaded. At this point of time the document is still visible and the event is still cancelable.
Note: Since 25 May 2011, the HTML5 specification states that calls to window.alert(), window.confirm(), and window.prompt() methods may be ignored during this event.
Solution
There are multiple ways to disable this popup as follows:
Firefox: If you are using Firefox as your Browser Client you can use an instance of FirefoxOptions() and set the preference dom.disable_beforeunload to true as follows:
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
FirefoxOptions firefox_option = new FirefoxOptions();
firefox_option.addPreference("dom.disable_beforeunload", true);
WebDriver firefox_driver = new FirefoxDriver(firefox_option);
firefox_driver.get("https://stackoverflow.com/");
Chrome: If you are using Chrome as your Browser Client you can use an instance of ChromeOptions() and add the argument --disable-popup-blocking as follows:
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions chrome_option = new ChromeOptions();
chrome_option.addArguments("--disable-popup-blocking");
chrome_option.addArguments("start-maximized");
chrome_option.addArguments("disable-infobars");
WebDriver chrome_driver = new ChromeDriver(chrome_option);
chrome_driver.get("https://stackoverflow.com/");
try using this :
public static void acceptAlertUsingJs(WebDriver driver) {
((JavascriptExecutor)driver).executeScript("window.alert = function(msg){return true;};");
((JavascriptExecutor)driver).executeScript("window.prompt = function(msg) { return true; }");
((JavascriptExecutor)driver).executeScript("window.confirm = function(msg) { return true; }");
}
Please try the below code and see if it helps:
if (isAlertPresent()){
driver.switchTo().alert().accept();
driver.switchTo().defaultContent();
}
}
public static boolean isAlertPresent() {
try {
driver.switchTo().alert();
Thread.sleep(5000);
return true;
}// try
catch (Exception e) {
return false;
}// catch
}
I have the same kind of issue a modal pop up window opens to which i am able to switch to and click the OK button but cannot fetch the text present in it. The modal dialog is shared in the screenshot and has no html tags hence i cannot locate the text in it using any locator. I tried using driver.switchTo().alert().getText() to fetch the text present in it.
If that is an alert you could handle using below methods:
driver.switchTo().alert().accept();
"Actions class":
Actions builder=new Actions(driver);
builder.sendKeys(keys.ESCAPE);
if the above two methods didn't work then there is a special alert type called "sweet alert" which can be inspected and write code for that.

Click loop until the (button) element found for multiple buttons in java

I want to click the 'Followed' button until it found in the web page.
I've below code:
#Test
public void testCar() throws Exception
{
driver.get("https://-----/login/");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.findElement(By.id("username")).clear();
driver.findElement(By.id("username")).sendKeys("user");
driver.findElement(By.id("password")).clear();
driver.findElement(By.id("password")).sendKeys("password");
driver.findElement(By.xpath("//button[#type='submit']")).click();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.findElement(By.xpath("//span[text()='Followed']")).click();
}
How can I do this? if not found the element then click next page & find the button again.
here is the next button HTML:
<span>Next Page</span>
Please help.
Just put a loop around with try catch
try {
while (true)
{
driver.findElement(By.xpath("//span[text()='Followed']")).click();
}
} catch (ElementNotFoundException ex) {
driver.findElement(By.xpath("//span[text()='Next Page']")).click()
}
If the element is found it will be clicked, if not then a element not found exception will be thrown and that time you can click on the Next page button
Check the condition weather Followed button available or not for that you have to use List to get followed webelements Like :
Boolean buttonNotFound = true;
while(buttonNotFound)
{
List<WebElement> follow = driver.findElements(By.xpath("//span[text()='Followed']"));
if(follow.size()!=0)
{
follow.get(0).click();
buttonNotFound=false;
}
else
{
driver.findElement(By.xpath("//span[text()='Next Page']")).click();
}
}
NOTE : Don't write ImplicitWait again and again, If you have mentioned at one place right below the get() then it is applicable for whole script. If some element require some more time to interact then use ExplicitWait.

How to Take screenshot using Robot Framework in selenium webdriver

I'm working on an automation project in java using selenium. When there is a failure, need to take a screenshot of web view. Used TakesScreenshot and it's working fine both in chrome-driver and in phantomjs-driver.
But this fails when an alert box is present. After some research, I understood that Selenium can't take a screenshot if alert is present. Alert must be handled first. And I can use java.awt.Robot, in such scenario, where the alert box is needed in my screenshot.
But Robot takes screenshot of my screen and won't get the web view, if using phantomjs-driver or if chrome is running minimized. But I need the screenshot with alert box (which represents the failure condition).
Is there any other solution for this issue?
If you really want to capture the screen with alert then there is a way. Put your code portion for taking screenshot inside a try-catch block. If any alert found, it will throw an exception and in the catch block handle it.
Code snippet:
Alert alert = null;
try {
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("screenshot.png"));
} catch (Exception e) {
alert = driver.switchTo().alert();
if(e.getMessage().contains("unexpected alert open:")){
//before taking screenshot, you may wait for some moment to be properly visible
try {
BufferedImage screencapture = new Robot().createScreenCapture((new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())));
File file = new File("screenshot.jpg");
ImageIO.write(screencapture, "png", file);
} catch (AWTException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
alert.accept(); //or you can use dismiss();
Note: For taking screenshot using robot your window must be visible.

Handle firefox security warning in selenium web driver

Security warning observed on Firefox:
The information you have entered on this page will be sent over an insecure connection and could be read by a third party.
Are you sure you want to send this information?
Click Continue or cancel
To click on continue I have tried using Robot class method
Robot robot =new Robot();
robot.keyPress(KeyEvent.VK_LEFT);
robot.keyPress(KeyEvent.VK_ENTER);
System.out.println("key pressed");
robot.keyRelease(KeyEvent.VK_ENTER);
But I get UnhandledAlertException: Unexpected modal dialog (text: The information you have entered on this page will be sent over an insecure connection and could be read by a third party.
Are you sure you want to send this information?): The information you have entered on this page will be sent over an insecure connection and could be read by a third party.
Are you sure you want to send this information?
I also tried manually clicking on continue , then continue with selenium script
1 Manually close
2 WebElement success = wait.until(ExpectedConditions
.visibilityOfElementLocated(By.cssSelector(".error-msg")));
Then i get WebDriver exception that ".error-msg" is not a Web Element
Following worked for me in Java
private void acceptSecurityAlert() {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS)
.pollingEvery(3, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
Alert alert = wait.until(new Function<WebDriver, Alert>() {
public Alert apply(WebDriver driver) {
try {
return driver.switchTo().alert();
} catch(NoAlertPresentException e) {
return null;
}
}
});
alert.accept();
}

How to restrict a user to login in only one tab/window using java and javascript?

My requirement is to give access like one login per user, For that I have updated the login Status to true in db when user login, and false when user logout.
But the problem is when user close the window without logout.
To handle window close I have implemented the following js code
var validNavigation = false;
function wireUpEvents() {
var dont_confirm_leave = 0;
var leave_message = 'You sure you want to leave?'
function goodbye(e) {
if (!validNavigation) {
if (dont_confirm_leave!==1) {
if(!e) e = window.event;
//e.cancelBubble is supported by IE - this will kill the bubbling process.
e.cancelBubble = true;
e.returnValue = leave_message;
//e.stopPropagation works in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
//return works for Chrome and Safari
return leave_message;
}
window.location = "logout.jsp";
}
}
window.onbeforeunload=goodbye;
// Attach the event keypress to exclude the F5 refresh
$(document).bind('keypress', function(e) {
if (e.keyCode == 116){
validNavigation = true;
}
});
// Attach the event click for all links in the page
$("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function() {
validNavigation = true;
});
// Attach the event click for all inputs in the page
$("input[type=submit]").bind("click", function() {
validNavigation = true;
});
// Attach the event click for all inputs in the page
$("input[type='button']").bind("click", function() {
validNavigation = true;
});
}
// Wire up the events as soon as the DOM tree is ready
$(document).ready(function() {
wireUpEvents();
});
Here it works for window close, means if user close the window it goes to logout page, but problem is it was going to logout page when user reloads the page.
So I need bind the reload event also like the above js code for f5, submit and anchor tags.
Pleae help me in this regard.
Thanks in Advance...
Two things came into my mind:
First of all the fact that the user is logged in, doesnt mean that theres any activity going on, some people leave there pc turned on with the browser running.
Second is that even if the user closes a page it doesnt necesserly means that he/she wanted to logout and its especially true if the user use two tab to navigate on your site.
So instead of trying to check when they close the tab I suggest considering the idea of logging them out only when they login from somewhere else and/or setting up a timer that automatically log them out after a certain amount of inactivity.

Categories