Friday, December 30, 2011

Webdriver - Issues with Sendkeys & Click

Webdriver -  Issues with Sendkeys & Click.

During my application automation I have noticed some instances where "SendKeys" and "Click" methods get executed successfully, but no action is performed on the screen.

I feel Webdriver team need to refine these methods further. I am not complaining about them, hats off to the team for merging Selenium1, webdriver and coming up with the architecture that support X Browsers on Y platforms, I like the browser native language concept which created a strong base so that we can make browser handle any user required action.

This issue occurred for the following elements.

1. Text field with numeric validations with default value (0.0).
   onkeypress="return NONUOM_ValidateKey(this, true); onchange="return CalculateLineItemTotal();

2. Elements in a complex Grid.

3. Objects in dynamic frame or some dynamic objects.

How to handle this situation ?

Use Javascipt. Below is the simple example. I have solved most of the issues using this technique.

Script = "document.getElementById('txtCost').value='"+UnitPriceInt+"';";
((JavascriptExecutor) driver).executeScript(Script);


Monday, December 19, 2011

QTP vs Selenium 1.0 vs Selenium 2.0 (Webdriver)

QTP vs Selenium 1.0 vs Selenium 2.0 (Webdriver)

Selenium 1.0 vs Selenium 2.0

1. Licence type
QTP - Commercial software (Concurrent and per user licence)
Selenium - Open source.
Webdriver - Open source.

2. Software size
QTP - Around 1.5GB
Selenium - Set of Libraries, around 20MB (Need to include other supporting software)
Webdriver - Set of Libraries, around 20MB (Need to include other supporting software)

3. Software Support
QTP - From HP
SeleniumSaucelabs.comElement34 , Commercial Support
Webdriver - Same as Selenium

4. Identifying objects.
QTP -  Object properties, Repository objects
Selenium - Html ID, xPath, CSS, DOM, Link text
Webdriver - Html ID, xPath, CSS, DOM, Partial Link text, Class Name

5. Spying object
Selenium - There is no option, can record script in Selenium IDE, can spy objects using IE developer tool bar, FireBug and also using
Webdriver - Same as Selenium, there is no option of recording the scripts. With the introduction of built in developer tool bar from IE8 made thing easy for IE.

6. Scripting language
QTP - VB Script
Selenium - Any language HTTP library (Java, C#, Python, Ruby...)
Webdriver - Java, .Net, Python, Ruby, Node JS

7. Environment.
QTP - Windows
Selenium - Windows, OS X, Linux, Solaris.
Webdriver - Windows, Mac, Linux, iOS, Android

8. Browsers supported
QTP - IE, Firefox (Run scripts)
Selenium - IE, Firefox, Safari, Opera
WebDriver - IE, Firefox, Safari, Opera, Chrome, Android, iPhone

9. Architecture
QTP - Not known, It makes tight integration with IE browser using Windows API's. I think it doesn't require any session information, it will retrieve all the opened browsers info and connect to it using windows APIs. It relay on .Net 3.5 libraries.
Selenium - It can be written in any language that support HTTP library, corresponding language bindings are sent to Selenium RC designed on Jetty, RC launch the browser by injecting the "BrowserBot" JavaScript into the browser. Screen operation are performed by the "BrowserBot" by communicating with RC using XMLHttp request.

WebDriver - Each browser is operated in a different way by using best suitable browser language, so that all the functionality can be accomplished.

IE - IE COM automation interfaces are wrapped in c++ classes and connected to Webdriver API.

What is "Thread Boundry"? Java is multi-thread and IE COMs have single thread, this created lot of problems. It is solved by holding the IE instance in a separate thread and using the PostThreadMessage Win32 API to communicate across the thread boundary.

Every language that WebDriver support has mechanism to call C code directly, so the C language was introduced between Webdriver and c++.

Special mechanism is used to make c to communicate with OOPs c++.

Using WebDriver JsonWireProtocol it communicate with a local instance of an HTTP server and connects to C++ DLL using a native-code interop technology such as JNA, ctypes, pinvoke or DL.

JNA (Java Native Access) - Java projects that run on different platforms, especially on windows. JNA makes it easy to call native functions.

Firefox - Javascript in an XPCOM component, it is implemented as Firefox extension.

HTTPD is embedded  HTTP server from Mozilla.

Dispatcher takes the request and iterate over the known list of URLs. Once the match is found. JSON object representing the command to execute is constructed.

This is then passed as a JSON string to a custom XPCOM component written by WebDriver team called the CommandProcessor.

Chrome - Controls the browser using Chrome's automation proxy framework. Consequently, the ChromeDriver is only compatible with Chrome version 12.0.712.0 or newer.

Opera - It is a vendor supported WebDriver implementation developed by Opera Software.
The OperaDriver uses the Scope interface (same as for Dragonfly) to communicate directly with Opera from Java. Consequently, the OperaDriver is only compatible with Opera version 11.5 or newer.

Having friendly relationship with different browser teams made WebDriver to support multi-browsers efficiently using different technologies. Selecting best suitable language for a browser is key aspect for its success, as it is interacting with its natural language we can be sure that any functionality can be accomplished.

I started my carrier with Winrunner in 2003, later moved into QTP, amazing tool at that time. For supporting  multi-browsers and QTP licence issues as team grows, moved to Selenium1. After seeing the Selenium2(Webdriver) performance, it was amazing. Now I write my entire automation code using Selenium2 Page Objects, TestNG and custom framework.

Commercial software's like QTP need to rethink on their age old design.
Selenium is a serious contender for QTP; opensource, multi-browser, mult-platform, multi-language, short releases and common APIs for all the browsers made it upper-hand.

Atoms are used across all the browsers to reduce the duplicate code, any issue relating to querying the DOM should fix all the browsers issues.

10. Limitations (I mean automation is not possible)
QTP -  As per my understanding nil (I don't want to mention about the Number precision, Text length...)
SeleniumFile upload/downloadModel dialog ... How to over come these limitations select links?
Webdriver - Model Dialog still don't work.  Issue Resolved 

11. Identifying objects
QTP - Browser.Page.Object.Method for each step.
Selenium - Directly execute methods, no browser page reference required.
WebDriver - Directly execute methods, no browser page reference required.

12. Debugging code (Setting breakpoints in the code)
QTP - Yes
Selenium - No (Need to read logs and understand the error)
Webdriver - No (Write wrapper around webdriver listener to read logs, from 2.15 it is automatically generating logs)

13. Control Opened browsers (Attach to running browsers)
QTP - Yes (Opened after QTP program)
Selenium - No (Session information is lost) .
Webdriver - No (Fix in Progress)

14. Supporting Applications
QTP - Web applications, SAP, Activex, VB, Windows...(Support provided using Addins)
Selenium - Only Web application.
Webdriver - Only Web application.

15. As performance testing tool
QTP - No, you can run one QTP application in one CPU.
Selenium - It can open many many browsers using GRID, many companies line PushToTest, BrowserMob, Gomez use selenium technology for running load test.
Webdriver - Same as Selenium, now we have GRID2.

16. Current Version
QTP - 11
Selenium - 1.0
Webdriver - 2.15

17. Object not found timeout
QTP - It will wait till the timeout happen.
Selenium - If browser status is Done, it will through exception. In some cases it will wait for time out. I did like this feature.
Webdriver - Same as Selenium, It has implicit and explicit timeouts.

18. Execute JavaScript
QTP - No (Not required, you can get entire page info directly from QTP)
Selenium - Yes
Webdriver - Yes

19. Access page DOM
QTP - Yes
Selenium - Yes
Webdriver - Yes

20. Flex objects
QTP - Yes
Selenium - Yes  Selenium Flex
Webdriver - Yes  Selenium Flex

21. Scripting complexity
QTP - Simple, but implementing framework is complex.
Selenium -Simple, but implementing framework is complex. Need to know following items for full fledge implementation.
Webdriver - Simple, but implementing page objects is slightly complex.

22. Cost
QTP - 9K USD per user (Approx) + Annual maintenance charges.
Selenium - FREE (Any number of users...)
Webdriver - FREE (Any number of users...)

23. IDE
Selenium - Any IDE (I prefer Eclipse)
Webdriver - Any IDE (I prefer Eclipse)

24. Flavors
QTP - QTP with different Add-in's

Selenium - Selenium core, Selenium IDE, Selenium RC, Selenium GRID.
Webdriver - Webdriver, GRID2.

25. Extendability
QTP - No
Selenium - Yes, you can customize and implement for new browsers.
Webdriver - Same as Selenium.

26. Exception Handling
QTP - Need to handle manually. Using .Exist, On error resume next, recovery scenarios. Script would stop in the middle by throwing run-time error if not handled properly. Programmer should have complete understanding where to use exception handling, else he suppress real errors.
Selenium - Handled automatically when used with TestNG, it will automatically move to next test case and user can implement Try...Catch to handle specific exceptions.
Webdriver - Same as Selenium. It has some extra exceptions like NoElementFound where code can be handled in a better way.

27. Reporting and Assertions(Checkpoints)
QTP - Reporting and checkpoints are built in the same package.
Selenium - Need to depend on testing frameworks like TestNG or Junit.
Webdriver - Same as Selenium.

28. Recording the script
QTP - Built in recorder that can generate script on IE.
Selenium - Selenium IDE as Firefox add on.
Webdriver - No

29. Script Execution
QTP - Just hit Play button.
Selenium - Need to run Selenium Server and it opens a separate window apart from the browser.
Webdriver - Just hit play button.

30. Page synchronization
QTP - Use .Sync method  to check the page load for every page navigation. This is the statement which I don't like to put in my code creating redundancy. I have redefined each method to element .Sync in my program.
Selenium - Use Wait for page load. This is the statement which I don't like to put in my code creating redundancy. I have created new methods eliminate from my program.
Webdriver - It is handle automatically, no method is required. Awesome job from the Web driver team, you guys really understood the concept and directly place the synchronization at the webdriver code level for those methods where there is browser navigation. This made be curios to understand how it is implemented at code level, came across this code (Highlighted in Green) in c++.
IE driver instance creation
int wdNewDriverInstance(WebDriver** result)
        *result = NULL;
                WebDriver *driver = new WebDriver();
                driver->ie = new InternetExplorerDriver();
                driver->implicitWaitTimeout = 0;

                openIeInstance = driver->ie;

                *result = driver;

                return SUCCESS;

        return ENOSUCHDRIVER;
} Open URL in the above instance, wait for page load
int wdGet(WebDriver* driver, const wchar_t* url)
        if (!driver || !driver->ie) return ENOSUCHDRIVER;
        try {
                return SUCCESS;
        } END_TRY;

bool Browser::Wait() {
        bool is_navigating = true;

        //std::cout << "Navigate Events Completed." << std::endl;
        this->is_navigation_started_ = false;

        HWND dialog = this->GetActiveDialogWindowHandle();
        if (dialog != NULL) {
                //std::cout "Found alert. Aborting wait." << std::endl;
                return true;

        // Navigate events completed. Waiting for browser.Busy != false...
        is_navigating = this->is_navigation_started_;
        HRESULT hr = this->browser_->get_Busy(&is_busy);
        if (is_navigating || FAILED(hr) || is_busy) {
                //std::cout << "Browser busy property is true.\r\n";
                return false;

        // Waiting for browser.ReadyState == READYSTATE_COMPLETE...;
        is_navigating = this->is_navigation_started_;
        READYSTATE ready_state;
        hr = this->browser_->get_ReadyState(&ready_state);
        if (is_navigating || FAILED(hr) || ready_state != READYSTATE_COMPLETE) {
                //std::cout << "readyState is not 'Complete'.\r\n";
                return false;

        // Waiting for document property != null...
        is_navigating = this->is_navigation_started_;
        CComQIPtr<IDispatch> document_dispatch;
        hr = this->browser_->get_Document(&document_dispatch);
        if (is_navigating && FAILED(hr) && !document_dispatch) {
                //std::cout << "Get Document failed.\r\n";
                return false;

        // Waiting for document to complete...
        CComPtr<IHTMLDocument2> doc;
        hr = document_dispatch->QueryInterface(&doc);
        if (SUCCEEDED(hr)) {
                is_navigating = this->IsDocumentNavigating(doc);

        if (!is_navigating) {

        return !is_navigating;
31. Handle AJAX calls
QTP - Manual
Selenium - Manual
Webdriber - Manual (There are certain classes to handle it, but didn't work for me)

32. XPath Support (Awesome technique to locate elements when there is no id or name)
QTP - Yes
Selenium - Yes (Very slow on IE)
Webdriver - Yes

33. Accessing windows objects (Folders, Excel, Notepad)
QTP - Easy (As it is developed in VB script native windows script. I hope this is one of the reason why qtp selected VB Script)
Selenium - Not so easy, need to depend on open APIs.
Webdriver - Same as selenium.

34. Code base
QTP - Huge, storing Actions occupy lot of space and more number of files. I prefer creating code in function libraries only (.vbs, .txt, .qfl)
Selenium - Small, text file with .java extension. Suitable with any configuration management tools.
Webdriver - Same as selenium.

35. Executing test on different systems
QTP - Need to setup QTP and copy the code execute it.
Selenium - Using ANT it is possible to compile into standalone jar file, so that it is easily executed from the command prompt.
Webdriver - Same as selenium.

36. APIs
QTP - Each object has methods and properties. QTP classified the objects into (WebEdit[Textbox], WebButton, WebList, WebRadio Button....). Objects are classified into Windows, Web, People soft, SAP, Visual Basic, Activex...., need to add extra licensed programs called Addin for supporting of the corresponding objects. Addin program can help QTP to identify the properties in specific environment. To identify an object on the screen, need to provide properties. Properties are classified into Mandate, Optional and ordinal properties.
To identify the an object on the screen, following statement is required.


Selenium - Directory based API, all methods exist in one class. It is a table based API that contain 3 columns

Selenium command, Locator(Object ID, Name, xPath...), list of parameters in array format.
Note: Browser, Page details are not required; its reference is automatically handled by Selenium session.

Webdriver - Complete OOPs.
Define Browser object (IE, Firefox, Chrome...)
Define Element object.
Run the method on the element object.

// Create an instance of WebDriver backed by Firefox
WebDriver driver = new FirefoxDriver();

// Now go to the Google home page

// Find the search box, search for something
WebElement searchBox = driver.findElement("q"));

// And now display the title of the page
System.out.println("Title: " + driver.getTitle());

37. Number of Methods
QTP - Each object has certain methods, most of the methods are unique like Set, Click, Select...
Selenium - Few methods.
Webdriver - You can complete most of the script using click and SendKeys.

38. Object Repository (Object information is stored separately during recording and can be edited if required)
QTP - Yes. Also provide option to define objects at code level called descriptive programming (DP).
Selenium - NO, only through code.
Webdriver - NO, only through code.

39. Page Objects Implementation
QTP - VB script don't supports complete OOPs, but can be achieved with Dual-Function Framework.
Selenium- I think no, it is not possible to move Selenium session from one class to another, but methods can be grouped as per the page by extending the Selenium interface.
Webdriver - Yes, support complete OOPs. (Planning to write a new post on this with an example).

40. Synthesizing events on the page
QTP - Synthesize events on DOM.
Selenium - Synthesize events on DOM.
Webdriver - Type looks very realistic as though real user is typing. I think they are sending the events to IE instance message queue. (Need to understand the technique used)

Over all comparison

Browsers - (IE/Firefox)
OS - (Windows)
Scripting - (VB Script)
Licence - ($8000 per user)
Limitations(No solution) - Nil

Webdriver -
Browsers - (IE, Firefox, Safari, Opera, Chrome, Android, iPhone),
OS - (Windows, Mac, Linux, iOS, Android)
Scripting - (Java, .Net, Python, Ruby, Node JS)
Licence - Free
Limitations(No solution) - Model-Popup (Some can be handled). By making small changes in the UI it can be easily tackled, display model-popup content in Div by graying the background. Issue Resolved 

Now Your Choice  ?


Friday, December 9, 2011

Webdriver - File upload (IE Driver)

Webdriver - File upload (IE Driver)

To upload file I have used different ways including (Auto It V3), but not successful.

It was really amazing when "SendKeys" method is able to open the Browse window dialog, browse the file and open the file. I have not seen the level of sophistication even in the HP QTP. Hats-off to the Webdriver team.

Attaching webdriver code and file upload control HTML.

driver.findElement("ctl00_CphePurchase_FileUpload1")).sendKeys("C:\\Selenium Files\\Signature.jpg");

I was curious to look at the "SendKeys" code that is handling the file upload, after digging the IE driver came across following code.

        static unsigned int WINAPI SendKeysCommandHandler::SetFileValue(void *file_data) {
                FileNameData* data = reinterpret_cast(file_data);
                HWND ie_main_window_handle = data->main;
                HWND dialog_window_handle = ::GetLastActivePopup(ie_main_window_handle);

                int max_wait = 10;
                while ((dialog_window_handle == ie_main_window_handle) && --max_wait) {
                        dialog_window_handle = ::GetLastActivePopup(ie_main_window_handle);

                if (!dialog_window_handle || (dialog_window_handle == ie_main_window_handle)) {
                        // No dialog directly owned by the top-level window.
                        // Look for a dialog belonging to the same process as
                        // the IE server window. This isn't perfect, but it's
                        // all we have for now.
                        max_wait = 10;
                        while ((dialog_window_handle == ie_main_window_handle) && --max_wait) {
                                ProcessWindowInfo process_win_info;
                                process_win_info.dwProcessId = data->ieProcId;
                                ::EnumWindows(&BrowserFactory::FindDialogWindowForProcess, (LPARAM)&process_win_info);
                                if (process_win_info.hwndBrowser != NULL) {
                                        dialog_window_handle = process_win_info.hwndBrowser;

                if (!dialog_window_handle || (dialog_window_handle == ie_main_window_handle)) {
                        LOG(WARN) << "No dialog found";
                        return false;

                return SendKeysToFileUploadAlert(dialog_window_handle, data->text);

        static bool SendKeysToFileUploadAlert(HWND dialog_window_handle, const wchar_t* value) 
                HWND edit_field_window_handle = NULL;
                int maxWait = 10;
                while (!edit_field_window_handle && --maxWait) {
                        edit_field_window_handle = dialog_window_handle;
                        for (int i = 1; fileDialogNames[i]; ++i) {
                                edit_field_window_handle = getChildWindow(edit_field_window_handle, fileDialogNames[i]);

                if (edit_field_window_handle) {
                        // Attempt to set the value, looping until we succeed.
                        const wchar_t* filename = value;
                        size_t expected = wcslen(filename);
                        size_t curr = 0;

                        while (expected != curr) {
                                ::SendMessage(edit_field_window_handle, WM_SETTEXT, 0, (LPARAM) filename);
                                curr = ::SendMessage(edit_field_window_handle, WM_GETTEXTLENGTH, 0, 0);

                        for (int i = 0; i < 10000; i++) 
                                HWND open_window_handle = ::FindWindowExW(dialog_window_handle, NULL, L"Button", L"&Open");
                                if (open_window_handle) {
                                        LRESULT total = 0;
                                        total += ::SendMessage(open_window_handle, WM_LBUTTONDOWN, 0, 0);
                                        total += ::SendMessage(open_window_handle, WM_LBUTTONUP, 0, 0);

                                        if (total == 0)
                                                return true;


                        LOG(ERROR) << "Unable to set value of file input dialog";
                        return false;

                LOG(WARN) << "No edit found";
                return false;


Sunday, November 27, 2011

Webdriver - Drop down select values

Webdriver - Drop down select values. (IE Driver)

There is no direct method to choose/click the values from the drop down.
I have used following code to select the list values. Also attaching the screen shot of the list box HTML for better understanding.

String UOMCode = "A1";

Also read following post


Monday, November 21, 2011

VB Script - Call Web-Service with parameters as inline attachment (Base 64)

VB Script - Call Web-Service with parameters as inline attachment (Base 64)

This code is written to automate web-service testing using QTP and Selenium. Actual code is more complicated, below code will help you understand in construction of web-service for the method mentioned in below screen shot.
Need to modify the SOAP message as per your method parameters and data type.

SOAPMessage = "" & _ 
     "" & Bytes() & "" & _

msgBox SOAPMessage
Set objHTTP = CreateObject ( "MSXML2.XMLHTTP")
Set xmlDOC = CreateObject ( "MSXML.DOMDocument") 
strWebserviceURL = URL '""
objHTTP.Open "POST", strWebserviceURL, False
'Set the Content-Type is very important 
objHTTP.SetRequestHeader "Content-Type", "text/xml;charset=utf-8"
'objHTTP.SetRequestHeader "SOAPAction", ""
objHTTP.SetRequestHeader "User-Agent", "Jakarta Commons-HttpClient/3.0"
objHTTP.SetRequestHeader "Host", Domain ' 
objHTTP.Send (SOAPMessage) 
bOK = xmlDOC.load (objHTTP.responseXML) 
'Look at the state value 
msgBox objHTTP.Status 
msgbox objHTTP.StatusText 
msgbox objHTTP.responseText
'objHTTP.Status = 200, return here to deal with a fragment of xml 
'If necessary, you can replace them to return the xml string of  
xmlStr = xmlDOC.xml 
xmlStr = Replace (xmlStr ,"&lt","<", 1, -1,1) 
xmlStr = Replace (xmlStr ,"&gt",">", 1, -1,1) 
msgbox xmlStr 

' HTTP is a text based protocol, it can't transmit binary content
' so content need to be converted into base 64 format
' Below function perform this job for you

Function Bytes()
 Const fsDoOverwrite     = true  ' Overwrite file with base64 code
 Const fsAsASCII         = false ' Create base64 code file as ASCII file
 Const adTypeBinary      = 1     ' Binary file is encoded

 ' Variables for writing base64 code to file
 Dim objFSO
 Dim objFileOut

 ' Variables for encoding
 Dim objXML
 Dim objDocElem

 ' Variable for reading binary picture
 Dim objStream

 ' Open data stream from picture
 Set objStream = CreateObject("ADODB.Stream")
 objStream.Type = adTypeBinary

 ' Create XML Document object and root node
 ' that will contain the data
 Set objXML = CreateObject("MSXml2.DOMDocument")
 Set objDocElem = objXML.createElement("Base64Data")
 objDocElem.dataType = "bin.base64"

 ' Set binary value
 objDocElem.nodeTypedValue = objStream.Read()

 ' Get base64 value and write to file
 'objFileOut.Write objDocElem.text
 'msgBox (objDocElem.text)
 Bytes = objDocElem.text

 ' Clean all
 Set objFSO = Nothing
 Set objFileOut = Nothing
 Set objXML = Nothing
 Set objDocElem = Nothing
 Set objStream = Nothing
End function
I am currently busy with other tasks, planning to put detailed explanation of the above code later.

Thursday, November 17, 2011

Selenium - Build standalone jar file using ANT

  Selenium RC Common Build Tasks




Tuesday, November 15, 2011

QTP, Selenium - Black/Empty screen shots - Windows

QTP, Selenium - Black/Empty screen shots - Windows

Black screen shot happen when desktop is not available. This will happen when you lock the PC, disconnect or minimize RDP (Remote Desktop). This is fail windows screen shot function, any tool need to relay on OS APIs for taking a screen shot. It is a known issue in all versions of windows.
Also some of the tool functions fail because windows switches to GUI-Less mode and don't display windows and controls.

There are FOUR options available

Option1: When tool is installed on local machine, install caffeine so that your system is not locked automatically when ideal as per the company policy.

Option2: Install  Ultra VNC Server on the remote machine or EC2, so that it can be accessed by IP address. In this option you can lock the machine with VNC on, still you can take the screen shot.

The Microsoft Windows operating system includes the Remote Desktop component that allows you to connect to a remote computer and work with it as with your local computer. This is a common way to run and monitor automated tests on remote computers: you connect to the test computer using a Remote Desktop Connection (RDC) and use the Remote Desktop window to work with the remote computer on your PC.
There is a pitfall using this scenario: you may not minimize the Remote Desktop window (that is, the window which displays the remote computer’s desktop), or your GUI tests will fail. If you minimize this window, the operating system switches the remote session to a GUI-less mode and does not display windows and controls. As a result, TestComplete (or TestExecute) are unable to interact with the tested application’s GUI as the GUI doesn’t actually exist in this case.
Keeping the Remote Desktop window visible may be inconvenient, as it will occupy some part of or even your entire screen, and you will have less space for running your local applications.
We have found a way to bypass this limitation. The workaround is simple: you need to change Registry keys on your computer (that is, the computer from which you connect to a remote TestComplete or TestExecute workstation). Here is a step-by-step description:
  1. Close Remote Desktop sessions opened on your computer.
  2. Launch the Registry editor (Regedit.exe).
  3. Locate any of the following Registry keys:
    • HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\
      (if you want to change the RDC settings for your user account)
    • -- or --
    • HKEY_LOCAL_MACHINE\Software\Microsoft\Terminal Server Client\
      (if you want to change the RDC settings for all accounts)
  4. Create a new DWORD value in this key namedRemoteDesktop_SuppressWhenMinimized. Specify 2 as the value data (As Decimal).
  5. If you use a 64-bit operating system, add the RemoteDesktop_SuppressWhenMinimized value to the following keys under the Wow6432Node node:
    • HKEY_CURRENT_USER\Software\Wow6432Node\Microsoft\Terminal Server Client\
      (for your user account)
    • HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Terminal Server Client\
      (for all user accounts)
    This way the Registry tweak will work in both 32- and 64-bit versions of the Remote Desktop client.
That’s all. Now minimizing the RDC window on your computer will not affect the remote computer’s GUI and the GUI will still be available to your automated GUI tests.

Option 4:

Here is the simple, but very useful instruction how to run GUI test automation scripts on the remote server.

1. Open "Remote desktop connection" window, click "Options" button, then "Save As..." and save "*.rdp" file in any place. 
2. Open *.rdp file in Notepad and add to the end of file string: "smart sizing:i:1" without quotes. Make sure that parameters "desktopwidth:i:1280" and "desktopheight:i:1024" has values which match desktop resolution on a server. If you wish, you can change parameter value "session bpp:i:8" to "session bpp:i:24" for more comfort colors. 
3. Use this *.rdp file for launching RDC session by clicking on it. 

After tests launch on the remote server you can change size the RDC Session window, but don't minimize and don't overlap it with another windows - it is very important. 

Optional: for keeping RDC Session window always on top, you can use free software "Hotkey manager" After install "Hotkey manager" run it, icon appears in system tray, then hold Ctrl button and right-click on "Maxmimize" button on RDC Session window, RDC window becomes always on top. For keeping window always on top, you can use other software too or just control it manually. 

In order to keep RDC closed, you can set specific registry values, as it is described at Running Tests in Minimized Remote Desktop Windows article.