-
Notifications
You must be signed in to change notification settings - Fork 2
Initial setup
To build a project, we use node
. Using node
version 12 and above is required. A typical project with several stages with JavaScript tests looks like this:
Webstorm_project_folder
.idea
--Idea internal files--
node_modules
--dependencies--
package.json
Project_name
| stage1
| | src
| | | --user files--
| | test
| | --test files--
| stage2
| | src
| | | --user files--
| | test
| | --test files--
| ...
| stageN
| | src
| | | --user files--
| | test
| | --test files--
As you can see, the project is divided into stages. Each stage does not overlap with other stages in any way. The src
package is intended for the user to write his code to the project. The test
folder is intended for writing tests to the project stage.
So, the initial setup for writing tests for a web project is as follows (let's say you're writing tests for the Tic-Tac-Toe project):
Idea_project
package.json
Tic-Tac-Toe
| stage1
| | src
| | | index.html
| | test
| | test.js
The file index.html
can contain some initial code for the student. He'll see it the first time he opens the project. Usually, this file looks like this for a student when opening a project for the first time:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello, World!</title>
</head>
<body>
</body>
</html>
But you will need to implement the project stage in this file. Since you will need to check whether your tests work or not.
Below is an initial example of the test.js
file:
const path = require('path');
const pagePath = path.join(__dirname, '../src/index.html');
const {StageTest, correct, wrong} = require('hs-test-web');
class Test extends StageTest {
page = this.getPage(pagePath)
tests = [
this.page.execute(() => {
// test #1
}),
this.page.execute(() => {
// test #2
}),
this.page.execute(() => {
// test #3
})
]
}
it("Test stage", async () => {
await new Test().runTests()
}
).timeout(30000);
The test code is executed inside the browser context, not in the node context, so you cannot use any node functions here despite the fact that IDE shows that you can. Local variables are not shared between tests, but global variables are shared. Every test should return either correct()
or wrong(message)
and message
will be shown to the user after the end of the test. Here's an example of 3 tests of the first stage in the Virtual Piano
project. Notice the global variable this.innerBodyElements
that is visible across all the tests.
// Test #1
this.page.execute(() => {
let bodyNodes = Array.from(document.body.childNodes);
this.innerBodyElements = bodyNodes.filter(
e => e.nodeType === Node.ELEMENT_NODE);
let len = this.innerBodyElements.length;
return len === 7 ?
correct() :
wrong(`There should be 7 elements in the body of the HTML document, found: ${len}`)
}
),
// Test #2
this.page.execute(() => {
let failNum = 0;
let failElem = '';
let i = 0;
for (let elem of this.innerBodyElements) {
i++;
elem = elem.nodeName.toLowerCase();
if (elem !== 'kbd') {
failNum = i;
failElem = elem;
break;
}
}
return failNum === 0 ?
correct() :
wrong(`Element #${failNum} is not <kbd> element, it's <${failElem}>`);
}),
// Test #3
this.page.execute(() => {
let failNum = 0;
let textInside = '';
let i = 0;
for (let elem of this.innerBodyElements) {
i++;
elem = elem.innerHTML;
if (elem.length !== 1) {
failNum = i;
textInside = elem;
break;
}
}
if (failNum === 0) {
return correct();
}
if (textInside.length === 0) {
return wrong(`Element #${failNum} is empty, ` +
`but should contain a single letter.`);
}
return wrong(`Element #${failNum} contains ${textInside.length} symbols, ` +
`but should contain a single letter. The text inside element is:\n"${textInside}"`);
})
Below is package.json
file that you can use that contains minimal dependencies needed for any project.
{
"devDependencies": {
"mocha": "^9.2.0",
"hs-test-web": "https://github.com/hyperskill/hs-test-web/archive/release.tar.gz",
"puppeteer": "^13.1.3"
},
"scripts": {
"test": "mocha"
}
}
You are not limited to using the EduTools plugin when creating tests for a project (you can just create a regular Web Storm project), but with the EduTools plugin, it may be more convenient.
To create a project with the EduTools plugin, you need to download install it from the market. Open Settings -> Plugins -> Marketplace -> EduTools
and install the plugin.
To create a project, you need to click File -> Learn and Teach -> Create New Hyperskill Course
Set the title and click Create
.
This is how your project should look like for now. Please, don't touch .yaml
files - they are internal for the EduTools plugin.
Next, you need to delete lesson1
and package-lock.json
. You should end up with a single file package.json
. Replace the contents of this file with what was given above.
Then, you should create a so-called Framework Lesson
and give it a name like a project name. For this, you need to create a new Lesson
and choose Framework lesson
in the dialog.
Then, you should create a new Task
inside this Framework Lesson
and give it the name stage1
. The task type should be Edu
.
Then remove task.js
and hstest/test.java
, create folders test
, src
create files src/index.html
, and test/test.js
and replace the contents of these files with what was provided above. Notice, that you need to name folder and file appropriately your project theme, don't stick to Tic-Tac-Toe
. This is just an example. You should end up with the following configuration:
To create tests for the second stage, click on Framework Lesson
named Tic-Tac-Toe
and add a new Task
. Name it stage2
. Your result should look like the following:
You created an initial setup and ready to write tests!
After you finished creating your project, you need to upload it to Stepik. To do this, please click on a project name (the one with 4 squares, not to the one with a book), and click Course Creator
-> Upload Hyperskill Lesson to Stepik
.