This is a migrated thread and some comments may be shown as answers.

DOM Refresh issue - AJAX

18 Answers 427 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Matt
Top achievements
Rank 1
Matt asked on 12 Apr 2012, 07:16 PM
I'm having issues with getting the DOM to refresh when I change pages (Doesn't actually change the page, but I believe it is using Ajax to display the new page). I'm creating automated smoke tests on Outlook Web App (OWA) 2010. When you switch from the Mail --> Calendar I can't get the DOM to refresh.

I have tried all of the refreshes that I could find.
Thread.Sleep(2000);
browser.Manager.ActiveBrowser.WaitForAjax(4000);
browser.Manager.ActiveBrowser.WaitUntilReady();
browser.Manager.ActiveBrowser.AutoDomRefresh = true
browser.Manager.ActiveBrowser.Frames.RefreshAllDomTrees();
browser.Manager.ActiveBrowser.RefreshDomTree();
browser.Manager.ActiveBrowser.WaitForElement(new HtmlFindExpression("id=###"), 4000, false);

It will only find the page elements on the previous page. Any suggestions on what I can do? I have tried both a click and a mouseclick
browser.ActiveBrowser.Find.ById<HtmlControl>("lnkCal").MouseClick();
browser.ActiveBrowser.Find.ById<HtmlControl>("lnkCal").Click();



18 Answers, 1 is accepted

Sort by
0
Plamen
Telerik team
answered on 17 Apr 2012, 04:20 PM
Hi Matt,

From your description you might be dealing with an AJAX postback. Instead of using the Refresh methods, try waiting for the AJAX Postback to complete as seen in this article. This ensures synchronization with the postback event.

If you are still unable to get this to work, you can point as to a publicly accessible application that demonstrates the issue and we'll be glad to assist you in finding the best way to overcome the problem.

Greetings,
Plamen
the Telerik team
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
0
Matt
Top achievements
Rank 1
answered on 17 Apr 2012, 10:11 PM
Hi Plamen,

Thanks for getting back with me. I read the article you recommended several times. I'm still struggling to adapt it with the Testing Framework and Visual Studio 2010 (I believe the article was written for the Test Studio Edition). I think you are correct in it must be a AJAX Postback issue. Even if I set the delay to 10 seconds (Thread.Sleep(10000);) it will never update the DOM elements on the new page. I tried to add the code snippets in the article, but I get an error Client Error: System.InvalidOperationException: Javascript call.

Basically if I click the Calendar link
ActiveBrowser.Find.ById<HtmlControl>("lnkCal").Click();

then the Calendar section will open, but I cannot find the Calendar DOM elements (i.e. It will only display the mail objects).

I have created a temporary login and password for the application I'm automating:
URL: https://mail.ex2.secureserver.net/owa
Email Address: telerik@54038.exhost2.secureserver.net
Password: Testing1

Please let me know any suggestions/options

Thanks,
Matt

If you need to see the code in my framework this is what I have (I have my framework setup with PageObjects Class & Navigate Class):
PageObjects
PageObjects
    public class OWANavigation
    {
        public OWANavigation(Browser b)
        {
            browser = b;
        }
 
        private Browser browser;
 
        public Element CalendarNav { get { return CalendarNavElement(); } }
 
        private Element CalendarNavElement()
        {
            return browser.ActiveBrowser.Find.ById("lnkCal");
        }

Navigation
Navigation
        public void Calendar()
        {
            browser.Manager.ActiveBrowser.Actions.Click(pageObjects_owanavigation.CalendarNav);
        }



0
Plamen
Telerik team
answered on 20 Apr 2012, 12:43 PM
Hi Matt,

Thank you for the provided access to your application. The problem is that all objects on the Calendar page are contained inside of a Frame. To access the frame elements and perform actions against them, you need to access the frame from the 'Frames[]' collection first.

Here is a sample code against your application:
// Launch an instance of the browser
Manager.LaunchNewBrowser();
 
ActiveBrowser.NavigateTo("https://mail.ex2.secureserver.net/owa");
 
HtmlInputPassword pass = ActiveBrowser.Find.ById<HtmlInputPassword>("password");
pass.Value = "Testing1";
 
ActiveBrowser.Find.ByExpression<HtmlInputSubmit>("type=submit").Click();
 
ActiveBrowser.Find.ById<HtmlControl>("lnkCal").MouseClick();
 
System.Threading.Thread.Sleep(8000);
 
//Refresh DOM tree
ActiveBrowser.RefreshDomTree();
 
//Get the IFrame
ArtOfTest.WebAii.Core.Browser frame = ActiveBrowser.Frames[0];
Assert.IsNotNull(frame);
 
//Click on the arrow button and navigate to next date in the Calendar
frame.Find.ById<HtmlDiv>("divNPN").MouseClick();
System.Threading.Thread.Sleep(3000);

This code will navigate to the Calendar page, get the frame from the 'Frames[]' collection and click on the arrow button to navigate to the next date in the Calendar. See this video.

Hope this helps!

Kind regards,
Plamen
the Telerik team
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
0
Matt
Top achievements
Rank 1
answered on 20 Apr 2012, 05:06 PM
Thanks for the help Plamen! I'll give that a try.
0
Yatindra
Top achievements
Rank 1
answered on 28 May 2013, 04:00 PM
Hi,

I am having a similar issue, i discovered in the web application that i was testing against, it generates modal pop-up(child) windows, the DOM of which gets added the DOM of the main page(parent page), so when i do a Manager.ActiveBrowser.RefreshDomTree() it discovers the element present on the child pop-up window.

So my sample code is below:

Manager.ActiveBrowser.Find.ByExpression<HtmlImage>(new HtmlFindExpression("tagname=img", "id="parentpagesubmitbtn")).Click();
Thread.Sleep(2000); //wait for a random time here 2 secs for the popup
Manager.ActiveBrowser.RefreshDomTree(); //refresh the dom
HtmlDiv divModalpopup = Manager.ActiveBrowser.Find.ByExpression<HtmlDiv>(new HtmlFindExpression("tagname=div", "id=divonthemodalpopup"));
               
I need to do a random wait of 2 secs even though the popup apears earlier, i noticed that if i do away with the thread.sleep(2000) ,the manager object cant find the element on the popup. Is there anyway to do away with the Thread.sleep and have something like the manager.waituntilready to wait till the popup content loads and then do a refresh on the DOM tree? I hope i explained myself clearly here. I dont want to introduce sleep in my code.

0
Matt
Top achievements
Rank 1
answered on 28 May 2013, 04:17 PM

@Yatindra - When I connect to a new window I usually add a statement similiar to: 

Manager.WaitForNewBrowserConnect("http://www.telerik.com", true, 3000);

This way I don't have to add a Thread.Sleep(3000) and it will continue once it is finds the new window.

0
Yatindra
Top achievements
Rank 1
answered on 28 May 2013, 04:20 PM
Hi Matt,

Thanks for the quick response. The issue is that Its a modal pop-up(usually a div) not a Html modal, so will that work for the same. Technically it doesnt open in a new browser window, but inside the same parent page container.
0
Matt
Top achievements
Rank 1
answered on 28 May 2013, 04:57 PM
@Yatindra - Sorry about that! You are right, I don't believe the WaitForNewBrowserConnect will work for you. Looking back at my solution I couldn't find anything I would recommend for your issue. The only other wait I use is:
Manager.ActiveBrowser.WaitForElement(new HtmlFindExpression("id=example"), 4000, false);

Hopefully Telerik Support will be able to mention a better solution.
0
Yatindra
Top achievements
Rank 1
answered on 28 May 2013, 05:35 PM
Hi Matt,

Although your suggestion works.. the condition that i have built the test system is that I will not be introducing any manual timeout(sec) in the code at any place, hence i am using the waituntilready() function in the code and there isnt a sleep or timeout condition anywhere in the code. I would like to stick to that design, is there any way i can let the page dictate that it has completed the loading rather than giving manual timeouts in the code? Any suggestion woulld be helpful
0
Plamen
Telerik team
answered on 29 May 2013, 02:47 PM
Hi Yatindra,

Actually Matt is right, the best way to handle this scenario is to use the WaitForElement method and pass the timeout value as an argument to that method. Note that this is not a hard-coded timeout. Test Studio will wait up to the specified timeout value, refreshing the DOM tree, and at the moment the element is found in the DOM, it will proceed with the rest of the test.
Manager.ActiveBrowser.Find.ByExpression<HtmlImage>(new HtmlFindExpression("tagname=img", "id=parentpagesubmitbtn")).Click();
 
//Wait for element to exists and refresh the DOM tree 
HtmlDiv divModalpopup = Manager.ActiveBrowser.WaitForElement(new HtmlFindExpression("tagname=div", "id=divonthemodalpopup"), 30000, false).As<HtmlDiv>();

See this article for more information.

@Matt
Thank you for assisting another customer. I've updated your Telerik points accordingly.

Regards,
Plamen
Telerik
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
0
Yatindra
Top achievements
Rank 1
answered on 29 May 2013, 02:50 PM
Plamen,

Thanks for the reply, this issue is that by design i let the page dictate when it is loaded all it DOM, take for example a scenario where i specify the timeout condition in the waitforelement, but the page hasnt completely loaded and some processes are still going on for the DOM to be completely loaded.
0
Plamen
Telerik team
answered on 29 May 2013, 03:29 PM
Hello Yatindra,

Unfortunately these are the only three options we can offer you right now:
  • ActiveBrowser.WaitUntilReady() - This will wait for the browser to return to a ready state, but if you have processes running on the background(AJAX Postback for example) after the ready state is returned this will not work.
  • Wait for an AJAX Postback to Complete - This ensures synchronization with the postback event.
  • WaitForElement - Waits for a specific element to exists in DOM.

Regards,
Plamen
Telerik
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
0
Matt
Top achievements
Rank 1
answered on 29 May 2013, 03:41 PM
Hi Yatindra,

One last suggestion I have is if your page has a lot of AJAX connections I've also had success implementing this custom AJAX wait from forum post (http://www.telerik.com/automated-testing-tools/community/forums/test-studio-express/automation-framework/need-a-better-way-to-wait-for-ajax-operation-to-complete.aspx).

public void AjaxWait()
{
    Wait.For<int>(c => ActiveAjaxConnections() == 0, 0, 10000);
}
 
public int ActiveAjaxConnections()
{
    return Actions.InvokeScript<int>("jQuery.active");
}
0
Yatindra
Top achievements
Rank 1
answered on 29 May 2013, 03:45 PM
Thanks Plamen and Matt, you guys have been very helpful indeed I appreciate the help, i hope that Telerik will come out with a better solution for complete DOM rendering without having to introduce timeouts in the code. I will use the waitfor element right now with the timeout until we get a better solution in the future.
0
Scott
Top achievements
Rank 1
answered on 05 Oct 2013, 12:59 AM
Hi there,
I am having a similar issue to others.  I have a "very" simple AJAX / Jquery UI auto-complete box and all I am trying to do is to insure that it is populated when an expected search term is entered. 

Here is my code:

 

[TestMethod]
public void VerifySearchAutocomplete()
{
    _homePage = new HomePage(Manager);
 
    _homePage.SearchTermTextbox.Text = "Jesus";
    _homePage.SearchTermTextbox.InvokeEvent(ScriptEventType.OnKeyDown);
    ActiveBrowser.WaitForAjax(10000);
    ActiveBrowser.RefreshDomTree();
 
    Assert.IsTrue(_homePage.SearchAutocompleteList.IsVisible());
    Assert.IsTrue(_homePage.SearchAutocompleteList.Items.Any());
}

The problem is in the ActiveBrowser.WaitForAjax().  If I step through the code manually, it works with no problem.  However, if I let the code just run on its own (or as part of a group of tests), then it fails.  I believe the issue is that the "WaitForAjax()" is returning and the "RefreshDomTree()" is being called before the DOM is actually updated. 

Any ideas would be great!

0
Boyan Boev
Telerik team
answered on 10 Oct 2013, 07:09 AM
Hello Scott,

Please send us the trace log. What is the exception when the code fails.

You can also try refresh the DOM first and then wait for Ajax. 

Hope to hear from you soon.

Regards,
Boyan Boev
Telerik
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
0
Scott
Top achievements
Rank 1
answered on 14 Oct 2013, 11:26 PM
Hi Boyan,
I am not sure what "trace log" you are referring to.  However, the error I get when the code fails is that the "Assert.True()" failed.  This is happening because it is not seeing the DOM refreshed.  I also tried reversing the "RefreshDOM" and "WaitForAjax" but no luck.  Any ideas?
0
Boyan Boev
Telerik team
answered on 17 Oct 2013, 01:14 PM
Hello Matt,

I mean the log from the test, where the error/exception appears.

You can try out also this:

1. Sleep the thread for 10-15 secs before the assert:

System.Threading.Thread.Sleep(20000);

2. Increase Ajax timeout.

If the issue persists we need to reproduce the issue on our end to give you a solution. Please provide us with a copy of your test and if it is possible grant us access to your application so we can reproduce the issue on our end and give you a solution. 

If direct access is not possible, capture a Fiddler trace and attach it to this support ticket in a zip file. If you are unfamiliar with how to do so, this link will provide you with step-by-step instructions for download and use. Please make sure to enable 'Decrypt HTTPS traffic' and 'Store binaries' options (see attached image) before starting capture.

Hope to hear from you soon. 

Regards,
Boyan Boev
Telerik
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
Tags
General Discussions
Asked by
Matt
Top achievements
Rank 1
Answers by
Plamen
Telerik team
Matt
Top achievements
Rank 1
Yatindra
Top achievements
Rank 1
Scott
Top achievements
Rank 1
Boyan Boev
Telerik team
Share this question
or