HTML CSS Javascript

HTML CSS Javascript

by Sam Suresh -
Number of replies: 10

Hello Richard Lobb,


Thank you for coderunner!

I teach HTML CSS , Javascript and PHP. Would like to use coderunner to test student input.

I have some basic questions;

I want students to write Javascript to given scenario.
Then code runner to test and feedback. Also possible to display the output?

For example this one.

In the 3rd column, it display the output.

Thank you for your time.

In reply to Sam Suresh

Re: HTML CSS Javascript

by Richard Lobb -

Hi Sam

I'm not quite sure how to fit your example into a CodeRunner context. For a CodeRunner programming question you need:

  1. A clear question spec, which asks the student to write some code that performs in some well specified way. 
  2. A way to grade the student's response with a program, which usually incorporates the student's answer, checking to see if it behaves as expected.
Since CodeRunner tests code on a headless server, you can't test GUI behaviour directly. Instead, you must build your own mock-ups of the GUI elements you wish the students to use, and incorporate those into the question template (usually within your own new question type). Even for simple GUI exercises this isn't trivial. However, here's a very simple example - you can decide whether you wish to proceed further.



This is a nodejs question, with the following template:

var inputActionString = "{{ TEST.stdin | e("js") }}";
var inputActions = inputActionString.toLowerCase().trim().split('\n');
var iAction = 0;

function nextUserAction()
{
    var action = null;
    if (iAction >= inputActions.length) {
        console.log("No user action defined!");
    } else {
        action = inputActions[iAction++];
        console.log("User action: " + action)
    }
    return action;
}


function alert(message)
{
    var action;
    console.log("Alert: " + message);
    action = nextUserAction();
    if (action !== 'click ok') {
        console.log('User action ' + action + " can't be applied to an alert");
    }
    return true;
}
    

function confirm(message)
{
    var action;
    console.log("Confirm: " + message);
    action = nextUserAction()
    if (action === 'click ok') {
        return true;
    } else if (action == 'click cancel')  {
        return false;
    } else if (action !== null) {
        console.log('Illegal user action: ' + action);
        return false;
    }
}

{{STUDENT_ANSWER}}

The standard input field of the testcase is used to supply a sequence of user actions. The two expected GUI components, alert and confirm are both mocks, which write a message to the console log when called. The correctness of console log output is used to verify the behaviour of the student's code.

I attach a Moodle/XML export of that question, but you should realise that this approach doesn't scale to more advanced GUI programs which use much in the way of HTML elements, as you are then faced with the near-impossible task of building a mock of the complete HTML DOM behaviour. Automated testing of HTML/JavaScript programs is a fundamentally hard problem.

Richard


In reply to Richard Lobb

Re: HTML CSS Javascript

by Sam Suresh -

Hi Richard!

Thank you for the detailed answer.

I understand how it works now.

However I find showing the output to students will give them a very clear understanding on what they are coding. Something like this: https://repl.it/CaAp.

Coderunner is almost there and I see it was created to solve more complex questions and automate test. However it can't output the code browser side (something like this when you click run https://repl.it/CaAp).

Thanks anyway.



In reply to Sam Suresh

Re: HTML CSS Javascript

by Richard Lobb -

Hi Sam

Yes, it sounds like you are after a web-based development environment for students. CodeRunner is intended primarily for testing and grading code that students have already written in their development environment.

Thanks for the interest and for generating an interesting thread, anyway.

Richard

In reply to Richard Lobb

Re: HTML CSS Javascript

by Sam Suresh -

Hi Richard,

I'm trying to playing around with your XML file. I got this error "qtype_coderunner/Failed to find prototype nodejs"  Am I missing anything?


Thanks


In reply to Sam Suresh

Re: HTML CSS Javascript

by Richard Lobb -

Yes, sorry Sam. I should have warned you that you need to have the nodejs question type installed first. To do that, just do a question-bank import of the Moodle XML file db/uoc_prototypes.xml (you'll need to be a Moodle administrator to do that).

I've just moved that question type to the built-in prototypes file, so it will be standard from now on (next time I push).

Richard

In reply to Sam Suresh

Re: HTML CSS Javascript

by Ismael Figueroa -

Similar to Richard's suggestion, I've been successful in using jsdom with the chai testing framework, in order to mock the HTML+JS DOM and create useful tests. I attach a sample question template, which corresponds to one of the W3Schools questions (http://www.w3schools.com/js/exercise.asp?filename=exercise_assignment1)


var jsdom = require("jsdom");
var chai = require("chai");
var should = chai.should();
var expect = chai.expect
var assert = chai.assert;

var __student_verbatim_answer__ = `
{{STUDENT_ANSWER}}
`;

var __student_answer__ = `
<!DOCTYPE html>
<html>
<body>

<p id="demo"></p> 

<script>
var x = 10;

{{STUDENT_ANSWER}}

document.getElementById("demo").innerHTML = x;
</script>

</body>
</html>
`;

var result = {};

{% if TEST.extra %}
var testExtra = {{TEST.extra}};
if (testExtra.hasOwnProperty("testname")) {
    result.testname = testExtra.testname;
}
{% else %}
result.testname = "{{TEST.testcode | e('js')}}";
{% endif %}

jsdom.env(__student_answer__, [], function (err, oldWindow) {
    jsdom.env({
       html: __student_answer__
        , features: {
            ProcessExternalResources: ['script']
        }        
        , onload: function(window) {
            scripts = window.document.getElementsByTagName("script");
            for (var i=0;i<scripts.length;i++) {
                if (scripts[i].src) console.log(i,scripts[i].src)
                else console.log(i,scripts[i].innerHTML)
            }
        }        
        , done: function (err, window) {
            try {
                {{TEST.testcode}};
                result.fraction = 1;
            } catch(testErr) {
                result.fraction = 0;
                result.got = testErr.message;
            }
            console.log(JSON.stringify(result));
        }
    });
});

Notice you have access to the oldWindow and the window object, representing before and after student code execution. As for the tests, for this particular question I have attached the test cases as images.

I'm sorry I don't have much more time to ellaborate on this, but please be in touch if you are interested, as we could create a common pool of HTML-related questions.

Cheers


 





Attachment Captura de pantalla 2016-07-08 a las 1.03.59 p.m..png
Attachment Captura de pantalla 2016-07-08 a las 1.04.04 p.m..png
In reply to Ismael Figueroa

Re: HTML CSS Javascript

by Richard Lobb -

Wow, this looks like a great question type, Ismael! I look forward to having a play with it when I have some spare time.

I'm not currently teaching any web/javascript courses, but it's possible I will be doing so next year. If that happens, you can expect to hear back from me :)  What level of course are you teaching, i.e. introductory programming or more advanced web development?

If anyone is interested I'm happy to set up a Javascript/HTML question repository "course" on this server, as I did recently for C, allowing uploading and downloading of questions to a question bank that only teachers can access.

Thanks for the contribution, Ismael

Richard

In reply to Ismael Figueroa

Re: HTML CSS Javascript

by Martijn Schoenmakers -

Hi Ismael,

Your TEMPLATE looks really nice and I'm eager to try it out myself. 
Though I'm running into problems with the Jobe server that does not recognize the required node packages (e.g. jsdom). 

Could you maybe share some information on how you setup the jobe server such that a certain set of nodejs packages are available for the scripts?

In reply to Martijn Schoenmakers

Re: HTML CSS Javascript

by Ismael Figueroa -
Dear Martin,


I'm not clear on what is your specific problem with the question template. I have checked on my server, and I'm using the default nodejs question type, that is, using applications/library/nodejs_task.php  

Can you provide a more specific error message or screenshot?


Regarding the installation of nodejs and related libraries, I'm using nvm to install node:

> nvm ls
->      v6.10.0
         system
default -> v6.10.0

And the executable at /usr/bin/nodejs, as specified in nodejs_task.php is:

> /usr/bin/nodejs --version
v4.8.0

And the installed packages are:

> npm ls
/var/www
└─┬ jsdom@9.2.1
  ├── abab@1.0.3
  ├── acorn@2.7.0
  ├── acorn-globals@1.0.9
  ├── array-equal@1.0.0
  ├── cssom@0.3.1
  ├── cssstyle@0.2.36
  ├─┬ escodegen@1.8.0
  │ ├── esprima@2.7.2
  │ ├── estraverse@1.9.3
  │ ├── esutils@2.0.2
  │ ├─┬ optionator@0.8.1
  │ │ ├── deep-is@0.1.3
  │ │ ├── fast-levenshtein@1.1.3
  │ │ ├── levn@0.3.0
  │ │ ├── prelude-ls@1.1.2
  │ │ ├── type-check@0.3.2
  │ │ └── wordwrap@1.0.0
  │ └─┬ source-map@0.2.0
  │   └── amdefine@1.0.0
  ├── iconv-lite@0.4.13
  ├── nwmatcher@1.3.8
  ├── parse5@1.5.1
  ├─┬ request@2.72.0
  │ ├── aws-sign2@0.6.0
  │ ├── aws4@1.4.1
  │ ├─┬ bl@1.1.2
  │ │ └─┬ readable-stream@2.0.6
  │ │   ├── core-util-is@1.0.2
  │ │   ├── inherits@2.0.1
  │ │   ├── isarray@1.0.0
  │ │   ├── process-nextick-args@1.0.7
  │ │   ├── string_decoder@0.10.31
  │ │   └── util-deprecate@1.0.2
  │ ├── caseless@0.11.0
  │ ├─┬ combined-stream@1.0.5
  │ │ └── delayed-stream@1.0.0
  │ ├── extend@3.0.0
  │ ├── forever-agent@0.6.1
  │ ├─┬ form-data@1.0.0-rc4
  │ │ └── async@1.5.2
  │ ├─┬ har-validator@2.0.6
  │ │ ├─┬ chalk@1.1.3
  │ │ │ ├── ansi-styles@2.2.1
  │ │ │ ├── escape-string-regexp@1.0.5
  │ │ │ ├─┬ has-ansi@2.0.0
  │ │ │ │ └── ansi-regex@2.0.0
  │ │ │ ├─┬ strip-ansi@3.0.1
  │ │ │ │ └── ansi-regex@2.0.0
  │ │ │ └── supports-color@2.0.0
  │ │ ├─┬ commander@2.9.0
  │ │ │ └── graceful-readlink@1.0.1
  │ │ ├─┬ is-my-json-valid@2.13.1
  │ │ │ ├── generate-function@2.0.0
  │ │ │ ├─┬ generate-object-property@1.2.0
  │ │ │ │ └── is-property@1.0.2
  │ │ │ ├── jsonpointer@2.0.0
  │ │ │ └── xtend@4.0.1
  │ │ └─┬ pinkie-promise@2.0.1
  │ │   └── pinkie@2.0.4
  │ ├─┬ hawk@3.1.3
  │ │ ├── boom@2.10.1
  │ │ ├── cryptiles@2.0.5
  │ │ ├── hoek@2.16.3
  │ │ └── sntp@1.0.9
  │ ├─┬ http-signature@1.1.1
  │ │ ├── assert-plus@0.2.0
  │ │ ├─┬ jsprim@1.2.2
  │ │ │ ├── extsprintf@1.0.2
  │ │ │ ├── json-schema@0.2.2
  │ │ │ └── verror@1.3.6
  │ │ └─┬ sshpk@1.8.3
  │ │   ├── asn1@0.2.3
  │ │   ├── assert-plus@1.0.0
  │ │   ├── dashdash@1.14.0
  │ │   ├── ecc-jsbn@0.1.1
  │ │   ├── getpass@0.1.6
  │ │   ├── jodid25519@1.0.2
  │ │   ├── jsbn@0.1.0
  │ │   └── tweetnacl@0.13.3
  │ ├── is-typedarray@1.0.0
  │ ├── isstream@0.1.2
  │ ├── json-stringify-safe@5.0.1
  │ ├─┬ mime-types@2.1.11
  │ │ └── mime-db@1.23.0
  │ ├── node-uuid@1.4.7
  │ ├── oauth-sign@0.8.2
  │ ├── qs@6.1.0
  │ ├── stringstream@0.0.5
  │ └── tunnel-agent@0.4.3
  ├── sax@1.2.1
  ├── symbol-tree@3.1.4
  ├── tough-cookie@2.2.2
  ├── webidl-conversions@3.0.1
  ├─┬ whatwg-url@3.0.0
  │ └── tr46@0.0.3
  └── xml-name-validator@2.0.1

I'm not quite sure why there are different version numbers between the "node" and "nodejs" executables...


Please let me know if this is helpful to you,

Best regards