0

I am trying to figure out how to get the JSON equivalent of a highchart graph returned to me using Selenium and C#. I got pretty far, but I am hitting a couple issues. For the specific highchart, perform the following steps:

Issue #1

I can use the below function in the Console tab of DEV tools to retrieve the data in JSON format, but it does not organize it correctly (it lists all EPA's first, then all values of those EPAs second) JSON.stringify(angular.element($('#EPAChart')).scope().$parent.vm['epaGraphData']);

When I plug this into Visual Studio with C# and Selenium and then try to convert this to a DataTable, it does not allow me because the data is not organized correctly. For a similar issue, see : Newtonsoft.Json JsonConvert To Datatable

using Newtonsoft.Json;
using OpenQA.Selenium;
string jsText = string.Format("return JSON.stringify(angular.element($('#EPAChart')).scope().$parent.vm['epaGraphData']);")
var jsResult = driver.ExecuteScript(jsText) as string;
JsonConvert.DeserializeObject<DataTable>(jsResult);

Issue #2

I have a Javascript/Jquery function which produces the JSON organized correctly, but I dont know how to call it using Selenium/C#. The code, driver.ExecuteScript, does not like this function, I guess because it is too complicated and uses variables, so driver.ExecuteScript (IJavaScriptExecutor->ExecuteScript) throws an exception. Here is the function:

var epadatasource = []; for(var i=0;i<angular.element($('#EPAChart')).scope().$parent.vm['epaGraphData'].Categories.length;i++){epadatasource.push({category: angular.element($('#EPAChart')).scope().$parent.vm['epaGraphData'].Categories[i], data: angular.element($('#EPAChart')).scope().$parent.vm['epaGraphData'].Data[i]}); }; JSON.stringify(epadatasource);

For Issue #2, how do I call the above function in C#/Selenium so that it doesnt throw an exception and instead returns my JSON? Or for issue #1, is there a workaround to organize that JSON correctly?

Mike Johnston
  • 237
  • 6
  • 20
  • These are two separate questions. You should break out Issue #2 here and put it into a new question to avoid confusion with the answers and make it easier to answer in case someone knows the answer to one but not the other. – JeffC Aug 04 '17 at 17:31
  • For Issue #2, put the whole thing in a `string` as you did in Issue #1 code and add `return` before the last command, e.g. `return JSON.stringify(...)` and it should work. It works in the console but in code, you have to return something. – JeffC Aug 04 '17 at 17:42
  • Thank. I added the answer – Mike Johnston Aug 04 '17 at 18:03

1 Answers1

0

I figured out a workaround for issue #1 and @jeffC provdided the solution to issue #2

Issue 1 resolution is to add JSON to C# object, then convert it to a new object, and deserialize it for a fixed JSON:

  public static string TransformJSON(string json, IWebElement chartElem)
    {
        string fixedJson = "";

        if (chartElem.GetAttribute("id") == "EPAChart")
        {
            dynamic obj = JsonConvert.DeserializeObject<EPAObservationCountOriginal>(json);
            List<EPAObservationCountFixed> fixedObject = new List<EPAObservationCountFixed>();
            for (int i = 0; i < obj.Categories.Length; i++)
            {
                fixedObject.Add(new EPAObservationCountFixed() { category = obj.Categories[i], data = obj.Data[i] });
            }

            fixedJson = JsonConvert.SerializeObject(fixedObject);
        }

        return fixedJson;
    }

    #endregion methods

    #region Class objects representing graphs

    public class EPAObservationCountFixed
    {
        public string category { get; set; }
        public string data { get; set; }
    }

    public class EPAObservationCountOriginal
    {
        public string[] Categories { get; set; }
        public string[] Data { get; set; }
    }

Issue 2 resolution is to add the word "return" in the function:

var epadatasource = []; for(var i=0;i<angular.element($('#EPAChart')).scope().$parent.vm['epaGraphData'].Categories.length;i++){epadatasource.push({category: angular.element($('#EPAChart')).scope().$parent.vm['epaGraphData'].Categories[i], data: angular.element($('#EPAChart')).scope().$parent.vm['epaGraphData'].Data[i]}); }; return JSON.stringify(epadatasource);
Mike Johnston
  • 237
  • 6
  • 20