How to connect to an already open browser?
Asked Answered
M

5

15

I would really appreciate a guide on how to connect to an already open browser using Selenium Webdriver via C#.

This issue eats around 30% of my script development time!

Marlinemarlinespike answered 14/10, 2011 at 10:8 Comment(8)
I dont thinks that is possiblePallaton
why dont you just create a test suite and use same selenium instance?Practice
How can I do that? After the test has stopped, how do you connect to an existing browser?Marlinemarlinespike
Ever find a solution to this?Gesture
No. I'm not sure about the answers below, please comment back if something works for youMarlinemarlinespike
If you started a test and then didn't quit the browser you could potentially re-attach to it IF you keep track of the Selenium SessionId and port on which to connect to the browser. Then you'd have to extend the RemoteWebDriver to allow you to pass in your own SessionId and point the url to the port you kept track of. NOTE: This could only possibly work if you've started the browser with Selenium.Mchale
Andrey, Have you tried my answer ?Vibrant
It is indeed possible. by using a derived class of remote webdriver. Please see this post binaryclips.com/2015/08/25/…Vibrant
K
1

Refer to Selenium Issue 18. This is a very popular feature request, which has unfortunately not been implemented. The comments suggest a few workarounds for now, I haven't tried them but you might find something useful.

Kare answered 14/10, 2011 at 19:35 Comment(3)
there is one in Java which could give you a pretty good idea of how the workaround is accomplished, then you can implement it in C#Kare
That's exactly what I need help with :)Marlinemarlinespike
The below answer posted by me shows how to connect to an already opened browser in Selenium WebDriver using C#Vibrant
S
1

You can specify starting and closing browser in [TestFixtureSetUp] and [TestFixtureTearDown] and remove it from [SetUp] and [TearDown]. All the tests in [TestFixture] will be run in the same browser. So if you have for example 10 classes and each of them contains 5 tests, instead of 50 browser's openings and closings there will be only 10.

    public IWebDriver driver { get; private set; };

    [TestFixtureSetUp]
    public void TestFixtureSetup()
    {
        driver = new FirefoxDriver();
        driver.Navigate().GoToUrl("http://www.google.com/");
    }

    [TestFixtureTearDown]
    public void TestFixtureTearDown()
    {
         driver.Quit();
    }

If you want to open and close your browser once, you can inherit [TestFixtureSetUp] and [TestFixtureTearDown] methods from base class and if you have one test class that is executed before others (A_test) and one that is executed last (Z_test) you can set and unset some flags that will tell if we should start browser or not:

namespace Tests
{
[TestFixture]
public abstract class Test
{
    private static bool _flagSetUp;
    private static bool _flagTearDown;
    public IWebDriver driver { get; private set; };

    protected Test()
    {
    }

    public static void SetFlag(bool flagSetUp, bool flagTearDown)
    {
        _flagSetUp = flagSetUp;
        _flagTearDown = flagTearDown;
    }

    [TestFixtureSetUp]
    public void TestFixtureSetup()
    {
        if(_flagSetUp)
        {
            driver = new FirefoxDriver();
            driver.Navigate().GoToUrl("http://www.google.com/");
            _flagSetUp = false;
        }
    }

    [TestFixtureTearDown]
    public void TestFixtureTearDown()
    {
        if(_flagTearDown)
        {
            driver.Quit();
        }
    }
}

namespace Tests
{
[TestFixture(new object[] { true, false })]
public class A_Test : Test
{
    public A_Test(bool flagSetUp, bool flagTearDown)
    {
        SetFlag(flagSetUp, flagTearDown);
    }

    [Test]
    public void Test1()
    {
       ...
    }
}

namespace Tests
{
[TestFixture(new object[] { false, true })]
public class Z_Test : Test
{
    public A_Test(bool flagSetUp, bool flagTearDown)
    {
        SetFlag(flagSetUp, flagTearDown);
    }

    [Test]
    public void Test2()
    {
       ...
    }
}

The last workaround looks like not good solution. Althouth first workaround also doesn't guarantee 100% tests isolation (btw don't forget to write driver.Navigate().GoToUrl("http://www.google.com/"); as first step for each test). So probably the best solution will be parallel execution and Setup, Teardown methods for each test.

Splenitis answered 29/3, 2012 at 19:45 Comment(1)
Can someone check if it works? I'm not working on Selenium at the momentMarlinemarlinespike
P
0

Since time is your primary issue and this is not natively supported. Why adopt an alternative approach. Develop/implement a basic connect & navigate to home page use case. Then extend that class for your more complex use case. Alternatively make Test case controller, then use a factory to instantiate your detailed tests, passing the webdriver instance into the test case.

Prod answered 1/2, 2012 at 10:28 Comment(0)
M
0

You can run your tests in parallel, but that is a just a good idea when you're ready to run all of your tests. Below is an idea that you can use while you're developing and running newly compiled code.

Serialize your WebDriver {browser} instance object into a file (or in memory in a Windows service if you prefer), and then retrieve (de-serialize) that file into an object each time you launch WebDriver. It takes a little massaging though, of the WebDriver source code.

When I get some time, I will update my answer here. I hope Stack Overflow will allow me to paste as much code changes as it took. Plus, I should still give credit to Erik in his answer and comments. Although it was my idea to begin with (for making WebDriver faster).

.NET: Serializing object to a file from a 3rd party assembly (to make Selenium WebDriver faster)

==========

Simple logic:

  • if serialized object file doesn't exist ==> open browser instance as normal, and create the file

  • if serialized object file exists ==> deserialize file into object ==> set browser instance equal to deserialized object (casted correctly of course)

==========

The other requirement is that you put in a condition into your method decorated with the [TearDown] attribute so your browser doesn't close when the script (test) finishes. The first time through, it'll take time to open it up. But once that browser window is open, you're good to go.

[TearDown]
public void TeardownTest()
{
    try
    {
        if (Config.CLOSE_BROWSER_AFTER_TEST_CASE)
        {
            driver.Quit();
        }
    }
    catch (Exception)
    {
        // Ignore errors if unable to close the browser
    }
    Assert.AreEqual("", verificationErrors.ToString());
}
Millhon answered 12/5, 2012 at 0:11 Comment(1)
instead of serializing the whole object, you can just save the session id and reuse the session id to connect to already opened instance. please see this post. binaryclips.com/2015/08/25/…Vibrant
V
0

you can use below code sample to achieve this task

IWebDriver WebDriver = null;


try
{
  System.Uri uri = new System.Uri("http://localhost:7055/hub");
  WebDriver = new RemoteWebDriver(uri, DesiredCapabilities.Firefox());
  Console.WriteLine("Executed on remote driver");
}
catch (Exception)
{
  WebDriver = new FirefoxDriver();
  Console.WriteLine("Executed on New FireFox driver");
}

if a firefox browser is opened using a Firefox web driver, you can use Remote WebDriver to use that browser instance. So First I try to initialize a Remote Web Driver, if no instance is running, then try block will fail and Catch block will open the Firefox driver. Now for example, your script fails on a specific location and the browser remained open. Now again run that initialization code, the try block will pass this time and remote web Driver will use the existing opened browser. (No new browser window will open).

Put this initialization in your Test Startup method
This block of code saves my ample amount of time. I have also written a blog post on it. You can read it here. http://www.binaryclips.com/2016/03/selenium-web-driver-in-c-how-to.html

Vibrant answered 16/9, 2014 at 10:38 Comment(12)
In a few words, your solution is not to use Selenim Firefox driver, and use the stand-alone-server instead. Even if i don't really like to run Java app's, i've to admit that standalone server has few headaches.Confirmand
I use this approach, while developing the scripts. Not when I execute them. It saves time in debugging etc. I don't have to re-open the browser again and again after fixing my code each time with this approachVibrant
Also, in C#, we don't have to open a standalone server to use remote webDriver. If you have opened the browser with firefox driver, Remote webDriver can attach to this browser.Vibrant
mmm interesting, didn't know about that feature. Do you need to supply any argument doing that? or does the remote just connect to the last instance?Confirmand
it juts connects to the last instance . You just have to provide this URL "localhost:7055/hub"Vibrant
And can I choose the id too?Confirmand
Which id are you talking about?Vibrant
Exactly the same ID used by the remoteWebdriver to create, handle or destroy the current sessions. Did u open that URL on a browser? Nothing happends with an active handle, or with an ID. I've look a bit inside and found org.openqa.selenium.remote.server.handler.GetAllSessions. Here is my id, but i don't know if i can invoke it to rehuse certain session instead the lastest session used.Confirmand
I did not use any id the first time as well. Why don't you just try my code on visual studio?Vibrant
Okey you don't know about the id, no problem.Confirmand
Why my answer is downvoted? Can anyone explain please ?Vibrant
And I do know about the id. Please see this answer about getting a session id in c#.#15767566Vibrant

© 2022 - 2024 — McMap. All rights reserved.