Skip to content
Snippets Groups Projects
Commit 7e8efcea authored by Lehtinen Teemu's avatar Lehtinen Teemu
Browse files

Add content for intro chapter

parent f7b5f80b
No related branches found
No related tags found
No related merge requests found
/* global module, require, console */
/* jshint globalstrict: true */
'use strict';
let Content = {
click_for_points: {
instructions: "This is an example of how automatically graded assignments appear on this course. Notice that it is always crucial to <strong>carefully read assignment instruction</strong> before starting to solve it. At this time there is no problem to solve. You are just expected to click the button on left to receive your points on this assigment.",
html: "<button class=\"green\">Click Me!</button>",
selector: ".exercise button",
events: "click",
points: function ($element, config, event) {
return {
points: 10,
feedback: 'Congratulations!'
};
},
maxPoints: 10,
title: "Click for points",
description: "An example of how these assignments work",
concepts: ["Automatic assessment"],
order: 0
},
fix_typo: {
instructions: "On the left you see a message that unfortunately contains a typo. Your task is to open the browser inspector tool, find the paragraph element <strong>&lt;p&gt;</strong> containing the message and then edit the element body to correctly contain the intended message \"<strong>Hello World!</strong>\".",
html: "<div class=\"acos-webdev-poi\"><p>Hello Wordl!</p></div>",
mutations: true,
points: function ($element, config, mutations) {
let $p = $element.find('.exercise p');
if ($p.length != 1) {
return {
points: 0,
feedback: 'The document is altered beyond repair. Avoid accidentally removing nodes. You should reset the assignment to start over.'
};
} else if ($p.eq(0).text() != 'Hello Wordl!') {
if ($p.eq(0).text() != 'Hello World!') {
return {
points: 5,
feedback: 'Almost there! You were able to change the node contents but the message is not exactly as requested.'
};
} else {
return {
points: 10,
feedback: 'Great work! You were able to change the node contents as requested.'
};
}
}
return undefined;
},
maxPoints: 10,
title: "Fix typo",
description: "Find and change element body",
concepts: ["Inspector", "DOM", "HTML"],
order: 1
},
change_color: {
instructions: "The blue area on left contains barely visible text. Your task is to use the browser inspector tool to locate the paragraph element <strong>&lt;p&gt;</strong> containing the barely visible text and then add a CSS property to apply another <strong>color</strong>. <em>Note that disabling current CSS rules does not grade the exercise.</em>",
html: "<div class=\"acos-webdev-poi\"><p class=\"blue\">The quick brown fox jumps over the lazy dog's back.</p></div>",
mutations: true,
points: function ($element, config, mutations) {
let $p = $element.find('.exercise p');
if ($p.length != 1) {
return {
points: 0,
feedback: 'The document is altered beyond repair. Avoid accidentally removing nodes. You should reset the assignment to start over.'
};
} else if (!config.graded && $p.eq(0).css('color') != 'rgb(173, 216, 230)') {
config.graded = true;
return {
points: 10,
feedback: 'Excellent! You changed the color of that text.'
};
}
return undefined;
},
maxPoints: 10,
title: "Change text color",
description: "Find and change text color using CSS",
concepts: ["Inspector", "DOM", "CSS"],
order: 2
},
disabled_button: {
instructions: "You need to click the button on left to receive your points on this assigment. Too bad that the button is disabled. Your task is to use the browser inspector tool to locate the <strong>button</strong>, remove the <strong>disabled</strong> attribute and finally click it.",
html: "<button class=\"green\" disabled>Click Me!</button>",
selector: ".exercise button",
events: "click",
points: function ($element, config, event) {
return {
points: 10,
feedback: 'Congratulations!'
};
},
maxPoints: 10,
title: "Disabled button",
description: "Find and enable button",
concepts: ["Inspector", "DOM", "HTML"],
order: 3
},
console_command: {
instructions: "This time the area on left does not have any visible content. However, this exercise defines a JavaScript function that can grant you points. Your task is to use the browser console to call the function like this: <code>giveMePoints();</code>",
html: "<div id=\"events\"></div>",
script: function giveMePoints() {
document.getElementById('events').dispatchEvent(new Event('grade'));
},
selector: "#events",
events: "grade",
points: function ($element, config, event) {
return {
points: 10,
feedback: 'Congratulations!'
};
},
maxPoints: 10,
title: "Console command",
description: "Call function in browser console",
concepts: ["Console", "JavaScript"],
order: 4
}
};
module.exports = Content;
{
"hidden_button": {
"html": "<div class=\"acos-webdev-poi\"><button class=\"green\" style=\"display:none\">Click me</button></div>",
"selector": ".exercise button",
"events": "click",
"instructions": "The blue area on left has a hidden button in the document object model. Your task is to use the web browser inspector to first display that button and then click it to receive your points.",
"maxPoints": 10,
"title": "Hidden button",
"description": "Find and display hidden button in browser inspector",
"concepts": ["Inspector", "DOM", "CSS"],
"order": 0
},
"delete_element": {
"html": "<ul><li class=\"acos-webdev-poi\">😀</li><li class=\"acos-webdev-poi angry-face\">😠</li><li class=\"acos-webdev-poi\">😀</li></ul>",
"selector": ".angry-face",
"events": "DOMNodeRemoved",
"instructions": "There are two happy and one angry face on left. Your task is to use the web browser inspector to delete the angry face from the document object model and keep the two happy faces.",
"maxPoints": 10,
"title": "Delete element",
"description": "Find and delete element in browser inspector",
"concepts": ["Inspector", "DOM"],
"order": 1
}
}
......@@ -2,14 +2,33 @@
/* jshint globalstrict: true */
'use strict';
let nj = require('nunjucks');
let fs = require('fs');
let AcosMod = function () {};
let Package = function () {};
let baseDir = __dirname;
let content = JSON.parse(fs.readFileSync(baseDir + '/content.json', 'utf8'));
let content = require('./content');
AcosMod.initialize = function (req, params, handlers, cb) {
Package.meta = {
'name': 'webdev-inspector',
'shortDescription': 'Exercise package using web browser inspector tool.',
'description': '',
'author': 'Lassi Haaranen & Teemu Lehtinen',
'license': 'MIT',
'version': '0.1.0',
'url': '',
'teaserContent': ['click_for_points', 'fix_typo'],
'contents': content
};
Package.packageType = 'content';
Package.contentTypeNamespace = 'webdev';
Package.namespace = 'webdev-inspector';
Package.register = function (handlers, app, conf) {
handlers.contentPackages['webdev-inspector'] = Package;
handlers.contentTypes.webdev.installedContentPackages.push(Package);
};
Package.initialize = function (req, params, handlers, cb) {
let templateDir = baseDir + '/templates/';
nj.configure(templateDir, { autoescape: false });
......@@ -23,33 +42,12 @@ AcosMod.initialize = function (req, params, handlers, cb) {
let templateParam = {
id: 'acos-webdev-inspector-' + params.name,
config: JSON.stringify(config),
acceptTest: config.acceptTest,
pointsCalculator: config.pointsCalculator
script: typeof(config.script) == 'function' ? config.script.toString() : undefined,
points: typeof(config.points) == 'function' ? config.points.toString() : undefined
};
params.headContent += nj.render('head.html', templateParam);
params.bodyContent += nj.render('body.html', templateParam);
cb();
};
AcosMod.register = function (handlers, app, conf) {
handlers.contentPackages['webdev-inspector'] = AcosMod;
handlers.contentTypes.webdev.installedContentPackages.push(AcosMod);
};
AcosMod.namespace = 'webdev-inspector';
AcosMod.contentTypeNamespace = 'webdev';
AcosMod.packageType = 'content';
AcosMod.meta = {
'name': 'webdev-inspector',
'shortDescription': 'Exercise package using web browser inspector tool.',
'description': '',
'author': 'Lassi Haaranen & Teemu Lehtinen',
'license': 'MIT',
'version': '0.1.0',
'url': '',
'teaserContent': ['hidden_button', 'delete_element'],
'contents': content
};
module.exports = AcosMod;
module.exports = Package;
......@@ -3,8 +3,8 @@
new ACOSWebdev(
$('#{{ id }}'),
{{ config }},
{% if acceptTest %}{{ acceptTest }}{% else %}undefined{% endif %},
{% if pointsCalculator %}{{ pointsCalculator }}{% else %}undefined{% endif %}
{% if points %}{{ points }}{% else %}undefined{% endif %}
);
});
{% if script %}{{ script }}{% endif %}
</script>
......@@ -18,39 +18,53 @@ describe('Content module acos-webdev-inspector', () => {
});
describe('Exercise hidden_button', () => {
describe('Exercise fix_typo', () => {
it('exercise page should open', () => {
browser.url('/html/webdev/webdev-inspector/hidden_button');
browser.url('/html/webdev/webdev-inspector/fix_typo');
});
it('should start with zero grade', () => {
let points = browser.$$('.guide-column .points');
points.should.have.lengthOf(1);
points[0].getText().should.equal('0 / 10 p.');
points[0].getText().should.contain('0 / 10');
points[0].getText().should.not.contain('10 / 10');
});
it('should include hidden button', () => {
let buttons = browser.$$('.exercise button');
buttons.should.have.lengthOf(1);
buttons[0].isDisplayed().should.be.false;
it('should include text paragraph', () => {
let p = browser.$$('.exercise p');
p.should.have.lengthOf(1);
p[0].getText().should.equal('Hello Wordl!');
});
it('button should be set visible and then clicked', () => {
it('change text', () => {
browser.execute(() => {
document.querySelector('.exercise button').removeAttribute('style')
document.querySelector('.exercise p').textContent = 'Hello!';
});
browser.waitUntil(() => $$('.explosion').length == 0, 4000, 'expected explosion effect to pass');
});
let button = browser.$('.exercise button');
button.isDisplayed().should.be.true;
button.click();
browser.waitUntil(() => $$('.explosion').length == 0, 4000, 'expected explosion effect pass');
it('should now display half grade', () => {
let points = browser.$$('.guide-column .points');
points.should.have.lengthOf(1);
points[0].getText().should.contain('5 / 10');
points[0].getAttribute('class').should.contain('yellow');
points[0].getAttribute('class').should.not.contain('green');
});
it('fix text', () => {
browser.execute(() => {
document.querySelector('.exercise p').textContent = 'Hello World!';
});
browser.waitUntil(() => $$('.explosion').length == 0, 4000, 'expected explosion effect to pass');
});
it('should now display full grade', () => {
let points = browser.$$('.guide-column .points');
points.should.have.lengthOf(1);
points[0].getText().should.equal('10 / 10 p.');
points[0].getText().should.contain('10 / 10');
points[0].getAttribute('class').should.contain('green');
points[0].getAttribute('class').should.not.contain('yellow');
});
it('reset button should exist and be clicked', () => {
......@@ -63,12 +77,13 @@ describe('Content module acos-webdev-inspector', () => {
});
it('state should have now reset to initial', () => {
let buttons = browser.$$('.exercise button');
buttons.should.have.lengthOf(1);
buttons[0].isDisplayed().should.be.false;
let p = browser.$$('.exercise p');
p.should.have.lengthOf(1);
p[0].getText().should.equal('Hello Wordl!');
let points = browser.$$('.guide-column .points');
points.should.have.lengthOf(1);
points[0].getText().should.equal('0 / 10 p.');
points[0].getText().should.contain('0 / 10');
points[0].getText().should.not.contain('10 / 10');
points[0].getAttribute('class').should.not.contain('green');
});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment