Watin not recognising confirmation dialog OK button - internet-explorer-8

I recently started a new testing job and my predecessor ran an automation suite using watin, which I've had no previous experience with so I'm sorry if I'm not able to give you the relevant information
When I run the suite it (against IE 8.0.7601.17514) seems to get stuck when ever there is a confirmation dialog and the next step is to press ok
//Enter invalid data
var confirmDialog = new ConfirmDialogHandler();
IE.DialogWatcher.Add(confirmDialog);
using (new UseDialogOnce(IE.DialogWatcher, confirmDialog))
{
//Click to reset data entry
IE.Page<DataEntryPage>().ResetVoucherButton.ClickNoWait();
confirmDialog.WaitUntilExists(40000);
confirmDialog.OKButton.Click();
WaitForPostBackToComplete.WaitForAsyncPostBackToComplete(IE);
}
It just hangs there and waits for the time out period to pass.
I thought the problem was with my IEStaticInstanceHelper.cs file but it seems to be correct
using System.Threading;
using WatiN.Core;
namespace WatiN
{
public class IEStaticInstanceHelper
{
private IE _ie;
private int _ieThread;
private string _ieHwnd;
public IE IE
{
get
{
var currentThreadId = GetCurrentThreadId();
if (currentThreadId != _ieThread)
{
_ie = IE.AttachTo<IE>(Find.By("hwnd", _ieHwnd));
_ieThread = currentThreadId;
}
return _ie;
}
set
{
_ie = value;
_ieHwnd = _ie.hWnd.ToString();
_ieThread = GetCurrentThreadId();
}
}
private int GetCurrentThreadId()
{
return Thread.CurrentThread.GetHashCode();
}
}
}
I've recently rebuilt my computer (well my sysadmin did) and this wasn't an issue before it was rebuilt, but I can't think what may have changed
Any help would be greatly appreciated
Edit
I didn't actually have to change the code, I just had to update my Watin Version as it couldn't handle what ever differences there were between earlier IE 8 dialog boxes and newer ones.

I had a similar problem with IE 9.
I used the following to simulate the shortcut keys on the dialogue
using (browser)
{
SendKeys.SendWait("+(%S)");
}
Send Keys = http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx
Does this help?

Related

Get active document when changed in Visual Studio extension

So I'm currently writing an extension for VS using their extensibility API, and I've run into a bit of a snag. I need some kind of event (or other solution) that triggers when you tab between files, and when that happens I need to get the path to the new active document.
The problem is everything in the API that I have tried either fires at the wrong time, or when it is called, the current active document hasn't been updated yet so when I get the path it's still the file I just tabbed out of.
I've tried implementing the IVsRunningDocTableEvents interface, I've tried using the Events.WindowEvents.WindowActivated event, nothing so far has worked correctly.
EditorClassifier1Provider.myEnvDTE.DTE.Events.WindowEvents.WindowActivated += WindowEvents_WindowActivated;
class RdtEvents : IVsRunningDocTableEvents
{
public RdtEvents()
{
ThreadHelper.ThrowIfNotOnUIThread();
var rdt = (IVsRunningDocumentTable)Package.GetGlobalService(typeof(IVsRunningDocumentTable));
rdt.AdviseRunningDocTableEvents(this, out _);
}
int IVsRunningDocTableEvents.OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
{
OpenConnectionCommand.docView = VS.Documents.GetActiveDocumentViewAsync().Result;
Message.Send(null, null);
OpenConnectionCommand.docView.Document.DirtyStateChanged += (s,e) => Message.Send();
OpenConnectionCommand.docView.TextView.Selection.SelectionChanged += (s,e) => Message.Send();
return Microsoft.VisualStudio.VSConstants.S_OK;
}
//...etc

How to tell if the active document is a text document?

I'm developing a Visual Studio extension in which one of the implemented commands needs to be available only when the active document is a text document (like e.g. the Visual Studio's "Toggle Bookmark" does). The problem is that I can't figure out how to tell when that's the case.
Right now I have a half working solution. In the package's Initialize method I subscribe to DTE's WindowActivated event, and then whenever a window is activated I check if the window DocumentData property is of type TextDocument:
protected override void Initialize()
{
base.Initialize();
var dte = Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
dte.Events.WindowEvents.WindowActivated += WindowEventsOnWindowActivated;
//More initialization here...
}
//This is checked from command's BeforeQueryStatus
public bool ActiveDocumentIsText { get; private set; } = false;
private void WindowEventsOnWindowActivated(Window gotFocus, Window lostFocus)
{
if (gotFocus.Kind != "Document")
return; //It's not a document (e.g. it's a tool window)
TextDocument textDoc = gotFocus.DocumentData as TextDocument;
ActiveDocumentIsText = textDoc != null;
}
The problem with this approach is that 1) Window.DocumentData is documented as ".NET Framework internal use only", and 2) this gives a false positive when a document that has both a code view and a design view (e.g. a .visxmanifest file) is open in design mode.
I have tried to use IVsTextManager.GetActiveView as well, but this is returning the last active text view opened - so if I open a .txt file and then a .png file, it returns data for the .txt file even if it's not the active document anymore.
So, how do I check if the active document is a text document, or the code view of a document that can have a designer... and if possible, not using "undocumented" classes/members?
UPDATE: I found a slightly better solution. Inside the window activated handler:
ActiveDocumentIsText = gotFocus.Document.Object("TextDocument") != null;
At least this one is properly documented, but I still have the problem of false positives with designers.
I finally got it. It's somewhat tricky, but it works and is 100% "legal". Here's the recipe:
1- Make the package class implement IVsRunningDocTableEvents. Make all the methods just return VSConstants.S_OK;
2- Add the following field and the following auxiliary method to the package class:
private IVsRunningDocumentTable runningDocumentTable;
private bool DocIsOpenInLogicalView(string path, Guid logicalView, out IVsWindowFrame windowFrame)
{
return VsShellUtilities.IsDocumentOpen(
this,
path,
VSConstants.LOGVIEWID_TextView,
out var dummyHierarchy2, out var dummyItemId2,
out windowFrame);
}
3- Add the following to the Initialize method of the package class:
runningDocumentTable = GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
runningDocumentTable.AdviseRunningDocTableEvents(this, out var dummyCookie);
4- Don't blink, here comes the magic! Implement the IVsRunningDocTableEvents.OnBeforeDocumentWindowShow method as follows:
public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
{
runningDocumentTable.GetDocumentInfo(docCookie,
out var dummyFlags, out var dummyReadLocks, out var dummyEditLocks,
out string path,
out var dummyHierarchy, out var dummyItemId, out var dummyData);
IVsWindowFrame windowFrameForTextView;
var docIsOpenInTextView =
DocIsOpenInLogicalView(path, VSConstants.LOGVIEWID_Code, out windowFrameForTextView) ||
DocIsOpenInLogicalView(path, VSConstants.LOGVIEWID_TextView, out windowFrameForTextView);
//Is the document open in the code/text view,
//AND the window for that view is the one that has been just activated?
ActiveDocumentIsText = docIsOpenInTextView && pFrame == logicalViewWindowFrame;
return VSConstants.S_OK;
}

Is it possible to execute some code when visual studio enters break mode?

I have a large proces that I need to debug and the proces could stop at anytime. I have configured Visual Studio 2017, to stop at any thrown exception, as in, even if it is handled, because I want to see what caused the exception. What I need is some sort of alarm when this happens, so that I can leave the program to run and then alert me if anything comes up. The only thing I have found is an alarm sound when a break point is hit, but it might not be a break point and I need more than a sound, I need to be able to execute some code, so that I can make my Phone go nuts or whatever. Is there any way I can trigger code when the debugger enters break mode?
Thanks in advance.
It is, using a VS package. You'll need to add this attribute on top of the class in order for code to run on package startup:
[ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids80.SolutionExists)] ///Able to run code on solution startup
Add these class values variables:
private DTE2 applicationObject;
private BuildEvents buildEvents;
private DebuggerEvents debugEvents;
then the following code can run:
protected override void Initialize()
{
base.Initialize();
applicationObject = (DTE2)GetService(typeof(DTE));
buildEvents = applicationObject.Events.BuildEvents;
debugEvents = applicationObject.Events.DebuggerEvents;
SetupEventHandlers();
}
And finally the code we have "all" being waiting for:
private void SetupEventHandlers()
{
//buildEvents.OnBuildDone += (scope, action) =>
//{
//};
debugEvents.OnEnterBreakMode += delegate (dbgEventReason reason, ref dbgExecutionAction action)
{
};
//var componentModel =
// GetGlobalService(typeof(SComponentModel)) as IComponentModel;
//if (componentModel == null)
//{
// Debug.WriteLine("componentModel is null");
// return;
//}
//var operationState = componentModel.GetService<IOperationState>();
//operationState.StateChanged += OperationStateOnStateChanged;
}

Firefox Selenium test freezes sometimes

I am using Selenium 2.46 and Firefox 31. Whenever my test gets to a point that an web-element does not exist (or an exception is thrown) my test freezes, but it does not happen when I use Chrome. Just to let you know I have already used different versions of selenium-java and Firefox. Please find the code below:
List<WebElement> divs = driverChrome.findElements(By.tagName("div"));
int i = 0;
while (true) {
boolean breakIt = true;
System.out
.println("Waiting for map to load completely, thanks for your patience.");
for (WebElement weDiv : divs) {
try {
if (weDiv.getText().equals("Loading")) {
Thread.sleep(2000);
breakIt = false;
break;
}
} catch (Exception e) {
}
}
if (breakIt) {
break;
}
driverChrome.manage().timeouts()
.implicitlyWait(5, TimeUnit.SECONDS);
divs = driverChrome.findElements(By.tagName("div"));
}
I am using this code to wait till a map is completely loaded
The most probable reason for your test to freeze is the while(true) loop. If the text "Loading" does not show up, there still can be an (invisible) element with that text.
Anyway, I would never use a wait mechanism without timeout. And I would always try to use methods provided by the framework.
WebDriver offers explicit and implicit wait mechanisms. This one-liner could replace your whole listing (waits for up to 60s, polling every two seconds):
new WebDriverWait(driver, 60000L, 2000L).until(ExpectedConditions.invisibilityOfElementWithText(By.tagName("div"), "Loading"));
Hope it helps. If not, check out other methods of ExpectedConditions or implement your own ExpectedCondition.

Selenium test 'Unable to locate element' in IE

I have created an automated test that logs a user in to a site and performs certain operations. The test first runs in Firefox, Chrome and then IE. It runs perfectly in Firefox, closes the browser and then performs the test in Chrome and again closes the browser. When the exact same test opens the URL in IE it says it is unable to locate the element 'UserName' for the login process.
I have a wait function which I tried to extend in case it was a problem with the page rendering but this didn't work. When using the dev tools and searching for the element it finds it no problem so I am confused as to how it fails in the test.
Does anyone know what could cause this in IE?
The HTML for the text field looks like this...
The Selenium code that works in FF and Chrome but not IE is:
private Results _Test_Login(IWebDriver driver)
{
Results rt;
driver.Navigate().GoToUrl("MyURL");
driver.FindElement(By.Id("UserName")).Click();
TextboxOperation type = new TextboxOperation("UserName", driver, "Success", EnumSearchType.ById);
OperationExecutor.PerformOperations(type);
rt = new Results(driver.Url, driver.PageSource, "Existing Users");
return rt;
}
[TestMethod]
public void Test_Login()
{
List<IWebDriver> drivers = new List<IWebDriver>() { firefoxDriver, chromeDriver, ieDriver };
foreach (IWebDriver driver in drivers)
{
Results results = _Test_Login(driver);
if (results.Exception != null)
{
throw results.Exception;
}
Assert.IsFalse(results.ErrorState);
}
}
Sometimes you need to put a pause just before trying to locate an element because the page or frame is not yet ready. Or, if you don't want to have a pause, you can use a time-limited while loop wrapping a try-catch that handles error conditions and retries the find if it fails.)

Resources