Search code examples
c#xpathloadinghtmlawesomium

Page not loading and hangs in Awesomium


I need help in loading a page fully. I’m trying to automate a search in Dassault Enovia PLM system. I’m able to successfully login to the site with help from Chris - How to login... and then navigate the search page as well, however the search page doesn’t load fully and it hangs. Following is my source code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Awesomium.Core;
using System.Threading;

namespace Awesom
{
    class Program2
    {
        dynamic document = null;

        public static void Main(String[] args)
        {
            Program2 pg = new Program2();

            Console.WriteLine("Started....");

            WebView wv = WebCore.CreateWebView(1024, 600);

            wv.Source = new Uri("http://somecompany.app.com/ematrix/emxLogin.jsp");

            FrameEventHandler handler = null;
            handler = (s, e) =>
            {
                if (e.IsMainFrame)
                {
                    // we have finished loading main page,
                    // let's unhook ourselves
                    wv.LoadingFrameComplete -= handler;

                    //LoginAndTakeScreenShot(wv);
                    pg.LoginAndTakeScreenShot1(wv);
                }
            };

            wv.LoadingFrameComplete += handler;

            WebCore.Run();
        }


        private void LoginAndTakeScreenShot1(WebView wv)
        {
            document = (JSObject)wv.ExecuteJavascriptWithResult("document");
            using (document)
            {
                String userInput = @"//*[@id=""divLogin""]/form/table/tbody/tr[2]/td/table/tbody/tr/td[3]/div/div/input";

                String userNameXpath = userInput + "[1]" ;

                var username = document.evaluate(userNameXpath, document, null, 9, null).singleNodeValue;
                username.value = "ffffAddd";

                String passwordXPath = userInput + "[2]";

                var password = document.evaluate(passwordXPath, document, null, 9, null).singleNodeValue;
                password.value = "aPassword";

                int i = 0;

                FrameEventHandler handler = null;
                handler = (sender, args) =>
                {
                    //BitmapSurface img = (BitmapSurface)wv.Surface;
                    //img.SaveToPNG(String.Format("loading{0}.png", ++i), true);

                    if (args.IsMainFrame)
                    {
                        if (!wv.IsLoading)
                        {
                            wv.LoadingFrameComplete -= handler;

                            BitmapSurface surface = (BitmapSurface)wv.Surface;
                            Thread.Sleep(30000);
                            surface.SaveToPNG("result.png", true);
                            OpenSearchPage(wv);

                            //WebCore.Shutdown();
                        }
                    }
                };

                wv.LoadingFrameComplete += handler;

                String loginButtonXPath = userInput + "[3]";

                var loginButton = document.evaluate(loginButtonXPath, document, null, 9, null).singleNodeValue;
                loginButton.click();
            }
        }

        private void OpenSearchPage(WebView wv)
        {
            using (document)
            {
                int i = 0;

                FrameEventHandler handler = null;
                handler = (sender, args) =>
                {
                    BitmapSurface img = (BitmapSurface)wv.Surface;
                    img.SaveToPNG(String.Format("loading{0}.png", ++i), true);
                    Console.WriteLine("Iteration {0}", i);

                    bool MainFrameLoaded = args.IsMainFrame;

                    //After 4 the iteration, Awesomium hangs

                    if (MainFrameLoaded && !wv.IsLoading)
                    {
                        wv.LoadingFrameComplete -= handler;
                        BitmapSurface surface = (BitmapSurface)wv.Surface;
                        Thread.Sleep(30000);
                        surface.SaveToPNG("search.png", true);
                        WebCore.Shutdown();
                    }
                };

                //Search Page URL

                wv.Source = new Uri("http://somecompany.app.com/ematrix/common/emxFullSearch.jsp?field=TYPES%3Dtype_Part%3APOLICY%3Dpolicy_ECPart%2Cpolicy_DevelopmentPart&showInitialResults=false&table=ENCPartSearchResult&selection=multiple&toolbar=ENCPartSearchToolbar&freezePane=ActiveECRECO%2CName&HelpMarker=emxhelpfullsearch&formInclusionList=PRT_DESCRIPTION&suiteKey=EngineeringCentral&StringResourceFileId=emxEngineeringCentralStringResource&SuiteDirectory=engineeringcentral");

                wv.LoadingFrameComplete += handler;
            }
        }
    }
}

The actual search page that is expected to load is as following and it loads as expected in all the browsers:

enter image description here

What loads in Awesomium is as follows:

enter image description here

Anyone please help to load the page as expected in Awesomium.

Kind Regards, Abbas


Solution

  • After a week of exploring Awesomium, I got the solution. FrameEventArgs.IsMainFrame in LoadingFrameComplete event doesn't guarantee that all the elements and frames of the required page is loaded, hence we need to have a mechanism ensure that. I've picked a HTMLElement and kept checking if that element has been loaded or not, upon the required element been loaded, I concluded that required page has been loaded. Following is the code that works for this issue.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.CompilerServices;
    using System.Reflection;
    using System.Threading;
    using System.IO;
    
    using Awesomium.Core;
    
    namespace AweSomiumExample
    {
        class Program
        {
            WebView wv;
            int i = 0;
            int k = 0;
            dynamic PageReady;
            bool DocumentReady;
    
            public String login { get; private set; }
            public String passw { get; private set; }
    
            public static void Main(String[] args)
            {
                Program pg = new Program();
            }
    
            public Program()
            {
                wv = WebCore.CreateWebView(1024, 600);
    
                wv.Source = new Uri("http://somecompany.app.com/ematrix/emxLogin.jsp");
    
                login = "ffffAddd";
                passw = "aPassword";
    
                wv.LoadingFrameComplete += MainPageLoadingFrameComplete;
                wv.DocumentReady += OnDocumentReadyHandler;
    
                WebCore.Run();
            }
    
            private void MainPageLoadingFrameComplete(Object sender, FrameEventArgs e)
            {
                try
                {
                    if (!e.IsMainFrame)
                    {
                        wait();
                    }
                    else
                    {
                        String userInput = @"//*[@id=""divLogin""]/form/table/tbody/tr[2]/td/table/tbody/tr/td[3]/div/div/input";
                        String userNameXpath = userInput + "[1]";
                        String passwordXPath = userInput + "[2]";
                        String loginButtonXPath = userInput + "[3]";
    
                        wv.LoadingFrameComplete -= MainPageLoadingFrameComplete;
    
                        dynamic xPathUserNameObj = GetXPathElement(userNameXpath);
                        using (xPathUserNameObj)
                        {
                            var username = xPathUserNameObj;
                            username.value = login;
                        }
    
                        dynamic xPathPasswordObj = GetXPathElement(passwordXPath);
                        using (xPathPasswordObj)
                        {
                            var password = xPathPasswordObj;
                            password.value = passw;
                        }
    
                        TakeScreenShot();
    
                        dynamic xPathLoginButtonObj = GetXPathElement(loginButtonXPath);
                        using (xPathLoginButtonObj)
                        {
                            var loginButton = xPathLoginButtonObj;
    
                            wv.LoadingFrameComplete += LoginFrameComplete;
    
                            loginButton.click();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log(ex.Message);
                    wait();
                }
            }
    
            private void LoginFrameComplete(Object sender, FrameEventArgs e)
            {
                try
                {
                    PageReady = (PageReady == null) ? GetXPathElement(@"//*[@id=""SearchIcon""]") : PageReady;
                    if (PageReady != null)
                    {
                        Log(String.Format("Running {0}", ++k));
                        wv.LoadingFrameComplete -= LoginFrameComplete;
                        TakeScreenShot();
    
                        wv.LoadingFrameComplete += SearchFrameComplete;
    
                        wv.Source = new Uri("http://somecompany.app.com/ematrix/common/emxFullSearch.jsp?field=TYPES%3Dtype_Part%3APOLICY%3Dpolicy_ECPart%2Cpolicy_DevelopmentPart&showInitialResults=false&table=ENCPartSearchResult&selection=multiple&toolbar=ENCPartSearchToolbar&freezePane=ActiveECRECO%2CName&HelpMarker=emxhelpfullsearch&formInclusionList=PRT_DESCRIPTION&suiteKey=EngineeringCentral&StringResourceFileId=emxEngineeringCentralStringResource&SuiteDirectory=engineeringcentral");
    
                        wait();
                        PageReady = null;
                    }
                    else
                    {
                        wait();
                    }
                }
                catch (Exception ex)
                {
                    Log(ex.Message);
                    wait();
                }
            }
    
            private void SearchFrameComplete(Object sender, FrameEventArgs e)
            {
                try
                {
                    PageReady = (PageReady == null) ? GetXPathElement(@"//*[@id=""NAME""]") : PageReady;
                    if (PageReady != null)
                    {
                        Log(String.Format("Running {0}", ++k));
                        wv.LoadingFrameComplete -= LoginFrameComplete;
                        TakeScreenShot();
    
                        Log("Success");
                        TakeScreenShot("Final");
                        wv.LoadingFrameComplete -= SearchFrameComplete;
                        wv.DocumentReady -= OnDocumentReadyHandler;
                        WebCore.Shutdown();
                    }
                    else
                    {
                        TakeScreenShot("SearchScreen");
                        wait();
                    }
                }
                catch (Exception ex)
                {
                    Log(ex.Message);
                    wait();
                }
            }
    
            private void OnDocumentReadyHandler(Object Sender, DocumentReadyEventArgs e)
            {
                Log(String.Format("Running {0}", ++k));
                if (e != null && e.ReadyState == DocumentReadyState.Loaded)
                {
                    TakeScreenShot("DocumentReady_True");
                    Log("DocumentReady = true");
                    DocumentReady = true;
                }
                else
                {
                    TakeScreenShot("DocumentReady_False");
                    Log("DocumentReady = false");
                    DocumentReady = false;
                    //WebCore.Run();
                }
            }
    
            private dynamic GetXPathElement(String xpath)
            {
                try
                {
                    if (wv.IsDocumentReady == false)
                    {
                        return null;
                    }
    
                    String xpathString = String.Format(@"document.evaluate('{0}',document,null,9,null);", xpath);
                    dynamic dc = (JSObject)wv.ExecuteJavascriptWithResult(xpathString);
                    if (dc != null && dc is JSObject)
                    {
                        using (dc)
                        {
                            dynamic SingleNodeObj = dc.singleNodeValue;
                            if (SingleNodeObj != null && SingleNodeObj is JSObject)
                            {
                                return SingleNodeObj;
                            }
                            else
                            {
                                return null;
                            }
                        }
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    Log(ex.Message);
                    return null;
                }
    
            }
    
            private void TakeScreenShot(String Name = "Image")
            {
                //Thread.Sleep(3000);
                BitmapSurface surface = (BitmapSurface)wv.Surface;
                surface.SaveToPNG(String.Format("{0}_{1}.png", ++i, Name), true);
                Log(String.Format("ScreenShot Taken {0}", i));
            }
    
            private static void Log(string text,
                            [CallerFilePath] string file = "",
                            [CallerMemberName] string member = "",
                            [CallerLineNumber] int line = 0)
            {
                Console.WriteLine("{0}_{1}({2}): {3}", Path.GetFileName(file), member, line, text);
            }
    
            private void wait(int waitTime = 10000)
            {
                Log(String.Format("Wait {0} seconds for the page to load", (int)(waitTime / 1000)));
                Thread.Sleep(waitTime);
            }
        }
    }
    

    Resultant Page Loaded: enter image description here