I have a grid hub running with some nodes, the grid URL is stored in a c# project App.Config file. My App.Config also specifies which browser to use to run tests against. In a WebDriver factory class I create a new instance of RemoteWebDriver pointing to the grid URL with the proper browser and capabilities.
My question is, what if I want to run my tests locally and bypass the grid sometimes for debugging purposes or whatever, I can specify an additional App.Config key, say Local = true or false, if set to true, don't use RemoteWebDriver. Is there an elegant way to provide this functionality? Can remotewebdriver run tests locally without using the grid? I want to avoid having to create additional factories and check whether the user requested a local run. Has anyone implemented something similar?
You wouldn't need to avoid using RemoteWebDriver in order to run tests locally. If you download and run the selenium-server-standalone on your local machine (with associated configuration done as well, so browser driver executables, PATH variables, etc), you can simply point your tests to your local hub instead of the remote hub.
Running the Selenium server in standalone mode starts both a hub and node at once with a default configuration (which can be changed via command line args or json config), but it's great for debugging tests without having to run on a production Grid.
Further Reading
Related
I'm automating tests using Selenium and C# and I need to open an external app from the browser. The problem is, I always get this notification and it blocks the test execution.
Does anyone know how to deal with this?
Chrome stores the settings for the acceptance of protocol handlers in the user profile. When running Chrome from Selenium, Chrome doesn't seem to use the standard Chrome user profile by default, and instead uses some default settings that are not persisted.
To get around this, you can launch Chrome from the command line manually and manually specify a new --user-data-dir=c:\foo\bar profile location. (Point it to a new/empty directory and Chrome will populate it for you.)
Using this manually-launched browser, navigate to the page you need to interact with, activate the link, click the "always open" checkbox, and run the program once.
Next, close Chrome and save a copy of the entire new user profile directory. When you run your Selenium tests, make sure to always pass Chrome the same command line options pointing it to that user profile. These settings are now persisted, so the link will open without user intervention in the future. (This question may be of help to feed the right command line args to Chrome.)
For repeatable tests, you will probably want to save a static copy of this profile and redeploy it whenever you launch Selenium.
If you are using Javascript+Selenium or WebdriverJS then use this :
chromeOptions = {
'args': ['--test-type',
'--start-maximized',
'use-fake-ui-for-media-stream',],
'prefs': {
protocol_handler: {
excluded_schemes: {
'yourprotocolname': false
}
}
},
};
DesiredCapabilities capabilities = DesiredCapabilities.InternetExplorer();
System.Environment.SetEnvironmentVariable("webdriver.ie.driver", #"C:\\IEDriverServer.exe");
instance = new RemoteWebDriver(new Uri("http://localhost:4444/wd/hub"), capabilities);
I also have the a system variable set, and the IEDriverServer is in the system path. I cannot run the IEDriver from command line (which makes me thinking is there something wrong with path configuration, or some security restriction)
note that the hub and the node are one and the same machine.
when I execute the test I get:
"System.InvalidOperationException:
The path to the driver executable must be set by the webdriver.ie.driver system property; for m....."![enter image description here][1]
I'm running this one one machine both acting as a hub and a node just to make a proof of concept it'll work for me.
There are a number of things I'd question about your approach to what you're trying to accomplish. First, if you're running your C# code on the same machine as the remote Java server (node/hub), why bother? You can easily just use the InternetExplorerDriver class and eliminate the Java server altogether.
Second, setting an environment variable is not the same as setting a Java system property. You can set the system property by using a -D command line flag on the command line with which you launch the Java .jar.
Finally, if you're actually running the Java server on a different machine from the C# code, and are correctly using RemoteWebDriver, bear in mind that you need IEDriverServer.exe on the machine running the Java server, and not the one running your C# code. Furthermore, you need the hub/node to be aware of the path to the executable on that machine, not to the executable where your C# code is running.
I've got it solved, used the appropriate version IEDriver and fixed the PATH and it worked.
I have a simple web service that looks something like this:
[WebMethod]
public OrderForecastItem GetOrderForecast(int shipTo, string catalogName, bool showPricing)
{
return OrderForecastManager.GetOrderForecast(shipTo, catalogName, showPricing);
}
I'm calling it from another place in a fairly simple way:
using (OrderForecastWS.OrderForecastWS service = new OurSite.Web.Reporting.OrderForecastWS.OrderForecastWS())
{
OrderForecastItem orderForecastItems = service.GetOrderForecast(2585432, "DENTAL", false);
}
After some gymnastics to get the systems to understand that I'm talking about the same type of objects on the client and server sides (I had to open the Reference.cs file inside my Web References, delete the generated OrderForecastItem and add a link to our real OrderForecastItem), the system runs and attempts to get the item.
Unfortunately, it now bombs during the service call, claiming:
Exception There is an error in XML document (1, 1113).(InvalidOperationException)
I can go to the web service in a browser, put in the same values, and I get a seemingly valid XML response. (It looks okay to me, and I ran it through the XML parser at W3Schools, and it cleared it.)
I think the numbers in the error are supposed to be the line and character number...but the browser seems to reformat the xml document, so I can't easily see what the original (1, 1113) location is.
I don't see an easy way to intercept the response and examine it, since it seems to be blowing up as soon as it gets it.
How can I debug this?
If you control the service, you can step into it. If it is a part of your solution and hosted in VS WebDev on your local box, just F11 from Visual Studio, if service is hosted remotely (eg by IIS on other computer) run remote debugging tool on service host msdn, and then you will be able to step in to the service remotely.
By the way, you can tell Visual Studio to re-use objects from referenced libraries for types from the service: just pick configure Service Reference from service context menu and tell which libraries to re-use.
On second thought this error may happen if returned XML could not be deserialized into your business object. May happen when class is changed on either side, or you are trying to use different version of business library than service is using.
If you use Firefox, I'd recommend Firebug. You'll be able to easily view the response from the website in its original format, which might get you closer to the line and position you're looking for.
I need to change my unit test from local to remote tests and so far I thought that all I had to do is change UrlToTest to point to another server... But VS keeps on insisting to create a Development Web Server instead of using the one that is already running.
So after reading some docs my question actually is do I have install Test Controller and Test Agent on both remote and local computer or what? What if the WebService is on Linux...
Note that I don't want to debug the application that I'm testing. I simply want tests to be executed for a WebService that is already running, that is deployed.
I probably should mention that all my tests consists of WebService calls and some checks like this:
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("MainProjectName", "/")]
[UrlToTest("http://servername:port/websitename/TestingOnlyWebForm.aspx")]
public void LoginEmptyDataTest()
{
IUserService userService = CreateIUserService();
string email = "";
string password = "";
ReturnMessage<User> actual;
actual = userService.Login(email, password);
Assert.AreNotEqual(true, actual.Status);
Assert.AreNotEqual("db_error", actual.Info);
}
But I have also more complicated tests in which I change some data and send it to another WebService and so on.
Note that UrlToTest previously was pointing to localhost at which point it works but starts a developer server which is not what I want.
What you are trying to is not possible. All that generated unit test is trying to do is to run the test locally on the machine either using the development server by specifying AspNetDevelopmentServerHost or by using local IIS, when AspNetDevelopmentServerHost is not present.
If you want to test remote services right click your unit test project and add a service reference. Point to your service give it a namespace, say Services, and generate the proxies. Once you have the proxies generated just instantiate them and call the methods. Also remove all the unneeded attributes from your test. Your test should roughly look like this:
[TestMethod]
public void LoginEmptyDataTest()
{
using (var userServiceClient = new Services.UserServiceClient(
"BasicHttpBinding_IUserService",
"http://someremotehost/userservice.svc"))
{
var result = userServiceClient.Login("user", "password");
// asserts go here
}
}
This may solve your immediate problem however you should re-think what you are doing as #eglasius said. what happens if the code you call changes state internally? Next test might fail because of that so you need clean-up strategies otherwise your tests will be very brittle and you'll end up ignoring them.
Update: passing an address at run-time. Change the first parameter to whatever enpoint configuration name you have in your config file.
I'll take a stab in the dark at this one because I did something similar recently.
In my case my test project referenced the service project to provide visibility of the service and data contracts the Web Service implements and consumes.
To resolve this - though it can be ignored - move the contracts to a new project. Then have the service and test projects reference the new project, and remove the test projects' reference to the service.
Hope that makes sense!
Once the reference is removed, VS will no longer feel the need to start up your service when you run your tests.
You can disable the startup of the Service Host in the Project settings of your WCF Service Project. Right Click - WCF Options - Uncheck "Start WCF Service Host when debugging another project in the same solution".
You really have to consider the nature of what you're trying to achieve here.
It's hard to tell exactly what you're hitting of the code. I have the impression, you have is a website that calls a web service. You're testing the client code in that context, instead of just testing the service.
If that's the case, remove the attributes and point the url to the correct service like UrbaEsc guided you to. If you don't remove the attributes, you're running the calling code in the context of the site.
Even if the above is not the scenario, and based on what you replied to UrbanEsc in the comments, you'd then be testing an external call to the webservice initiated from the same site process.
You said:
"Found it, but VS still starts something on localhost and then trys to reach external server... Seems like VS is just not designed for real remote testing of webservices"
Read the above. I'd say you need to better understand what you're enabling. You can certainly test remote web services, like you can do pretty much anything you can code. You do that from client code that knows nothing different that what any other external client of the service would know. Support doesn't stop there, as you can do load testing of the service.
Note that what you're doing aren't unit tests, these are integration tests. Or depending on the scope of your system, full system tests.
I have a developer tool that I want to run from an internal site. It scans source code of a project and stores the information in a DB. I want user to be able to go to the site, chose their project, and hit run.
I don't want the code to be uploaded to the site because the projects can be large. I want to be able to run my assembly locally on their machine. Is there an easy way to do this?
EDIT: I should note, for the time being, this needs to be accomplished in VS2005.
EDIT 2: I am looking for similar functionality to TrendMicro's Housecall. I want the scan to run locally, but the result to be displayed in the web page
You could use a ClickOnce project (winform/wpf) - essentially a regular client app, deployed via a web-server. At the client, it can do whatever it needs. VS2005/VS2008 have this (for winform/wpf) as "Publish" - and results in a ".application" file that is recognised by the browser (or at least, some browsers ;-p).
You might be able to do the same with Silverlight, but that has a stricter sandbox, etc. It would also need to ask the web-server to do all the db work on its behalf.
I want to be able to run my assembly
locally on their machine
Sounds like you want them to download the tool and run it from their local machine, does that work for you?
Any code can scan files given the location and permissions. For a website to open an exe on a different machine and permit that to run and get access to the files contained on the web server would require a horrifically low level of security that would mean the entire system is practically completely open to attack. If your system is completely behind a firewall and hence protected from outside intererance then you want to look more at the permissions and less at the code.
To run an exe on a machine try following notepad example, though you may have to use a specified directory as well
ProcessStartInfo psi = new ProcessStartInfo("notepad.exe");
psi.WindowStyle = ProcessWindowStyle.Hidden;
Process p = new Process();
p.EnableRaisingEvents = true;
p.Exited += new EventHandler(ExitHandlerToKillProcess);
p.StartInfo = psi;
p.Start();
and when done dont forget to kill the Process. Alternately use javascript. Either way watch the security permissions and remember the risks of doing this.
I would probably write some sort of command line tool or service that does the processing and extraction of project data. Then I would use a page to update/register projects that the web server and the command line tool both have common access to. then at specified times either manually or via cron or similar mechanisms extract the data to your database. once you have this, you just use the website to display last extraction times and the extracted data.
if the projects/end users are on a different subnet etc, then you will need the end users to run the tool and then have it post the data into the database.