Execute JavaScript from within a C# assembly - c#

I'd like to execute JavaScript code from within a C# assembly and have the results of the JavaScript code returned to the calling C# code.
It's easier to define things that I'm not trying to do:
I'm not trying to call a JavaScript function on a web page from my code behind.
I'm not trying to load a WebBrowser control.
I don't want to have the JavaScript perform an AJAX call to a server.
What I want to do is write unit tests in JavaScript and have then unit tests output JSON, even plain text would be fine. Then I want to have a generic C# class/executible that can load the file containing the JS, run the JS unit tests, scrap/load the results, and return a pass/fail with details during a post-build task.
I think it's possible using the old ActiveX ScriptControl, but it seems like there ought to be a .NET way to do this without using SilverLight, the DLR, or anything else that hasn't shipped yet. Anyone have any ideas?
update: From Brad Abrams blog
namespace Microsoft.JScript.Vsa
{
[Obsolete("There is no replacement for this feature. " +
"Please see the ICodeCompiler documentation for additional help. " +
"http://go.microsoft.com/fwlink/?linkid=14202")]
Clarification:
We have unit tests for our JavaScript functions that are written in JavaScript using the JSUnit framework. Right now during our build process, we have to manually load a web page and click a button to ensure that all of the JavaScript unit tests pass. I'd like to be able to execute the tests during the post-build process when our automated C# unit tests are run and report the success/failure alongside of out C# unit tests and use them as an indicator as to whether or not the build is broken.

The code should be pretty self explanitory, so I'll just post that.
<add assembly="Microsoft.Vsa, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies>
using Microsoft.JScript;
public class MyClass {
public static Microsoft.JScript.Vsa.VsaEngine Engine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
public static object EvaluateScript(string script)
{
object Result = null;
try
{
Result = Microsoft.JScript.Eval.JScriptEvaluate(JScript, Engine);
}
catch (Exception ex)
{
return ex.Message;
}
return Result;
}
public void MyMethod() {
string myscript = ...;
object myresult = EvaluateScript(myscript);
}
}

You can use the Microsoft Javascript engine for evaluating JavaScript code from C#
Update: This is obsolete as of VS 2008

You can run your JSUnit from inside Nant using the JSUnit server, it's written in java and there is not a Nant task but you can run it from the command prompt, the results are logged as XML and you can them integrate them with your build report process.
This won't be part of your Nunit result but an extra report.
We fail the build if any of those test fails.
We are doing exactly that using CC.Net.

I don't know of any .NET specific way of doing this right now... Well, there's still JScript.NET, but that probably won't be compatible with whatever JS you need to execute :)
Obviously the future would be the .NET JScript implementation for the DLR which is coming... someday (hopefully).
So that probably leaves running the old ActiveX JScript engine, which is certainly possible to do so from .NET (I've done it in the past, though it's a bit on the ugly side!).

If you're not executing the code in the context of a browser, why do the tests need to be written in Javascript? It's hard to understand the bigger picture of what you're trying to accomplish here.

Could it be simpler to use JSUnit to write your tests, and then use a WatiN
test wrapper to run them through C#, passing or failing based on the JSUnit results?
It is indeed an extra step though.
I believe I read somewhere that an upcoming version of either MBUnit or WatiN will have the functionality built in to process JSUnit test fixtures. If only I could remember where I read that...

Related

Is it possible to execute an arbitrary class in C# with a Main method, similar to that in Java?

I've recently had to migrate to the C# world. Coming from the Java land, I could add a public static void main(String[] args) method to any class and select to run that class from Eclipse/Netbeans for any code/logic that I wanted to quickly test.
Is there an equivalent of the same capability in C#.Net/Visual Studio? I've tried doing that and the best I can do is to execute it from the command prompt via csc.exe. However, for some reason, it complains about not finding the relevant DLLs - it seems to expect to run that class in complete isolation without any dependency on "external code" (i.e., code residing in that VS project/solution where the class resides).
Reason for this capability: All project files are marked as class libraries and sometimes I just wish to check if a particular set of methods/data/logic will work as expected with the current code base. In Java, I'd quickly write it in the main method and execute that class to see how it goes prior to committing it to version control. However, there seems to be no easy way to trigger the execution of "my class" with all dependencies correctly handled by csc.exe
Current Solution: Add this testing code to the unit test project and select to execute that particular "test" so as to check if the idea seems to work fine (it may fire DB calls or webservice class etc., and not be purely a logical flow of computation). This seems to work fine and is my current way of doing things. I was wondering if the Main method was even possible/recommended.
Question: Is this even possible with C#/VS or not recommended?
Update: I can't add a console project just to achieve this since the addition of projects is tightly controlled by the source control team. Hence the question of the Main method 'hack' for quick and dirty checks/tests.
Your project type needs to be Console Application for it to "recognize" a Program.Main method, not Class Library. The intent is for a Class Library to be an encapsulated grouping of functionality that can only be accessed by a project that is set up to allow for user input. Those can be a Console Application, Web project (MVC/API), or Desktop (WPF).
If you just want to execute a test against the code within a Class Library project, you can also create a Unit Test project, add a reference and execute very explicit tests against the functionality you're looking to achieve.
You can find out the differences between the different project types by examining the .csproj files in your favorite text editor.
In Visual Studio go New->Project then select Console Application (in Windows\Classic Desktop in VS2015). This gives you a basic console application with...
static void Main(string[] args)
{
}
setup and ready to go. However for simply trying out code you may find this cumbersome (creating a new project and folder just to test code) and for testing code (that doesn't rely on existing libraries) you could use something like .NET Fiddle...
https://dotnetfiddle.net/
Where you can quickly create and test code there and run it via the browser.

How to run a SpecFlow test through a test harness?

Good afternoon/morning/evening folks,
I was wondering is it possible for me to "execute" a SpecFlow test via some sort of test harness (not NUnit)?
Previously my test harness I built ran MS Unit tests by calling methods from within the DLL that was created when I compiled the tests.
I'm assuming the same is possible in theory since a DLL is created, but im wondering how it will get all of the arguments etc.
So in short, is this possible if so is there a straight forward way to do this or am I barking up the wrong tree?
It's possible, but I'm not clear why you would want to.
Specflow is basically just a clever way of generating tests. Normally these are nUnit tests, but they can also be switched to use mstest. When you save your edits to the .feature file then VS runs a Custom Tool that converts your plaintext into a .feature.cs file that contains a code version of what you wrote with nUnit attributes applied to the methods.
Later, an nUnit runner (nUnit, resharper, gallio, teamcity etc) loads the dll and looks for all public methods marked with [Test] inside public classes marked with [TestFixture]. These methods get called.
There is nothing to stop you writing your own runner, however I'm not sure why you would do that. nUnit provides extensive reporting of the success of your test run in xml format, so its probably faster just to write something to parse that.
So I decided to invest some time on this and figured that using reflection was the way to do this task.
Here is some of my code:
TestRunner.TestDLLString = getDLL(project);
var TestDLL = Assembly.LoadFrom(TestDLLString);
Type myClassType = TestDLL.GetType("SeleniumDPS." + testname);
var instance = Activator.CreateInstance(myClassType);
MethodInfo myInitMethod = myClassType.GetMethod("Initialize");
try
{
myInitMethod.Invoke(instance, null);
}
catch (Exception ex)
{
//Error logging etc
}
I then repeat that for the "[TestMethod]" etc. I understand some people dislike reflection but in this instance the performance isnt critical so it works quite well for us.
So essentially what im doing is reading on the name of the test from an XML file then searching the DLL for that test method, then executing the Intitialize method, and later on executing the test method itself. After the test is run I then execute the cleanup method.
It might seem a bit hacky and NUnit might seem the logical choice for some, but as I mentioned earlier I needed a customizable approach. Thanks for all the suggestions though.

How can i pass my tests directly to nunit

I want to run C90 tests in NUnit. I have written a short adapter that actually works, but i want to get rid of writing that adapter and instead make a tool that opens nunit and passes in loadable data so that nunit can run the tests.
I spare you the codeload i wrote so far and just summarize its usage:
I wrtie my C90 tests as callable dll functions with annotations above them like comments. Example /TEST/. As of now the test returns 0 or 1 for pas fail information.
A C# Pathinspector inspects all *.c files for annotations and extracts the loadinformation.
A C# Executer manages the execution of the tests and returns PASS/FAIL information.
What i want to do instead of my Executer is to create either the Launchinformation for NUnit and pass that into a freshly created gui, or create C# code to pass into the freshly created gui.
I know how to create an NUnit gui runner, but i dont know how to pass information into it.
Nunit source is online available, however it uses a lot of singletons during initialisation so i would argue against it.
One way could be to actually write and compile cs files and pass those compiled into nunit.
The best approach seems to be writing an xUnit compliant framework from scratch.

Calling back to VBScript from C#

I'd liked to know whether it is possible to call a function in VBScript from C#. Let me try to clarify. I'm using an application (Quick Test Professional or "QTP") that automates another application, mostly using VBScript. There is the ability, via an add in model, to extend the test functionality by writing add-ins to the testing application (QTP) that are .NET assemblies. The basic workflow is that the VBScript tests automate the test application, and can call methods on a class in the extensibility add in assembly to do more complicated things. This part works fine.
What I'd like to know is whether it is possible for my C# code (in the extensibility add in assembly) to call back to a function in the VBScript. I don't think the test application framework (QTP) explicitly supports this, so I'm wondering if there is any way to do this using standard interop techniques. I was half way thinking of using GetRef() to get a reference to the VBScript function of interest, passing this as a parameter to a method I call in the extensibility addin (I suspect I would run into marshaling issues even at this point?) and then within the C# code of my extensibility add in, somehow call a method on this object; this is where I'm completely lost (since I don't know how to do this without the necessary type information normally used in reflection).
I'm thinking this may not be possible, but would like confirmation if that's the case.
Thank you!
In the end not so hard but finding it out was harder
In vbscript set a=getref
In c# declare the ref as an object
https://community.saas.hpe.com/t5/Unified-Functional-Testing/C-compile-on-the-fly-thru-dotnetfactory/m-p/1611299#M22811
private object _UFTCallBackFunction = null;
public int callMeBack2()
{
string[] retParts = {"Yep this is value 1"};
_UFTCallBackFunction.GetType().InvokeMember("",
System.Reflection.BindingFlags.InvokeMethod, null,
_UFTCallBackFunction, retParts);
return 0;
}
public void InitUFTCallBack(object UFTCallBackFunction)
{
_UFTCallBackFunction = UFTCallBackFunction;
}
And then in vbs
Set oCallMe = GetRef("CallMeBackWithAParameter")
oTestCom.InitUFTCallBack(oCallMe)
oTestCom.callMeBack2()
Function callMeBackWithAParameter(P1)
print "I wass called back from C# having value " & P1
End Function
How does the VBScript call the C# code? I suspect that it is really calling on QTP, and QTP is calling the C# code. In that case, only QTP could possibly call the VBScript back.
Under what circumstances would your C# code call back? I doubt that VBScript can be called back asynchronously.
That's a toughie.
You MAY want to try writing an event handler in the VBScript side for the .NET component and raising an event on the .NET side when you want the function to be called.
Just be warned it may not even work, as it really depends on QTP's scripting engine. And even if it should, don't be surprised if it becomes an exercise in frustration.
See examples on WSH and event handling http://msdn.microsoft.com/en-us/library/ms974564.aspx Again, this probably won't apply to QTP, but it's to give you an idea of potential approach to the problem.
Edit: Additional link which may or may not help!
http://www.west-wind.com/presentations/dotnetfromVfp/DotNetFromVfp_EventHandling.asp

How to Inject code in c# method calls from a separate app

I was curious if anyone knew of a way of monitoring a .Net application's runtime info (what method is being called and such)
and injecting extra code to be run on certain methods from a separate running process.
say i have two applications:
app1.exe that for simplicity's sake could be
class Program
{
static void Main(string[] args)
{
while(true){
Somefunc();
}
}
static void Somefunc()
{
Console.WriteLine("Hello World");
}
}
and I have a second application that I wish to be able to detect when Somefunc() from application 1 is running and inject its own code,
class Program
{
static void Main(string[] args)
{
while(true){
if(App1.SomeFuncIsCalled)
InjectCode();
}
}
static void InjectCode()
{
App1.Console.WriteLine("Hello World Injected");
}
}
So The result would be Application one would show
Hello World
Hello World Injected
I understand its not going to be this simple ( By a long shot )
but I have no idea if it's even possible and if it is where to even start.
Any suggestions ?
I've seen similar done in java, But never in c#.
EDIT:
To clarify, the usage of this would be to add a plugin system to a .Net based game that I do not have access to the source code of.
It might be worth looking into Mono.Cecil for code injection. It won't work online the way you described in your question, but I believe it may do what you want offline (be able to find a given method, add code to it, and write out the modified assembly).
http://www.codeproject.com/KB/dotnet/MonoCecilChapter1.aspx
Well, to do that without App1's permission is difficult. But assuming you actually want to create an extension point in App1, it's relatively straightforward to do what you're suggesting with some kind of extensibility framework. I suggest:
SharpDevelop's add-in architecture
Mono.Addins
MS's Managed Extensibility Framework
Since I am more familiar with MEF, here's how it would look:
class Program
{
[ImportMany("AddinContractName", typeof(IRunMe))]
public IEnumerable<IRunMe> ThingsToRun { get; set; }
void SomeFunc()
{
foreach(IRunMe thing in ThingsToRun)
{
thing.Run();
}
/* do whatever else ... */
}
}
You need to use the Profiling API to make the second program profile the first one. You can then be notified of any method calls.
Another idea is to write an app that will change the exe you want to monitor. It would do things similar to what profiling tools do when they "instrument" your app. Basically, you use reflection to browse the app, then you re-create the exe (with a different file name) using the Emit features of .NET and insert your code at the same time.
Of course, if the app attempted to do things securely, this new version may not be allowed to communicate with its other assemblies.
With the clarifications you made in a comment, it seems to me you would be better off disassembling and reassembling using ildasm and ilasm.
Depending on how the author packaged/structured his application, you might be able to add a reference to his EXE file from your own project and just execute his code from within your own application. If that works, it's just a matter of using Reflection at that point to get at useful interfaces/events/etc that you can plug into (if they are marked private...otherwise just use them directly :). You can add a reference to any EXE built with the default settings for debug or release builds, and use it just like a DLL.
If that doesn't work there are advanced tricks you can use as well to swap out method calls and such, but that is beyond the scope of this reply...I suggest trying the reference thing first.
Injecting code into a running app is possible. This is a working example, but involves injection into an unmanaged dll.
Inject code in the assembly with Mono Cecil
You can try out CInject to inject your C# OR VB.NET code into assemblies

Categories

Resources