How to Take screenshot using Robot Framework in selenium webdriver - java

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.

Related

Create Java Desktop Notification

The requirement is to create a desktop notification which can register a click-event. I cannot use web-sockets or any browser notifications.
I am unable to use Tray-Icons and SystemTray because they cannot register Click-Events on DISPLAY MESSAGE. They can have click-events on the trayicon but not on the display message. The closest example - "When we register a click on a Skype message, it opens Skype for us"
Screenshot
On clicking the above Notification Skype chat opens-up. The same functionality is not supported with Tray-Icons. Either a work around it or a new approach will be do.
Hope I am clear thanks.
I used the following repository from github DorkBox.
Simply add maven dependency as instructed on the github link. However, I was unable to check how to change the UI for the notifications.
Notify.create()
.title(text)
.text(title)
.position(Pos.TOP_RIGHT)
.onAction( new ActionHandler<Notify>() {
#Override
public void handle(Notify value) {
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(new URI(targetUrl));
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
})
.hideAfter(5000)
.shake(250, 5)
.darkStyle() // There are two default themes darkStyle() and default.
.showConfirm(); // You can use warnings and error as well.
Add the following code in your main block and you are good to go.

Opening a PDF in a javafx aplication

I'm developing a javafx application that opens a PDF when I pres a button. I'm using the xdg-open command in linux like this:
String[] command = {"xdg-open",path}
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
but when i pres the button nothing happens.
I tested it in a different project and it opened the PDF without problem.
Any idea how can i fix this?
Here's the method that I use. A simple call to the Desktop.getDesktop().open() method will open any given File using the system's default application.
This will also open the file in a background Thread so your application doesn't hang while waiting for the file to load.
public static void openFile(File file) throws Exception {
if (Desktop.isDesktopSupported()) {
new Thread(() -> {
try {
Desktop.getDesktop().open(file);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
This code show the document in the default browser :
File file = new File("C:/filePath/Test.pdf");
HostServices hostServices = getHostServices();
hostServices.showDocument(file.getAbsolutePath());
I hope this help!!
I have used ICEpdf's org.icepdf.core.pobjects.Document to render the pages of my PDF's; as described here. This gives a ava.awt.image.BufferedImageper page. I convert this to a JavaFX node:
Image fxImage = SwingFXUtils.toFXImage(bufferedImage, null);
ImageView imageView = new ImageView(fxImage);
From there you can write your own simple paging viewer in JavaFX. The rendering is fast and the result looks as hoped for.

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.

Android - Unhandled java.net.MalformedURLException

I'm getting a MalformedURLException some code in my Android Studio project. My aim is to get and display an image from a web page, and the URL seems to be fine, but it's giving me this error.
I have already put the code in a try,catch, but that is still giving me the error.
Here is the code to grab the image and display it:
try
{
url = new URL(items.get(position).getLink());
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
}
catch (IOException e)
{
throw new RuntimeException("Url Exception" + e);
}
holder.itemTitle.setText(items.get(position).getTitle());;
holder.itemHolder.setBackgroundDrawable(new BitmapDrawable(bmp));
items.get(position).getLink() is meant to get the link that is being displayed in a ListView, but even something like URL url = new URL("https://www.google.com") doesn't work.
Thanks.
your url is formatted without the protocol at the beginning try
url = new URL("http://"+items.get(position).getLink());
sometimes the url string may have special characters, in which case you need to encode it properly please see this.
And also, the url you posted in the comment is not an image.
it is exception beacuse of url class
add antoher catch like
catch (MalformedURLException e) {
e.printStackTrace();
}
Just click alt+enter and then import try catch section... this helped me...

Setting focus on login via Selenium Webdriver for Robot to work

I'm testing an internal website that can only be accessed via internet explorer that uses windows authentication to validate a users credentials and have to test multiple accounts, so I need to be able to "log in" to the website as different people (I previously contemplated having several machines each logged in as the relevant accounts but cant do this).
If I go to the page as my webdriver account I get a standard internet explorer "Windows Security" popup where I can enter my login details without a problem. Only issue so far is webdriver doesn't recognise the popup.
I thought I could use the Java Robot class to do this and have ripped off some code I found to plug into my Selenium webdriver scripts and it almost works, trouble is it only works if I manually click on the login window presented for it to copy and paste the details (see code below). Any suggestions as to how I can use Selenium or robot to set focus on this object before copying and pasting?
public Boolean loginDetails(individualThreadSession threadSesh){
Action myAction = new Action();
final String USERNAME= "loginID";
final String PASSWORD= "myPassword";
myAction.simpleWait(1);
Robot robot = null;
try {
robot = new Robot();
} catch (AWTException e) {e.printStackTrace();}
type(robot, USERNAME);
myAction.simpleWait(1);
robot.keyPress(KeyEvent.VK_TAB);
myAction.simpleWait(1);
robot.keyRelease(KeyEvent.VK_TAB);
myAction.simpleWait(1);
type(robot, PASSWORD);
myAction.simpleWait(1);
robot.keyPress(KeyEvent.VK_ENTER);
myAction.simpleWait(1);
robot.keyRelease(KeyEvent.VK_ENTER);
myAction.simpleWait(1);
return(true);
}
public static void type(Robot robot, String characters) {
Action myAction = new Action();
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection stringSelection = new StringSelection( characters );
clipboard.setContents(stringSelection, null);
robot.keyPress(KeyEvent.VK_CONTROL);
myAction.simpleWait(1);
robot.keyPress(KeyEvent.VK_V);
myAction.simpleWait(1);
robot.keyRelease(KeyEvent.VK_V);
myAction.simpleWait(1);
robot.keyRelease(KeyEvent.VK_CONTROL);
myAction.simpleWait(1);
}
I've also tried just entering the individual key strokes instead of copy and pasting the information but that does work either, I need to give the screen focus before it'll work... :S
Also tried this but still doesn't set focus on the Windows Security dialog...
Alert aa = threadSesh.driver.switchTo().alert();
aa.sendKeys(USERNAME);
That is because the focus is not present on the authentication window. You cannot try ALT+TAB with Robot as it is not a seperate window. For your scenario i think "AutoIT" can be appropriate solution. If you want to go ahead with AutoIT, let me know i can send some sample code.
import java.io.Serializable;
import com.sun.jna.WString;
public interface AutoITX extends com.sun.jna.Library, Serializable {
public static int AU3_INTDEFAULT = -2147483647;
public int AU3_WinWaitActive(WString szTitle, WString szText, int nTimeout);
}
Create an object for AutoITX say objAutoIT. Call the WinWaitActivate() with below parameters.
Replace windowTitle, windowText(can be empty), waitTime as per your requirement.
objAutoIT.AU3_WinWaitActive(WString(windowTitle), WString(windowText), waitTimeInSecs);
I've managed to create a standalone exe using autoit (the software to write and compile could be better I must say but its free so I can't complain) with the following code: -
Func _WinWaitActivate($title,$text,$timeout=100)
WinWait($title,$text,$timeout)
If Not WinActive($title,$text) Then WinActivate($title,$text)
WinWaitActive($title,$text,$timeout)
EndFunc
_WinWaitActivate("Windows Security","")
Send("myloginID{TAB}mypassword{ENTER}")
I then call that within my code with the following once I've navigated to the page that brings up the popup: -
try {
Runtime.getRuntime().exec("C:\\test\\test.exe");
} catch (IOException e) {
e.printStackTrace();
}
And hey presto! The minute that login appears it enters the login details... I suppose it'l have to do for now! :)

Categories