#StackBounty: #c# #selenium #selenium-webdriver #deprecation-warning How to fix 'IHasInputDevices is obsolete. Use the Actions or A…

Bounty: 50

After upgrading the Selenium NuGet packages in our solution to version 3.141.0 (both Selenium.WebDriver and Selenium.Support), the IHasInputDevices interface now has a warning:

‘IHasInputDevices’ is obsolete. ‘Use the Actions or ActionsBuilder class to simulate mouse and keyboard input.’

Screenshot of deprecation warning in Visual Studio

I created a utility class called LazyWebDriver, which implements the IWebDriver, IHasInputDevices and IActionExecutor interfaces. The LazyWebDriver class delays the instantiation of ChromeDriver until a member of IWebDriver gets accessed. This allows us to pass an IWebDriver object around and delay the appearance of the browser window, in case a test fails during the setup phase.

Code for the LazyWebDriver class:

public class LazyWebDriver : IWebDriver/*, IHasInputDevices*/, IActionExecutor
{
    private System.Func<IWebDriver> createDriver;
    private IWebDriver driver;

    private IWebDriver Driver
    {
        get
        {
            if (driver == null)
                driver = createDriver();

            return driver;
        }
    }

    public string Url
    {
        get => Driver.Url;
        set => Driver.Url = value;
    }

    public string Title => Driver.Title;

    public string PageSource => Driver.PageSource;

    public string CurrentWindowHandle => Driver.CurrentWindowHandle;

    public ReadOnlyCollection<string> WindowHandles => Driver.WindowHandles;

    public IKeyboard Keyboard => ((IHasInputDevices)Driver).Keyboard;

    public IMouse Mouse => ((IHasInputDevices)Driver).Mouse;

    public bool IsActionExecutor => ((IActionExecutor)Driver).IsActionExecutor;

    public LazyWebDriver(System.Func<IWebDriver> createDriver)
    {
        this.createDriver = createDriver;
    }

    public void Close()
    {
        Driver.Close();
    }

    public void Dispose()
    {
        Driver.Dispose();
    }

    public IWebElement FindElement(By by)
    {
        return Driver.FindElement(by);
    }

    public ReadOnlyCollection<IWebElement> FindElements(By by)
    {
        return Driver.FindElements(by);
    }

    public IOptions Manage()
    {
        return Driver.Manage();
    }

    public INavigation Navigate()
    {
        return Driver.Navigate();
    }

    public void Quit()
    {
        Driver.Quit();
    }

    public ITargetLocator SwitchTo()
    {
        return Driver.SwitchTo();
    }

    public void PerformActions(IList<ActionSequence> actionSequenceList)
    {
        ((IActionExecutor)Driver).PerformActions(actionSequenceList);
    }

    public void ResetInputState()
    {
        ((IActionExecutor)Driver).ResetInputState();
    }
}

The warning indicates to use the Actions or ActionBuilder class, so I removed the IHasInputDevices interface from the LazyWebDriver class, and attempted to use the Actions class:

[TestClass]
public class DeprecatedInterfaceTest
{
    [TestMethod]
    public void Test()
    {
        using (var driver = new LazyWebDriver(() => new ChromeDriver()))
        {
            driver.Navigate().GoToUrl("https://www.stackoverflow.com");

            var link = driver.FindElement(By.CssSelector("a[href='/teams/customers']"));
            var actions = new Actions(driver);

            actions = actions.MoveToElement(link);
            actions = actions.Click(link);
            actions.Perform();
        }
    }
}

The test failed with the following error message:

Test method DeprecatedInterfaceTest.Test threw exception:
System.ArgumentException: The IWebDriver object must implement or wrap a driver that implements IHasInputDevices.
Parameter name: driver

The test fails at this line:

var actions = new Actions(driver);

I did some searching online, and I didn’t find a way to eliminate the IHasInputDevices interface and use the Actions class as indicated in the obsolete warning. It also appears the ActionBuilder class is used to queue up a bunch of Actions objects.

How can I eliminate the IHasInputDevices interface and still use the Actions class?


Get this bounty!!!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.