I am currently attempting to add functionality to a program such that if a user closes a child window, it will also close the parent window that created it. I boot the starting program, select an option in the menu that will create the parent window, which then creates the child window. The program already has a endProcess function that prints something to the parent window so I figured it would be a good place to accomplish this task. Here is that function:
private synchronized void endProcess(Exec.FinishedEvent e) {
exec.removeFinishedListener(this);
exec = null;
String str;
if (e.getExitValue() != 0) {
JOptionPane.showMessageDialog(this, exec, "Exec '"+e.getExec()+"' failed: return value: "+e.getExitValue(), JOptionPane.ERROR_MESSAGE);
str = "Process FAILED [exit="+e.getExitValue()+"]: '"+e.getExec()+"'\n";
} else
str = "Process Done [exit="+e.getExitValue()+"]: '"+e.getExec()+"'\n";
statusLabel.setText(str);
outputTextArea.append("*****" + str);
//this.dispose();
//this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
The bottom two commented out lines are what I have tried to add. (Two different ideas) Both of these work properly in that when I close the child window, the parent window also closes. However, it also freezes the original program window and will not respond to anything. I believe I am somehow calling some sort of kill function to the original program window as well? Thank you and let me know if I need to provide anything else!
To clarify...
Original Program = Window that first opens when booting the program
Parent Window = Command I run in the original program to produce the child window (I wish this one to close and NOT the Original Program when closing the child)
Child Window = The Window created from the Parent Window that I wish to also close the Parent Window upon the Child Window's closing.
Related
Hi all I am learning Selenium & I am not really clear about how the above two functions work:
Problem Statement:
I have a practice assignment say: Go to http://the-internet.herokuapp.com/
Click on a link> Multiple Windows A Window opens> Click on>> Click Here Another Window opens>> from this window grab text and print it After that go back to this http://the-internet.herokuapp.com/windows and print text.
Flow: http://the-internet.herokuapp.com/>>>http://the-internet.herokuapp.com/windows>>>http://the-internet.herokuapp.com/windows/new
Que1) If I use driver.getWindowHandle() and print it for each window its value remains constant so does this method always returns the parent window or it works differently.
Ques2) When I use driver.getWindowHandles() it is returning 2 values in the set. Does driver.getWindowHandles() return the parent window as well. (I am not sure if there should be 2 or 3 values as I have 3 URLS I thought the set should have 3)
Ques3) Can someone share the most effective way to work with multiple child window id's:
Set with iterator method
People also convert Set to Arraylist and then use get method. [which is a better way]
Code:
driver.get("http://the-internet.herokuapp.com/");
String p1=driver.getWindowHandle();
System.out.println(p1);
text1=driver.findElement(By.xpath("//a[#href='/windows']"));
text1.click();
WebElement
text2=driver.findElement(By.xpath("//a[#href='/windows/new']"));
text2.click();
Set<String> child=driver.getWindowHandles();
System.out.println(child.size());
ArrayList<String> children=new ArrayList<String>(child);
System.out.println(children);
driver.switchTo().window(children.get(1));
System.out.println(driver.findElement(By.xpath("//div[#class='example']/h3")).getText());
driver.close();
driver.switchTo().window(children.get(0));
System.out.println(driver.findElement(By.xpath("//div[#class='example']/h3")).getText());
driver.switchTo().window("");
System.out.println(driver.getCurrentUrl());
driver.close();
driver.get("http://the-internet.herokuapp.com/");
String p1=driver.getWindowHandle(); //Gets the newly opened and the only window handle
System.out.println("This is parent window handle " + p1);
text1=driver.findElement(By.xpath("//a[#href='/windows']"));
text1.click(); //Navigates, no new window opened. Handle remains the same
//WebElement 'Unnecessary code
text2=driver.findElement(By.xpath("//a[#href='/windows/new']"));
text2.click(); //opens second window/tab as per the settings. there are 2 window handles here for current driver instance
Set<String> child=driver.getWindowHandles(); //set of 2
System.out.println(child.size());
// ArrayList<String> children=new ArrayList<String>(child);' modifying this
String strSecondWindowHandle = "";
for(String str : s) // as set is not an ordered collection we need to loop through it to know which position holds which handle.
{
if(str.equalsIgnoreCase(p1) == false) //to check if the window handle is not equal to parent window handle
{
driver.switchTo().window(str) // this is how you switch to second window
strSecondWindowHandle = str;
break;
}
}
// System.out.println(children);
// driver.switchTo().window(children.get(1)); //not required
System.out.println(driver.findElement(By.xpath("//div[#class='example']/h3")).getText());
driver.close(); // now this will close the second window
driver.switchTo().window(p1); // switches to main window
System.out.println(driver.findElement(By.xpath("//div[#class='example']/h3")).getText());
// driver.switchTo().window(""); //not required as it is the same window
System.out.println(driver.getCurrentUrl());
driver.close(); //closes the main window
So to answer your questions
Window handle is automatically and uniquely assigned by the operating system (Windows) to each newly opened window
Q1 --> Until and unless you explicityly switch the windows, the window handle remains the same. switching is the key here.
Q2 --> Navigating does not change the handles. it is not page specific rather it is window specific. getWindowHandles will return all the open browser windows opened by WebDriver instances that is currently running. Already open windows are not included.
Q3 --> Using the for loop demonstrated above, you open the window, find the ID which is not your parent window handle, store it in a variable. Repeat the procedure for more windows.
You can see in the documentation what are the main differences between getWindowHandle() and getWindowHandles() methods:
getWindowHandle(): Return an opaque handle to this window that uniquely identifies it within this driver instance.
getWindowHandles(): Return a set of window handles which can be used to iterate over all open windows of this WebDriver instance by passing them to switchTo().WebDriver.Options.window()
In simpler terms, driver.getWindowHandles() stores the set of handles for all the pages opened simultaneously, but driver.getWindowHandle() fetches the handle of the web page which is in focus. It gets the address of the active browser and it has a return type of String.
I want to dispose a frame in its constructor when the condition is true.
this.dispose is not disposing frame. I want that, when my constructor is called, if condition i.e (configurationBean.getCode().equals(macPass)) is true then a new frame have to be called and this frame must have to be closed. Else this frame have to be created.
public ConfigurationFrame() {
String pcMac = getPcMacAddress();
String macPass = getPassword(pcMac);
ConfigurationDao configurationDao = new ConfigurationDaoImpl();
ConfigurationBean configurationBean = configurationDao.checkCode(macPass);
if(configurationBean == null)
initComponents();
else if(configurationBean.getCode().equals(macPass))
{
new MainLoginFrame().setVisible(true);
this.dispose();
super.setVisible(false);
}
}
}
Note that your question is a classic "XY Problem" type question where you ask "how do I do X", when the best solution is "Don't do X but instead do Y". In other words you definitely do not want to dispose of a top-level window object such as a JFrame in its constructor as you're trying to do.
I think that what you want to do (a guess) is to
Test the configuration of things
If OK, display the main GUI
If not OK, then display a window that allows the user to re-set the configuration
Key point: then re-test if the configuration is OK,
And if so, then display main GUI
Repeat as necessary.
If so, then I would use a while loop to show the set configuration window and exit the loop if the configuration is OK, but also allow the user to exit the loop if they simply want to quit or can't set the configuration OK. Something like this:
// configurationGood: true if config is good
// justQuit: true if the user has had enough and wants to quit
while (!configurationGood && !justQuit) {
// create configuration dialog here
// calling constructors, and all
// use a **modal** dialog here
// change configurationGood and/or justQuit values in here
}
if (!justQuit) {
// create and display main application here
}
Note that
this code is not called within any GUI window constructor, but rather prior to displaying the GUI
The re-set configuration window shouldn't be a JFrame but rather a modal JDialog
This way the program code flow halts while the dialog is displayed and only resumes after the dialog has been dealt with.
This allows the code within the while loop to query the dialog the state of its fields and use this to re-test that the configuration is OK
I am writing a script which will call a bunch of other scripts, passing proper parameters when necessary. Since multiple scripts are being called, multiple points of failure are possible. If a script fails halfway through the flow, it is logged and the user will be prompted to resume from that position when the program next starts.
Both a server and a user have the ability to start the program. One is autonomous, one is not. In the case of autonomy, I want the prompt to resume to have a 10 second timeout so if no input is received, the script will just start at the beginning.
I have moved from the static showOptionDialog to a JOptionPane constructed dialog so I can access it programmatically to kill it after 10 seconds. My issue is with the constructor, no prompt will occur.
What I have tried:
I have verified the code is entering the code block via the debug
Log() script below.
As you can see, I have tried adding a JFrame
constructor. The JFrame constructor, .add(), and
frame.SetVisible(true) are new additions that have yielded no prompt
as well.
I have also commented out the 10 second
dialog.setVisible(false) just in case it was getting called
prematurely.
I am sure I'm missing something obvious, but I can't see it.
if(foundErroredScript != null)
{
Log("debug - Found errored script, \"" + foundErroredScript + "\"");
//Resume prompt
Object[] options = {"Yes, resume", "No, start over"};
JFrame frame = new JFrame();
JOptionPane pane = new JOptionPane("Would you like to resume from \"" + foundErroredScript + "\", AKA the last run script which errored?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options);
frame.add(pane);
final JDialog dialog = pane.createDialog("Found last errored module");
Timer timer = new Timer(10000, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//dialog.setVisible(false);
}
});
timer.setRepeats(false);
timer.start();
frame.setVisible(true);
dialog.setVisible(true);
Log("User selected " + pane.getValue());
I figured it out.
After following mKorbel's advice to simplify and isolate, I moved the JOptionPane to its own simple class. I accidentally flipped the MessageType and OptionType. The program threw an exception when isolated, but doesn't when running inside the main program. This happens because the main program logic, which branches out from a class constructor, is originally called from the Main method which throws IOException.
So instead of this,
JOptionPane pane = new JOptionPane("Would you like to resume from \"here\", AKA the last run script which errored?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options);
it should be this,
JOptionPane pane = new JOptionPane("Would you like to resume from \"here\", AKA the last run script which errored?",
JOptionPane.QUESTION_MESSAGE,
JOptionPane.YES_NO_OPTION,
null,
options);
Silly mistake.
EDIT: I also removed the frame, as it was unnecessary for a primarily GUI-less application.
I am developing a rcp application .I am using a Novocode swt balloon window . I need to display one BaloonWindow on button click.but whenever I click on button each time create a new balloon window
My code is below
public Object execute(ExecutionEvent event) throws ExecutionException {
try {
BalloonWindow baloonWindow=new BalloonWindow(HandlerUtil.getActiveWorkbenchWindow(event).getShell(),SWT.ON_TOP|SWT.TOOL|SWT.CLOSE);
baloonWindow.setText("XYZ");
baloonWindow.setAnchor(SWT.RIGHT|SWT.TOP);
baloonWindow.setLocation(1290, 90);
Composite c = baloonWindow.getContents();
String array[]=new String[2];
array[0]="A";
array[1]="B";
c.setLayout(new FillLayout());
TableViewer t=new TableViewer(c,SWT.NONE);
t.setContentProvider(new ArrayContentProvider());
t.setInput(array);
c.pack(true);
baloonWindow.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
anybody can help me.how to show only one balloon window at time.if a balloon window is open then another balloon window should not be allowed to open or there should remain only one balloon window open at any given point of time.
I'm not quite sure I understood you ultimate goal, so here are two possibilities:
First (at most one BalloonWindow at a time)
Create a static boolean field isOpen in your class containing the execute() method. Set this variable to true once you created the BalloonWindow and check this variable each time you enter execute(). If it is false, create a new BalloonWindow, if it is true, return.
Second (close the BalloonWindow)
The BalloonWindow has a method open(). Use this method to open it instead of setVisible(true). If you want to close the BalloonWindow, just call close(). setVisible(false) would have the same visual effect (the window is gone), but it would still be there (only invisible). close really closes the window.
We are using webdriver for our functional tests. But our application uses the showModalDialog JS function a lot to open a popup. When we try to test this functionality with webdriver it hangs from the moment the popup is opened.
We tried several things to test this:
Using the workaround explained here. But this seems to be a fix for selenium and not for webdriver. We tried it but it didn't work.
Searching for a good alternative, HtmlUnit opened the modal dialog and could interact with it, but it has it's drawbacks like no visual help to fix certain tests and it stopped execution when it detected a JS error in a JS library we have to use but have no control over.
How can we test this or work around this problem?
From my experiences with various automation tools interaction with "webpage dialog" windows opened from IE using window.showModalDialog() or window.showModelessDialog() is not available.
Since the window is not a "true" window (look at the taskbar, it doesn't even show up) most tools can't "inspect" it and/or interact with it.
However if you do find a tool that will, please advise - there are many people looking for such a beast.
That all said, if you can possibly avoid using either of these 2 proprietary methods you'll have much more luck.
(and yes, for the picky ones, Firefox and Chrome have adopted these kind of dialogs but they don't work quite the same)
None of the answers answer the question. If the driver hangs, then you can't call any methods on it. The question is NOT about finding the pop up, it is about how to stop the driver hanging. The only way I have found is to not use showModalDialog. This can be done by adding the folowing to your test code :
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
which calls window.open each time your JavaScript calls window.showModalDialog.
I am using webdriver.SwitchTo().Window() method but my concern is my popup window does not have "Name"
When I use webdriver.WindowHandles it return only one handle, I am using this statement after popup window open.
As I don't have name / handle I cannot switch from parent window to child window.
Any other solution to do the same functionality
First we have to switch to the active element:
driver.switchTo().activeElement();
To check whether we have actually switched to the correct active element:
driver.switchTo().activeElement().getText();
Even if the window doesn't have name u can use
driver.switchTo.defaultcontent();
and perform the operation you want to execute
or else you can get the window handle name using the below command
for (String handle : driver.getWindowHandles()) {
driver.switchTo().window(handle); }
hope this should work for you.
Issue 284 is for WebDriver. It seems that it will be implemented only after Issue 27 will be implemented, so the fix should be in Beta 1 or 2 of WebDriver.
Set<String> beforePopup = driver.getWindowHandles();
Set<String> afterPopup = driver.getWindowHandles();
afterPopup.removeAll(beforePopup);
if(afterPopup.size()==1){
System.out.println(afterPopup.toArray()[0]);
}
driver.switchTo().window((String) afterPopup.toArray()[0]);
What I have been using and it works great for us on with IE and Firefox is to go through popups
and look for a a unique text on the popup you are trying to interact with. Here is the method, let me know if it works for you. Please note the line driver = driver.switchTo().window(windowHandle);
public void switchWindow(String containingText, WebDriver driver) throws Exception {
if ( StringUtils.isEmpty(containingText))
return;
int counter = 1;
int numOfpopups = driver.getWindowHandles().size();
System.out.println("Waiting for popup to load..... # handles:" + numOfpopups);
while ( numOfpopups < 2 && ((counter%10) != 0) ) {
counter++;
try{Thread.sleep(1000);}catch (Exception e) {}
}
System.out.println("Done waiting for..... " + counter + " seconds");
if (driver.getWindowHandles().size() < 2)
throw new BrowserException("Timeout after " + counter + " secs. No popup present. ");
System.out.println("Going through window handles...");
for (String windowHandle : driver.getWindowHandles()) {
driver = driver.switchTo().window(windowHandle);
if ( driver.getPageSource().contains(containingText)
return;
else
continue;
}
throw new Exception("Window containing text '" + containingText + "' not found");
}
To my knowledge, webdriver has no built-in functionality to handle modal windows as of now. Webdriver will hang once you click button which opens modal window. This happens due to JS on parent window halts until child window is closed.
To handle modal windows such as this one, see below for possible workaround written in Java. The main idea is to perform action that opens modal window (click on the button) in new thread.
/**
* Click button to open modal window and switch to it
* #param we webElement handle of a button
*/
public void clickToOpenModal(final WebElement we) {
//Get handles of all opened windows before opening modal window
Set<String> initWindowHandles = getDriverInstance().getWindowHandles();
//Create new thread and click button to open window
Thread thread1 = new Thread() {
#Override
public void run() {
//Click button
click(we);
}
};
thread1.start();
//Wait for window to appear
waitForWindow(initWindowHandles, pauseL);
thread1.interrupt();
thread1 = null;
//Get handles of all opened windows after opening modal window
Iterator<String> it = getDriverInstance().getWindowHandles().iterator();
//Select handle of modal window
String windowHandle = "";
while(it.hasNext()){
windowHandle = it.next();
}
//Switch focus and work on the modal window
getDriverInstance().switchTo().window(windowHandle);
}
The solution by Hugh Foster works, i tried this and succeeded
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
You can find the url of modal dialog then open it on another tab, it will work as normal.
In case you want to deal with open modal dialog, you can try to send "tab" key for move around objects and "send keys... enter" for setText or click.
Note: Below is some information why you cannot use selenium webdriver for work with that modal.
Modal pop-up - This is very specific to IE, Microsoft defined it as
When Windows Internet Explorer opens a window from a modal or modeless HTML dialog box by using the showModalDialog method or by using the showModelessDialog method, Internet Explorer uses Component Object Model (COM) to create a new instance of the window. Typically, the window is opened by using the first instance of an existing Internet Explorer process. When Internet Explorer opens the window in a new process, all the memory cookies are no longer available, including the session ID. This process is different from the process that Internet Explorer uses to open a new window by using the open method.
http://msdn.microsoft.com/en-us/library/ms536759(VS.85).aspx
MSDN blog on Modal dialog
When user select Model popup, parent window is blocked waiting for the return value from the popup window. You will be not able to see the view source of the page, need to close the popup then only the parent window is activated.