public interface IAlertDialogHandler : IDialogHandler { string Message { get; } bool Exists(); void ClickOK(); void WaitUntilExists(); void WaitUntilExists(int waitInSeconds); } public interface IConfirmDialogHandler : IAlertDialogHandler { void ClickCancel(); } public class FirefoxAlertDialogHandler : IAlertDialogHandler { private const string FindDialogWindowIdScript = @"for (i = 0; i < getWindows().length; i++) { if (getWindows()[i].location.toString().indexOf('commonDialog.xul') >= 0) { i; break; } else { -1; } }"; private const string DialogHasCorrectButtonsScript = "typeof getWindows()[{0}].document.documentElement.getButton('accept') !== 'undefined' && typeof getWindows()[{0}].document.documentElement.getButton('cancel') !== 'undefined' && getWindows()[{0}].document.documentElement.getButton('cancel').hidden;"; private const string ClickOKButtonScript = "typeof getWindows()[{0}].document.documentElement.getButton('accept').click()"; private const string WindowClassName = "MozillaDialogClass"; private string _message = string.Empty; FFDocument _nativeDocument; int _windowIndex = -1; public FirefoxAlertDialogHandler(DomContainer hostBrowser) { FireFox hostFirefoxInstance = hostBrowser as FireFox; if (hostFirefoxInstance != null) { _nativeDocument = hostFirefoxInstance.NativeDocument as FFDocument; } } protected FFDocument NativeDocument { get { return _nativeDocument; } } protected virtual string HasCorrectButtonsScript { get { return DialogHasCorrectButtonsScript; } } protected int WindowIndex { get { if (_nativeDocument != null && _windowIndex == -1) { _windowIndex = _nativeDocument.ClientPort.WriteAndReadAsInt(FindDialogWindowIdScript); } return _windowIndex; } } protected bool HasCorrectButtons { get { bool hasButtons = false; if (_nativeDocument != null) { hasButtons = _nativeDocument.ClientPort.WriteAndReadAsBool(HasCorrectButtonsScript, WindowIndex); } return hasButtons; } } public string Message { get { return _message; } } public bool Exists() { return WindowIndex >= 0 && HasCorrectButtons; } public void ClickOK() { if (_nativeDocument != null) { _nativeDocument.ClientPort.WriteAndRead(ClickOKButtonScript, WindowIndex); } } public void WaitUntilExists() { WaitUntilExists(30); } public void WaitUntilExists(int waitDurationInSeconds) { var tryActionUntilTimeOut = new TryFuncUntilTimeOut(TimeSpan.FromSeconds(waitDurationInSeconds)); tryActionUntilTimeOut.Try(() => Exists()); if (!Exists()) { throw new WatiNException(string.Format("Dialog not available within {0} seconds.", waitDurationInSeconds)); } } #region IDialogHandler Members public bool CanHandleDialog(WatiN.Core.Native.Windows.Window window, IntPtr mainWindowHwnd) { bool canHandle = false; if (window.ClassName == WindowClassName) { canHandle = Exists(); } return canHandle; } public bool HandleDialog(WatiN.Core.Native.Windows.Window window) { while (window.Exists()) { Thread.Sleep(200); } return true; } #endregion } public class FirefoxConfirmDialogHandler : FirefoxAlertDialogHandler, IConfirmDialogHandler { private const string DialogHasCorrectButtonsScript = "typeof getWindows()[{0}].document.documentElement.getButton('accept') !== 'undefined' && typeof getWindows()[{0}].document.documentElement.getButton('cancel') !== 'undefined';"; private const string ClickCancelButtonScript = "getWindows()[{0}].document.documentElement.getButton('cancel').click()"; public FirefoxConfirmDialogHandler(DomContainer hostBrowser) : base(hostBrowser) { } protected override string HasCorrectButtonsScript { get { return DialogHasCorrectButtonsScript; } } public void ClickCancel() { NativeDocument.ClientPort.WriteAndRead(ClickCancelButtonScript, WindowIndex); } } public class IEAlertDialogHandler : AlertDialogHandler, IAlertDialogHandler { public void ClickOK() { this.OKButton.Click(); } } public class IEConfirmDialogHandler : ConfirmDialogHandler, IConfirmDialogHandler { public void ClickCancel() { this.CancelButton.Click(); } public void ClickOK() { this.OKButton.Click(); } }