How to test small snippets of javascript code without a web browser? - javascript

I am trying to teach beginners javascript. Here is what I am trying to do:
I will give them a snippet of code such as a function with something incorrect:
const square = function(x) {
return x + x; // Wrong! This will double the number, not square them.
};
They will submit the code back to me.
I would like to write some test cases which would run on their code and evaluate if they are correct.
Does it make sense for them to submit their code as js files, and then I have a node.js project which reads their files and passes values to their functions and tests the response ?
Or does it make more sense to use a unit testing framework like mocha and chai etc ?

Both options would work, i.e Node directly or a test framework with test suites on their machines.
If you really want to get all their submissions and evaluate them on your own, you can simply ask them to export a function with a predefined name, in this case of this square exercise, it could be export function square { ..., then you add all those files to a folder, list all them using the fs module with something like fs.readdir/fs.readdirSync and dynamically call require on each file and execute the square function.
Note that this approach means you'll be running untrusted code on your machine, e.g one could potentially delete a file on your system (or actually do everything else possible with the privileges you execute the program). But you suggested that it's a beginner class and it looks like you know everyone, so that approach may be acceptable and in that manner, you don't have to send test cases for everyone and teach them how to run them (although it would be good at some point to do so).

Related

Writing Javascript tests without NodeJS

I've been struggling with going back to the roots of doing non-node reliant javascript, in this particular case for a test. Like many developers, i've fallen into the trap of learning frameworks, and in turn have forgotten / never understood some of the basic paradigms with javascript programming.
The problem
I'm trying to test a simple es6 script i've created for a collapsible element. It can be tested with a framework, however the script is simply inserted into the bottom of a html file, rather than be executed in any more complex way, and needs to remain functional without a complex procedure behind it. I understand that this is not the conventional way to do this, you could easily make the problem trivial with modern tech, but it's the way i'm required to put this together.
Collapsible.js
const initialiseCollapsible = (collapsible) => {
let collapsibleButton = collapsible.querySelector(".collapsible__button");
let collapsibleContent = collapsible.querySelector(".collapsible__content");
collapsibleButton.setAttribute("aria-expanded", "false");
collapsibleContent.setAttribute("aria-hidden", "true");
collapsibleButton.addEventListener("click", () => {
// cast the value of aria-expanded as a boolean
let expanded =
collapsibleButton.getAttribute("aria-expanded") === "false"
? false
: true;
// Toggle the expanded attribute
collapsibleButton.setAttribute("aria-expanded", !expanded);
collapsibleContent.setAttribute("aria-hidden", expanded);
});
};
(() => {
[...document.getElementsByClassName("collapsible")].forEach((collapsible) => {
initialiseCollapsible(collapsible);
});
})();
The file is meant to loop through all instances of .collapsible, adding event listeners so they can toggle correctly, and closing them initially (The content has to be accessible with javascript disabled).
1) Module functionality
With es6 moduling, i'm aware that it's transpiled normally using something such as babel. And with requireJS, I still don't understand whether module.exports is going to be understood by the browser, currently it throws errors because it doesn't understand the syntax. Is there a way of going around this? So I can write a functional script to be called in a html file, while still being able to import this into a test file to run tests on? I'm assuming I could just end up copy and pasting it for the sake of having it available is necessary.
2) Testing the thing
I'm struggling to contemplate how to test this piece of code accurately. I see a few potential tests:
Given a collapsible html element,
The expanded / hidden are correctly set to start (testing the query selector works and that the set attributes are working correctly)
Problem I don't quite understand how to emulate this without some sort of virtual dom that I can tamper with, are there good libraries for this? Ones that will allow me to create a document htmlelement that I can run the script code on to see the changes.
The collapsible button now has a clickEvent on it that matches the code of the example. Problem This feels almost like a functional test to me, i'm testing that something happens when I click the button, almost like cucumber / selenium would be a better route for this. There's a large amount of overhead there for something so simple however, is there an easier way to do this?
I realise this is probably around 10 questions in 1, but if you have any feedback / solutions for the problems posed, feel free to contribute.

How to develop a javascript library from an already existing npm module (codius)

never done this before.
I'm using https://github.com/codius/codius-host. Codiu§ development has been abandoned, but I want to salvage part of it to use for my own project. I really need to be able to run codius commands from browser, so I need to develop a library or what you call it.
var codius = require('codius')
codius.upload({host: http://contract.host}
codius-host comes packed with command-line integration,
$ CODIUS_HOST=https://codius.host codius upload
How do I make a .js script do what the command-line command does ?
also posted on https://stackoverflow.com/questions/31126511/if-i-have-a-npm-tool-that-uses-comman-line-commands-how-can-i-create-a-javascri
hard time asking this questions since don't know where to start. help.
Assuming that you have access to the codius-host source code you should find the piece of code which manages the command line arguments. I am sure that they do handle the command and the command line arguments from an entry module/function and than later delegate the real job to a different module/function. What you need to do is to provide correct parameters to the functions which the function/module that handles command line argument calls with command line parameters.
In addition to that there are some nodejs libraries that might imitate a command line call from the program itself. One of those I know is shelljs:
https://www.npmjs.com/package/shelljs
You might want to check this out as well. With this one without bothering with the source code you might be able to imitate command line behaviour.

JavaScript: How to compensate the lack of interfaces in delegate pattern?

Using RequireJS, I've build a small script. Depending on what is passed to a function, another file gets required – so it's something like a real simple factory probably. Imagine it like this:
function MyThing(a) {
if (a > 2) {
this.script = require['lib1'];
} else {
this.script = require['lib2'];
}
}
I other languages (I am coming from PHP), I can implement the same interface in both classes and be sure that lib1 and lib2 both share the functions defined in the interface.
If it worked like that in JavaScript, down the road I could call this.script.getId() or something like that and it would just work, no matter if lib1 or lib2 would be used.
Unfortunately, there are no interfaces in JavaScript (this Answer explained very well why it wouldn't make sense), so I am a bit stuck on how I should deal with it.
Of course I could create something like an interface that maps to both libs, but I have the feeling this would be the wrong way to deal with it.
What is the right approach towards the problem I am encountering?
You can just use duck typing, which exploits the fact that JS can convert anything and everything into a boolean value. If a function exists, its coerced boolean is true, so:
var lib = doMagicLoading();
// does the lib support the function we need?
if (lib.functionINeed) {
// it does, so we can simply move on along our intended code path.
lib.functionINeed();
} else {
// if it does not, that might be a problem, or it might not be. Warn us:
console.warn("library does not implement the function I Need...");
}
This is also how JavaScript code makes sure it does "the right thing" on different browsers that support different versions of JS, for instance. Step 1: test whether the function exists. Step 2: call it if does, or do something else if it doesn't.
Of course, in your case, as the programmer responsible for having working code you can actually guarantee well behaved code, because of course you wrote tests for your scripts, to make sure both code paths do the right thing, and you bundled your code using r.js before deploying. If not: it's time to start writing tests. Don't just trust developers to write working code -- that includes yourself =)

How to Encode JavaScript files?

How can I encode my JavaScript file like DLL files?
I mean nobody can understand the code like Dll created from CS file in C#.
I need this because I want to give my functions to some company, but I do not want they to understand inside my functions....just can call the functions.
I see the jQuery files are encode to variables (a,b,c,d,....).
for example encode this simple code:
function CookiesEnabled() {
var result = false;
createCookie("testing", "Hello", 1);
if (readCookie("testing") != null) {
result = true;
eraseCookie("testing");
} return result;
};
There really isn't any way to encrypt/encode code like that in JS (at least I do not know of any way), but the standard way is to use good minifiers i.e. programs that collapse your code, remove comments rename local variables from good long names to stuff like width and height to stuff like a and b. And even re-structure your code so its as compact as possible. They usually end up non-human readable.
Minifing is usually even called JS compiling, but its not really. As with is a good one, well not going to go there, there are so many, but for my purposes I've been using the Microsoft official bundler:
http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
You should also check out this question (all of the big names that I know are all there.):
Is there a good JavaScript minifier?

Calling a function in a JavaScript file with Selenium IDE

So, I'm running these Selenium IDE tests against a site I'm working on. Everything about the tests themselves is running fine, except I would like to do a bit of clean-up once I'm done. In my MVC3 Razor based site, I have a JavaScript file with a function that gets a JsonResult from a Controller of mine. That Controller handles the database clean-up that Selenium IDE otherwise couldn't handle.
However, I'm having a hard time finding any sort of documentation on how to do this. I know I can do JavaScript{ myJavascriptGoesHere } as one of the Values for a line in the test, but I can't seem to find a way to tell it to go find my clean-up function.
Is it even possible for Selenium IDE to do this sort of thing?
If it comes down to it, I can just make a separate View to handle the clean-up, but I'd really like to avoid that if possible.
Thanks!
If you want to execute your own JavaScript function that exists in your test page from Selenium IDE, you need to make sure you access it via the window object. If you look at the reference for storeEval for instance, it says:
Note that, by default, the snippet will run in the context of the
"selenium" object itself, so this will refer to the Selenium object.
Use window to refer to the window of your application, e.g.
window.document.getElementById('foo')
So if you have your own function e.g. myFunc(). You need to refer to it as window.myFunc().
This can be very handy for exercising client-side validation without actually submitting the form, e.g. if you want to test a variety of invalid and valid form field values.
If you use runScript, that should already run in the window's context.
This works for me.
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
string title = (string)js.ExecuteScript("myJavascriptGoesHere");
Make sure your javascript works first before using it here!
Actually to access your page javascript space, you need to get the real window of your page : this.browserbot.getUserWindow()
See this statement to get the jQuery entry point in your page (if it has jQuery of course ^^ )
https://stackoverflow.com/a/54887281/2143734

Categories

Resources