End Goal for serializing FirefoxDriver (my question here) = making WebDriver faster!!
Below is a link that describes how to serialize an object. But it requires you implement from ISerializable for the object you are serializing. What I'd like to do is serialize an object that I did not define--an object based on a class in a 3rd party assembly (from a project reference) that is not implementing ISerializable. Is that possible? How can this be done?
http://www.switchonthecode.com/tutorials/csharp-tutorial-serialize-objects-to-a-file
Property (IWebDriver = interface type):
private IWebDriver driver;
Object Instance (FireFoxDriver is a class type):
driver = new FirefoxDriver(firefoxProfile);
================
3/21/2012 update after answer posted
Why would this throw an error? It doesn't like this line:
serializedObject.DriverInstance = (FirefoxDriver)driver;
...
Error:
Cannot implicitly convert type 'OpenQA.Selenium.IWebDriver' to 'OpenQA.Selenium.Firefox.FirefoxDriver'. An explicit conversion exists (are you missing a cast?)
Here is the code:
FirefoxDriverSerialized serializedObject = new FirefoxDriverSerialized();
Serializer serializer = new Serializer();
serializedObject = serializer.DeSerializeObject(@"C:\firefoxDriver.qa");
driver = serializedObject.DriverInstance;
if (driver == null)
{
driver = new FirefoxDriver(firefoxProfile);
serializedObject.DriverInstance = (FirefoxDriverSerialized)driver;
serializer.SerializeObject(@"C:\firefoxDriver.qa", serializedObject);
}
Here are the two Serializer classes I built:
public class Serializer
{
public Serializer()
{
}
public void SerializeObject(string filename, FirefoxDriverSerialized objectToSerialize)
{
Stream stream = File.Open(filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize);
stream.Close();
}
public FirefoxDriverSerialized DeSerializeObject(string filename)
{
FirefoxDriverSerialized objectToSerialize;
Stream stream = File.Open(filename, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
objectToSerialize = (FirefoxDriverSerialized)bFormatter.Deserialize(stream);
stream.Close();
return objectToSerialize;
}
}
[Serializable()]
public class FirefoxDriverSerialized : FirefoxDriver, ISerializable
{
private FirefoxDriver driverInstance;
public FirefoxDriver DriverInstance
{
get { return this.driverInstance; }
set { this.driverInstance = value; }
}
public FirefoxDriverSerialized()
{
}
public FirefoxDriverSerialized(SerializationInfo info, StreamingContext ctxt)
{
this.driverInstance = (FirefoxDriver)info.GetValue("DriverInstance", typeof(FirefoxDriver));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("DriverInstance", this.driverInstance);
}
}
=================
3/23/2012 update #2 - fixed serialization/de-serialization, but having another issue
This fixed the calling code. Because we're deleting the *.qa file when we call the WebDriver.Quit() because that's when we chose to close the browser. This will kill off our cached driver as well. So if we start with a new browser window, we'll hit the catch block and create a new instance and save it to our *.qa file (in the serialized form).
FirefoxDriverSerialized serializedObject = new FirefoxDriverSerialized();
Serializer serializer = new Serializer();
try
{
serializedObject = serializer.DeSerializeObject(@"C:\firefoxDriver.qa");
driver = serializedObject.DriverInstance;
}
catch
{
driver = new FirefoxDriver(firefoxProfile);
serializedObject = new FirefoxDriverSerialized();
serializedObject.DriverInstance = (FirefoxDriver)driver;
serializer.SerializeObject(@"C:\firefoxDriver.qa", serializedObject);
}
However, still getting this exception:
Acu.QA.Main.Test_0055_GiftCertificate_UserCheckout:
SetUp : System.Runtime.Serialization.SerializationException : Type 'OpenQA.Selenium.Firefox.FirefoxDriver' in Assembly 'WebDriver, Version=2.16.0.0, Culture=neutral, PublicKeyToken=1c2bd1631853048f' is not marked as serializable.
TearDown : System.NullReferenceException : Object reference not set to an instance of an object.
The 3rd line in this code block is throwing the exception:
public void SerializeObject(string filename, FirefoxDriverSerialized objectToSerialize)
{
Stream stream = File.Open(filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize); // <=== this line
stream.Close();
}
====================
update #3 - 3/24/2012 - simplified FirefoxDriver instance by not passing anything to the constructor. I'll make it more complex later by passing in FirefoxProfile into the constructor. I still get the same exception as update #2.
Calling code:
FirefoxDriverSerialized serializedObject = new FirefoxDriverSerialized();
Serializer serializer = new Serializer();
try
{
serializedObject = serializer.DeSerializeObject(@"C:\firefoxDriver.qa");
driver = serializedObject.DriverInstance;
}
catch
{
//driver = new FirefoxDriver(firefoxProfile);
driver = new FirefoxDriver();
serializedObject.DriverInstance = (FirefoxDriver)driver;
serializer.SerializeObject(@"C:\firefoxDriver.qa", serializedObject);
}
Also had to add ": base()" to my constructor in my serialized object class:
[Serializable()]
public class FirefoxDriverSerialized : FirefoxDriver, ISerializable
{
private FirefoxDriver driverInstance;
public FirefoxDriver DriverInstance
{
get { return this.driverInstance; }
set { this.driverInstance = value; }
}
public FirefoxDriverSerialized() : base()
{
}
public FirefoxDriverSerialized(SerializationInfo info, StreamingContext ctxt)
{
this.driverInstance = (FirefoxDriver)info.GetValue("DriverInstance", typeof(FirefoxDriver));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("DriverInstance", this.driverInstance);
}
}
=============
Update #4 - just documenting stub signatures for OpenQA.Selenium.Firefox.FirefoxDriver class
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using System;
namespace OpenQA.Selenium.Firefox
{
public class FirefoxDriver : RemoteWebDriver, ITakesScreenshot
{
// CLASS DATA MEMBERS
//public static readonly bool AcceptUntrustedCertificates;
//public static readonly string BinaryCapabilityName;
//public static readonly bool DefaultEnableNativeEvents;
//public static readonly int DefaultPort;
//public static readonly string ProfileCapabilityName;
// CONSTRUCTORS
//public FirefoxDriver();
//public FirefoxDriver(FirefoxProfile profile);
//public FirefoxDriver(ICapabilities capabilities);
//public FirefoxDriver(FirefoxBinary binary, FirefoxProfile profile);
//public FirefoxDriver(FirefoxBinary binary, FirefoxProfile profile, TimeSpan commandTimeout);
// PROPERTIES
protected FirefoxBinary Binary { get; }
protected FirefoxProfile Profile { get; }
// METHODS
//protected override RemoteWebElement CreateElement(string elementId);
//public Screenshot GetScreenshot();
//protected void PrepareEnvironment();
//protected override void StartClient();
//protected override void StopClient();
}
}