Search code examples
c#seleniumselenium-webdriverselenium-chromedriverselenium4

Could not load type 'OpenQA.Selenium.Internal.IWrapsElement' from assembly 'WebDriver, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null'


I am creating automated tests with selenium and specflow using C#. Today I had to update Selenium.WebDriver to version 4.0.0-beta4 because of logging functionality, which has a bug in previous versions with AvailableLogTypes property, which was always throwing null reference exceptions. After updating to selenium 4, another problem raised up. Build works fine without errors or warnings but when I run tests, following exception is thrown:

Message: 
    System.TypeLoadException : Could not load type 'OpenQA.Selenium.Internal.IWrapsElement' from assembly 'WebDriver, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null'.

Stack Trace: 
    DefaultPageObjectMemberDecorator.CreateProxyObject(Type memberType, IElementLocator locator, IEnumerable`1 bys, Boolean cache)
    DefaultPageObjectMemberDecorator.Decorate(MemberInfo member, IElementLocator locator)
    PageFactory.InitElements(Object page, IElementLocator locator, IPageObjectMemberDecorator decorator)
    PageFactory.InitElements(Object page, IElementLocator locator)
    PageFactory.InitElements(ISearchContext driver, Object page)
    LoginPageElements.ctor(IWebDriver driver) line 12
    PortalSharedPageSteps.CheckUIElementsOfLoginScreen() line 32
    LoginPageTestSteps.CheckUIElementsOfLoginScreenStep() line 21
    BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration)
    TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments, TimeSpan& duration)
    TestExecutionEngine.ExecuteStep(IContextManager contextManager, StepInstance stepInstance)
    TestExecutionEngine.OnAfterLastStep()
    TestRunner.CollectScenarioErrors()
    LoginPageTestFeature.ScenarioCleanup()
    LoginPageTestFeature.LoginPageTest() line 9

From official release notes of selenium:

Per v4.0.0a1 in https://github.com/SeleniumHQ/selenium/blob/master/dotnet/CHANGELOG "Moved IWrapsDriver and IWrapsElement from the OpenQA.Selenium.Internal namespace to the OpenQA.Selenium namespace. This should be a no-op for the vast majority of users, requiring only a recompile of code, given that both of these interfaces feature return types in the base namespace, meaning that users likely already have "using" statements for the root namespace in their source. If errors are encountered, changing the namespace in the code and rebuilding should resolve the error."

I double checked for all occurrences of OpenQA.Selenium.Internal namespace and found out, that this namespace is not even used in my code. So I supposed that everything will work fine, but no ...

Later on I found out that everything works if I remove DotNetSeleniumExtras.PageObjects nuget package. That's nice, but I need this package to be able to use PageFactory.InitElements() for page objects initialization and FindsBy attribute to bind UI elements. I inspected DotNetSeleniumExtras.PageObjects package and it also uses selenium 4.

Do you have any ideas how to solve this problem ? Let me know if you need to see source code (it is quite extensive so, I did not want to bloat this post)


Solution

  • So here is how I fixed this:

    1. I removed DotNetSeleniumExtras packages from code.
      After that, I was finally able to gather performance logs from browser because I got rid of errors shown in my question.
    2. After removal of DotNetSeleniumExtras package I lost PageFactory for initialization of page objects.
      I fixed this problem by converting all web elements (properties of page object) into computed properties:
    public class PageObject
    {
        private readonly IWebDriver driver;         
    
        public IWebElement PageLink => driver.FindElement(By.XPath(@"my custom XPath"));
        public IWebElement TitleMain => driver.FindElement(By.Id("some Id"));
    
        // etc
    
        public PageObject(IWebDriver webDriver)
        {
             driver = webDrvier;
        }
    }
    

    Code below shows an example how class above would be used:

    var pageObj = new PageObject(driver);
    Console.Writeline(pageObj.PageLink.Enabled);
    

    PS: thanks to RichEdwards for giving me a hint how to solve this problem