From e58f4f971ce0c017bb6f88297cf525d9f030d928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se> Date: Sun, 23 May 2021 20:57:28 +0200 Subject: [PATCH 1/7] Add libraries section to backend --- docs/source/overview/server.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/source/overview/server.md b/docs/source/overview/server.md index 9f322c4e..0d27a89b 100644 --- a/docs/source/overview/server.md +++ b/docs/source/overview/server.md @@ -6,6 +6,17 @@ It also needs to make sure that only authorized people can access these. The other responsibility is to sync slides, timer and answers between clients in an active competition. Both of these will be described in more detail below. +## Libraries + +The server is built in [Flask](https://flask.palletsprojects.com/en/2.0.x/). +A few extensions to Flask are also used. +[flask-smorest](https://flask-smorest.readthedocs.io/en/latest/) is used to defined the API routes. +It is this libray that automatically documents the API on `localhost:5000` using Swagger. +[marshmallow](https://marshmallow.readthedocs.io/en/stable/) is used to convert database objects in JSON and to parse JSON back into Python objects. +[SQLAlchemy](https://www.sqlalchemy.org/) is used to interface with the SQL database that is used. +More specifically [Flask-SQLAlchemy](https://flask-sqlalchemy.palletsprojects.com/en/2.x/) is used to integrate it with Flask. +[Flask-Bcrypt](https://flask-bcrypt.readthedocs.io/en/latest/) is used to encrypt passwords. + ## Receiving API calls An API call is a way for the client to communicate with the server. @@ -65,14 +76,14 @@ In this way, for example, an entire competition with its teams, codes, slides an ## Active competitions Slides, timers, and answers needs to be synced during an active presentation. -This is done using SocketIO together with flask_socketio. +This is done using SocketIO together with flask*socketio. Sent events are also authorized via JWT, basically the same way as the for the API calls. But for socket events, the decorator that is used to authenticate them is `@authorize_user()`. Whenever a client joins a competition they will connect via sockets. A single competition cannot be active more than once at the same time. This means that you will need to make a copy of a competition if you want to run the same competition at several locations at the same time. All of the functionality related to an active competition and sockets can be found in the file `app/core/sockets.py`. -The terms *active competition* and *presentation* are equivalent. +The terms \_active competition* and _presentation_ are equivalent. ### Starting and joing presentations @@ -84,7 +95,7 @@ The server can see what is stored in the JWT and do different things depending o ### Syncing between clients -[comment]: # (What does `sync` mean? It isn't explained) +[comment]: # "What does `sync` mean? It isn't explained" The operator will emit the `sync` event and provide either a slide or a timer to update it on the server. The server will then send `sync` to all connected clients with the updated values, regardless of what was actually updated. -- GitLab From 04bb29880dad29303704538be5ab9b73ac76c0b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se> Date: Mon, 24 May 2021 10:34:18 +0200 Subject: [PATCH 2/7] Update server overview --- docs/source/overview/server.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/source/overview/server.md b/docs/source/overview/server.md index 0d27a89b..8c7277b9 100644 --- a/docs/source/overview/server.md +++ b/docs/source/overview/server.md @@ -37,7 +37,7 @@ When the server receives an API call it will first check that the call is author The authorization is done using JSON Web Tokens (JWT) by comparing the contents of them with what is expected. Whenever a client logs into an account or joins a competition, it is given a JWT generated by the server, and the client will need to use this token in every subsequent request sent to the server in order to authenticate itself. -The needed authorization is specified by the `@protect_route()` decorator. +The needed authorization is specified by the `ExtendedBlueprint.authorization()` decorator. This decorator specifies who is allowed to access this route, which can either be users with specific roles, or people that have joined competitions with specific views. If the route is not decorated everyone is allowed to access it, and the only routes currently like that is, by necessity, logging in as a user and joining a competition. @@ -53,9 +53,9 @@ This is why the server can simply read the contents of the JWT to be sure that t ### Parsing request -After the request is authorized the server will need to parse the contents of the request. -The parsing is done with [reqparse](https://flask-restx.readthedocs.io/en/latest/parsing.html) from RestX (this module is deprecated and should be replaced). -Each API call expects different parameters in different places and this is specified in each of the files in `app/apis/` folder, together with the route. +The server receives data in three ways: In the query string, body and header. +The data in the body and header is sent in JSON format and needs to be converted into Python dictionaries. +What data a route needs is specified by a marshmallow schema and blueprint from flask-smorest. ### Handling request @@ -67,7 +67,7 @@ Everything related to the database is located in the `app/database/` folder. ### Responding When the server har processed the request it usually responds with an item from the database. -Converting a database object to json is done with [Marsmallow](https://marshmallow.readthedocs.io/en/stable/). +Converting a database object to json is done with marshmallow. This conversion is specified in two files in the folder `app/core/`. The file `schemas.py` converts a record in the database field by field. The file `rich_schemas.py` on the other hand converts an `id` in one table to an entire object in the another table, thus the name rich. @@ -76,18 +76,18 @@ In this way, for example, an entire competition with its teams, codes, slides an ## Active competitions Slides, timers, and answers needs to be synced during an active presentation. -This is done using SocketIO together with flask*socketio. +This is done using SocketIO together with flask-socketio. Sent events are also authorized via JWT, basically the same way as the for the API calls. -But for socket events, the decorator that is used to authenticate them is `@authorize_user()`. +But for socket events, the decorator that is used to authenticate them is `sockets.authorization()`. Whenever a client joins a competition they will connect via sockets. A single competition cannot be active more than once at the same time. This means that you will need to make a copy of a competition if you want to run the same competition at several locations at the same time. All of the functionality related to an active competition and sockets can be found in the file `app/core/sockets.py`. -The terms \_active competition* and _presentation_ are equivalent. +The terms _active competition_ and _presentation_ are equivalent. ### Starting and joing presentations -Whenever a code is typed in to the client it will be checked via the `api/auth/login/code` API call. +Whenever a code is typed in to the client it will be checked via the `api/auth/code` API call. If there is such a code and it was an operator code, the client will receive the JWT it will need to use to authenticate itself. If there is such a code and the associated competition is active, the client will also receive a JWT for its corresponding role. Both of these cases will be handled by the default `connect` event, using the JWT received from the API call. @@ -97,8 +97,9 @@ The server can see what is stored in the JWT and do different things depending o [comment]: # "What does `sync` mean? It isn't explained" -The operator will emit the `sync` event and provide either a slide or a timer to update it on the server. -The server will then send `sync` to all connected clients with the updated values, regardless of what was actually updated. -The server will also store the timer and active slide in order to `sync` clients when they join. -The operator can also emit `end_presentation` to disconnect all clients from its competitions. +There are two other events that is used. +The operator will emit the `sync` event to sync some values to all other clients connected to the same competition. +The server will then send `sync` to all connected clients with the values that was updated. +The server will also store these values and will sync these when a client joins a competition. +The operator can also emit `end_presentation` to disconnect all clients from its competition. This will also end the presentation. -- GitLab From 584413fd2142cc12992e3fa3163f925f30ee7846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se> Date: Mon, 24 May 2021 10:39:30 +0200 Subject: [PATCH 3/7] Remove replace restx with smorest --- docs/source/development/further.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/docs/source/development/further.md b/docs/source/development/further.md index 543de426..8b6d8b7d 100644 --- a/docs/source/development/further.md +++ b/docs/source/development/further.md @@ -20,15 +20,3 @@ A list of all the questions that needs to be supported (and more) can be found o Here we will give a list of things we think will improve the system. It is not certain that they are a better solutions but definitely something to look into. - -### Replace Flask-RESTX with flask-smorest - -[comment]: # (This is already implemented) - -We currently use [Flask-RESTX](https://flask-restx.readthedocs.io/en/latest/) to define our endpoints and parse the arguments they take, either as a query string or in the body. -But when responding we use [Marshmallow](https://flask-smorest.readthedocs.io/en/latest/) to generate the JSON objects to return. -We believe that [flask-smorest](https://flask-smorest.readthedocs.io/en/latest/) would integrate a lot better with Marshmallow. -This would give us the ability to more easily show the expected arguments and the return values for our endpoints using Swagger (when visiting `localhost:5000`). -Currently we only show the route. -The work required also seems to be rather small because they look quite similar. -This would also remove the deprecated [reqparse](https://flask-restx.readthedocs.io/en/latest/parsing.html) part from Flask-RESTX, which is desirable. -- GitLab From 1e8c453bbc7eb7032d0847cb6a7a10401e2ade1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se> Date: Mon, 24 May 2021 10:40:52 +0200 Subject: [PATCH 4/7] Remove restx import --- server/app/database/__init__.py | 2 -- server/app/database/controller/delete.py | 2 -- server/app/database/controller/edit.py | 2 -- server/app/database/controller/utils.py | 2 -- 4 files changed, 8 deletions(-) diff --git a/server/app/database/__init__.py b/server/app/database/__init__.py index 92e6dc8e..4e6c7df6 100644 --- a/server/app/database/__init__.py +++ b/server/app/database/__init__.py @@ -6,8 +6,6 @@ database. It can add, get, delete, edit, search and copy items. from app.apis import http_codes from flask_smorest import abort from flask_smorest.pagination import PaginationParameters - -# from flask_restx import abort from flask_sqlalchemy import BaseQuery from flask_sqlalchemy.model import Model from sqlalchemy import Column, DateTime diff --git a/server/app/database/controller/delete.py b/server/app/database/controller/delete.py index 3a617d3c..d85228cf 100644 --- a/server/app/database/controller/delete.py +++ b/server/app/database/controller/delete.py @@ -7,8 +7,6 @@ from app.apis import http_codes from app.core import db from app.database.models import QuestionAlternativeAnswer, QuestionScore, Whitelist from flask_smorest import abort - -# from flask_restx import abort from sqlalchemy.exc import IntegrityError diff --git a/server/app/database/controller/edit.py b/server/app/database/controller/edit.py index a5e35352..d9930633 100644 --- a/server/app/database/controller/edit.py +++ b/server/app/database/controller/edit.py @@ -5,8 +5,6 @@ This file contains functionality to get data from the database. from app.apis import http_codes from app.core import db from flask_smorest import abort - -# from flask_restx.errors import abort from sqlalchemy import exc diff --git a/server/app/database/controller/utils.py b/server/app/database/controller/utils.py index acfddc13..9c321cdc 100644 --- a/server/app/database/controller/utils.py +++ b/server/app/database/controller/utils.py @@ -8,8 +8,6 @@ from app.core.codes import generate_code_string from app.database.models import Code from flask_smorest import abort -# from flask_restx import abort - def move_order(orders, order_key, from_order, to_order): """ -- GitLab From f7415e47d7554870bfd286f51005cf249dbb260b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se> Date: Mon, 24 May 2021 11:13:57 +0200 Subject: [PATCH 5/7] Address some comments --- docs/source/contact.md | 2 +- docs/source/development/external.md | 2 -- docs/source/installation/client.md | 3 +-- docs/source/installation/server.md | 3 +-- docs/source/overview/overview.md | 4 +--- docs/source/overview/server.md | 8 +++----- docs/source/user_manual/editor.md | 3 +-- docs/source/user_manual/presentation.md | 24 +++++++++++------------- 8 files changed, 19 insertions(+), 30 deletions(-) diff --git a/docs/source/contact.md b/docs/source/contact.md index eebe583d..add8a014 100644 --- a/docs/source/contact.md +++ b/docs/source/contact.md @@ -14,4 +14,4 @@ Please feel free to contact us if you have any questions. | Carl Schönfelder | carsc272@student.liu.se | Utvecklingsledare | Backend | Databas | | Emil Wahlqvist | emiwa210@student.liu.se | Analysansvarig | Frontend | Presentationseditor | -[comment]: # (Should this really be in swedish?) \ No newline at end of file +[comment]: # 'Should this really be in swedish?' diff --git a/docs/source/development/external.md b/docs/source/development/external.md index ee8c3b35..83d02ad5 100644 --- a/docs/source/development/external.md +++ b/docs/source/development/external.md @@ -12,5 +12,3 @@ It's very helpful when developing APIs. [DB Browser for SQlite](https://sqlitebrowser.org/) is used to see what is currently stored in the database. You can even edit values. - -[comment]: # (Add VS CODE?) \ No newline at end of file diff --git a/docs/source/installation/client.md b/docs/source/installation/client.md index e5768e9c..f7a88652 100644 --- a/docs/source/installation/client.md +++ b/docs/source/installation/client.md @@ -19,5 +19,4 @@ npm install You should now be ready to start the client. Try it by running `npm run start`. A web page should open where you can see the [login page](../user_manual/login.md). - -[comment]: # (Should we mention the task for starting the client?) +If you are using VS Code you can also start the client with the [task](../development/vscode.md) `start client`. diff --git a/docs/source/installation/server.md b/docs/source/installation/server.md index 3c867f43..889c2465 100644 --- a/docs/source/installation/server.md +++ b/docs/source/installation/server.md @@ -41,5 +41,4 @@ pip install -r requirements.txt You should now be ready to start the server. Try it by running `python main.py` and navigate to `localhost:5000`. If everything worked as it should you should see a list of all available API calls. - -[comment]: # (Should we mention the task for starting the server?) +If you are using VS Code you can also start the server with the [task](../development/vscode.md) `start server`. diff --git a/docs/source/overview/overview.md b/docs/source/overview/overview.md index 5a46ed19..fec1ff24 100644 --- a/docs/source/overview/overview.md +++ b/docs/source/overview/overview.md @@ -16,10 +16,8 @@ This is to make sure that whoever tries to communicate has the correct level of ### API -[comment]: # (What does "that will proxy the request to the main Python server" mean?) - API calls are used for simple functions that the client wants to perform, such as getting, editing, and saving data. -These are sent from the client to the backend Node server that will proxy the request to the main Python server. +These are sent from the client to the backend Node server that will forward the request to the main Python server. The request will then be handled there and the response will be sent back. The Node server will then send them back to the client. diff --git a/docs/source/overview/server.md b/docs/source/overview/server.md index 8c7277b9..73b56dba 100644 --- a/docs/source/overview/server.md +++ b/docs/source/overview/server.md @@ -95,11 +95,9 @@ The server can see what is stored in the JWT and do different things depending o ### Syncing between clients -[comment]: # "What does `sync` mean? It isn't explained" - There are two other events that is used. -The operator will emit the `sync` event to sync some values to all other clients connected to the same competition. +The operator will emit the `sync` event to syncronise some values to all other clients connected to the same competition. The server will then send `sync` to all connected clients with the values that was updated. -The server will also store these values and will sync these when a client joins a competition. -The operator can also emit `end_presentation` to disconnect all clients from its competition. +The server will also store these values and will syncronise these when a client joins a presentation. +The operator can also emit `end_presentation` to disconnect all clients from its presentation. This will also end the presentation. diff --git a/docs/source/user_manual/editor.md b/docs/source/user_manual/editor.md index 7091cce6..c0ab9408 100644 --- a/docs/source/user_manual/editor.md +++ b/docs/source/user_manual/editor.md @@ -9,6 +9,7 @@ Switch to a different slide by clicking on it. In the bottom left corner you will be able to add a new slide using the "Ny sida" button. Delete or copy a slide simply by right clicking on it and choosing the appropriate option. In the top right corner you will be able to change which view you see and edit. +By right clicking on a component you will be able to delete it or copy it to the same or a different view.  @@ -31,5 +32,3 @@ Below that you will be able to add and remove text and image components as well The background image for the competition can be overridden by explicitly setting it on a specific page.  - -[comment]: # 'Perhaps mention right clicking a component to make a copy to another view?' diff --git a/docs/source/user_manual/presentation.md b/docs/source/user_manual/presentation.md index 2bb125a5..aeac5265 100644 --- a/docs/source/user_manual/presentation.md +++ b/docs/source/user_manual/presentation.md @@ -1,13 +1,12 @@ -[comment]: # "Why is this file named 'presentation' but the main headline is 'Active competitions'?" +# Presentations -# Active competitions - -There are many different views during a competition. -Below it is described how to start a competition, how to join a competition, and how the different kinds of views work. +An active (i.e. started) competition is for simplicity's sake called a presentation. +There are many different views during a presentation. +Below it is described how to start a competition, how to join a presentation, and how the different kinds of views work. ## Competition codes -You can join a competition with codes. +You can join a presentation with codes. This can either be done by pasting the link that can be copied when listing the codes or can be typed by hand in the login page. All the views have different purposes and therefore looks a little bit different from one another. @@ -16,17 +15,16 @@ All the views have different purposes and therefore looks a little bit different There are two ways to start a competition. The first way is to navigate to the competition manager, press the three dots "..." and press "Starta". You will then enter the operator view. -From there you will be able to go between slides with the "<" and ">" buttons or start the timer, both will be synced between all clients connected to that competition. -You will also be able to view the scores for the teams and view all codes to the competition. +From there you will be able to go between slides with the "<" and ">" buttons and start the timer, both will be synced between all clients connected to that presentation. +You will also be able to view all codes to the competition. +You can also show the current score for all teams to the audience.  ## Team -[comment]: # 'What is meant with "(or the code for one of the teams)"? Doesnt a team have to log in using a code?' - -The team view (or the code for one of the teams) will be used by teams. -It shows the current slide (that the operator has decided) and allows the user to answer questions on the slide that will be saved. +The team view will be used by teams. +It shows the current slide (that the operator has decided) and allows the user to answer questions on the slide, which will be saved.  @@ -41,7 +39,7 @@ The audience view will look like the operator view but without the buttons. [comment]: # 'Update image to show that the current slide is highlighted.' The judge view will show show the same slide as team view. -To the left you will be able to move between different slides without affecting the other clients and will be shown och which slide the operator currently is. +To the left you will be able to move between different slides without affecting the other clients and will be shown on which slide the operator currently is. To the right you will see what the teams have answered on every question, what score each team got on each question, their total score and be able to set the score of a team on any and all questions. In the bottom right you will see instructions for how to grade the current question. -- GitLab From 41d284049624dd558215ecbf4b7a47d81692a3a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se> Date: Mon, 24 May 2021 15:12:12 +0200 Subject: [PATCH 6/7] Update documentation from comments --- docs/source/contact.md | 22 ++++++++++------------ docs/source/development/vscode.md | 2 -- docs/source/documentation/client.md | 2 -- docs/source/user_manual/editor.md | 3 +-- docs/source/user_manual/presentation.md | 2 -- 5 files changed, 11 insertions(+), 20 deletions(-) diff --git a/docs/source/contact.md b/docs/source/contact.md index add8a014..8fc5ed57 100644 --- a/docs/source/contact.md +++ b/docs/source/contact.md @@ -3,15 +3,13 @@ The people involved in the project, their email, their role in the project, what they worked on generally and, if anything, they worked on most will be described below. Please feel free to contact us if you have any questions. -| Namn | Email | Roll | Generellt | Speciellt | -| ------------------ | ----------------------- | ---------------------- | --------- | ---------------------- | -| Albin Henriksson | albhe428@student.liu.se | Testledare | Frontend | | -| Sebastian Karlsson | sebka991@student.liu.se | Arkitekt | Frontend | | -| Victor Löfgren | viclo211@student.liu.se | Konfigurationsansvarig | Backend | Dokumentation, Sockets | -| Björn Modée | bjomo323@student.liu.se | Kvalitetsamordnare | Frontend | Redux | -| Josef Olsson | josol381@student.liu.se | Teamledare | Backend | | -| Max Rüdiger | maxru105@student.liu.se | Dokumentansvarig | Frontend | | -| Carl Schönfelder | carsc272@student.liu.se | Utvecklingsledare | Backend | Databas | -| Emil Wahlqvist | emiwa210@student.liu.se | Analysansvarig | Frontend | Presentationseditor | - -[comment]: # 'Should this really be in swedish?' +| Name | Email | Role | Generally | Especially | +| ------------------ | ----------------------- | ------------------------ | --------- | ------------------------------ | +| Albin Henriksson | albhe428@student.liu.se | Test Leader | Front end | Presentations, Editor, Testing | +| Sebastian Karlsson | sebka991@student.liu.se | Architect | Front end | Editor, Uploading pictures | +| Victor Löfgren | viclo211@student.liu.se | Configuration Management | Back end | Documentation, Sockets, API | +| Björn Modée | bjomo323@student.liu.se | Quality Assurance | Front end | Redux | +| Josef Olsson | josol381@student.liu.se | Team Leader | Back end | Database, Testing | +| Max Rüdiger | maxru105@student.liu.se | Document Management | Front end | | +| Carl Schönfelder | carsc272@student.liu.se | Development Leader | Back end | Database, Uploading pictures | +| Emil Wahlqvist | emiwa210@student.liu.se | Analyst | Front end | Editor | diff --git a/docs/source/development/vscode.md b/docs/source/development/vscode.md index 86c4a97f..be5e7ed9 100644 --- a/docs/source/development/vscode.md +++ b/docs/source/development/vscode.md @@ -13,8 +13,6 @@ The Python and Pylance extensions help with linting Python code, auto imports, s Prettier is an extension used to format JavaScript and TypeScript. ESLint is used to lint JavaScript and TypeScript code. -[comment]: # ("is used to lint JavaScript" what is lint? It's not explained) - Live Share is an extension that is used to write code together at the same time, much like a Google Docs document. There were however a few issues with the Python extension that made Live Share hard to work with. diff --git a/docs/source/documentation/client.md b/docs/source/documentation/client.md index fe424fe5..ca1dcfe8 100644 --- a/docs/source/documentation/client.md +++ b/docs/source/documentation/client.md @@ -16,5 +16,3 @@ start ./docs/index.html ``` If you want to include the documentation from the tests, go to the file `client/tsconfig.json` and comment out the line `"exlude": "**/*.test.*"`. - -[comment]: # (There should be a task for this, or does one exist already?) \ No newline at end of file diff --git a/docs/source/user_manual/editor.md b/docs/source/user_manual/editor.md index c0ab9408..c3c99901 100644 --- a/docs/source/user_manual/editor.md +++ b/docs/source/user_manual/editor.md @@ -1,7 +1,6 @@ # Editor -[comment]: # 'Explain where to find the competition name. Perhaps an image or link to Admin?' - +The [competition manager](./admin.md) will list all competitions. After clicking on a competition name you will enter the editor and will be able to edit it. The Teknikåttan logo in the top left corner will take you back to the Admin page and right under that all slides are shown. A newly created competition will have one empty default slide. diff --git a/docs/source/user_manual/presentation.md b/docs/source/user_manual/presentation.md index aeac5265..03845fa4 100644 --- a/docs/source/user_manual/presentation.md +++ b/docs/source/user_manual/presentation.md @@ -36,8 +36,6 @@ The audience view will look like the operator view but without the buttons. ## Judge -[comment]: # 'Update image to show that the current slide is highlighted.' - The judge view will show show the same slide as team view. To the left you will be able to move between different slides without affecting the other clients and will be shown on which slide the operator currently is. To the right you will see what the teams have answered on every question, what score each team got on each question, their total score and be able to set the score of a team on any and all questions. -- GitLab From f2aefe7d276349f433760d25d3401c248dbb1271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se> Date: Mon, 24 May 2021 15:19:17 +0200 Subject: [PATCH 7/7] Write some text on client testing and development --- docs/source/development/client.md | 4 ++-- docs/source/testing/client.md | 4 +++- docs/source/testing/e2e.md | 5 ++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/source/development/client.md b/docs/source/development/client.md index c868be74..3cef7f40 100644 --- a/docs/source/development/client.md +++ b/docs/source/development/client.md @@ -1,10 +1,10 @@ # Frontend -[comment]: # (TODO) +Here it is described how to work with the frontend in the system. ## Working with TypeScript -[comment]: # (TODO) +The main programming languange used for the front end is TypeScript. ### npm diff --git a/docs/source/testing/client.md b/docs/source/testing/client.md index b0201a48..367eee00 100644 --- a/docs/source/testing/client.md +++ b/docs/source/testing/client.md @@ -1,3 +1,5 @@ # Testing the client -[comment]: # (TODO) \ No newline at end of file +The clients tests are the files named `<name>.test.ts`. +They test the file called `<name>.ts`. +They are run using the [VS Code task](../development/vscode.md) `Unit tests`. diff --git a/docs/source/testing/e2e.md b/docs/source/testing/e2e.md index 62d70386..2fdffa7a 100644 --- a/docs/source/testing/e2e.md +++ b/docs/source/testing/e2e.md @@ -1,3 +1,6 @@ # End to end tests -[comment]: # (TODO) \ No newline at end of file +The end to end tests are tests that test the entire system, both the server and the client. +They are stored in the folder `/client/src/e2e/`. +Both the client and the server need to be running for the end to end tests to work. +The tests are run using the [VS Code task](../development/vscode.md) `Run e2e tests`. -- GitLab