简体   繁体   中英

How to get Selenium to operate two browser windows using only one driver selenium (using c# and chromedriver)?

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).

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

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.

您需要明确告诉Selenium您希望与哪个选项卡进行交互,在这种情况下,它将是;

driver.SwitchTo().Window(driver.WindowHandles.Last());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM