I am trying to implement a method 'waitForNewWindow' in Java using selenium WebDriver. This method is all about waiting to check if a new window is opened. If a new window is opened in the specified time, i need to return true, else return false.
public boolean waitForNewWindow(String target) {
try {
Thread.sleep(30000);
if(driver.switchTo().window(target)!=null) {
log.info("New window is opened");
return true;
}
}catch(Exception e) {
log.debug(e);
return false;
}
return true;
}
But here, I don't want to use thread.sleep(time). The waiting time needs to be specified as below:
WebDriverWait wait = new WebDriverWait(driver, TIMEOUT);
Moreover, in the above code, the control is switching to the new window, which is not expected. Can someone please provide your answers on how to implement my requirement?
the below mentioned code checks for the number of windows to appear with time out
public void waitForNumberOfWindows(final int length){
new WebDriverWait(driver, 30) {
}.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return driver.getWindowHandle().length()==length;
}
});
}
it will check for the expected number of windows to be present at that instance and will return true if the count matches with in the specified timeout(30 in above code)
You can not specify a timeout like you want. You have to use Thread.sleep().
Regarding your control moving to new window because of your below line the control is moving to new tab
driver.switchTo().window(target)
If you want to simply check if there is two windows open or not, you can write something like below
while( driver.getWindowHandle().length() != 2){
Thread.sleep(2000);
}
Finally got the implementation of waitForNewWindow method, using the WebDriverWait object as below:
try {
ExpectedCondition<Boolean> e = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver wd) {
if (wd.switchTo().window(newTarget) != null) {
log.info("New window is opened with the window id : "
+ newTarget);
driver.switchTo().window(parentHandle);
return true;
} else {
return false;
}
}
};
WebDriverWait wait = new WebDriverWait(driver, TIMEOUT);
if (wait.until(e)) {
log.info("the wait for the expected condition is successful");
return true;
}
} catch (Exception e1) {
log.debug(e1);
return false;
}
Tested the same and its working fine.
Related
I am trying to load the URL: (https://shop.countdown.co.nz/shop/browse/beer-wine) using selenium webdriver, but despite waiting for jquery to load and ajax to finish, the entire webpage does not get loaded! I am new to WebDriver, so if someone could load this page and post the code, I would appreciate that. The webpage does get loaded inside Chrome and I can see a lot of content inside the tag .
Here is my newbie code that I used to load this page:
public static void waitForAjaxToFinish(WebDriver driver) {
WebDriverWait wait = new WebDriverWait(driver, 10000);
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver wdriver) {
return ((JavascriptExecutor) driver).executeScript("return jQuery.active == 0").equals(true);
}
});
}
public static void waitForJQueryToBeActive(WebDriver driver) {
Boolean isJqueryUsed = (Boolean) ((JavascriptExecutor) driver)
.executeScript("return (typeof(jQuery) != 'undefined')");
if (isJqueryUsed) {
while (true) {
// JavaScript test to verify jQuery is active or not
Boolean ajaxIsComplete = (Boolean) (((JavascriptExecutor) driver)
.executeScript("return jQuery.active == 0"));
if (ajaxIsComplete)
break;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
private static void useSelenium() throws Exception {
WebDriver driver = new ChromeDriver();
waitForAjaxToFinish(driver);
waitForJQueryToBeActive(driver);
try {
driver.get(COUNTDOWN_URL_MAIN);
System.out.println(driver.getPageSource());
} finally {
driver.quit();
}
}
I have a program that searches the given directory and adds all the files to a list view. My problem is that the ui thread gets stuck while the search is busy. I have tried using tasks but can’t get it to work in async. The list view must be updated after each file has been found.
I have done a lot of reading about the TPL and how to use it but can’t get it to work in this case. I got it to work where the processing of data is in one method that create a task to process it. Can any one tel me what is wrong in the code below and how to fix it?
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
WalkDirectory(new DirectoryInfo(drive));
});
}
public void testTaskUpdateLabel(string labelTeks)
{
Task taskUpdateLabel = new Task(() =>
{
label4.Text = labelTeks;
});
taskUpdateLabel.Start(uiScheduler);
}
public void testTaskUpdateLabel(string labelTeks)
{
Task taskUpdateLabel = new Task(() =>
{
label4.Text = labelTeks;
});
taskUpdateLabel.Start(uiScheduler);
}
public bool WalkDirectory(DirectoryInfo directory)
{
if (directory == null)
{
throw new ArgumentNullException("directory");
}
return this.WalkDirectories(directory);
}
private bool WalkDirectories(DirectoryInfo directory)
{
bool continueScan = true;
continueScan = WalkFilesInDirectory(directory);
if (continueScan)
{
DirectoryInfo[] subDirectories = directory.GetDirectories();
foreach (DirectoryInfo subDirectory in subDirectories)
{
try
{
if ((subDirectory.Attributes & FileAttributes.ReparsePoint) != 0)
{
continue;
}
if (!(continueScan = WalkDirectory(subDirectory)))
{
break;
}
}
catch (UnauthorizedAccessException)
{
continue;
}
}
}
if (continueScan)
{
testTaskUpdateLabel(directory.FullName);
}
return continueScan;
}
private bool WalkFilesInDirectory(DirectoryInfo directory)
{
bool continueScan = true;
// Break up the search pattern in separate patterns
string[] searchPatterns = _searchPattern.Split(';');
// Try to find files for each search pattern
foreach (string searchPattern in searchPatterns)
{
if (!continueScan)
{
break;
}
// Scan all files in the current path
foreach (FileInfo file in directory.GetFiles(searchPattern))
{
try
{
testTaskUpdate(file.FullName);
}
catch (UnauthorizedAccessException)
{
continue;
}
}
}
return continueScan;
}
If you use a BackgroundWorker class, the UI will work and progress can be updated in the ProgressChanged event handler.
MSDN Reference
Can any one tel me what is wrong in the code below and how to fix it?
The problem is here
public void testTaskUpdateLabel(string labelTeks)
{
Task taskUpdateLabel = new Task(() =>
{
label4.Text = labelTeks;
});
taskUpdateLabel.Start(uiScheduler);
}
You should not use TPL to update the UI. TPL tasks are for doing non UI work and UI should only be updated on the UI thread. You already moved the work on a thread pool thread (via Task.Run), so the only problem you need to solve is how to update the UI from inside the worker. There are many ways to do that - using Control.Invoke/BeginInvoke, SynchronizationContext etc, but the preferred approach for TPL is to pass and use IProgress<T> interface. Don't be fooled by the name - the interface is an abstraction of a callback with some data. There is a standard BCL provided implementation - Progress<T> class with the following behavior, according to the documentation
Any handler provided to the constructor or event handlers registered with the ProgressChanged event are invoked through a SynchronizationContext instance captured when the instance is constructed.
i.e. perfectly fits in UI update scenarios.
With all that being said, here is how you can apply that to your code. We'll use IProgress<string> and will call Report method and pass the full name for each file/directory we find - a direct replacement of your testTaskUpdateLabel calls.
private void button1_Click(object sender, EventArgs e)
{
var progress = new Progress<string>(text => label4.Text = text);
Task.Run(() =>
{
WalkDirectory(new DirectoryInfo(drive), progress);
});
}
public bool WalkDirectory(DirectoryInfo directory, IProgress<string> progress)
{
if (directory == null) throw new ArgumentNullException("directory");
if (progress == null) throw new ArgumentNullException("progress");
return WalkDirectories(directory, progress);
}
bool WalkDirectories(DirectoryInfo directory, IProgress<string> progress)
{
// ...
if (!(continueScan = WalkDirectories(subDirectory, progress)))
// ...
if (continueScan)
progress.Report(directory.FullName);
// ...
}
bool WalkFilesInDirectory(DirectoryInfo directory, IProgress<string> progress)
{
// ...
try
{
progress.Report(file.FullName);
}
// ...
}
I got it to work by making the walkDirectory, walkDirectories and WalkFiles methods async. Thus using the await keyword before I call the testUpdate and testUpdateLabel methods. This way the listview is updated with the search results while the search is running without blocking the UI thread. I.E. the user can cancel the search when the file he was searching for has been found.
Is there any way to get window title without making any switch in selenium?
presently I'm using below code:
public boolean switchToWindowByTitle(String title){
String currentWindow = driver.getWindowHandle();
Set<String> availableWindows = driver.getWindowHandles();
if (!availableWindows.isEmpty()) {
for (String windowId : availableWindows) {
String switchedWindowTitle=driver.switchTo().window(windowId).getTitle();
if ((switchedWindowTitle.equals(title))||(switchedWindowTitle.contains(title))){
return true;
} else {
driver.switchTo().window(currentWindow);
}
}
}
return false;
}
Page Title is the <title> tag and appears at the top of a browser window which is part of the HTML DOM within the <header> section of the <html>.
So Selenium driven WebDriver needs to have the focus on the specific Browsing Context to extract the Page Title.
Where as Window Handle is a unique identifier that holds the address of all the windows and can return the string value. All the browser will have a unique window handle. This getWindowHandles() function helps to retrieve the handles of all windows.
So Selenium driven WebDriver can collect the Window Handles from the Browsing Context even without having individual focus on them.
Conclusion
So it is not possible to get the title of window/tab without switching to the specific Window / TAB.
This Code will do the purpose. Call this function as follows
swithToWindow("window Name");
public static Boolean switchToWindow(String title) {
String Parent_window = driver.getWindowHandle();
Set<String> handles = driver.getWindowHandles();
for(String handle : handles) {
driver.switchTo().window(handle);
if (driver.getTitle().equalsIgnoreCase(title)) {
return true;
}
}
driver.switchTo().window(Parent_window);
return false;
}
ArrayList<String> tabs = new ArrayList<String> driver.getWindowHandles());
driver.switchTo().window(tabs.get(1));
String parentWindow=driver.getWindowHandle();
Set<String> windows= driver.getWindowHandles();
for(String child:windows){
try{
if(!child.equalsIgnoreCase(parentWindow)){
driver.switchTo().window(child);
String windowTitle=driver.getTitle();
if(windowTitle.equals("book My Show")){
System.out.println("Window found");
}
else{
System.out.println("no windows found");
}
}
}catch(Exception e){
e.printStackTrace();
System.out.println("");
}
}
driver.switchTo().window(parentWindow);
}
}
I am beginning to write a Test Automation Framework in Java (language that I am comfortable with) for my Web Application. Currently, it is entirely tested on UI. No Backend / API testing in near sight.
I plan to use Selenium Web Driver. This framework will support both Functional/Integration and Performance testing.
I am building with Open Source Solutions for the first time (over using tools like LoadRunner) and my needs are this framework will work with Continuous Integration tools like Jenkins/Hudson and an in-house Test Management tool for reporting results.
I searched for this specific scenario but could not find one. I know there will be numerous integrations, plug-ins, etc... that needs to be built. My question is can you provide some pointers (even good reads is OK) towards beginning to build this framework with Open source solutions ?
Selenium will allow you to automate all your web (browsers) actions
automations.
Junit/TestNG as the testing framework,
including their default reports system
Maven for the project
management and lifecycle (including test phase with surefire
plugin)
Jenkins is a good integration tool that will easily
run the setup above
Good luck!
I am giving here framework functions which reduces code very much
public TestBase() throws Exception{
baseProp = new Properties();
baseProp.load(EDCPreRegistration.class.getResourceAsStream("baseproperties.properties"));
// Firefox profile creation
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("network.proxy.type", ProxyType.AUTODETECT.ordinal());
profile.setPreference("browser.cache.disk.enable", false);
profile.setPreference("network.proxy.http", "localhost");
profile.setPreference("network.proxy.http_port",8080);
driver = new FirefoxDriver(profile);
//System.setProperty("webdriver.ie.driver","E:\\Phyweb Webdriver\\IEDriverServer.exe");
//driver = new InternetExplorerDriver();
driver.manage().window().maximize();
}
//To find WebElement by id
public static WebElement FindElement(String id)
{
try
{
webElement= driver.findElement(By.id(id));
}
catch(Exception e)
{
Print(e);
}
return webElement;
}
//To find WebElement by name
public static WebElement FindElementByName(String name)
{
try
{
webElement= driver.findElement(By.name(name));
}
catch(Exception e)
{
Print(e);
}
return webElement;
}
//To find WebElement by Class
public static WebElement FindElementByClass(String classname)
{
try
{
webElement= driver.findElement(By.className(classname));
}
catch(Exception e)
{
Print(e);
}
return webElement;
}
//To get data of a cell
public static String GetCellData(XSSFSheet sheet,int row,int col)
{
String cellData = null;
try
{
cellData=PhyWebUtil.getValueFromExcel(row, col, sheet);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return cellData;
}
//To click a button using id
public static void ClickButton(String id,String label)
{
try
{
WebElement webElement= FindElement(id);
Snooze();
webElement.click();
PrintMessage(label+" is selected");
}
catch(Exception e)
{
Print(e);
}
}
//To click a button using class
public void ClickButtonByClass(String classname,String label)
{
try
{
WebElement webElement= FindElementByClass(classname);
Snooze();
webElement.click();
PrintMessage(label+" is selected");
}
catch(Exception e)
{
Print(e);
}
}
//To enter data into Textbox
public String editTextField(int rownum, int celnum,WebElement element ,XSSFSheet sheet,String Label)
{
XSSFRow row = sheet.getRow(rownum);
XSSFCell Cell = row.getCell(celnum);
String inputValue = Cell.getStringCellValue().trim();
element.clear();//To clear contents if present
try
{
element.sendKeys(inputValue);
String elementVal=element.toString();
if(elementVal.contains("password"))
{
PrintMessage("Password is entered");
}
else
{
PrintMessage("Value entered for "+Label+" is "+inputValue);
}
}
catch(Exception e){
Print(e);
//cv.verifyTrue(false, "<font color= 'red'> Failed due to : </font> "+e.getMessage());
}
return inputValue;
}
//To enter data into Textbox
public String editTextFieldDirect(WebElement element ,String text,String label)
{
element.clear();//To clear contents if present
try
{
element.sendKeys(text);
String elementVal=element.toString();
if(elementVal.contains("password"))
{
PrintMessage("Password is entered");
}
else
{
PrintMessage("Value entered for "+label+" is "+text);
}
}
catch(Exception e){
Print(e);
//cv.verifyTrue(false, "<font color= 'red'> Failed due to : </font> "+e.getMessage());
}
return text;
}
//To select Radio button
public void ClickRadioButton(String id)
{
try
{
WebElement webElement= FindElement(id);
Snooze();
webElement.click();
text=webElement.getText();
PrintMessage(text+" is selected");
}
catch(Exception e)
{
Print(e);
}
}
//To select Link
public void ClickLink(String id,String label)
{
try
{
ClickButton(id,label);
}
catch(Exception e)
{
Print(e);
}
}
//To Click an Image button
public void ClickImage(String xpath)
{
try
{
WebElement webElement= FindElement(id);
Snooze();
webElement.click();
text=GetText(webElement);
PrintMessage(text+" is selected");
}
catch(Exception e)
{
Print(e);
}
}
//Select a checkbox
public void CheckboxSelect(String id,String label)
{
try
{
WebElement webElement= FindElement(id);
Snooze();
webElement.click();
PrintMessage("Checkbox "+label+" is selected");
}
catch(Exception e)
{
Print(e);
}
}
//To select value in Combobox
public void SelectData(String id,String label,String cellval)
{
try
{
WebElement webElement= FindElement(id);
Snooze();
webElement.click();
String elementStr=webElement.toString();
int itemIndex=elementStr.indexOf("value");
if(itemIndex>-1)
{
int endIndex=elementStr.length()-3;
String item=elementStr.substring(itemIndex+7, endIndex);
if(cellval=="0")
{
PrintMessage(item+" is selected for "+label);
}
else
{
PrintMessage(cellval+" "+label+" is selected");
}
}
else
{
PrintMessage(cellval+" is selected for "+label);
}
}
catch(Exception e)
{
Print(e);
}
}
//To check if WebElement with id exists
public static boolean isExists(String id)
{
boolean exists = false;
driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
try
{
exists=driver.findElements( By.id(id) ).size() != 0;
}
catch (Exception e)
{
Print(e);
}
if(exists==true)
return true;
else
return false;
}
//To check if WebElement with name exists
public static boolean isExistsName(String name)
{
boolean exists = false;
driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
try
{
exists=driver.findElements( By.name(name) ).size() != 0;
}
catch (Exception e)
{
if(e.getMessage().contains("InvalidSelectorError"))
{
System.out.println("");
}
else
Print(e);
}
if(exists==true)
return true;
else
return false;
}
//Explicit wait until a element is visible and enabled using id
public void ExplicitlyWait(String id)
{
try
{
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id(id)));
}
catch(Exception e)
{
Print(e);
}
}
//Explicit wait until a element is visible and enabled using classname
public void ExplicitlyWaitByClass(String classname)
{
try
{
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.className(classname)));
}
catch(Exception e)
{
Print(e);
}
}
//Explicit wait until a element is visible and enabled using id
public void ExplicitlyWaitSpecific(int sec,String id)
{
try
{
WebElement myDynamicElement = (new WebDriverWait(driver, sec))
.until(ExpectedConditions.presenceOfElementLocated(By.id(id)));
}
catch(Exception e)
{
Print(e);
}
}
//Snooze for 10 seconds
public static void Snooze()
{
try
{
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
catch(Exception e)
{
Print(e);
}
}
//Snooze for Secs
public static void SnoozeSpecific(int seconds)
{
try
{
driver.manage().timeouts().implicitlyWait(seconds, TimeUnit.SECONDS);
}
catch(Exception e)
{
Print(e);
}
}
//Sleep for milliSeconds
public static void Sleep(int milisec) throws InterruptedException
{
Thread.sleep(milisec);
}
//To get text using text()
public static String GetText(WebElement element)
{
try
{
text=element.getText();
}
catch(Exception e){
Print(e);
}
return text;
}
//To get text using getAttribute("value")
public static String GetTextAttribute(WebElement element)
{
try
{
text=element.getAttribute("value");
}
catch(Exception e){
Print(e);
}
return text;
}
//To Print error messages to both Console and Results file
public static void Print(Exception e)
{
Reporter.log("Exception is :"+e.getMessage());
System.out.println(e);
}
//To Print messages to both Console and Results file
public static void PrintMessage(String str)
{
Reporter.log(str);
System.out.println(str);
}
//To Print Blank row
public static void BlankRow()
{
Reporter.log(" ");
System.out.println(" ");
}
//To Print Sub header
public static void Header(String str)
{
BlankRow();
Reporter.log("***********************"+str+" Verifications***********************");
System.out.println("***********************"+str+" Verifications***********************");
BlankRow();
}
//To Print Sub header
public static void SubHeader(String str)
{
BlankRow();
Reporter.log("-----------------------"+str+" Verifications-----------------------");
System.out.println("-----------------------"+str+" Verifications-----------------------");
BlankRow();
}
So long as you have a command line for kicking off your framework and you report back using the xunit log format then you should be good for integration with any number of Continuous integration frameworks.
Your trade off on running a browser instance under load will be fewer virtual users per host and a very careful examination of your load generator resources under load. Don't forget to include monitoring API in your framework for system metrics under load and an auto evaluation engine related to SLA metrics acceptance to determine pass of fail criteria under load at a given load point.
We are begining to develop something very related to your needs; Java, Webdriver, Jenkins, Maven, etc. We are quite new to automation here, but still have good Java ressources.
We are builing our framework based on Tarun Kumar from www.seleniumtests.com.
He's got a lot of good videos from Youtube (sounds quality is not so good), and he manage to create something very user friendly, using PageObjects Pattern.
If you don't have any clue where to start, I would start from there.
Good luck!
I created a java library on the top of selenium which simplifies test automation of a website. It has an implicit waiting mechanism and is easy to use:
https://github.com/gartenkralle/web-ui-automation
Example:
import org.junit.Test;
import org.openqa.selenium.By;
import common.UserInterface;
import common.TestBase;
public class Google extends TestBase
{
private final static String GOOGLE_URL = "https://www.google.com/";
private final static By SEARCH_FIELD = By.xpath("//input[#id='lst-ib']");
private final static By AUTO_COMPLETION_LIST_BOX = By.xpath("//*[#id='sbtc']/div[2][not(contains(#style,'none'))]");
private final static By SEARCH_BUTTON = By.xpath("//input[#name='btnK']");
#Test
public void weatherSearch()
{
UserInterface.Action.visitUrl(GOOGLE_URL);
UserInterface.Action.fillField(SEARCH_FIELD, "weather");
UserInterface.Verify.appeared(AUTO_COMPLETION_LIST_BOX);
UserInterface.Action.pressEscape();
UserInterface.Action.clickElement(SEARCH_BUTTON);
}
}
Selenium WebDriver is surely a tool for UI automation and we use it extensively to do cross Browser testing on Cloud Solutions like Browser Stack.
Our use case let us build an open source Framework "omelet" built in Java using TestNG as test runner , which takes care of almost everything related to web-testing and leaves us to actually automated application rather than thinking about reports , parallel run and CI integration etc.
Suggestion, Contribution always welcome :)
Documentation over here and
Github link over here
Do remember to checkout 5 min tutorial on website
For Functional Regression test:
Selenium Webdriver - Selenium a Web based automation tool that automates anything and everything available on a Web page. you use Selenium Webdriver with JAVA.
Watij- Web Application Testing in Java
Automates functional testing of web applications through real web browsers.
TestProject - It supports for testing both web and Mobile (Android & iOS).
For Non-functional test:
Gatling- For performance testing and Stress testing
Apache JMeter - For Volume, Performance, Load & Stress testing
CI tool:
Jenkins- Jenkins provides continuous integration services for software development.
For Functional Regression test:
TestProject
Selenium
Cucumber : It's a BDD tool
For Non-functional: Performance and Load testing:
JMeter
Note: TestComplete is a very good commercial tool.
I have a MVP like application, all expensive operations are using Async calls and display an Ajax like gif that indicates the user that something is happening without blocking the main thread.
Example:
Data entry form, user clicks Save, an async operation takes place and when it finishes restores the screen to an editable form without blocking the UI thread (in other terms, not blocking other visible windows in the application).
Everything works fine in here, but given the following scenario:
User tries to close the Form, and gets a confirmation message that asks the user if he is sure that he is going to close if he prefers to Save before closing.
When the users clicks 'Save' the same logic explained before takes place, but I'm forced to wait for this call to finish in the UI thread (in case there are any errors in the async call or whatever) and I can`t find any way of doing it other way without blocking the UI thread.
Any suggestions? Thanks!
--- Edit ----
What I'm doing right now is waiting on all my WaitHandles in the Presenter with this loop:
while (!WaitHandles.All(h => h.WaitOne(1)))
Application.DoEvents();
It feels a little dirty.. but at least it simulates non blocking the thread. Is this something that for some reason I should not be doing?
Here is an example of the "hide method". Granted, it's not MVP, it's just an example.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
class Form1 : Form
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public Form1()
{
Text = "First Form";
Button button;
Controls.Add(button = new Button { Text = "Launch 2nd Form", AutoSize = true, Location = new Point(10, 10) });
button.Click += (s, e) => new Form2 { StartPosition = FormStartPosition.Manual, Location = new Point(Right, Top) }.Show(this);
}
}
class Form2 : Form
{
public Form2()
{
Text = "Second Form";
dirty = true;
}
private bool dirty;
protected override void OnClosing(CancelEventArgs e)
{
DialogResult result;
if (dirty && (result = new ConfirmSaveForm().ShowDialog(this)) != DialogResult.No)
{
if (Owner != null)
Owner.Activate();
Hide();
e.Cancel = true;
SaveAsync(result == DialogResult.Cancel);
}
base.OnClosing(e);
}
protected override void OnClosed(EventArgs e)
{
Trace.WriteLine("Second Form Closed");
base.OnClosed(e);
}
private void SaveAsync(bool fail)
{
SaveAsyncBegin();
var sad = new Action<bool>(PerformAsyncSave);
sad.BeginInvoke(fail, (ar) =>
{
try { sad.EndInvoke(ar); }
catch (Exception ex) { Invoke(new Action<Exception>(SaveAsyncException), ex); return; }
Invoke(new Action(SaveAsyncEnd));
}, null);
}
private void SaveAsyncBegin()
{
// Update UI for save
}
private void PerformAsyncSave(bool fail)
{
Trace.WriteLine("Begin Saving");
Thread.Sleep(1000); // Do some work
if (fail)
{
Trace.WriteLine("Failing Save");
throw new Exception("Save Failed");
}
dirty = false;
}
private void SaveAsyncEnd()
{
Trace.WriteLine("Save Succeeded");
Close();
}
private void SaveAsyncException(Exception ex)
{
Trace.WriteLine("Save Failed");
Show();
MessageBox.Show(this, ex.Message, "Save Failed", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
class ConfirmSaveForm : Form
{
public ConfirmSaveForm()
{
Text = "Confirm Save";
FormBorderStyle = FormBorderStyle.FixedDialog;
ControlBox = false;
ClientSize = new Size(480, 50);
StartPosition = FormStartPosition.CenterParent;
Controls.Add(new Button { Text = "Yes, Fail", DialogResult = DialogResult.Cancel, Size = new Size(150, 30), Location = new Point(10, 10) });
Controls.Add(new Button { Text = "Yes, Succeed", DialogResult = DialogResult.Yes, Size = new Size(150, 30), Location = new Point(160, 10) });
Controls.Add(new Button { Text = "No", DialogResult = DialogResult.No, Size = new Size(150, 30), Location = new Point(320, 10) });
AcceptButton = Controls[0] as IButtonControl;
}
}