Selenium WebDriver : Verify Print Window dialog displayed on the page - java

I have a scenario to verify Print Properties dialog (Windows component) opening up correctly after clicking on Print link. Aware of Robot utility class in Java which can emulate keyboard events like Escape/Enter etc. to operate on that window.
Is there any way we can verify the new dialog opened up is a Print dialog - something to verify dialog title i.e. Print or retrieve text from that windows dialog or something else which will confirm dialog to be a Print dialog.

The print dialog comes from the os, which selenium can't handle (yet). Therefore you won't be able to check for existence. The only way to I can think of is using a java.awt.Robot, send VK_ESCAPE and assert that the test continues.
As a starter you could try out this:
Runnable r = new Runnable() {
#Override
public void run() {
try {
Robot r = new Robot();
r.delay(1000);
r.keyPress(KeyEvent.VK_ESCAPE);
r.keyRelease(KeyEvent.VK_ESCAPE);
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
Actions actions = new Actions(getDriver());
actions.sendKeys(Keys.CONTROL).sendKeys("p");
Thread t = new Thread(r);
t.start();
actions.perform();
//some stupid asserts that we reached here

If you are operating in windows (which I am going to assume you are) you can use the inspect.exe tool that comes along with visual studio. It will allow you to interact with the dialogue box and even send any information that you want accurately including selecting elements from the drop down or any other interaction needed. This even works if you wish to save files using selenium, but to answer your question, you can even use it to detect if that window is indeed there. How you want to proceed from there is your call.
//using System.Windows.Automation;
//using System.Windows.Forms;
AutomationElement desktop = AutomationElement.RootElement;
AutomationElement Firefox = desktop.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "MozillaWindowClass"));
AutomationElement PrinterComboBox = PrintForm1.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "1139"));
SelectionPattern selectPrinterComboBox = (SelectionPattern)PrinterComboBox.GetCurrentPattern(SelectionPattern.Pattern);
AutomationElement ItemInDropdown = PrinterComboBox.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "SelectPrintMethod"));
SelectionItemPattern ItemInDropdownSelectItem = (SelectionItemPattern)ItemInDropdown.GetCurrentPattern(SelectionItemPattern.Pattern);
ItemInDropdownSelectItem.Select();
AutomationElement OKButton = PrintForm1.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "1"));
InvokePattern ClickOK = (InvokePattern)OKButton.GetCurrentPattern(InvokePattern.Pattern);
ClickOK.Invoke();

Related

Open new tab in Firefox and Chrome with Selenium is not working

I read a lot of options related with the way to open new windows with Selenium. All the questions and answers are from a few years ago and maybe that's why they are not working to me. And that's why I would like to open this question again.
My first approach was using javascript action:
((JavascriptExecutor) getDriver()).executeScript("window.open('','NewWindow');");
My issue here is the different result in Firefox and Chrome. Firefox opens a new window and Chrome opens a new tab. This means that my test case is not working as expected if I executed in different browsers.
After that I think about a different approach. If I send the shortcut to open a new tab maybe both browsers will work with the same behavior. And here started my nightmare. None of the next options open anything in the current Chrome and Firefox versions:
Send keys concatenate the shortcut:
getDriver().findElement(By.xpath(".//body")).sendKeys(Keys.COMMAND+"T");
Send keys multiple keys sequence:
getDriver().findElement(By.xpath(".//body")).sendKeys(Keys.COMMAND,"T");
Send Keys chord
getDriver().findElement(By.xpath(".//body")).sendKeys(Keys.chord(Keys.COMMAND + "T"));
Using actions
final Actions builder = new Actions(getDriver());
builder.keyDown(Keys.COMMAND).sendKeys("T").perform();
I'm thinking about try with the COMMAND key Down click on any link, but maybe there is an other easy way to open a new tab in different browsers. And this is my question, do you now an efficient way to open a new tab, not a new window, in different browsers with the same action?
ADITIONAL INFORMATION
Selenium version -> 3.141.59
Chrome version -> 79.0.3945.79
Firefox version -> 70.0.1
Thank you in advance.
This may be help you:-
Using JavascriptExecutor:-
Open new blank window:-
((JavascriptExecutor)driver).executeScript("window.open('about:blank','_blank');");
Open new window with specific url:
((JavascriptExecutor)driver).executeScript("window.open('http://www.yahoo.com','_blank');");
Using Robot class:-
Robot class in Selenium is used for simulating keyboard and mouse events. So, in order to open a new tab, we can simulate the keyboard event of pressing Control Key followed by ‘t’ key of the keyboard. After the new tab gets opened, we need to switch focus to it otherwise the driver will try to perform the operation on the parent tab only.
For switching focus, we will be using getWindowHandles() to get the handle of the new tab and then switch focus to it.
//Use robot class to press Ctrl+t keys
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_T);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_T);
//Implicit Wait
//driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS) ;
Thread.sleep(2000);
//Switch focus to new tab
ArrayList<String> tabs = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(tabs.get(1));
//Launch URL in the new tab
driver.get("http://google.com");*/
Two approach of Robot Class to Open url in new tab using selenium
public class NewTab
{
public static void main(String[] args) throws InterruptedException, AWTException {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.facebook.com/");
Robot r = new Robot();
r.keyPress(KeyEvent.VK_CONTROL);
r.keyPress(KeyEvent.VK_T);
r.keyRelease(KeyEvent.VK_CONTROL);
r.keyRelease(KeyEvent.VK_T);
Set<String> tabs = (Set<String>)driver.getWindowHandles();
for(String tab : tabs)
{
driver.switchTo().window(tab);
System.out.println(driver.getTitle());
if(driver.getTitle().contains("New Tab"))
driver.get("http://www.google.com/");
}
}
}
Another way, without using the for loop
public class NewTab {
public static void main(String[] args) throws InterruptedException, AWTException {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
Robot r = new Robot();
r.keyPress(KeyEvent.VK_CONTROL);
r.keyPress(KeyEvent.VK_T);
r.keyRelease(KeyEvent.VK_CONTROL);
r.keyRelease(KeyEvent.VK_T);
String Base = driver.getWindowHandle();
Set<String> tabs = (Set<String>)driver.getWindowHandles();
tabs.remove(Base);
driver.switchTo().window(tabs.toArray()[0].toString());
driver.get("http://www.facebook.com/");
}
}
Please try below code.
I didn't use javascript.
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL,"t");
driver.findElement(By.linkText("urlLink")).sendKeys(selectLinkOpeninNewTab);
As a user asked how I finally solved this, my solution was this:
// Save the current window reference
final String parentWindow = driver.getWindowHandle();
// Look for the element I would like to click
final WebElement elem = driver.findElement(By.xpath(xpath));
// Create an action to be performed
final Actions builder = new Actions(driver);
// The OSKEY is a global variable where depending on the OS is saved CMD or CTR
// With the special key chord, the program clicks on the element
builder.keyDown(OSKEY).click(elem).perform();
For me is working without browser problems.

How to input data into external GUI using Java runtime exec

I am trying to write java code to access and use the DullRazor software.
Please refer to this image of the DullRazor application:
I had an idea of creating a Java runtime program that could loop through all images I need to process(the software only allows 1 image at a time) and complete the necessary steps required for the DullRazor software to successfully alter an image for every image I have.
The DullRazor software works as follows:
-Source File: Requires the path to an image(jpg in my case) to be altered i.e c://Isic-Images//image0000.jpg.
-Target File: Requires the location for the new image with a new image name i.e c://finalLocation//newImage.jpg
-Start: Run the program after giving the inputs in the correct format as described above.
My thinking is iterating through all my images, creating new ones and incrementing the name(img00, img001 etc..).
I have never attempted anything like this in Java and I have had some trouble accessing the Input fields of the software as well as the application's start button.
The code below is just very basic for opening the application, but I am unsure how to access the various items in the DullRazor application and being able to input Strings in those aforementioned fields(again, refer to the DullRazor picture).
private String trainingPath = "C:\\Users\\user\\AppData\\Local\\Temp\\ISIC-Images\\Training\\0";
private String finalPath = "C:\\Users\\user\\finalLocation\\";
public static void main(String[] args) {
try {
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec("C:\\Users\\user\\Desktop\\dullrazor.exe");
System.out.println("Opening DullRazor");
OutputStream output = process.getOutputStream();
InputStream input = process.getInputStream();
Thread.sleep(2000);
process.destroy();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException s) {
s.printStackTrace();
} finally {
System.out.println("Closing Dullrazor");
}
}
I have just been testing a bit with the code above, but I am unsure on how to proceed.
Tell me if there is anything that needs clarifying.
Any help is greatly appreciated, thanks.
You can use Java's java.awt.Robot class to control mouse and keyboard on the screen.
This is a simple example entering "test1" and "test2" into two input fields:
Robot r = new Robot();
r.mouseMove(22, 125);
r.mousePress(InputEvent.BUTTON1_DOWN_MASK);
r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
r.keyPress('T');
r.keyRelease('T');
r.keyPress('E');
r.keyRelease('E');
r.keyPress('S');
r.keyRelease('S');
r.keyPress('T');
r.keyRelease('T');
r.keyPress('1');
r.keyRelease('1');
r.mouseMove(200, 125);
r.mousePress(InputEvent.BUTTON1_DOWN_MASK);
r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
r.keyPress('T');
r.keyRelease('T');
r.keyPress('E');
r.keyRelease('E');
r.keyPress('S');
r.keyRelease('S');
r.keyPress('T');
r.keyRelease('T');
r.keyPress('2');
r.keyRelease('2');
The above code in action:
If the position of the new application window does not change with each start, and the tool is not about to be deployed to users, this might already suffice. However, if it changes the position with each start, the challenge is to find the window position to add the relative input element positions from there. There are Windows (platform) specific approaches facilitating the Win32 API through JNA, though I'm not familiar with it and whether it is still available in current Microsoft Windows versions.
See these related questions on determining other windows positions:
Windows: how to get a list of all visible windows?
How to get the x and y of a program window in Java?
Using robot works perfectly in order to input into the targeted fields and clicking start/clear button on the application.
In order to find the x & y positions of the application I used runtime exec to open dullrazor and then take a screenshot of the screen with the application up where mouse clicks reveals the x and y position of the current click. Below is the code for finding x & y which I found at this Stackoverflow thread:
Robot robot = new Robot();
final Dimension screenSize = Toolkit.getDefaultToolkit().
getScreenSize();
final BufferedImage screen = robot.createScreenCapture(
new Rectangle(screenSize));
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JLabel screenLabel = new JLabel(new ImageIcon(screen));
JScrollPane screenScroll = new JScrollPane(screenLabel);
screenScroll.setPreferredSize(new Dimension(
(int)(screenSize.getWidth()/2),
(int)(screenSize.getHeight()/2)));
final Point pointOfInterest = new Point();
JPanel panel = new JPanel(new BorderLayout());
panel.add(screenScroll, BorderLayout.CENTER);
final JLabel pointLabel = new JLabel(
"Click on any point in the screen shot!");
panel.add(pointLabel, BorderLayout.SOUTH);
screenLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
pointOfInterest.setLocation(me.getPoint());
pointLabel.setText(
"Point: " +
pointOfInterest.getX() +
"x" +
pointOfInterest.getY());
}
});
JOptionPane.showMessageDialog(null, panel);
System.out.println("Point of interest: " + pointOfInterest);
}
});
Thank you try-catch-finally for a great answer.

File download in Selenium webdriver using robot class

When I Clicked download button using it opens a download pop up in firefox. Its running correctly and saving the files but when i iterate in loop its not saving instead its opening the file.Any solution for below mentioned code it ?
for (int j = 0; j < StoreSelectedYear_size; j++) {
System.out.println(StoreSelectedYear.get(j));
YearSelection(StoreSelectedYear.get(j));
Thread.sleep(5000);
filedownload(i);
}
StoreSelectedYear.clear();
}
}
public void YearSelection(String StoreSelectedYearStr) throws InterruptedException, AWTException {
Select yearselction = new Select(driver.findElement(By.cssSelector("#u14_input")));
yearselction.selectByVisibleText(StoreSelectedYearStr);
Thread.sleep(5000);
}
public void filedownload(int i) throws AWTException, InterruptedException {
driver.findElement(By.xpath("//button[#id='export']")).click();
Thread.sleep(6000);
Robot robot = new Robot();
robot.delay(5000);
// Thread.sleep throws InterruptedException
if (i == 0) {
robot.keyPress(KeyEvent.VK_DOWN);
robot.delay(2000);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyPress(KeyEvent.VK_ENTER);
}
Firefox save image:
You could try an alternate solution by getting the src attribute of the download element, and then using an http library such as HttpUnit to make a direct request to download the file.
This has the added benefit that it will do the work of giving you the file as an object easier if you need to validate or manipulate it within your tests if that matches your use case.
I suggest this because if you're doing this for a job, then utilizing a solution that doesn't require manipulating screen coordinates and window position is often always a better option. And there is likely little value in testing the download prompt, since it doesn't exist in the sandbox with your app.
You can retrieve the cookies in use by your current selenium test session with this code just in case this is compelling to you.
Set<Cookie> seleniumCookies = driver.manage().getCookies();
org.apache.http.client.CookieStore cookieStore = new org.apache.http.client.BasicCookieStore();
for (Cookie seleniumCookie : seleniumCookies) {
org.apache.http.impl.cookie.BasicClientCookie basicClientCookie =
new BasicClientCookie(seleniumCookie.getName(), seleniumCookie.getValue());
basicClientCookie.setDomain(seleniumCookie.getDomain());
basicClientCookie.setExpiryDate(seleniumCookie.getExpiry());
basicClientCookie.setPath(seleniumCookie.getPath());
cookieStore.addCookie(basicClientCookie);
}
return cookieStore;
This will essentially convert your cookies into a form usable by the apache http library, which you can use to make requests to your app without the app realizing you stepped out of selenium. And if your requests make changes to the cookies in this example, then you can re-set the cookies in selenium afterwards with the new versions.

How can I close my close my browser or switch to pop up when automating Google sign in?

I am trying to refresh my Selenium knowledge. So, I am writing a script to navigate through my Google account. After I successfully sign in to Google, a pop up appears under my profile icon on the upper right side in Firefox. I no longer get these pop ups when I sign manually. This is probably because of cookies or some other browser setting. I do not care about the reason why this occurs.
However, since it occurs, I believe it may be preventing my script from closing the browser with driver.close(); I also tried driver.quit(); Neither of these are causing the browser to close.
So, I thought I would try switching windows by doing an iteration through the windows. This is not allowing me to select the pop up that appears to close it.
I also tried to create an Alert alert and switch to it:
driver.switchto.alert();
driver.dismiss();
This is not dismissing this pop up in Google either.
In the end, I do not care about this pop up. I know I listed 2 separate issues here. But, in the end, I just want to close the browser. If I can also learn how to switch to this pop up and click the x to close it, that is a bonus.
//Code added here -------------------------
public void sign_out( WebDriver driver )
{
//At this point,I am already signed in. But, that Google pop up appears
//The pop up says "Get to Google faster. Switch your default search engine to Google."
//Wait for "x" to appear
myDynamicElement = (new WebDriverWait(driver, wait_for_element_time)).until(ExpectedConditions.visibilityOfElementLocated(By.xpath(x_path_x_pop_up)));
//This is set above as a class member
//final String x_path_x_pop_up = "/html/body/div/div[3]/div[1]/div/div/div/div[2]/div[4]/div/a";
WebElement x_icon = driver.findElement(By.xpath(x_path_x_pop_up));
//Click x to close it
x_icon.click();
String myWindowHandle = driver.getWindowHandle();
String subWindowHandle = null;
Set<String> handles = driver.getWindowHandles(); // get all window handles
Iterator<String> iterator = handles.iterator();
while (iterator.hasNext()){
subWindowHandle = iterator.next();
}
driver.switchTo().window(subWindowHandle); // switch to popup window
// driver.switchTo().window(myWindowHandle);
// This never happens now on this click of the profile icon in Google to sign out.
//Click on profile icon
m_profile_icon.click();
//Wait for "Sign Out" button to appear
myDynamicElement = (new WebDriverWait(driver, wait_for_element_time)).until(ExpectedConditions.visibilityOfElementLocated(By.xpath(x_path_sign_out_button)));
//Get sign out button
WebElement sign_out_button = driver.findElement(By.xpath(x_path_sign_out_button) );
sign_out_button.click();
}
}
Well as long as you are working in Java you can try the Robot framework and sendKeys as a workaround (ALT+F4):
import java.lang.reflect.*;
import java.awt.Robot;
import java.awt.event.KeyEvent;
public class RobotUtilities {
public static void sendKeyCombo(String keys[]) {
try {
Robot robot = new Robot();
Class<?> cl = KeyEvent.class;
int [] intKeys = new int [keys.length];
for (int i = 0; i < keys.length; i++) {
Field field = cl.getDeclaredField(keys[i]);
intKeys[i] = field.getInt(field);
robot.keyPress(intKeys[i]);
}
for (int i = keys.length - 1; i >= 0; i--)
robot.keyRelease(intKeys[i]);
}
catch (Throwable e) {
System.err.println(e);
}
}
// main for testing purposes
public static void main(String args[]) {
String [] keys = {"VK_ALT", "VK_F4"};
sendKeyCombo(keys);
}
}
Alternative more robust solution using windowHandles:
I took this from here
You can switch between windows as below:
// Store the current window handle
String winHandleBefore = driver.getWindowHandle();
// Perform the click operation that opens new window
// Switch to new window opened
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
}
// Perform the actions on new window
// Close the new window, if that window no more required
driver.close();
// Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);
// Continue with original browser (first window)
So, my problem had to do with errors in the JUnit part of my code. I commented out these sections. Once everything was error free, the driver.quit() closed the browser.
I also did some research and found that JUnit does not allow passing class values between different #Test tests. So, I also moved all of my open browser and close browser into the same #Test. This cleaned everything up as well.

FontMetrics return garbage font descent

I am facing a weird problem in Eclipse, and even after lot of search, haven't found any Bugs also in this regard. My Problem is with the
handle field in FontMetrics Class. Since the API says its Platform Dependent, there is not much I can do about it. The problem is like this:
I have to export some diagrams, made of draw2d widgets and connections, to Word and PDF. Till now, the export feature was available as an Action to the toolbar of the Editor, in which Diagrams are drawn. It has been working fine. All I do is paint the FigureCanvas to an SWT Image, and save it to a File. There are APIs available with me, which then insert it to Word/PDF. Now, I need to that offline, i.e. without actually drawing the diagram on Screen. I did something like this to achieve this:
Job job = new Job("Making DFD for " + data.getName()) {
#SuppressWarnings("unchecked")
#Override
protected IStatus run(IProgressMonitor monitor) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
Composite composite = new Composite(shell, SWT.NONE);
try {
imageFolder = new File(tempFolder + IOUtils.FILE_SEPARATOR +
"dfd-" + (new Date()).getTime());
composite.setLayout(new FillLayout());
final FigureCanvas canvas = new FigureCanvas(composite);
ArrayList<DFDFigureData> figureData = renderer.getDfdFigureDatas();
final DFDMaker3 dfdMaker;
dfdMaker = new DFDMaker3(canvas, "", figureData, null, false);
Logger.println("Shell Size:", shell.computeSize(-1, -1, true));
display.syncExec(new Runnable(){
public void run() {
dfdMaker.makeDFD();
shell.setSize(-1, -1);
dfdMaker.selectNode(-1, display);
}
});
Logger.println("Shell Size:", shell.computeSize(-1, -1, true));
/* Image Export Stuff Goes here */
return Status.OK_STATUS;
} catch (Exception e) {
Logger.println("Error in DFD Creation Job", e.toString());
return Status.CANCEL_STATUS;
} finally {
composite.dispose();
shell.dispose();
display.dispose();
}
}
};
job.setPriority(Job.SHORT);
job.schedule();
When I run this for the first time, both the Log statements tell me a good story:
Shell Size::: Point {72, 98}
Shell Size::: Point {1216, 524}
But when I run the same code 2nd time, without closing the application, I get:
Shell Size::: Point {72, 98}
Shell Size::: Point {1216, 1945541082}
The large Height value of the shell spoils everything. After intense debugging, I found that the second time, a FlowPage, that I am using, get a wrong value for Font's descent. The method FontMetrics.getDescent() returns a Random large value.
I am not sure how exactly to proceed in this. I've disposed all the resources that I used the first time. The Display, Shell, Composite, Canvas, and even the GC and SWTGraphics. Can anyone tell me if its a bug? If not, any idea how can I find the problem here?

Categories