Ui Automation testing driven by windows service - c#

I am trying to clean up the process around our UI Automation testing.
Right now we have a console application that we run on a server that listens for RPC calls using Apache Thrift, depending on the test being run this application will either launch Selenium with the browser the user has specified (Chrome, IE, Firefox) or it will launch our WPF desktop application.
My goal is to allow this console application to be run as a windows service for a couple puposes:
A user is no longer needed to be logged into the server.
A third party app is no longer needed to prevent the screen saver from activating.
Will effectively allow the tests to be run in a farm so that multiple can be run in parallel
So my question is provided a server with no active user sessions and this service running, is it possible for the service to spin up both Selenium with a web browser and the WPF application and be able to drive them still.
If it isn't possible, what about programatically logging into the server?

The only way you can do this is by using PhantomJS ( or some other headless browser ). Windows services do NOT have access to running browsers on a desktop (although they used to back in the Windows XP and Windows 2000 Server days). Since then Microsoft has locked down those permissions even though you see a 'interact with desktop' checkbox on the service, I don't think it will work.
Also, Selenium Grid servers MUST run in the foreground on a remote server (for the same reasons). The only exception is, using PhantomJS on the Grid, your grid servers can run as a service to start headless browsers. Of course, running Grid node as a service and grid hub as a service is not a trivial thing to configure (using YAJSW) but its doable. Your milage may vary if you go that route as I have not actually tried it. The idea is that you could write batch DOS scripts to start/register YAJSW to run grid as a service.

Related

Is it possible to run selenium as a windows service using C#? [duplicate]

So that we may perform front-to-back web UI testing, we are using Selenium and ChromeDriver to automate page loads/interaction as part of our testing pack.
This is behaving as expected during developer testing (on a developer's local machine), but we are struggling to perform these checks as part of our continuous integration build.
Our server plant is *NIX based, and all of our CI infrastructure runs on these machines. So that we may test Chrome under Windows (our delivery mechanism), we have configured a Selenium Grid. When the CI tests run, they access the grid, in order to locate a Windows node to run the tests on.
We have had a Windows desktop provisioned solely for the purpose of running these tests. This contains our standard enterprise build of Windows 7. This machine will be periodically rebooted in-line with the IT department's update policy.
In an effort to ensure the Selenium server is always running, we have added the Selenium Server (running in "node" mode) as a Windows service. The selenium Server is configured to start-up ChromeDriver to invoke the simulated user-interaction.
However, when running the tests from CI they fail due to timeout. Our working theory is, the system user that is running the service cannot create interactive windows. A web search has raised reference to the "Session 0" problem, but with little to no constructive advice on how to move forward.
Starting the Selenium Server process manually from an interactive session is not a viable solution, as this is leading to brittle tests - which are failing due to an infrastructure problem, rather than a genuine test regression.
How can we have an instance of Selenium Server started via a Windows Service whenever the system reboots, that is capable of launching Chrome instances?
It could be easily done with NSSM.
Installation of services looks like these:
nssm install seleniumhub java -jar C:\selenium\selenium-server-standalone-2.45.0.jar -role hub -hubConfig C:\selenium\hub.json
nssm install seleniumnode java -jar C:\selenium\selenium-server-standalone-2.45.0.jar -role node -nodeConfig C:\selenium\node.json
It provides easily way to remove service if needed:
nssm remove seleniumnode confirm
Add destination to nssm to your PATH variable and run from console as admin
UPDATE April 2021
NSSM is not supported for more than 3 years. So please consider other options like winsw or any other. WinSW does the same job as NSSM and allows to keep run configuration in xml.
You cannot run Selenium Grid as a windows service ever since Windows Vista. Microsoft calls it "Session 0 Isolation". You could do it in Windows 2000 or XP but since the time that Vista came out, Microsoft no longer will let Grid interact with the desktop (or any other UI programs for that matter). Regardless of the fact that you still see that "interact with desktop" checkbox, it is a red herring. So, you MUST run Selenium Grid in the foreground on that server in order for it to get access to the session. If it is running Windows Server, you could in theory have multiple sessions and leave Grid running in the foreground on one of the non-zero user sessions.
Right now you can't help it - it used to work fine in session 0 but for the past few days after chrome update only works for interactive sessions.
Related bugs:
https://code.google.com/p/selenium/issues/detail?id=8029
https://code.google.com/p/chromium/issues/detail?id=422218
My preferred solution to this problem (and my default choice for running Selenium Grid as a service) is to use a simple tool called AlwaysUp. It has a free 30 day trial to try it out.
What to do:
Download AlwaysUp
Configure AlwaysUp to start the Selenium Grid node on startup
Configure AlwaysUp to run the Selenium node as a specific user (not the default System user)
This way the the node will run as a service, survive machine restarts and work with the latest version Chrome.
If the user account you use to login to the machine is different from the user account you specify to run the node as a service then you will not see the browsers pop up on the desktop as they are running in a different user session. The end result is that it is almost identical to running as a normal service but gets round the Session 0 issue.
Yeah, you should use NSSM. Important is, that you add your windows account in the "Log on" tab, or any other valid account. If you run your node with the "Local System account" option, you will get the session 0 problem. With a normal user session, the nodes run smoothly invisible in the background :)
we don't use selenium GRID, we were disappointed with its stability. We use a "Jenkins Grid", that is jenkins slaves nodes on various servers.
The slaves are services with the interact with desktop flag. They run as services with NSSM, and the SERVICE_INTERACTIVE_PROCESS flag. Making sure that NoInteractiveProcess is set to 1 (cf https://learn.microsoft.com/en-us/windows/desktop/services/interactive-services).
We don't have the fancy features of the grid (that is balancing according the browser types slots). Instead, we have Jenkins balancing the test jobs using a slave node or another.
Initially we did not use the interact with desktop flag, having browsers to run without "real" display, but the behavior was not very stable (especially with resize commands).
Hope this helps.
As I explained on this thread, I found that using a small paid tool FireDaemon Pro saved me a lot of time from trying to configure NSSM and other free tools.
It works well in the background, and restarts Selenium along with the server, which was my main requirement for running Selenium Standalone Server as a Windows Service.
This free tool would probably do it:
http://yajsw.sourceforge.net/
For that to work, you need a wrapper.conf file and a script to run the YAJSW wrapper. I takes time to read the documentation, but it is a free solution.
I wrote an example shared here, that installs JBoss7 as a Windows service.
Of course, you can simplify my example by a lot.

Run desktop app via WEB app

I have desktop application that can be installed on the users computer with "setup" msi file like any other application.
I'm developing web application and I need somehow to integrate the desktop application with the web application. Web application is developed using PHP (desktop application is developed using C#), and when clicking on one button on the web application, the desktop application needs to be launched.
Is there a way of doing this? I was thinking about a few scenarios:
-Maybe if possible to install the app directly on the server and to launch it from there?
-Maybe to be required the user to have the app installed on his computer and to call the app from there?
If possible I would prefer to not use the second approach because it's better if the third party to not be involved - it will be more user friendly if the application is launched directly. But any help will be appreciated because at this point I'm not sure if that is possible to be done at all.
You can install app at server an run it with exec() or "`" operator - but to control gui of app you need to use some like autoit ant etc.
If you ultimately decide to require your users to have the client application installed and expect majority of the users to be on Windows, you could register your application to handle specific scheme and parse its command line when started. More on this here:
http://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
You'd register a custom scheme and then intercept in in the application's command line arguments. The whole URL will be passed as an argument, e.g.:
myapp://parameter1,parameter2
The browser will mostly ask whether or not the user trusts the application to handle this scheme with an option to remember this setting.
If you don't have access to the source code of the client application, you can develop a middleware, some sort of a launcher that handles the URL and then runs the client application after maybe modifying some configuration files based on the URL or otherwise controlling the third-party application to do as you with.
As for solution #1, I don't think C# matters if your application can run on Mono, so you should be able to just run it from PHP. However, this probably won't work on web hosting and you will have to get a VPS for that.
There are very good (security) reasons why it is hard to launch client-side processes from web browsers.
Do you have access to the source code of the C# app? If so, you could consider modifying it to take advantage of Microsoft ClickOnce deployment.
Some references:
http://msdn.microsoft.com/en-us/library/t71a733d.aspx
http://msdn.microsoft.com/en-us/library/t71a733d(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/6ae39a7c.aspx
http://www.codemag.com/Article/0902031
Here's an old article on deploying WinForms applications via ClickOnce with Visual Studio 2005: http://msdn.microsoft.com/en-us/library/ms953320.aspx
It can possibly be done with IIS but it can be cumbersome setting it up to run as the current user, especially since it would probably also need to run elevated for an app that needs to attach to the current user's desktop.
Easiest is to install a Windows LAMP distro (like WAMP: http://www.wampserver.com/en/) and then run the httpd.exe directly from an elevated (Admin) command prompt; do not run apache as a service!
Once you do this performing and exec("command"); call in php will bring up a desktop app as if it was invoked from an admin command prompt. Obviously you need to set up the apache server to be accessible from outside the local system, etc.

Windows Application in future to be controlled over browser

I am writing a Windows application using C#. I am planning on later to allow it to be controlled over the intranet using browser also. So in future we should be able to control it both using the local interface or over the intranet from the browser.
Is there any pre-defined architecture which will allow me to do this? What are the methods of achieving this? I am new to C#/.Net.
EDIT:
The windows application needs to access the communication ports extensively, and needs to be pretty stable and would probably run for some days together.
Thanks...
I can't tell you if a specific package exists that would ease the development. But, if I were to attempt it, after Googling and not finding something already available and meeting my needs, I would likely make my application a WCF host. Create service entry points to accept control messages remotely. You would also need some well-know location where to register your application so the remote system could find it. You should be sure to provide the user with a way of disabling the application remote control feature.
Your host interface will need to run on its own thread to remain performant. Since you are new to C#, and presumably windows forms application development, you will need to read up on how to properly talk to the GUI controls from a non-GUI thread.
Alternatively, you may want to implement your application as two distinct units, one with a GUI that does all the user interaction. It would form service requests to send to the host portion (with no GUI). Your app could then operate locally or be controlled remotely.
One solution I have used in a similar situation has three parts :-
1) Win32 (local) Service
Manages the COM ports and does whatever is necessary with the attached hardware
2) WinForms/Console Application
Runs on the local machine and communicates with the local service via named pipes or TCP.
3) Web Server + Web App
Runs on local or remote machine & communicates with local service.
The local user can shut the WinForms application down and log-off without affecting the service or remote users.
The newest version of Silverlight (the version that ships with Visual Studio 2010) allows what Microsoft terms the "Out Of Browser Experience" (OOB for short).
This allows the user to set up the Silverlight application as a desktop application as well as running through a browser.
Rudi Grobbler has just blogged about how he went about setting this up on his PC.

How to do things within a windows service?

I have an application, written by me in C#.net 2.0 - when the application is opened, a timer will check every 3 seconds for x. If x happens, it shows a warning in a windows form.
Is there a possibility to install this timer and the windows form call in a windows-service? So that the timer ticks every time a system is up and shows the message then?
No, it is not possible to have a service display a form. This is by design, since a service is supposed to run without a user interface
You can have a regular application that communicates with your service and displays the warning, but I don't know how exactly this is done.
IMO, you don't need a service, just create a regular application without a main form that runs in the background, performs your check, and displays a warning when necessary. You can add that application to the Run section of HKLM or HKCU, so that it is always started when a user logs on to the system.
Windows Forms cannot be displayed from a Windows Service. A Service runs only in the background.
You can have a separate Windows application that communicates with the Windows service and display warnings, information, etc.
To do this, the service runs on the LocalSystem account, and you have to enable the property for the service to interact with the desktop.
Services are forbidden from interacting with the desktop, including displaying windows or forms. In windows 2003 and XP you could work around the issue by marking the service 'interactive' and this would allow the service to display on the user session, but as of Windows 2008 and Vista this is enforced and services can no longer interact in any fashion with the user.
When services need to display anything, the solution is to split the logic into two separate processes, one being the service and one being a normal user process. The user process runs launched by the user, in its session (it can be launched automatically at session start up) and it connects to the service via some IPC channel (shared memory, named pipes, sockets etc). The service can then display anything it wishes to the user by asking the user process half of the application to display what it needs to display.
As others have said, remember that a windows service is supposed to be a background, never-interacting-with-the-user program. Many services run even when the user is not logged on -- how would they go about displaying a form when there's no desktop for them to display it on?
That said, it shounds like you're trying to shoehorn something into a service that shouldn't be a service. If you want something that runs in the background and still interacts with the user, look into making a lightweight system try application. In fact... here's a helpful tutorial:
Lightweight System Tray Application (NotifyIcon Based)

Screenshot of process under Windows Service

We have to run a process from a windows service and get a screenshot from it.
We tried the BitBlt and PrintWindow Win32 calls, but both give blank (black) bitmaps.
If we run our code from a normal user process, it works just fine.
Is this something that is even possible? Or could there be another method to try?
Things we tried:
Windows service running as Local System, runs process as Local System -> screenshot fails
Windows service running as Administrator, runs process as Administrator -> screenshot fails.
Windows application running as user XYZ, runs a process as XYZ -> screenshot works with both BitBlt or PrintWindow.
Tried checking "Allow service to interact with desktop" from Local System
We also noticed that PrintWindow works better for our case, it works if the window is behind another window.
For other requirements, both the parent and child processes must be under the same user. We can't really use impersonation from one process to another.
Currently i can't find the corresponding links, but the problem is, that a windows service runs in another session than a normal user application.
In XP this was not fully true. Here are all services started in Session 0 and the first user who logs into the system will also run in Session 0. So in that case, tricks like Allow service to interact with desktop work. But if you fast switch to another user he gets the Session 1 and has no chance to interact with the service directly. This is also true if you connect through RDP to a server version (like 2003 or 2008). These logins will also start in a session higher than 0.
Last but not least there is another drawback by using the interaction with the desktop:
If you enable this option and your service is running under the (default) SYSTEM account it won't be able to create a network connection anymore.
The correct way to get a custom GUI that works with a service is to separate them into two processes and do some kind of IPC (inter process communication). So the service will startup when the machine comes up and a GUI application will be started in the user session. In that case the GUI can create a screenshot, send it to the service and the service can do with it, whatever you like.
Have you tried to run as Local System with the "Allow service to interact with desktop" checked?
I don't think this is possible.
We had to change our scenario where our application wasn't started from a service, but was a standard windows program that has a NotifyIcon in the corner.
If someone still finds a real answer, let me know.
It works using Local System with the "Allow service to interact with desktop"
You can set it programatically using this sample code:
http://www.vbforums.com/showthread.php?t=367177 (it's vb.net but very simple)

Categories