1

I have the necessity of dynamically create instance of a page (using selenium) at runtime. The idea is to retrieve the class name from a string and initialize it.

Let's say that I have a "GenericPage":

    public class GenericPage
    {
       public void Proceed(string testName)
       {
         //Basic implementation
       }
    }

The second class inherit from GenericPage implementing Proceed

public class WhatIsYourNamePage : GenericPage
{
    [FindsBy(How = How.Id, Using = "fieldName")]
    [CacheLookup]
    private IWebElement UserName { get; set; }

    [FindsBy(How = How.Id, Using = "fieldSurname")]
    [CacheLookup]
    private IWebElement UserSurname { get; set; }

    [FindsBy(How = How.Id, Using = "submit-first-inner-1")]
    [CacheLookup]
    private IWebElement Submit { get; set; }

    new public void Proceed(string testName)
    {
        var userData = ExcelDataAccess.GetTestData(testName);
        UserName.EnterText(userData.fieldName, Costants.UserNameElementName);
        UserSurname.EnterText(userData.fieldSurname, Costants.SurnameElementName);
        Thread.Sleep(5000);
        Submit.ClickOnIt(Costants.SubmitButtonElementName);
        Thread.Sleep(5000);
    }
}

So here it is what I have tried to dynamically create WhatIsYourNamePage:

var type = Type.GetType("WhatIsYourNamePage");
var myObject = (GenericPage)Activator.CreateInstance(type);
myObject.Proceed("LogInTest");

Issue is that in this way it calls GenericPage.Proceed, but I want WhatIsYourNamePage.Proceed.

Of course I can change:

var myObject = (WhatIsYourNamePage)Activator.CreateInstance(type);

But I need to do this dynamically from a string. How?

igorc
  • 2,024
  • 2
  • 17
  • 29
Elminster_cs
  • 87
  • 1
  • 2
  • 14
  • Have a read here: https://stackoverflow.com/questions/159978/c-sharp-keyword-usage-virtualoverride-vs-new – kiziu Jun 26 '17 at 13:06

2 Answers2

1

Suppose you should declare Proceed method as virtual. Don't use new keyword to override the method in the inherited class (unless you really know what you are doing as it does not override method (OOP polymorphism) but hides it). So just override it with keyword override. If you do it in this way - the myObject.Proceed("LogInTest"); will be called in the inherited class without further code changing.

Something like this:

public class GenericPage
{
   public virtual void Proceed(string testName)
   {
     //Basic implementation
   }
}

public class WhatIsYourNamePage : GenericPage
{
    [FindsBy(How = How.Id, Using = "fieldName")]
    [CacheLookup]
    private IWebElement UserName { get; set; }

    [FindsBy(How = How.Id, Using = "fieldSurname")]
    [CacheLookup]
    private IWebElement UserSurname { get; set; }

    [FindsBy(How = How.Id, Using = "submit-first-inner-1")]
    [CacheLookup]
    private IWebElement Submit { get; set; }

    public override void Proceed(string testName)
    {
        var userData = ExcelDataAccess.GetTestData(testName);
        UserName.EnterText(userData.fieldName, Costants.UserNameElementName);
        UserSurname.EnterText(userData.fieldSurname, Costants.SurnameElementName);
        Thread.Sleep(5000);
        Submit.ClickOnIt(Costants.SubmitButtonElementName);
        Thread.Sleep(5000);
    }
}
Kantora
  • 111
  • 4
0

Although working with "new" methods hiding methods with the same name from a base class is always tricky, you can solve your problem by calling the method like this:

type.GetMethod("Proceed").Invoke(myObject, new[] { "LogInTest" });
Peter M.
  • 1,240
  • 2
  • 9
  • 25