How can I run Internet Explorer Selenium tests as a specific domain user? How can I run Internet Explorer Selenium tests as a specific domain user? selenium selenium

How can I run Internet Explorer Selenium tests as a specific domain user?


We have many enterprise clients that use Windows Authentication for intranet facing applications and we are starting to run many Selenium tests for confirmation, regression, etc.

We've taken the helpful code from Steven's answer and refactored it into a re-usable class similar to other Impersonate posts that just weren't working for us because we wanted the tests to work both locally in development and deployed as part of the Visual Studio Team System release process.

The uri method was not working locally and neither were impersonating methods using Win32 native methods.

This one worked so here it is.

Example of a test using Steven's code refactored into a helper

[TestMethod]public void ThisApp_WhenAccessedByUnathorizedUser_ShouldDisallowAccess(){    string userName = "ThisAppNoAccess";    string password = "123456";    string domainName = Environment.MachineName;    using (new Perkins.Impersonator(userName, domainName, password))    {        // - Use Remote Web Driver to hook up the browser driver instance launched manually.        using (var driver = new RemoteWebDriver(new Uri("http://localhost:9515"), DesiredCapabilities.Chrome()))        {            var desiredUri = Helper.Combine(Helper.BaseURL, "/ThisApp/#/appGrid");            TestContext.WriteLine("desiredUri: {0}", desiredUri);            driver.Navigate().GoToUrl(desiredUri);            Helper.WaitForAngular(driver);            var noPermissionNotificationElement = driver.FindElementByXPath("//div[@ng-show='!vm.authorized']/div/div/div/p");            var showsNoPermissionNotification = noPermissionNotificationElement.Text.Contains("You do not have permissions to view ThisApp.");            Assert.AreEqual(true, showsNoPermissionNotification, "The text `You do not have permissions to view ThisApp.` is not being displayed!");        }    }}

The helper class

// Idea from http://stackoverflow.com/a/34406336/16008// - Launch the browser driver manually with other user's credentials in backgroundpublic class Perkins{    public class Impersonator : IDisposable    {        Process _driverProcess = null;        string _driverPath = @"chromedriver.exe";        /// <summary>        /// Impersonates the specified user account by launching the selenium server under that account.  Connect to it via RemoteWebDriver and localhost on port 9515.        /// </summary>        /// <remarks>        /// We may later want to enhance this by allowing for different ports, etc.        /// </remarks>        /// <param name="userName">Name of the user</param>        /// <param name="domainName">Name of the domain or computer if using a local account.</param>        /// <param name="password">The password</param>        public Impersonator(string userName, string domainName, string password)        {            ProcessStartInfo processStartInfo = new ProcessStartInfo(_driverPath);            processStartInfo.UserName = userName;            System.Security.SecureString securePassword = new System.Security.SecureString();            foreach (char c in password)            {                securePassword.AppendChar(c);            }            processStartInfo.Password = securePassword;            processStartInfo.Domain = domainName; // this is important, mcollins was getting a 'stub received bad data' without it, even though rglos was not            processStartInfo.UseShellExecute = false;            processStartInfo.LoadUserProfile = true; // this seemed to be key, without this, I get Internal Server Error 500            Thread startThread = new Thread(() =>            {                _driverProcess = Process.Start(processStartInfo);                _driverProcess.WaitForExit();            })            { IsBackground = true };            startThread.Start();        }        public void Dispose()        {            // - Remember to close/exit/terminate the driver process and browser instance when you are done.            if (_driverProcess != null)            {                // Free managed resources                if (!_driverProcess.HasExited)                {                    _driverProcess.CloseMainWindow();                    _driverProcess.WaitForExit(5000);                    // Kill the process if the process still alive after the wait                    if (!_driverProcess.HasExited)                    {                        _driverProcess.Kill();                    }                    _driverProcess.Close();                }                _driverProcess.Dispose();                _driverProcess = null;            }        }    }}

Perhaps this will help someone else with the same issue.


This is in fact possible. I ran into the exact problem you had. Basically, here are the steps you need to do.

  1. Launch the browser driver manually with other user's credentials in background

    Process driverProcess;string driverPath; // The path to Selenium's IE driver.ProcessStartInfo info = new ProcessStartInfo(driverPath){    UserName = "UserName", // The user name.    Password = new SecureString(), // The password for the user.    UseShellExecute = false,    LoadUserProfile = true,    Arguments = "about:blank"};// Start the driver in background threadThread startThread = new Thread(    () => {        try        {            driverProcess = Process.Start(info);            driverProcess.WaitForExit();        }        catch        {            // Close the process.        }    }){    IsBackground = true};startThread.Start();
  2. Use Remote Web Driver to hook up the browser driver instance launched manually.

    var remoteDriver = new RemoteWebDriver(Uri("http://localhost:5555"), DesiredCapabilities.InternetExplorer());
  3. Remember to close/exit/terminate the driver process and browser instance when you are done.

    // Close the process when done.if (driverProcess != null){    // Free managed resources    if (!driverProcess.HasExited)    {        driverProcess.CloseMainWindow();        driverProcess.WaitForExit(5000);        // Kill the process if the process still alive after the wait        if (!driverProcess.HasExited)        {            driverProcess.Kill();        }        driverProcess.Close();    }    driverProcess.Dispose();    driverProcess = null;}


This similar question links to this Microsoft support article. Essentially you need

System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();IWebDriver webDriver = new InternetExplorerDriver();// do your stuff here.impersonationContext.Undo();

There's additional code in the support article about impersonating a specific user.