DOM Refresh issue - AJAX

19 posts, 0 answers
  1. Matt
    Matt avatar
    6 posts
    Member since:
    Jul 2010

    Posted 12 Apr 2012 Link to this post

    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();



  2. Plamen
    Admin
    Plamen avatar
    8 posts

    Posted 17 Apr 2012 Link to this post

    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
  3. Matt
    Matt avatar
    6 posts
    Member since:
    Jul 2010

    Posted 17 Apr 2012 Link to this post

    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);
            }



  4. Plamen
    Admin
    Plamen avatar
    8 posts

    Posted 20 Apr 2012 Link to this post

    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
  5. Matt
    Matt avatar
    6 posts
    Member since:
    Jul 2010

    Posted 20 Apr 2012 Link to this post

    Thanks for the help Plamen! I'll give that a try.
  6. Yatindra
    Yatindra avatar
    8 posts
    Member since:
    Apr 2013

    Posted 28 May 2013 Link to this post

    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.

  7. Matt
    Matt avatar
    6 posts
    Member since:
    Jul 2010

    Posted 28 May 2013 Link to this post

    @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.

  8. Yatindra
    Yatindra avatar
    8 posts
    Member since:
    Apr 2013

    Posted 28 May 2013 Link to this post

    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.
  9. Matt
    Matt avatar
    6 posts
    Member since:
    Jul 2010

    Posted 28 May 2013 Link to this post

    @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.
  10. Yatindra
    Yatindra avatar
    8 posts
    Member since:
    Apr 2013

    Posted 28 May 2013 Link to this post

    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
  11. Plamen
    Admin
    Plamen avatar
    8 posts

    Posted 29 May 2013 Link to this post

    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
  12. Yatindra
    Yatindra avatar
    8 posts
    Member since:
    Apr 2013

    Posted 29 May 2013 Link to this post

    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.
  13. Plamen
    Admin
    Plamen avatar
    8 posts

    Posted 29 May 2013 Link to this post

    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
  14. Matt
    Matt avatar
    6 posts
    Member since:
    Jul 2010

    Posted 29 May 2013 Link to this post

    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");
    }
  15. Yatindra
    Yatindra avatar
    8 posts
    Member since:
    Apr 2013

    Posted 29 May 2013 Link to this post

    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.
  16. Scott
    Scott avatar
    2 posts
    Member since:
    Oct 2013

    Posted 04 Oct 2013 Link to this post

    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!

  17. Boyan Boev
    Admin
    Boyan Boev avatar
    1039 posts

    Posted 10 Oct 2013 Link to this post

    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
  18. Scott
    Scott avatar
    2 posts
    Member since:
    Oct 2013

    Posted 14 Oct 2013 Link to this post

    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?
  19. Boyan Boev
    Admin
    Boyan Boev avatar
    1039 posts

    Posted 17 Oct 2013 Link to this post

    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
Back to Top