I'm getting an error when doing waitforelement to disappear, see below.
Any ideas to whats going wrong?, if i put in a sleep of 2sec or so it works. My guess is that the wait happens between dom refreshes or something like that but i don't know how to get around it.
Whats happening on the page, is that click save Btn closes a modal popup and I attempt to wait for it to disappear.
Code:
private HtmlFindExpression modalH2 = new HtmlFindExpression("xpath=//div[@id='tf-modal-window-top']/h2");
_Frame.Find.ByExpression<HtmlAnchor>(saveButton).Click(true);
ActiveBrowser.WaitForElement(modalH2, SharedValues.LongtTimeout, true);
Error:
Test method Iit.TradingFloor.TestWebUI.UrlRedirectionTests.UrlRedirection_Admin_SearchRedirection threw exception:
System.ApplicationException: Exception thrown during the wait for a condition. Error: Unexpected error while waiting on condition. Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Refresh() failed due to an unexpected exception. ---> ArtOfTest.WebAii.Exceptions.FindException: Find Details:
- No FindParams defined.
- Start Element: [Element: 'html:0']
at ArtOfTest.WebAii.ObjectModel.Element.Refresh()
--- End of inner exception stack trace ---
at ArtOfTest.WebAii.ObjectModel.Element.Refresh()
at ArtOfTest.WebAii.ObjectModel.Element.Refresh(Boolean forceDomTreeRefresh)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at ArtOfTest.Common.WaitAsync.CallRefreshIfNeeded[T](T target)
at ArtOfTest.Common.WaitAsync._worker_DoWork[T,V](Object waitParam)
22 Answers, 1 is accepted

If I put in a Thread.Sleep it seems to work, but I think thats a crappy solution :)
Are you connecting to and closing the Modal dialog as demonstrated here? That approach ensures ActiveBrowser properly transfers from the main window to the dialog window, and back to the main window after the dialog is closed.
Anthony
the Telerik team
Test Studio Trainings

When I inspect the modal it contains an iFrame which i have no problems connecting to, and a H2 heading which i have no problems finding.
So what we do is the following:
Click open
Validate H2
Connect to iFrame
<Do stuff>
Click close btn (Inside IFrame)
Validate that the modal H2 disappears from the dom. (This is the part that fails)
Our current work around is a try catch implementation that retries for XX secs.
Perhaps you're testing an HTML Popup instead of a Modal Popup? These unique approaches are required to ensure the ActiveBrowser instance properly transfers between windows. If you're correctly closing the popup, then it shouldn't be necessary to pick an element in the popup and wait for it to disappear. Nevertheless, here's a sample I crafted using that method with a Modal Popup:
string
frameName =
"Frame1"
;
ArtOfTest.WebAii.Core.Browser myFrame = ActiveBrowser.Frames[frameName];
HtmlFindExpression exp =
new
HtmlFindExpression(
"tagname=h2"
,
"textcontent=Tester"
);
HtmlButton b = myFrame.Find.ByExpression<HtmlButton>(
"textcontent=Show Modal Example"
);
b.MouseClick();
//Connect to modal (IE only)
ArtOfTest.WebAii.BrowserSpecialized.InternetExplorer.InternetExplorerActions ieActions = (ArtOfTest.WebAii.BrowserSpecialized.InternetExplorer.InternetExplorerActions)ActiveBrowser.Actions;
ieActions.ConnectIEDialog(
"Modal1 -- Webpage Dialog"
, 300);
Manager.WaitForNewBrowserConnect(
"codefrog.html"
,
true
, 5000);
Assert.IsTrue(ActiveBrowser.IsIEDialog);
//Close modal and wait for H2 element to disappear
HtmlAnchor a = Find.ByContent<HtmlAnchor>(
"Close Window"
);
a.Click(
true
);
ActiveBrowser.WaitForElement(exp, 5000,
false
);
ActiveBrowser.Close();
//Focus returned to parent browser
ActiveBrowser.NavigateTo(
"http://google.com"
);
If you require further assistance, please provide a full code block against a public site so I can see the issue first-hand.
Kind regards,
Anthony
the Telerik team
Test Studio Trainings

So can you show me the right way of handling this one?, couldn't really get your code snippet working.
How to open the modal:
- Go to http://www.tradingfloor.com/topics/commodities
- Click follow(without being logged in)
You should see a sign in box open.
This is a similar implementation to the one I have problems with except for the iframe, and I already run various login test against this one without any problems.
NOTE: The one with the iframe also works fine, the problem is that it's slow to close down so i need a way of waiting for it to be closed before the test can move on and its that wait that fails, and only now and then.
Thank you for the sample site. The "Sign in" overlay screen that appears after clicking the "Follow this Topic" button is not an HTML nor a Modal Popup, therefore the previously provided code and links are not relevant. The overlay screen is simply a <div> element that's hidden until you click the button to show it.
This means you'll need to target an element in the overlay screen that does not exist in the subsequent screen. Here is sample code that worked for me:
HtmlInputButton btn = Find.ByExpression<HtmlInputButton>(
"value=Follow this Topic"
);
btn.Click();
//The close "X" image is unique to the overlay
HtmlImage img = Find.ById<HtmlImage>(
"tf-modal-window-close"
);
img.Wait.ForExists(5000);
HtmlInputText un = Find.ById<HtmlInputText>(
"ContentPlaceHolderSiteHeading_siteHeading_topSignInOut_topEmail"
);
un.Text =
"test"
;
HtmlInputPassword pw = Find.ById<HtmlInputPassword>(
"ContentPlaceHolderSiteHeading_siteHeading_topSignInOut_topPassword"
);
pw.Text =
"abc123"
;
HtmlAnchor signIn = Find.ById<HtmlAnchor>(
"ContentPlaceHolderSiteHeading_siteHeading_topSignInOut_loginSubmit"
);
signIn.Click();
//Wait for the image to not exist
img.Wait.ForExistsNot(5000);
ActiveBrowser.NavigateTo(
"http://google.com"
);
HtmlInputText t = Find.ById<HtmlInputText>(
"gbqfq"
);
t.Text =
"Telerik"
;
Kind regards,
Anthony
the Telerik team
Test Studio Trainings

I refactored my code to look like this.
public void ClickSaveBtn()
{
Element h2 = currentTest.Find.ByExpression(modalH2);
GetSaveBtn().Click();
h2.Wait.ForExistsNot(SharedValues.LongtTimeout);
}
And at least for now i can't get it to fail.
But i still think there's a bug in the
ActiveBrowser.WaitForElement(modalH2, SharedValues.LongtTimeout, true);
code. Because if i use that to wait for the modalH2 to disappear it fails with the before mentioned error, not every time but often.
I'm still getting this error now and then:
I cannot reproduce this anywhere that is public available, so if that is required i need to look into if that is even something that can be done.
Error message:
Test method Iit.TradingFloor.TestWebUI.UrlRedirectionTests.UrlRedirection_QueryStringTest threw exception:
System.ApplicationException: Exception thrown during the wait for a condition. Error: Unexpected error while waiting on condition. Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Refresh() failed due to an unexpected exception. ---> ArtOfTest.WebAii.Exceptions.FindException: Find Details:
- No FindParams defined.
- Start Element: [Element: 'html:0']
at ArtOfTest.WebAii.ObjectModel.Element.Refresh()
--- End of inner exception stack trace ---
at ArtOfTest.WebAii.ObjectModel.Element.Refresh()
at ArtOfTest.WebAii.ObjectModel.Element.Refresh(Boolean forceDomTreeRefresh)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at ArtOfTest.Common.WaitAsync.CallRefreshIfNeeded[T](T target)
at ArtOfTest.Common.WaitAsync._worker_DoWork[T,V](Object waitParam)
Error stack Trace:
ArtOfTest.Common.WaitSync.CheckResult(WaitSync wait, String extraExceptionInfo)
ArtOfTest.Common.WaitSync.For[T,V](Func`3 func, T target, V custom, Boolean invertCondition, Int32 timeout, WaitResultType errorResultType)
ArtOfTest.WebAii.Synchronization.Wait.ForCondition(Func`3 condition, Boolean invertCondition, Object custom, Int32 timeout, WaitResultType errorResultType)
ArtOfTest.WebAii.Synchronization.Wait.ForExistsNot(Int32 timeout)
Iit.TradingFloor.TestWebUI.PageObjects.RedirectEditPopup.ClickSaveBtn() in C:\Source Control\0071 Trading Floor v3.0\Main\Source\TestWebUI\PageObjects\RedirectEditPopup.cs: line 51
Iit.TradingFloor.TestWebUI.UrlRedirectionTests.<
UrlRedirection_QueryStringTest
>b__2() in C:\Source Control\0071 Trading Floor v3.0\Main\Source\TestWebUI\Tests\UrlRedirectionTests.cs: line 105
Iit.TradingFloor.TestWebUI.BaseClasses.WebUITestBase.ExecuteTest(Action actionToExecute) in C:\Source Control\0071 Trading Floor v3.0\Main\Source\TestWebUI\BaseClasses\WebUITestBase.cs: line 185
Iit.TradingFloor.TestWebUI.UrlRedirectionTests.UrlRedirection_QueryStringTest() in C:\Source Control\0071 Trading Floor v3.0\Main\Source\TestWebUI\Tests\UrlRedirectionTests.cs: line 86

/// <
summary
>
/// More resilient version of Teleriks wait for element, Build due to problems when waiting for modal to close.
/// OBS: only use if problems with Teleriks wait have been proved.
/// </
summary
>
public Element CustomWaitForElement(Browser activeBrowser, HtmlFindExpression exp, int timeout, bool invert)
{
int maxWaits = timeout / 250;
int waits = 0;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (waits <
maxWaits
)
{
try
{
Element
el
=
activeBrowser
.WaitForElement(exp, timeout, invert);
return el;
}
catch
{
if (stopwatch.ElapsedMilliseconds >= timeout)
{
stopwatch.Stop();
throw;
}
waits++;
Thread.Sleep(250);
}
}
throw new Exception("Custom wait failed after: " + stopwatch.ElapsedMilliseconds);
}
We have been trying very hard to reproduce this "TargetInvocationException" with no success so far. If you are able to point us to a publicly accessible website where we can observe this error we'd like to investigate it further.
Also we highly recommend using Element.Wait.ForExists and Element.Wait.ForExistsNot over activeBrowser.WaitForElement. It's simply a better object oriented approach.
Cody
the Telerik team
Test Studio Trainings

I will start using the element.wait instead and I will let you know if i either see this in a place that's public accessible or if I can make a test server available.
For now, thanks for the help and my workaround works for us so it's not a huge issue.
NOTE:
The area where i see this is an area with a very long list of information which makes IE choke when i close the fake modal which makes it take a while for it to close.
What happens is that the ifame inside closes immediately but the popup window take maybe 5sec to close due to the list of data.
Very interesting behavior regarding the popup with the iframe. If you can give us a way to repro these problems we'll be here to investigate. I am happy you've worked a solution that works for you.
Greetings,Cody
the Telerik team
Test Studio Trainings

You said that using Element.Wait is better than ActiveBrowser.Wait but when i try i get the below problem
Code i tested with:
_currentTest.ActiveBrowser.WaitForElement(tagAutoCompleteList, SharedValues.DefaultTimeout, false);
_currentTest.Find.ByExpression<
HtmlUnorderedList
>(tagAutoCompleteList).Wait.ForExists(SharedValues.DefaultTimeout);
Line1:
Works fine
Line2:
Throws object not set to an instance of an object.
But I'm trying to wait for the object to appear, so did i misunderstand you or am i misusing the function??
I say it's "better" only from the point of view that it's a little simpler to use and uses an object oriented approach instead of the procedural approach that WaitForElement represents. I am pretty sure that internally they function the same way.
That is interesting (and I admit disappointing) behavior for the Wait.ForExists function. I've tried to reproduce the error you are getting with no luck so far. Can you point me to a publicly access website and give me repro steps so i can see this happen in action here?
Cody
the Telerik team
Test Studio Trainings

Yes om monday when i get to work i will make you some code that can reproduce the problem on a public site.

I created a bit of code which should be able to reproduce the problem.
Pre-setup:
- Go to http://www.tradingfloor.com
- Signup a user
- Replace my [INSERT HERE] with your login info
- Run test ;)
What i experience is that i get a "object not set to an instance of a object" error when running below code, and if i replace the wait on object with a ActiveBrowser.WaitForElement it works fine.
Looking forward to see what you come up with.
Manager.LaunchNewBrowser(BrowserType.InternetExplorer);
ActiveBrowser.NavigateTo("http://www.tradingfloor.com/");
// Login user
Find.ById<
HtmlAnchor
>("loginButton").Click();
Find.ById<
HtmlInputText
>("~topSignInOut_topEmail").Text = "[INSERT USERNAME HERE]";
Find.ById<
HtmlInputPassword
>("~topSignInOut_topPassword").Text = "[INSERT PWD HERE]";
Find.ById<
HtmlInputCheckBox
>("~topSignInOut_topStaySignedIn").Click();
Find.ById<
HtmlAnchor
>("~topSignInOut_loginSubmit").Click();
// Wait for dashboard page
Find.ByExpression("tagname=h1").Wait.ForContent(FindContentType.InnerText, "My dashboard");
//
Find.ByExpression<
HtmlTextArea
>("class=~squawkInput").Click();
HtmlInputText input = Find.ByExpression<
HtmlInputText
>("id=~ShareYourInsight_TagsTextBox");
input.Text = "forex";
input.InvokeEvent(ScriptEventType.OnKeyDown);
HtmlFindExpression exp = new HtmlFindExpression("tagname=ul", "class=~as-list");
// ActiveBrowser.WaitForElement(exp, 5000, false);
Find.ByExpression<
HtmlUnorderedList
>(exp).Wait.ForExists(5000);
What exactly was supposed to break in the code you sent me? I do find this line is throwing a null reference exception:
Find.ByExpression<HtmlUnorderedList>(exp).Wait.ForExists(5000);
Based on the content of the webpage at the time this is expected. There is no <ul class=as-list... or anything like it. Thus it is correctly failing.
Maybe the confusion is that Find.ByExpression<HtmlUnorderedList>(exp) will do an immediate search for the element and this happens before the Wait.ForExists gets control. Since no such element exists on the page, it is returning null which cannot be used by .Wait.ForExists.
Instead you need to create and "element proxy" object and call the Wait.ForExists method on this proxy object. For example:
HtmlFindExpression exp =
new
HtmlFindExpression(
"tagname=ul"
,
"class=~as-list"
);
HtmlUnorderedList ulist =
new
Element(exp, Find, ActiveBrowser).As<HtmlUnorderedList>();
// ActiveBrowser.WaitForElement(exp, 5000, false);
//Find.ByExpression<HtmlUnorderedList>(exp).Wait.ForExists(5000);
ulist.Wait.ForExists(30000);
Does this clear up any confusion?
Greetings,
Cody
the Telerik team
Test Studio Trainings

Ill play around with that way of waiting.

I am using: Element.Wait.WaitForExistsNot(30000). The element is a DIV, of class 'ScreenMask', that just shows the spinning 'working' image.
I get an identical callstack. I understand you were not able to repro, but as I said, it is intermittent. With the call stack, perhaps you can track down the issue:
Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Refresh() failed due to an unexpected exception. ---> ArtOfTest.WebAii.Exceptions.FindException: Find Details:
- No FindParams defined.
- Start Element: [Element: 'html:0']
- Search log during Find:
Searching for element starting at '[Element: 'html:0']'
Using FindParam:
[Find logic: Use 'TagIndex' where tag 'title' has index '0' and (none) ]
Element found is: '[Element: 'title:0']'
Attributes validation PASSED!
Validating tag name passed as part of the FindParam.
Element identification and validation succeeded!
at ArtOfTest.WebAii.ObjectModel.Element.Refresh()
--- End of inner exception stack trace ---
at ArtOfTest.WebAii.ObjectModel.Element.Refresh()
at ArtOfTest.WebAii.ObjectModel.Element.Refresh(Boolean forceDomTreeRefresh)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at ArtOfTest.Common.WaitAsync.CallRefreshIfNeeded[T](T target)
at ArtOfTest.Common.WaitAsync._worker_DoWork[T,V](Object waitParam)
at ArtOfTest.Common.WaitSync.CheckResult(WaitSync wait, String extraExceptionInfo, Object target)
at ArtOfTest.Common.WaitSync.For[T,V](Func`3 func, T target, V custom, Boolean invertCondition, Int32 timeout, WaitResultType errorResultType)
at ArtOfTest.WebAii.Synchronization.Wait.ForCondition(Func`3 condition, Boolean invertCondition, Object custom, Int32 timeout, WaitResultType errorResultType)
at ArtOfTest.WebAii.Synchronization.Wait.ForExistsNot(Int32 timeout)
at Ratecard_Episode.OrigRepeatBoth.WaitForResults() in
Nothing obvious appears. I've filed a bug on this here so that our developers can consider it. Can you help us with a way to reproduce this, a test and publicly accessible URL?
Cody
Telerik
Test Studio Trainings

The problem occurred when I was using htmlControl.WaitForNotExists(htmlFindExpression).
The element would be removed, but Telerik was always throwing the exception you were getting:
rtOfTest.WebAii.Exceptions.FindException: Find Details:- No FindParams defined.- Start Element: [Element: 'html:0']
The solution that worked for me was to set Manager.ActiveBrowser.AutoDomRefresh to true.
Try something like this:
Initialize(settings);
Manager.LaunchNewBrowser();
Manager.ActiveBrowser.Window.Maximize();
Manager.ActiveBrowser.NavigateTo("Wherever you want to go");
Manager.ActiveBrowser.AutoWaitUntilReady = true;
Manager.ActiveBrowser.AutoDomRefresh = true;
Thank you for sharing the solution that is working for you. I cannot explain why it's working because:
1) Manager.ActiveBrowser.NavigateTo has a built in Wait Until Ready. No follow up Wait Until Ready should be needed
2) Manager.ActiveBrowser.AutoWaitUntilReady is set to true by default. Your setting of it should not have any effect
3) Manager.ActiveBrowser.AutoDomRefresh is set to true by default. Your setting of it should not have any effect
But if that works for you, please by all means continue using it.
Regards,
Cody
Telerik
Test Studio Trainings