This repository contains the web user interface of the Nuvla solution. It is built as a modern single page application.
The ui is built entirely in Clojurescript (that's cool), using re-frame and reagent as foundation, and Semantic UI for basic widgets and styling.
Our aim is to build a user experience such that users can start capturing, deploying and managing containers on any virtualised environments (e.g. public cloud, private cloud and infrastructure, as well as NuvlaEdge devices). And all this with no or minimum training.
More details on the overall Nuvla eco-system is available here.
nuvla/ui- A Docker container containing the static content of the UI served by nginx. Available from the nuvla/ui repository on Docker Hub.
For development you need nodejs, leiningen and caddy
On Mac OS, the npm command comes with the Node.js distribution of
Homebrew. Just run the command brew install node.
brew install node
brew install leiningen
brew install caddyFor other distributions or for direct installation on Mac OS, take a look at tools website for instructions.
The ui can be installed on its own or as part of a full Nuvla stack. Stand alone installations must be configured to point to an existing Nuvla server.
You can also run your own Nuvla test server locally, which is great for testing. You'll find instructions here.
You will need to point your development ui environment to a Nuvla server. For that you have a few choices:
- Deploy a test server
- Point to an already deployed server (e.g. https://nuvla.io)
You then need to configure your local Nuvla ui to point to the Nuvla server (next section).
To run your UI dev server and your backend server from the same host address we use Caddy as a reverse-proxy during development. Caddy installs local certificates automatically, so we can run the development environment on a "real" URL.
First, create a new file called Caddyfile with this content:
# this is a comment
{
local_certs
}
nui.localhost {
reverse_proxy localhost:8280
reverse_proxy /api/* {
to https://nuvla.io # this points to a server of your chosing
# uncomment following lines if your api server is using an untrusted certificate
# transport http {
# tls_insecure_skip_verify
# }
}
}
From the same directory where the Caddyfile is located, you run the command caddy run (or caddy start to run it in
the background).
If you want to point the API somewhere else, you can change your Caddyfile
from reverse_proxy /api/* https://nuvla.io to e.g. reverse_proxy /api/* localhost:8200 and run the
command caddy reload (no need to restart anything else).
Run npm ci --legacy-peer-deps inside code folder of the cloned repository. This only needs to be done once at the beginning and
then whenever dependencies change.
When you now run lein dev from the code folder, you can visit the Nuvla-Ui at https://nui.localhost.
We use Portfolio for component showcasing and
playwright for component testing.
By running lein dev a Porfolio server is started automatically on port 8281.
To execute all component tests run the following command (Portfolio needs to be running for this command to work):
npm run test:components
or for headed mode:
npm run test:components:headed
We use playwright for e2e-testing.
To run playwright locally, inside the code directory, you cp .env.e2e.TEMPLATE .env.e2e and set the environment
variables specified in that file.
Tests are located in the code/test/e2e/ directory.
- Run
npm run test:e2e:genyou open the playwright Test Generator.
It allows you to visit a website, record all interactions and let playwright generate all code necessary to replay
those interactions.
-
Copy the generated code into a new file. You can remove the code used to log in, as all tests run with a logged-in user (you can change the user in the
.env.e2efile). Adjust the code to suit your needs, e.g., writing assertions usingexpect.As an alternative, you can save the output of the code generation directly to a file:
npm run test:e2e:gen -- -o test.spec.js- Put new tests inside the
code/test/e2e/loggedindirectory. The file has to end with.spec.js(.tsfor typescript files is possible).
Four additional commands are configured in package.json to run the tests (all starting with test:e2e).
Run all tests:
npm run test:e2eRun a single file by specifying a path, treated as a regex:
npm run test:e2e logoutWatch the test folder and run a test if the test file changes:
npm run test:e2e:watchRun tests in headed mode, i.e. a browser window opens and you can see the test run.
You have to specify a path; this example runs all tests:
npm run test:e2e:headedThe headed test runs are also available in watch mode. You do not have to provide a path regex: the path is provided by the watching process.
npm run test:e2e:headed:watchIt is possible to run the tests in parallel.
Because they share the same logged in session (through global-setup.js), it could be that tests fail if
the logout.spec.js tests runs first.
To prevent this, only run tests inside the loggedin folder.
npm run test:e2e loggedin -- --workers 5By adding a page.pause() inside a test file and running in headed mode, you can stop and open an inspector view.
When a test fails, you find a trace.zip file inside the respective directory in the code/test-report folder. You can
open it by
npx playwright show-trace test-results/<path-to-test-file>-<test-name>-retry<retrynumber>/trace.zipnpx playwright --helpand
npx playwright test --helpnpm run test:unit- Shadow-clj build project:
lein dev
- Get nREPL server port from file or from console:
- console:
shadow-cljs - nREPL server started on port 60325 - file:
code/.shadow-cljs/nrepl.port
- console:
- Wait until shadow-cljs finish compilation
- Browse to UI page in web browser to load javascript runtime
- Connect with nRepl client
- Select project in nRepl, load test file and run-tests
(shadow/repl :nuvla-ui) (load-file "test/cljs/sixsq/nuvla/ui/edges/utils_test.cljs") (cljs.test/run-tests 'sixsq.nuvla.ui.edges.utils-test)
shadow-cljs can create a bundle size report.
npx shadow-cljs run shadow.cljs.build-report nuvla-ui report.htmlThis saves the report as report.html in resources/public/ui/js.
To contribute code to this repository, please follow these steps:
-
Create a branch from master with a descriptive, kebab-cased name to hold all your changes.
-
Follow the developer guidelines concerning formatting, etc. when modifying the code.
-
Once the changes are ready to be reviewed, create a GitHub pull request. With the pull request, provide a description of the changes and links to any relevant issues (in this repository or others).
-
Ensure that the triggered CI checks all pass. These are triggered automatically with the results shown directly in the pull request.
-
Once the checks pass, assign the pull request to the repository coordinator (who may then assign it to someone else).
-
Interact with the reviewer to address any comments.
When the reviewer is happy with the pull request, he/she will "squash & merge" the pull request and delete the corresponding branch.
The bulk of the code in this repository is written in Clojurescript.
The formatting follows the standard formatting provided by the Cursive IntelliJ plugin with all the default settings except that map and let entries should be aligned.
Additional, formatting guidelines, not handled by the Cursive plugin:
-
Use a new line after the
:requireand:importkeys in namespace declarations. -
Alphabetize the required namespaces. This can be automated with
lein nsorg --replace. -
Use 2 blank lines between top-level forms.
-
Use a single blank line between a block comment and the following code.
IntelliJ (with Cursive) can format easily whole directories of source code. Do not hesitate to use this feature to keep the source code formatting standardized.
You can import the repository through IntelliJ, using the "leiningen" method in the dialog.
If you have the IntelliJ command line installed, the shadow-cljs heads-up display, should open files in the IntelliJ editor.
The command for opening Chrome with the security disabled, can be configured as an "external tool" in IntelliJ. In "Preferences", go to the "Tools" -> "External Tools" panel.
You can reset the logging level for kvlt from the REPL when running in development mode. From the REPL do:
=> (require '[taoensso.timbre :as timbre])
=> (timbre/set-level! :info)
The default value is :debug which will log all the HTTP requests
and responses. This is useful when debugging interactions with
Nuvla, but annoying otherwise.
Release process instructions are available here.
Copyright © 2019-2024, SixSq SA
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.