0

I am attempting to control two browser windows via selenium using c# and a single chromedriver. The reason being that I need to share session details accross browser windows.

The code that I have tried and failed with is below;

    var options = new ChromeOptions();
    options.AddArguments("chrome.switches", "--disable-extensions --disable-extensions-file-access-check --disable-extensions-http-throttling --disable-infobars --enable-automation ");           
    options.AddUserProfilePreference("credentials_enable_service", false);
    options.AddUserProfilePreference("profile.password_manager_enabled", false);
    options.PageLoadStrategy = PageLoadStrategy.Default;

    ChromeDriverService service = ChromeDriverService.CreateDefaultService();
    service.HideCommandPromptWindow = true;
    var Driver = new ChromeDriver(service, options);

    //THIS WILL OPEN A NEW WINDOW. BUT BECAUSE IT IS A NEW DRIVER DOES NOT WORK FOR SHARING SESSION DETAILS.
    //var TestDriver = new ChromeDriver(service, options);
    //TestDriver.Manage().Window.Maximize();

    //THIS JUST OPENS UP A NEW TAB. NOT A NEW WINDOW (IT WOULD SEEM MOST DOCUMENTATION SUGGESTS THAT IT SHOULD)
    IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;
    jscript.ExecuteScript("window.open();", "google.com.au");

    //TRY USING THE SEND KEYS TECHNIQUE. NOTHING HAPPENS
    var test = Driver.FindElement(By.TagName("html"));
    test.SendKeys(Keys.Control + "n");
    test.SendKeys(Keys.Control + "t");

    //TRY AGAIN USING THE SEND KEYS TECHNIQUE USING A DIFFERENT TAG. NOTHING HAPPENS
    var blah = Driver.FindElements(By.TagName("body"));
    blah[0].SendKeys(Keys.Control + "t");

    //TRY USING ACTIONS. NOTHING HAPPENS
    Actions action = new Actions(Driver);
    action.SendKeys(OpenQA.Selenium.Keys.Control + "n");
    action.Build().Perform();

I may resort to AutoIt to open a browser if I have to, but one more dependency is not what I need. Documentation everywhere around the web seems to suggest than all the options I tried above should work...I suspect it may be a chromedriver issue of some kind.

Any ideas on how to achieve my goal would be greatly appreciated

UPDATE.
Arnons answer below lead me to the solution. If you are in a similar situation the best thing to do is just open up the browser console (from developers tools) and experiment with javascript until you get what you want. Then just execute that. In the end executing the following code has worked for me.

IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;            
jscript.ExecuteScript("window.open('https://www.bing.com.au','_blank','toolbar = 0, location = 0, menubar = 0')");

The other alternative was to use Autoit, which I also got working, much easier than I did figuring out the javascript. But one less dependency is best :)

UPDATE2. Further complications arise with trying to control the window as an independent browser window. I believe any new window created from a parent window, has the same process id (at least my testing has indicated so), and for all intense and purpose is treated as a tab in the selinium driver. I therefore conclude that certain things are just not possible (for example relocating the child browser window on the screen).

Obbles
  • 533
  • 3
  • 17
  • I think that a tab is a really a window. Perhaps you need to detach the tab from the browser to a window, but i guess you can't do it with selenium. – Jaime García Pérez Sep 10 '18 at 12:32
  • A tab is a window. Chromedriver treats them the same. You should be able to do what you want with a tab. You just need to switch to the new window to control it and switch back as needed. – JeffC Sep 10 '18 at 13:53
  • I don't think you can have two browser windows and one webdriver instance. One webdriver == one chromedriver instance. One option is you can have two webdriver instances and multithread them, and maybe use a static class to share data between the sessions. – Andrio Sep 10 '18 at 14:15
  • @andrio. That sounds interesting but I suspect asking for troubles...I think I'd go the autoit route before trying that. JeffC is correct from my experience. A tab is a window and are treated the same with chromedriver. I can achieve what I want with a tab in terms of actual website functionality wise, but for various reasons, I need two browser windows open on seperate screens...thats the sticking point... – Obbles Sep 10 '18 at 14:26

3 Answers3

1

I should have read the question better, here is my solution. Ended up using this for selecting windows that popped up after clicking a button but should work with swapping between windows.

//---- Setup Handles ----
//Create a Handle to come back to window 1
string currentHandle = driver.CurrentWindowHandle;

//Creates a target handle for window 2
string popupWindowHandle = wait.Until<string>((d) =>
{
    string foundHandle = null;

    // Subtract out the list of known handles. In the case of a single
    // popup, the newHandles list will only have one value.
    List<string> newHandles = driver.WindowHandles.Except(originalHandles).ToList();
    if (newHandles.Count > 0)
    {
        foundHandle = newHandles[0];
    }
    return foundHandle;
});

//Now you can use these next 2 lines to continuously swap
//Swaps to window 2
driver.SwitchTo().Window(popupWindowHandle);

// Do stuff here in second window 

//Swap back to window 1
driver.SwitchTo().Window(currentHandle);

// Do stuff here in first window
William.Avery
  • 60
  • 1
  • 7
  • Hi William, thank you for your input, interesting code. I am not sure it solves the issue though. This code is creating a new driver foreach list. I was looking to have two browsers for one driver. – Obbles Sep 11 '18 at 09:23
  • I went ahead and edited my response to show a more accurate solution. Hope this helps. – William.Avery Sep 11 '18 at 15:36
  • Thanks William. Still not sure it answer the question, this will get the handles (which is helpful code to me) but it doesn't actually do the opening of the second browser window.... I'm tied up away from deving atm, but will return in the next few days to test it out and something like this will probably form part of my final solution. ty. – Obbles Sep 13 '18 at 07:31
1

Your first attempt using ExecuteJavaScript was very close, but In order for it to open a new window instead of new tab, you should add the following arguments: `"_blank", "toolbar=0,location=0,menubar=0" to it. See this question for more details.

Arnon Axelrod
  • 1,444
  • 2
  • 13
  • 21
  • Thanks Arnon, I've run out of time at the moment to give your suggestion a workout, but a rudimentary test so far still just opens it as a tab rather than a window. This could be entirely my lack of programing skill. Will return with sample code in the next few days. Thanks heaps. – Obbles Sep 13 '18 at 07:27
  • Try to play with this command through the browser's console, and if you succeed, execute that command through Selenium. – Arnon Axelrod Sep 13 '18 at 17:35
  • Brilliant, this looks like its going to work. Thank you arnon. When I was testing before I was attempting to do it in my code like this -> string[] myArray = new string[] {"'https://www.bing.com.au','_blank','toolbar = 0, location = 0, menubar = 0'"}; jscript.ExecuteScript("window.open();", myArray[0]); ...just doing a single string worked like this --> jscript.ExecuteScript("window.open('https://www.bing.com.au','_blank','toolbar = 0, location = 0, menubar = 0')"); ...the window is a bit messed up with these settings but some more trials and I think I will get there... – Obbles Sep 13 '18 at 19:31
0

You need to explicitly tell Selenium which tab you wish to interact with, which in this case would be;

driver.SwitchTo().Window(driver.WindowHandles.Last());
Robbie Wareham
  • 3,380
  • 1
  • 20
  • 38
  • Thanks Robbie, I just tried this now. And it did not appear to make any difference. I added that line of code after the jscript.ExecuteScript line in my sample code above. No difference that I can see – Obbles Sep 10 '18 at 14:32
  • Read `driver.windowHandles` into a variable, and ensure there are 2. If there are not 2, then your new window is not part of the original Selenium instance. If there are two, try switching the other! – Robbie Wareham Sep 10 '18 at 14:51
  • I am not even getting to the stage where I have two windows. I am stuck with one window and multiple tabs. There are handles for each tab, but I have now tried sending keys to both windows/tabs (switching to each one first), but stil no go... – Obbles Sep 10 '18 at 21:52
  • I've successfully got it working using autoit to send keys to open the window. Checking the window handles, selenium still has control when I do it that way. It's very hacky, but I am fairly certain it is working at this stage. Needs a bit of a workout first though... – Obbles Sep 10 '18 at 22:18
  • For anyone reading this. Autoit easily opens up the new tab, but then controlling the browser can be a little troublesome. For example. Driver.Manage() is only designed to work with one browser window. It's still a viable avenue, but there are some further issues to hurdle...I am still working through those... – Obbles Sep 11 '18 at 09:19