Fluent Bytes

"The only source of knowledge is experience" - Albert Einstein-

How to reuse your browser window between tests in CodedUI

When you run automated test scenario’s against web applications, it often takes a lot of time to get to the initial state of your application from where you want to run a test scenario.

When you run a standard CodeUI test and use the BrowserWindow class to start the web browser, it will automatically close the browser when the test method is done. This is nice an clean and great if you don’t want previous tests to potentially influence your test run. So the fact that this is the default makes a lot of sense.

A question that I get asked rather often is, if there is a way to reuse the browser window across different test methods. The answer is yes! this is possible although not immediately apparent how.

so CodedUI uses a Playback Engine that gets initialized when you run the first test and that get’s cleaned up when you are done. this is done implicit by MSTest when it sees the [CodedUITest] attribute on top of your test class. This is important to know, because when the Playback Engine is not initialized and you use the CodedUI object model like for instance the BrowserWindow class, you will get error messages like:

Microsoft.VisualStudio.TestTools.UITest.Extension.TechnologyNotSupportedException: The browser  is currently not supported.

This even happens when you use a plain vanilla BrowserWindow.Launch call.

So why is this important to know? Well when you want to start the BrowserWindow once for all tests, it is required to start the browser window prior to your test method. So for that you might want to leverage the [ClassInitialize] attribute. This can be placed on  a static method that has one parameter TestContext. this method will be called only once for your test class and is therefore ideal to start the Browser Window. The issue is that when this method is called the playback engine is not initialized yet, so therefore we need to initialize it ourselves. This is simple to do, by just calling the method Initialize() on the Playback object.

But there are some more issues that make a simple and obvious solution unusable. (e.g. Create an instance of the BrowserWindow in the Initialize and then reuse it in every method) The Issue is that the Test Engine will run each test method potentially on another Thread. When you start the BrowserWindow in the initialize and then use it in every test method you would access the BrowserWindow class instance from different threads and apparently this results in unexpected behavior of the BrowserWindow class. So what we need to do is initialize a new BrowserWindow class for each test method while still reusing the same browser instance. This is possible, but the way to achieve this is by using the Process class of the BrowserWindow.

What you do is you initialize the browser once in the Initialize method of your class and you then get the process class for that instance of the browser. Next in each test method you create a new instance of the BrowserWindow class but there we use the FromProcess() method in stead of the Launch Method. This will wrap a new Instance of the BrowserWindow on the current process, hence reusing the browser session.

There is one final thing we need to fix, before this works. That is that after a test method completes the Browser Window is cleaned up automatically. This can be prevented by setting the property CloseOnPlaybackCleanup to false on the initial instance of the BrowserWindow we create.

So to conclude you can have a look at the code sample below, where you can see the steps you need to take to reuse the browser window cross multiple test methods in your test class. I created a very simple test that reuses the browser that browses to the Bing home page and searches for a search term.

Enjoy!

Marcel

CTO at Xpirit, Microsoft Regional Director, Visual studio ALM MVP, Speaker, Pluralsight Author and IT Architect Consultant

19 Comments

  1. Marcel,

    Hi Marcel,
    Isn’t possible use this code as a cross browser, is it?

  2. Hi Marcel,

    Thanks for this post. One comment/question, are you missing the “(TestContext context)” parameter on the [ClassCleanup] method, I copied this code locally and it never executes the ClassCleanup method. Thoughts?

    Thank you

    • I just pasted the code in a new CodedUI project and I see the breakpoint is hit in the Cleanup method. You do need to put the [CodedUITest] attribute on top of your class. Is that what is missing?

      • Hi Marcel,

        For some reason, once I hit the [ClassCleanup] method, I get a “Browser not supported” Exception (which I don’t get at [ClassInitialize]). I don’t know if this matters, but I am using VS2012.

        Anyways, thank you so much for your tutorials and Pluralsight videos, I am following both since I am trying to build a robust and reliable UI Automation framework using Coded UI.

        • Martin,
          I think I now found the issue you are referring to.
          This is the same issue as I had with the initialization. Apparently the Playback session is already cleaned up in the Cleanup method.

          There is an easy fix to the problem.
          change the method to re- initialize the playback engine and then create the browser window. After that close it and clean up the session.
          Something like this:

          if(!Playback.IsInitialized)
          Playback.Initialize();

          BrowserWindow _bw = BrowserWindow.FromProcess(proc);
          _bw.Close();

          Playback.Cleanup();

          Hope that helps.
          With kind regards,
          Marcel

  3. Hi Marcel,

    I’m currently progressing through your pluralsight videos on Coded UI. I was interested in how you could achieve reuse of the browser between tests and came across this post.

    I had problems, so I took your code as is, but everywhere I try and get a BrowserWindow reference using FromProcess I get the follow exception:

    Microsoft.VisualStudio.TestTools.UITest.Extension.UITestControlNotFoundException: Unable to find the main window of the underlying process.
    at Microsoft.VisualStudio.TestTools.UITesting.ApplicationUnderTest.SetCurrentProcessPrivate(Process value)
    at Microsoft.VisualStudio.TestTools.UITesting.ApplicationUnderTest.c__DisplayClassb.b__a()
    at Microsoft.VisualStudio.TestTools.UITesting.CodedUITestMethodInvoker.InvokeMethod(Func1 function, UITestControl control, Boolean firePlaybackErrorEvent, Boolean logAsAction)
    at Microsoft.VisualStudio.TestTools.UITesting.ApplicationUnderTest.set_Process(Process value)
    at Microsoft.VisualStudio.TestTools.UITesting.BrowserWindow.FromProcessPrivate(Process processToWrap)
    at Microsoft.VisualStudio.TestTools.UITesting.BrowserWindow.c__DisplayClass1b.b__1a()
    at Microsoft.VisualStudio.TestTools.UITesting.CodedUITestMethodInvoker.InvokeMethod(Func
    1 function, UITestControl control, Boolean firePlaybackErrorEvent, Boolean logAsAction)
    at Microsoft.VisualStudio.TestTools.UITesting.BrowserWindow.FromProcess(Process processToWrap)
    at ReuseTheBrowser.CodedUITestMethodFirstTest() in CodedUITest2.cs: line 31
    Test method ReuseTheBrowser.CodedUITestMethodFirstTest threw exception:

    Any help would be much appreciated.

    Thanks

    • can you share your code so I can take a look, since I am not sure why this would happen

      • Brandon Russell

        June 12, 2015 at 12:49 pm

        I am having the same issue as well, using Visual Studio 2010 test agent server. Runs fine on our local boxes. Any clue to why it would be failing on the test agent server with that error message?

        “Unable to find the main window of the underlying process”

        • it seems the browser can not be found based on the process identification. How do you start your run on an agent? are you using MTM to do it? if so what does the video recording show? does it show the browser starting?

      • Hi Marcel,
        I also had the same problems when working with joomla Administrator page. It appears an error “Unable to find the main window of the underlying process” after finishing the TC1 when i ran both 2 TCs 1 & 2.
        Here is my code:
        [ClassInitialize]
        public static void initializeTest(TestContext context)
        {
        Playback.Initialize();
        var _bw = BrowserWindow.Launch(new Uri(“http://192.168.191.135:8888/joomla/administrator/index.php”));
        proc = _bw.Process;
        _bw.CloseOnPlaybackCleanup = false;
        }
        [TestMethod]
        public void TestCase01()
        {
        BrowserWindow _bw = BrowserWindow.FromProcess(proc);
        login(username, password);
        createNewArticle(title, category);
        [TestMethod]
        public void TestCase02()
        {
        BrowserWindow _bw = BrowserWindow.FromProcess(proc);
        editArticle(title, category);

        Any help would be much appreciated. sorry for my bad English.

  4. Hi Marcel,

    I’m having an issue more or less like this, my sine is using asp pages and is working with Frames. From last week something change and is not recognizing me the frames, I have a Banner frame and a Main frame.
    After login, the browserWindow object was lost after Mouse.click(btn) and the new asp page for the frame is not recognized. And basically this happen after all click any button, if I’m on the main page after login, the different frames are lost and the objects inside are unable to work with them. Do you have an idea about How I can continue with my browserWindow after click the button and change to another asp page inside the frame?

    Thanks.

    • I have never seen such behavior. are you able to share a video capture of what is going on and a part of your code to better understand your issue?

  5. Hi Marcel,

    I have used your approach as mentioned above. But, I have a query related to this. Can we do same thing in “Assembly Initialize” attribute or that will cause issues?

  6. Hi Marcel
    I have some queries. Assume user1 is logged in using chrome browser and simultaneously user2 is logged in using IE. Presently control is in IE. Now I am able to move the control to chrome through coded ui and c# code. But I am unable to perform any actions (Ex: clicking, entering text in text boxes etc……..) I heard that it’s not possible to do so using coded ui. Please help.

    Thanks in advance

    • As far as I know you can not switch the CodedUI drivers on the fly for different tests, but I also have not tried this myself. It is possible to switch between MSAA and Web e.g. but not between Web and Selenium. that is due to the nature the plugin is build. Once you select a browser, you finish the test with that browser. Is there a specific scenario you need with 2 browsers open? just curious about the scenario here.

  7. I feel like I may be missing something simple here, but is there a way to share the browser instance between test _classes_ ?

    With this implementation I am getting one browser per test class. Should all of my tests be moved into a single test class? Wouldn’t this be a bit sloppy after going through all of the trouble of following the Page Object pattern?

    Thanks in advance for any insight you can provide!

    • Nope, you are not missing anything. If you want to share cross classes then you need to find a way to deterministic have one starting point and end test case, which would be hard I think. Then you need to share the process ID as a static and then attach to that process in startup of the class.

Leave a Reply

Your email address will not be published.

*

© 2017 Fluent Bytes

Theme by Anders NorenUp ↑