Cross Browser Testing

Feb 6, 2013 at 5:57 PM
Edited Feb 6, 2013 at 7:24 PM
Hi,

I have managed to write a few very simple tests that run in IE from both VS2010 and VS2012 (with binding redirects).

I was wondering if support will be added for Cross Browser Testing. http://blogs.msdn.com/b/visualstudioalm/archive/2012/10/30/introducing-cross-browser-testing-with-coded-ui-tests.aspx

At the moment I have tried to run the tests in Chrome by:
BrowserWindow.CurrentBrowser = "chrome";
but i am getting the following error
Initialization method CuiteCodedUI.ClientScreen.ClientScreenTestFixture.TestInitialize threw exception. Microsoft.VisualStudio.TestTools.UITest.Extension.UITestControlNotFoundException: Microsoft.VisualStudio.TestTools.UITest.Extension.UITestControlNotFoundException: Could not locate the browser window, window name not specified..
    at Microsoft.VisualStudio.TestTools.UITest.Extension.CrossBrowser.CrossBrowserFactory.Locate(PropertyExpressionCollection searchProperties, PropertyExpressionCollection filterProperties)
   at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.SearchTopLevelWindow(ISearchArgument topLevelSearchArg, String topLevelElementQueryId)
   at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.GetTitleUpdatedTopLevelWindow(ISearchArgument topLevelSearchArg, String queryId, IList`1 windowTitles)
   at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.GetTopLevelElement(Boolean useCache, Boolean useCacheOnly, ISearchArgument searchArg, IList`1 windowTitles, ref Int32 timeLeft)
   at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.GetUITestControlRecursive(Boolean useCache, Boolean alwaysSearch, ISearchArgument searchArg, IList`1 windowTitles, ref Int32 timeLeft)
   at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.GetUITestControlRecursive(Boolean useCache, Boolean alwaysSearch, ISearchArgument searchArg, IList`1 windowTitles, ref Int32 timeLeft)
   at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.GetElement(Boolean useCache, ISearchArgument searchArg)
   at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.Search(ISearchArgument searchArg)
   at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FindInternal()
   at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FindControlIfNecessary()
   at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.WaitForControlReadyPrivate(Int32 millisecondsTimeout, Boolean doLogging)
   at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.<>c__DisplayClass1d.<WaitForControlReady>b__1c()
   at Microsoft.VisualStudio.TestTools.UITesting.CodedUITestMethodInvoker.InvokeMethod(Func`1 function, UITestControl control, Boolean firePlaybackErrorEvent, Boolean logAsAction)
   at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.WaitForControlReady(Int32 millisecondsTimeout)
   at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.WaitForControlReady()
   at CUITe.Controls.CUITe_ControlBase`1.Click() in c:\Working\codeplex\cuite\CUITe\Controls\CUITe_ControlBase.cs: line 207
   at CuiteCodedUI.ClientScreen.ClientScreenTestFixture.TestInitialize() in ClientScreenTestFixture.cs: line 29
Is there any way where i could specify the window name? so that the test could run in Chrome.

I think my problem is due to the IE hard-code variables in the CUITe_BrowserWindow class:
  1. this.SearchProperties[UITestControl.PropertyNames.ClassName] = "IEFrame"; (line 22) (the search properties differ for different browsers)
  2. to a very small extent - Process[] pro_list = Process.GetProcessesByName("iexplore");
Are there any way/ plans to allow these to be specified in the future? with a provider/ abstract factory pattern to get the browser specific methods?

Thank you
Feb 6, 2013 at 8:20 PM
I have managed to do the following to allow CUITe to run in Chrome:
public class BrowserIndependentWindow : CUITe_BrowserWindow
    {
        public BrowserIndependentWindow()
        {
            if(BrowserWindow.CurrentBrowser.Equals("Chrome", StringComparison.InvariantCultureIgnoreCase))
            {
                SearchProperties.Clear();
                SearchProperties[UITestControl.PropertyNames.ClassName] = "Chrome_WidgetWin_1";
                SearchProperties[UITestControl.PropertyNames.Name] = sWindowTitle;
            }
        }
    }

    public class DynamicBrowserIndependentWindow : CUITe_DynamicBrowserWindow
    {
        public DynamicBrowserIndependentWindow(string title) : base(title)
        {
            if (BrowserWindow.CurrentBrowser.Equals("Chrome", StringComparison.InvariantCultureIgnoreCase))
            {
                SearchProperties.Clear();
                SearchProperties[UITestControl.PropertyNames.ClassName] = "Chrome_WidgetWin_1";
                SearchProperties[UITestControl.PropertyNames.Name] = sWindowTitle;
            }
        }
    }
(I have not tried the DynamicBrowserIndependentWindow as it seem the site I'm testing CUITe on is IE specific :( my bad and thus does not get to the point I could test it on)


The BrowserIndependentWindow control work even tho sWindowTitle is null when the constructor is run. Though it seem to be able to find the correct window and continue. In my object repository class I extend DynamicBrowserIndependentWindow or DynamicBrowserIndependentWindow instead of the CUITe_BrowserWindow and CUITe_DynamicBrowserWindow.

Any ideas on how I could make this better with the current CUITe release?
Coordinator
Feb 7, 2013 at 9:02 AM
Hi QuanEdys,

Thank you for sharing the code for initial support of cross-browser testing with CUITe.

I'm anticipating its inclusion in CUITe soon enough. :)

In regards to sWindowTitle being null when the constructor is run, you will have to define it in your object repository class.

Here is a sample object repository class from the latest code:
    public class TestHtmlPage : CUITe_BrowserWindow
    {
        public new string sWindowTitle = "A Test";
        public CUITe_HtmlParagraph p = new CUITe_HtmlParagraph("id=para1");
        public CUITe_HtmlUnorderedList list = new CUITe_HtmlUnorderedList("id=unorderedList");
    }
Notice how sWindowTitle is defined.

Thank you.
Feb 7, 2013 at 6:29 PM
Edited Feb 7, 2013 at 6:57 PM
I have managed to use the same technique to get it working with firefox.

so the finally code:
public class BroswerConstants
    {
        public const string InternetExplorer = "ie";
        public const string FireFox = "firefox";
        public const string Chrome = "chrome";
    }

    public class BroswerWindowClassesConstants
    {
        public const string FireFox = "MozillaWindowClass";
        public const string Chrome = "Chrome_WidgetWin_1";
    }


    public class BrowserIndependentWindow : CUITe_BrowserWindow
    {
        public BrowserIndependentWindow()
        {
            if (BrowserWindow.CurrentBrowser.Equals(BroswerConstants.Chrome, StringComparison.InvariantCultureIgnoreCase))
            {
                SearchProperties.Clear();
                SearchProperties[UITestControl.PropertyNames.ClassName] = BroswerWindowClassesConstants.Chrome;
                SearchProperties[UITestControl.PropertyNames.Name] = sWindowTitle;
            }
            else if (BrowserWindow.CurrentBrowser.Equals(BroswerConstants.FireFox, StringComparison.InvariantCultureIgnoreCase))
            {
                SearchProperties.Clear();
                SearchProperties[UITestControl.PropertyNames.ClassName] = BroswerWindowClassesConstants.FireFox;
                SearchProperties[UITestControl.PropertyNames.Name] = sWindowTitle;
            }
        }
    }

    public class DynamicBrowserIndependentWindow : CUITe_DynamicBrowserWindow
    {
        public DynamicBrowserIndependentWindow(string title) : base(title)
        {
            if (BrowserWindow.CurrentBrowser.Equals(BroswerConstants.Chrome, StringComparison.InvariantCultureIgnoreCase))
            {
                SearchProperties.Clear();
                SearchProperties[UITestControl.PropertyNames.ClassName] = BroswerWindowClassesConstants.Chrome;
                SearchProperties[UITestControl.PropertyNames.Name] = sWindowTitle;
            }
            else if (BrowserWindow.CurrentBrowser.Equals(BroswerConstants.FireFox, StringComparison.InvariantCultureIgnoreCase))
            {
                SearchProperties.Clear();
                SearchProperties[UITestControl.PropertyNames.ClassName] = BroswerWindowClassesConstants.FireFox;
                SearchProperties[UITestControl.PropertyNames.Name] = sWindowTitle;
            }
        }
    }
It could be made a lot nicer...

In my implementation, even with the 'sWindowTitle' defined as 'Abc' (in a extended class), the IndependentWindow class will always see sWindowTitle as null, this is because the extended class 'TestHtmlPage' defines it as NEW. which means it will only be used when IndependentWindow class is casted as TestHtmlPage.

eg.

Inside the context of the IndependentWindow class try the following :
  1. this.sWindowTitle - will equal null
  2. ( this as TestHtmlPage ).sWindowTitle - will equal "A Test" - assuming TestHtmlPage extends BrowserIndependentWindow
so it seem that the search property for both firefox and chrome just need the UITestControl.PropertyNames.Name to be specified in the search parameters and the coded UI bridge to chrome/ff doesn't use it?

Just wanted to add that I'm really liking this framework.
Coordinator
Feb 8, 2013 at 11:50 AM
Hi QuanEdys,

I've just checked in some code that works for me with ie and chrome.

Please see the sample tests in .\Sample_CUITeTestProject (NET45)\CrossBrowserHtmlControlTests.cs.

Unfortunately, trying to run it with firefox does not even launch firefox and results in the following exception:

Microsoft.VisualStudio.TestTools.UITest.Extension.UITestException: An error occurred while connecting to Firefox
Result StackTrace:
at Microsoft.VisualStudio.TestTools.UITest.Extension.CrossBrowser.Utility.MapAndReThrow(Exception exception)
at Microsoft.VisualStudio.TestTools.UITest.Extension.CrossBrowser.CrossBrowserService.Launch(Uri uri)
at Microsoft.VisualStudio.TestTools.UITest.Extension.CrossBrowser.CrossBrowserFactory.Launch(Uri uri)
at Microsoft.VisualStudio.TestTools.UITesting.BrowserWindow.LaunchPrivate(Uri uri)
at Microsoft.VisualStudio.TestTools.UITesting.BrowserWindow.<>c__DisplayClass3d.<Launch>b__3c()
at Microsoft.VisualStudio.TestTools.UITesting.CodedUITestMethodInvoker.InvokeMethod[T](Func`1 function, UITestControl control, Boolean firePlaybackErrorEvent, Boolean logAsAction)
at Microsoft.VisualStudio.TestTools.UITesting.BrowserWindow.Launch(Uri uri)
at CUITe.Controls.HtmlControls.CUITe_BrowserWindow.Launch(String url, String title) in c:\Working\codeplex\cuite\CUITe\Controls\HtmlControls\CUITe_BrowserWindow.cs:line 91

I am wondering if you experience the same issue with firefox?

I am running:
Windows 7 Home Premium x64
Visual Studio 2012 Premium Update 1
Visual Studio 2012 Cross Browser Testing Setup for Selenium Components
Internet Explorer 9.0.8112.16421
Firefox 18.0.2
Chrome 24.0.1312.57

Thank you.
Feb 8, 2013 at 5:24 PM
Hi,

Yes i did get that error.

The reason is because the latest selenium drivers (which is used by the coded UI cross browser library to run in chrome and ff) only supports up to FireFox 17, you will need to downgrade your FireFox version.

Thank you
Coordinator
Mar 5, 2013 at 8:20 AM
Thank you very much, QuanEdys.

I am wondering how you found this out?

Is there a documentation link you can refer me to please?

Thank you. :)
Mar 5, 2013 at 7:43 PM
Same way you did. My code worked fine on Chrome, but not firefox 18.... so i finally found it on the net. I think this was the link I read before as well.

here - i
Mar 8, 2013 at 1:03 AM
Hey guys,

I'm using 1.06 Beta, and I can get the following to launch the appropriate page in the appropriate browser:

public void OpenTrupanionWebsite(string browser)
    {
        BrowserWindow.CurrentBrowser = browser;
        CUITe_BrowserWindow window = CUITe_BrowserWindow.Launch<TrupanionHomePage>(baseUrl);            
    }

but when I do

TrupanionHomePage homePage = CUITe_BrowserWindow.GetBrowserWindow<TrupanionHomePage>();

it only works in Internet Explorer. In Chrome / FF the getbrowserwindow call doesn't find the browser window, and all of the controls are null

The page clas looks like this:

public class TrupanionHomePage : CUITe_BrowserWindow
{
    public new string sWindowTitle = "Pet insurance by Trupanion";
            ...
}

any help would be appreciated
Mar 8, 2013 at 1:37 AM
Hey,

It normally takes 12 hours for a reply from icnocop for me due to my time zones as i'm in NZ.

First thing: have you downlaoded http://blogs.msdn.com/b/visualstudioalm/archive/2012/10/30/introducing-cross-browser-testing-with-coded-ui-tests.aspx

It is only for VS 2012.

second: what are you passing in as 'browser' ? 'chrome'/'firefox'

Also make sure you are using firefox 17 when you test on firefox.
Mar 8, 2013 at 5:11 AM
Edited Mar 8, 2013 at 6:35 AM
Hey QuanEdys,


I have installed VS 2012 update 2 ctp 4, and the the cross browser package with the selenium .net binding and chrome driver.

In terms of what I'm passing in for browser, I followed the example in the sample test case that icnocop provided for both chrome and firefox, both repro the issue.

Launching the browser works using this code:
public void OpenTrupanionWebsite(string browser)
        {
            BrowserWindow.CurrentBrowser = browser;
            CUITe_BrowserWindow window = CUITe_BrowserWindow.Launch<TrupanionHomePage>(baseUrl);            
        }
and the window object seems to be ok that way, but when I try:
TrupanionHomePage homePage = CUITe_BrowserWindow.GetBrowserWindow<TrupanionHomePage>(); 
All of the controls are null

I am using firefox 18, that could be an issue, so I will retry with 17.

I am using chrome 25.0.1364.152

thanks again

... tried FF 17.01, still get this error for all controls:
threw an exception of type 'Microsoft.VisualStudio.TestTools.UITest.Extension.UITestControlNotFoundException' int {Microsoft.VisualStudio.TestTools.UITest.Extension.UITestControlNotFoundException}
Jun 13, 2013 at 10:41 PM
I'm hoping to get some more visibility on this thread, as I have upgraded the chromium drivers,and still can't get chrome to work.
Coordinator
Jun 15, 2013 at 10:29 AM
Hi stevewar,

What does the TrupanionHomePage class look like?

Thank you.
Aug 5, 2013 at 1:25 PM
Edited Aug 5, 2013 at 1:25 PM
Hi,

I am getting the same exception as stevewar:

            BrowserWindow.CurrentBrowser = "Chrome";
            CUITe_BrowserWindow.Launch<Web_login>("http://mywebsite.com");
           Web_login newGM = CUITe_BrowserWindow.GetBrowserWindow<Web_login>();
Web_login class
namespace NamespaceName.ObjectRepository
{
    public class Web_login : CUITe_BrowserWindow
    {
        //Login Page
        public new string sWindowTitle = "Page Title";
        public CUITe_HtmlEdit txtUserName = new CUITe_HtmlEdit("Id=UserUsername");
        public CUITe_HtmlPassword txtPassword = new CUITe_HtmlPassword("Id=UserPassword");
        public CUITe_HtmlInputButton btnLogin = new CUITe_HtmlInputButton("Value=Login");
    }
Some help would be great :)
Aug 6, 2013 at 9:26 AM
Hi,

Ill have a try this weekend...

But if i remember correctly i got an error when i was trying to search for controls as the object returned from selenium web driver was not just html element. They also contained the ff/chrome window/menu/ tab objects.

I can not remember what error i was getting when this happened tho.

You could always try my original approach (at the top of the thread) and see if that give the same error. It might help narrow the offending code either way.

Thank you

QuanEdys
Feb 25 at 8:22 PM
Hi QuanEdys,

I am still facing this issue with VS 2012 update 2. I tried your original approach as well with no luck.

Is there anything new added to the CUITe to support this?

Thanks,
NepKeto