Using Nightwatch to Test Comments & Doctype - javascript

I am an IT instructor and have begun utilizing Nightwatch to test students' homework to see if it is meeting specs.
I can test all the "normal" elements/attributes with no problem. My issue is on some stuff that you would probably not normally test in a production environment.
I want to test that they are using the correct HTML5 doctype, which lies outside of the root, of course, and I believe Nightwatch begins with the HTML node.
I also harp on them about using comments to make their own life and that of their fellow developer easier. So, I would like to test that they are leaving comments. Some parts of the comment are required and consistent, but other parts vary, such as their name within the comment. Here is a sample of a comment...
The Name of the Page
Sample Page for the Widgets
Author: your name
Date: the date
Again, I would probably not be testing for comments and doctype in the real world, but wonder if it is possible with Nightwatch?
I have tried the containsText() and text.to.contain() methods already with no success.
Any thoughts and guidance would be appreciated.
Also, I am not opposed to using another testing tool or any other middleware that might help if you know of any. I have not found any in my searching, nor have I found a solution to my quandary.

I would say that Nightwatch has not been designed to accomplish such a task. It is an amazing framework to perform acceptance testing on a GUI (Graphical User Interface), but it is not a web crawler. Browser automation is a resource-intensive operation, especially when you automate a real web browser via Selenium WebDriver. So if the code structure matters more than the graphical part, I would recommend you to use more "minimalistic" libraries like CasperJS. It is based on PhantomJS, a WebKit headless browser.
Nightwatch
If you want to keep Nightwatch, the best thing you can do is using regular expressions with the .source() method which returns a serialization (string) of the DOM:
browser
.url("http://www.website.com")
.source(function (res) {
if (/<!--/.test(res.value)) {
console.log("Comment detected!");
}
})
This works to detect at least one comment, but you will not be able to check the DOCTYPE because it is not returned by the .source() method. Using XPath, the root element would be /html.
Moreover, here we use a basic console.log for comments, which is not ideal to perform a test. But the problem is that most Nightwatch assertion methods expect a CSS selector...
Casper
This is much easier here...
With Casper, you can use the .getHTML() method to get a serialization of the DOM. But here, the DOCTYPE is returned and you can use assertions (.assertMatch()) to validate the result against regular expressions. Your code could have the following structure:
casper.test.begin('Test website', function (test) {
casper.start('http://www.website.com', function () {
var html = this.getHTML();
test.assertMatch(html, /<!DOCTYPE html>/);
test.assertMatch(html, /<!--.*-->/);
});
casper.then(function () {
// Your code...
});
casper.run(function() {
test.done();
});
});
I have tested this code on a random page that contains a valid HTML5 document type declaration and some comments. It works fine.

Related

How can I write a script to automatically walk through a process like my user would?

I have some valuable processes on my site that I'd like to track regularly to make sure they are working. I wrote some javascript that will run the actions if the starting page contains a particular parameter, but I can't figure out how to properly execute the script without opening the page in a browser.
My best guess is I need some sort of chron driven bot for this, but I don't even know where I should begin with that and haven't found anything in my searching. I tried a cURL request, but it doesn't seem to fire the js. Really, if I could just find a way to properly initialize the js with a chron job that would be sufficient.
The key here is that I need it to execute the javascript so I can imitate user actions.
I'm working on a WordPress install, so it would need to be a php or javascript based solution. How can I build something like this?
Use an interaction testing framework like Ember.js. that should allow you to test your UI Interactions.
See the link above to get some detailed information on how to use the library.
Here is a code snippet from the Ember.js library to see if a user is
redirected properly if not authenticated (100% javascript!):
module('Integration: Transitions', {
teardown: function() {
App.reset();
}
});
test('redirect to login if not authenticated', function() {
visit('/');
click('.profile');
andThen(function() {
equal(currentRouteName(), 'login');
equal(currentPath(), 'login');
equal(currentURL(), '/login');
});
});
Ember.js is an excellent way to test your user interactions and your UI components.
Learn more here: http://emberjs.com/guides/testing/testing-user-interaction/
UPDATE:
See this answer for another solution that combines CasperJS and PhantomJS to test user interfaces.
Good luck!
If you don't want to have a browser open to do it you could use a headless browser like PhantomJS

What is a Javascript test framework?

This could be a stupid question. Jasmine, Qunit, Mocha, Unit.js, etc - as far I as I know are Javascript test frameworks. But what is a Javascript test framework? What it is for actually? Is it any different from these Javascript frameworks below?
ember.js
backbone
require.js
Jasmine,
describe('Hello world', function() {
it('says hello', function() {
expect(helloWorld()).toEqual("Hello world!");
});
});
It seems like that is what node.js does, isn't?
What do you need to test?
(Short overview)
A test framework is a set of tools that allows you to test the functionality of your code (in this case your Javascript code).
It allows you to test certain functions and check if the output/result matches your expectations.
They allow you to test certain conditions and how your code react on that, like missing or unset variables, unexpected data in your variables and so on.
And one of the advantages is the test automation. This allows you to run a bunch of test automatically and it will give you result if every single test. This way you can see which test fails after you made some changes in your code.
Also you should consider reading the link mplungjan provided.
(If I missed something mandatory to say, then leave a comment, I will add that)

Programatically retrieve count of javascript errors on page

I'd like to write a test case (using Selenium, but not the point of this question) to validate that my web application has no script errors\warnings or unhanded exceptions at certain points in time (like after initializing a major library).
This information can easily be seen in the debug consoles of most browsers. Is it possible to execute a javascript statement to get this information programatically?
It's okay if it's different for each browser, I can deal with that.
not so far read about your issue (as far as I understood your problem) here
The idea be the following:
I found, however, that I was often getting JavaScript errors when the page first loaded (because I was working on the JS and was introducing errors), so I was looking for a quick way to add an assert to my test to check whether any JS errors occurred. After some Googling I came to the conclusion that there is nothing built into Selenium to support this, but there are a number of hacks that can be used to accomplish it. I'm going to describe one of them here. Let me state again, for the record, that this is pretty hacky. I'd love to hear from others who may have better solutions.
I simply add a script to my page that will catch any JS errors by intercepting the window.onerror event:
<script type="text/javascript">
window.onerror=function(msg){
$("body").attr("JSError",msg);
}
</script>
This will cause an attribute called JSError with a value corresponding to the JavaScript error message to be added to the body tag of my document if a JavaScript error occurs. Note that I'm using jQuery to do this, so this specific example won't work if jQuery fails to load. Then, in my Selenium test, I just use the command assertElementNotPresent with a target of //body[#JSError]. Now, if any JavaScript errors occur on the page my test will fail and I'll know I have to address them first. If, for some strange reason, I want to check for a particular JavaScript error, I could use the assertElementPresent command with a target of //body[#JSError='the error message'].
Hope this fresh idea helps you :)
try {
//code
} catch(exception) {
//send ajax request: exception.message, exception.stack, etc.
}
More info - MDN Documentation

How would I solve a coding puzzle with Javascript?

There is a website called Gild.com that has different coding puzzles/challenges for users to do. They can be completed in wide array of languages including Javascript. I am interested in solving these puzzles in Javascript, but I am unsure of the following:
How am I supposed to access the input file which is supposed to be passed as an argument?
How am I supposed to output the result?
My understanding of Javascript is that it is run from within an HTML page and that output really is only in the form of placing values in the HTML, modifying the DOM, etc. For that reason it is not clear to me how Javascript can be used for solving these types of problems. Can someone who has used Gild before or has some insights into my question suggest how to proceed?
An example of a problem would be: the given input file contains a positive integer, find the sum of all prime numbers smaller than that integer and output it.
EDIT: Some of the solutions below involve using external resources, but on Gild, I am supposed to put my solution in their editor and then submit it that way, like the following picture shows:
In other words, I don't think my solution can have access to Node.js or other external resources.
Edit: Here are some interesting articles that I have found that I think are the answer to my question:
http://www.phpied.com/installing-rhino-on-mac/
http://www.phpied.com/javascript-shell-scripting/
I haven't spent much time on Gild, but I do a lot of similar types of problems on Project Euler. I think the best way to go is probably Node.js.
If you're not familiar, Node is basically server-side JavaScript that runs in Google's V8 engine. Installing it on your own Mac/Windows machine takes about 2 minutes. It's also really fast (considering it's JavaScript).
And you'd use it like this:
var fs = require('fs'); // the filesystem module
var contents = fs.readFileSync('theFile.txt', 'utf-8');
// Do stuff with the file contents...
Everything after those first two lines can be done with the same JS you'd write in the browser, right down to calling console.log() to spit out the answer.
So, if you wrote your script in a file on your desktop called getprimes.js, you'd open up your terminal and enter node ~/Desktop/getprimes.js (assuming you're on a Mac)
If you're:
on a Mac,
planning to do a lot of these puzzles, and
willing to pay $10, then
I highly recommend CodeRunner. It encapsulates runtimes for a variety of languages — from C to JavaScript — and lets you quickly build and run any sort of one-off code. Just hack together your code, ⌘R, and the results are printed right there in the same window.
I haven't used any file-based JavaScript in CodeRunner, but I imagine kennis's suggestions would apply. To output your results:
console.log(...)
Easy as pie!

Javascript Sandbox?

Would it be possible to sandbox user-submitted Javascript by overriding various functions such as alert, window.location, and eval?
I'm not looking for a perfect solution. I'm sure some people would still find a way to rearrange divs to spell out swear words or something malicious, but if I could disable page redirects 100% reliably I would be mostly happy.
I tried in Chrome, and doing something like
context={}; //use this to prevent `this` from being `window`
context.f=function(){
var window=null,location=null,eval=function(){};
console.log(window); //also the other two
};
context.f();
seems promising. If I replace the console line with user-submitted code (checking for paren balancing), would that be an absurdly bad idea or a mildly bad idea? On Chrome I can still break things by going through this to Function and redefining things, but that would be acceptable to me.
You can use Microsoft Web Sandbox or Google Caja.
Here are two more possible solutions (disclaimer: I just started looking for this myself, so I am not an expert).
This is very interesting, uses web workers to sandbox untrusted code:
https://github.com/eligrey/jsandbox
even though, I wonder if that is maintaned anymore, or if the following html5 "sandbox" iframe attribute supersedes it:
http://www.w3schools.com/html5/att_iframe_sandbox.asp
vm.js is a javascript virtual machine implemented in pure coffeescript(should run in relatively old browsers) and can be used as a lightweight in-process sandbox. It can break infinite loops and shields global objects from modifications.
Depending on what this needs to do, you could always run the javascript in a document-context-free environment, like through Rhino, and then grab the results server-side and clean/insert those.
You could also try Douglas Crockford's AdSafe, though it does limit the possibilities of JavaScript.
Masking the globals with local variables is not secure actually. Preprocessing the untrusted code with tools like Google Caja may help, but it's not necessary:
For a web-browser simply running a code in a Worker is enough - it seems to be pretty restricted nowadays. See update below
For Node.js you may fork() in a sandboxed process and execute the code there (using the child_process module).
There are also some libraries for simplifying the sandboxing, one of those created by myself is Jailed (there's also a demo with JS-Console which executes user-submitted code in a sandbox).
Update: obviously I was wrong, the worker is not secure by itself, as it can access some of same-origin stuff, like IndexedDB for instance. I have submitted a related question. The solution is to additionally put the worker into a sasndboxed iframe, which is also implemented in my Jailed library.
Use HTML5 "sandbox" iframe attribute.
I made a javascript function for this.
function evalUnsafe(userCode) {
var vars = [];
var legal = {console: 'console', alert: 'alert'};
for(var b in this) {
if (!(b in legal)) {
vars.push(b);
}
}
var funcs = vars.join(",");
var code = "(function sandbox(" + funcs + ") {function runthis() {eval(" + JSON.stringify(userCode) + ");};var a = new runthis();})();";
eval(code);
}
And then you can do this
Example 1:
evalUnsafe("alert(window);");
Example 2 (from a php file):
evalUnsafe(<?php echo json_encode(file_get_contents("example.js"));?>);
You can download it from here:
https://github.com/oyvindrestad/javascriptsandbox

Categories