[CodedStep(@
"Find and click on course link"
)]
public
void
FindAndClickOnCourseLink()
{
string
textContent = ((
string
)(System.Convert.ChangeType(Data[
"CourseName"
],
typeof
(
string
))));
HtmlAnchor expectedLink =
null
;
var attempts = 0;
while
(expectedLink ==
null
)
{
var rows = Find
.ById(
"activitiesTable"
)
.As<HtmlTable>()
.AllRows;
expectedLink = rows
.Select(row => row.Cells[0].Find.AllByContent<HtmlAnchor>(textContent).FirstOrDefault())
.Where(a => a !=
null
)
.FirstOrDefault();
attempts++;
//TODO: This is not very elegant but it works, needs something better.
if
(attempts > 20)
{
break
;
}
System.Threading.Thread.Sleep(250);
}
expectedLink.Click();
}
}
12 Answers, 1 is accepted
That's pretty much the best way to wait for an AJAX postback to complete. The only thing I would change is to use a System.Diagnostics.Stopwatch, adding it to your while statement instead of counting attempts.
Kind regards,Cody
the Telerik team
Have you looked at the new Online User Guide for Telerik Test Studio?

Thanks for your reply, I will add the stopwatch instead. However it is slightly disappointing, I was hoping that there was a way tell it to wait until all active connections to the web server have closed, which would signify that all AJAX operations are completed. For example in selenium I can write a waitForCondition against "selenium.browserbot.getUserWindow().$.active == 0" to check that all jQuery connections have closed, after which I can continue executing the test.
I would need to perform this kind of operation on different parts of our website many times throughout my test scripts and this is quite a lot of code to write each time, I was hoping for something similar to the above.
Thank you very much for that tip!! I did some research on how selenium.browserbot.getUserWindow().$.active == 0 works and came up with something that does work pretty slick for AJAX. Here is the code:
[CodedStep(
"Wait for AJAX"
)]
public
void
AjaxWait()
{
Wait.For<
int
>(c => ActiveAjaxConnections() == 0, 0, 10000);
}
public
int
ActiveAjaxConnections()
{
return
Actions.InvokeScript<
int
>(
"jQuery.active"
);
}
In this example I am waiting up to 10 seconds for all AJAX connections to close. Feel free to contact me again if you need additional help with this. Kind regards,
Cody
the Telerik team
Have you looked at the new Online User Guide for Telerik Test Studio?

That's just what I was looking for, thanks for your help. I'll add it to my tests and get back to you if I have any trouble with it.
thanks,
Ross

I'm thinking this solution will help me with knowing when an ajax call is finished...
Thanks-
Steve
Is this the exact error message that VS2010 is reporting?
'C#: There is no such reference available here'
I don't recognize that error message and do not understand what it means. Can you send me a clear screen shot of the error message? Or better yet can you send me your test project for diagnosis? I don't need to run your test, I'll just make sure it compiles correctly and send you back the necessary corrections.
Cody
the Telerik team
Test Studio Trainings

Here is a fairly complete yet simply sample:
using
System;
using
System.Text;
using
System.Collections.Generic;
using
System.Linq;
using
Microsoft.VisualStudio.TestTools.UnitTesting;
using
ArtOfTest.WebAii.Core;
using
ArtOfTest.WebAii.ObjectModel;
using
ArtOfTest.WebAii.TestTemplates;
using
ArtOfTest.WebAii.TestAttributes;
using
ArtOfTest.WebAii.Win32.Dialogs;
using
ArtOfTest.WebAii.Controls.HtmlControls;
using
ArtOfTest.WebAii.Controls.HtmlControls.HtmlAsserts;
using
ArtOfTest.WebAii.Messaging.Http;
namespace
ProxySample
{
/// <summary>
/// Summary description for WebAiiVSUnitTest1
/// </summary>
[TestClass]
public
class
WebAiiVSUnitTest1 : BaseTest
{
#region Additional test attributes
private
TestContext testContextInstance =
null
;
/// <summary>
///Gets or sets the VS test context which provides
///information about and functionality for the
///current test run.
///</summary>
public
TestContext TestContext
{
get
{
return
testContextInstance;
}
set
{
testContextInstance = value;
}
}
//Use ClassInitialize to run code before running the first test in the class
[ClassInitialize()]
public
static
void
MyClassInitialize(TestContext testContext)
{
}
//Use ClassCleanup to run code after all tests in a class have run
[ClassCleanup()]
public
static
void
MyClassCleanup()
{
}
// Use TestInitialize to run code before running each test
[TestInitialize()]
public
void
MyTestInitialize()
{
#region WebAii Initialization
// Initializes WebAii manager to be used by the test case.
// If a WebAii configuration section exists, settings will be
// loaded from it. Otherwise, will create a default settings
// object with system defaults.
//
// Note: We are passing in a delegate to the VisualStudio
// testContext.WriteLine() method in addition to the Visual Studio
// TestLogs directory as our log location. This way any logging
// done from WebAii (i.e. Manager.Log.WriteLine()) is
// automatically logged to the VisualStudio test log and
// the WebAii log file is placed in the same location as VS logs.
//
// If you do not care about unifying the log, then you can simply
// initialize the test by calling Initialize() with no parameters;
// that will cause the log location to be picked up from the config
// file if it exists or will use the default system settings (C:\WebAiiLog\)
// You can also use Initialize(LogLocation) to set a specific log
// location for this test.
Initialize(
this
.TestContext.TestLogsDir,
new
TestContextWriteLine(
this
.TestContext.WriteLine));
// If you need to override any other settings coming from the
// config section you can comment the 'Initialize' line above and instead
// use the following:
/*
// This will get a new Settings object. If a configuration
// section exists, then settings from that section will be
// loaded
Settings settings = GetSettings();
// Override the settings you want. For example:
settings.DefaultBrowser = BrowserType.FireFox;
// Now call Initialize again with your updated settings object
Initialize(settings, new TestContextWriteLine(this.TestContext.WriteLine));
*/
// Set the current test method. This is needed for WebAii to discover
// its custom TestAttributes set on methods and classes.
// This method should always exist in [TestInitialize()] method.
SetTestMethod(
this
, (
string
)TestContext.Properties[
"TestName"
]);
#endregion
//
// Place any additional initialization here
//
}
// Use TestCleanup to run code after each test has run
[TestCleanup()]
public
void
MyTestCleanup()
{
//
// Place any additional cleanup here
//
#region WebAii CleanUp
// Shuts down WebAii manager and closes all browsers currently running
this
.CleanUp();
#endregion
}
#endregion
private
void
RequestLogger(
object
sender, HttpRequestEventArgs e)
{
// TODO Implement this
Manager.Log.WriteLine(String.Format(
"{0} {1} {2}"
, e.Request.HttpVersion, e.Request.HttpMethod, e.Request.RequestUri));
foreach
(
string
key
in
e.Request.Headers)
{
Manager.Log.WriteLine(String.Format(
"{0}:{1}"
, key, e.Request.Headers[key]));
}
}
private
void
ResponseLogger(
object
sender, HttpResponseEventArgs e)
{
// TODO Implement this
Manager.Log.WriteLine(String.Format(
"{0} {1} {2}"
, e.Response.HttpVersion, e.Response.StatusCode, e.Response.StatusDescription));
foreach
(
string
key
in
e.Response.Headers)
{
Manager.Log.WriteLine(String.Format(
"{0}:{1}"
, key, e.Response.Headers[key]));
}
}
[TestMethod]
public
void
TestMethod1()
{
//
// Place your test code here
//
Manager.Settings.UseHttpProxy =
true
;
Manager.LaunchNewBrowser();
ActiveBrowser.NavigateTo(
"http://msdn.microsoft.com/"
);
Find.ByContent<HtmlAnchor>(
"l:Library"
).Click();
Find.ByContent<HtmlAnchor>(
"l:.NET Development"
).Click();
RequestListenerInfo reqLI =
new
RequestListenerInfo(RequestLogger);
Manager.Http.AddBeforeRequestListener(reqLI);
ResponseListenerInfo respLI =
new
ResponseListenerInfo(ResponseLogger);
Manager.Http.AddBeforeResponseListener(respLI);
Find.ByAttributes<HtmlAnchor>(
"title=MSDN Library"
).Click();
Manager.Http.RemoveBeforeRequestListener(reqLI);
Manager.Http.RemoveBeforeResponseListener(respLI);
}
}
}
To best assist you further with this endeavor getting the part of your test code where the problem lies will speed up our investigation for you immensely. Let us know if we can be of further assistance. Kind regards,
Cody
the Telerik team
Test Studio Trainings

"Is there some obvious reason why this is so?" - Not without some additional details about what problem you are running into, any error messages you see, what behavior you are actually getting (compared to what you expected to get). Even better would be if you can send me a sample solution that demonstrates the problem that I can run locally, reproduce the problem and investigate what's causing it.
Greetings,Cody
the Telerik team
Test Studio Trainings

Thanks for helping me think out loud...
Steve
That's great news!...not that you're an "idiot" but that you it's working the way you want to now and figured it out on your own.
All the best,Cody
the Telerik team
Test Studio Trainings