Scope
I want to do automated web testing with Selenium and execute JavaScript. The string func1 contains my js-function and it is passed to ExecuteScript(func1) it returns an array of objects which look like this {label:'start', time: 121}.
I want to cast the result of ExecuteScript into List<timings>
var result = jsExecutor.ExecuteScript(func1);
var list = (ReadOnlyCollection<object>)result;
var timings = (List<Timing>)list;
I received the error
Cannot convert type 'System.Collections.ObjectModel.ReadOnlyCollection<object>'
to 'System.Collections.Generic.List<CoreConsoleApp.TestExecutions.Timing>'
This is func1
string func1= @"var t = window.performance.timing;
var timings = [];
timings.push({ label: 'navigationStart', time: t.navigationStart });
timings.push({ label: 'PageLoadTime', time: t.loadEventEnd - t.navigationStart });
return timings;" // result is an array of js-objects
The code below is a snippet of the selenium part
public struct Timing
{
public string label;
public int time;
}
using (var driver = new FirefoxDriver())
{
...
var jsExecutor = (IJavaScriptExecutor)driver;
var result = jsExecutor.ExecuteScript(func1);
var list = (ReadOnlyCollection<object>)result;
}
Questions
The selenium docs state that ExecuteScript attempts to return a List for an array.
Func1 should return array of {label: string, time: number} it should be easy to cast the result var list = (ReadOnlyCollection<object>)result into List<string,int> timings = (List<timings>)list;
- What can i do to cast 'System.Collections.ObjectModel.ReadOnlyCollection' into List?
More Info
Start Firefox var driver = new FirefoxDriver() open a URL driver.Navigate().GoToUrl(url); find a certain button IWebElement button = driver.FindElement(By.Name("btnK")); submit the form button.Submit(); After the submission execute JavaScript ExecuteScript(func1) and write the result to the console
The above all works. But i have trouble to cast the JavaScript into a list of c# objects.
So my workaround is this
var result = jsExecutor.ExecuteScript(func1);
var list = (ReadOnlyCollection<object>)result;
foreach (object item in list)
{
var timing = (Dictionary<string, object>)item;
foreach(KeyValuePair<string, object> kvp in timing)
{
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
}
This puts out:
Key = label, Value = navigationStart
Key = time, Value = 1529720672670
Key = label, Value = PageLoadTime
Key = time, Value = 1194
Key = label, Value = DOMContentLoadedTime
Key = time, Value = 589
Key = label, Value = ResponseTime
