Skip to content

Commit

Permalink
Merge pull request #7442 from TheThingsNetwork/fix/e2e-test-setup
Browse files Browse the repository at this point in the history
Update e2e instructions
  • Loading branch information
ryaplots authored Jan 27, 2025
2 parents 72f3d76 + 57ee21c commit c6cdc60
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 117 deletions.
269 changes: 157 additions & 112 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,11 @@ This creates a database, migrates tables and creates a user `admin` with passwor
$ go run ./cmd/ttn-lw-stack -c ./config/stack/ttn-lw-stack.yml start
```

5. Run the Frontend with

```bash
$ tools/bin/mage js:serve
```

6. Login to The Things Stack via the Console
5. Login to The Things Stack via the Console

In a web browser, navigate to `http://localhost:1885/` and login using credentials from step 3.

7. Customizing configuration
6. Customizing configuration

To customize the configuration, copy the configuration file `/config/stack/ttn-lw-stack.yml` to a different location (ex: the `.env` folder in your repo). The configuration is documented in the [Configuration Reference](https://thethingsstack.io/reference/configuration/).

Expand Down Expand Up @@ -251,123 +245,39 @@ The folder structure of the frontend looks as follows:
├── template.go go template module used to render the frontend HTML
```

#### Development Configuration

> To use a convenient interactive launcher for the development environments without any further setup required, please see the (interactive development stack launcher tool)[#interactive-development-stack-launcher-tool]
In order to set up The Things Stack to support running the frontend via `webpack-dev-server`, the following environment setup is needed:

```bash
# .dev.env
export NODE_ENV="development"
export TTN_LW_LOG_LEVEL="debug"
export TTN_LW_IS_OAUTH_UI_JS_FILE="libs.bundle.js account.js"
export TTN_LW_CONSOLE_UI_JS_FILE="libs.bundle.js console.js"
export TTN_LW_CONSOLE_UI_CANONICAL_URL="http://localhost:8080/console"
export TTN_LW_CONSOLE_OAUTH_AUTHORIZE_URL="http://localhost:8080/oauth/authorize"
export TTN_LW_CONSOLE_OAUTH_LOGOUT_URL="http://localhost:8080/oauth/logout"
export TTN_LW_CONSOLE_OAUTH_TOKEN_URL="http://localhost:8080/oauth/token"
export TTN_LW_IS_OAUTH_UI_CANONICAL_URL="http://localhost:8080/oauth"
export TTN_LW_IS_EMAIL_NETWORK_IDENTITY_SERVER_URL="http://localhost:8080/oauth.js"
export TTN_LW_CONSOLE_UI_ASSETS_BASE_URL="http://localhost:8080/assets"
export TTN_LW_IS_EMAIL_PROVIDER="dir"
export TTN_LW_IS_EMAIL_DIR=".dev/email"

export TTN_LW_CONSOLE_UI_IS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_AS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_NS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_JS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_GS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_EDTC_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_GCS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_QRG_BASE_URL="http://localhost:8080/api/v3"

export TTN_LW_IS_OAUTH_UI_IS_BASE_URL="http://localhost:8080/api/v3"
```

We recommend saving this configuration as an `.dev.env` file and sourcing it like `source .dev.env`. This allows you to easily apply development configuration when needed.

The development server can also be run with a staging environment (`.staging.env`) with the following set up:

```bash
# .staging.env
export NODE_ENV="development"
export TTN_LW_LOG_LEVEL="debug"

export TTN_LW_AS_WEBHOOKS_TEMPLATES_DIRECTORY="<GOPATH>/src/github.com/TheThingsNetwork/webhook-templates"
export TTN_LW_CONSOLE_OAUTH_AUTHORIZE_URL="https://tti.staging1.cloud.thethings.industries/oauth/authorize"
export TTN_LW_CONSOLE_OAUTH_LOGOUT_URL="https://tti.staging1.cloud.thethings.industries/oauth/logout"
export TTN_LW_CONSOLE_OAUTH_TOKEN_URL="https://tti.staging1.cloud.thethings.industries/oauth/token"
export TTN_LW_CONSOLE_UI_ASSETS_BASE_URL="http://localhost:8080/assets"
export TTN_LW_CONSOLE_UI_CANONICAL_URL="http://localhost:8080/console"
export TTN_LW_CONSOLE_UI_JS_FILE="libs.bundle.js console.js paint.js"
export TTN_LW_IS_OAUTH_UI_CANONICAL_URL="http://localhost:8080/oauth"
export TTN_LW_IS_OAUTH_UI_JS_FILE="libs.bundle.js oauth.js"

export TTN_LW_CONSOLE_UI_SUPPORT_LINK="https://thethingsstack.io"

export TTN_LW_CONSOLE_UI_IS_BASE_URL="https://tti.staging1.cloud.thethings.industries/api/v3"
export TTN_LW_CONSOLE_UI_AS_BASE_URL="https://tti.staging1.cloud.thethings.industries/api/v3"
export TTN_LW_CONSOLE_UI_NS_BASE_URL="https://tti.staging1.cloud.thethings.industries/api/v3"
export TTN_LW_CONSOLE_UI_GS_BASE_URL="https://tti.staging1.cloud.thethings.industries/api/v3"
export TTN_LW_CONSOLE_UI_JS_BASE_URL="https://tti.staging1.cloud.thethings.industries/api/v3"
export TTN_LW_CONSOLE_UI_QRG_BASE_URL="https://tti.staging1.cloud.thethings.industries/api/v3"
export TTN_LW_CONSOLE_UI_EDTC_BASE_URL="https://tti.staging1.cloud.thethings.industries/api/v3"

export TTN_LW_CONSOLE_OAUTH_CLIENT_ID="localhost-console"
export TTN_LW_CONSOLE_OAUTH_CLIENT_SECRET="console"

export TTN_LW_TLS_CERTIFICATE=<GOPATH>/src/github.com/TheThingsNetwork/lorawan-stack/cert.pem
export TTN_LW_TLS_KEY=<GOPATH>/src/github.com/TheThingsNetwork/lorawan-stack/key.pem
export TTN_LW_TLS_ROOT_CA=<GOPATH>/src/github.com/TheThingsNetwork/lorawan-stack/cert.pem
export TTN_LW_TLS_SOURCE="file"
export TTN_LW_TLS_INSECURE_SKIP_VERIFY="true"
```

> Note: It is important to **source these environment variables in all terminal sessions** that run The Things Stack or the `tools/bin/mage` commands. Failing to do so will result in erros such as blank page renders. See also [troubleshooting](#troubleshooting).
#### Optional Configuration

##### Disable [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/)

If you experience trouble seeing the WebUIs updated after a code change, you can also disable hot module replacement and enforce a hard reload on code changes instead. This method is a bit slower but more robust. To do so apply the following variable:

```bash
WEBPACK_DEV_SERVER_DISABLE_HMR="true"
```

> Note: Webpack-related configuration can be loaded from environment variables only. It cannot be sourced from a config file.
#### Interactive development stack launcher tool

##### Enable TLS in `webpack-dev-server`
In order to easily launch development environments in different deployment contexts, this mage target configures and starts a development environment for The Things Stack, allowing users to choose between local and staging environments, enable branding, and configure cloud-hosted mock setups. You can launch it via:

```bash
WEBPACK_DEV_SERVER_USE_TLS="true"
$ tools/bin/mage dev:serveDevWebui
```
This option uses the key and certificate set via `TTN_LW_TLS_KEY` and `TTN_LW_TLS_CERTIFICATE` environment variables. Useful when developing functionalities that rely on TLS.

> Note: To use this option, The Things Stack for LoRaWAN must be properly setup for TLS. You can obtain more information about this in the **Getting Started** section of the The Things Stack for LoRaWAN documentation.
#### Serving
It will interactively guide you through the desired setup and launches the The Things Stack as well as a frontend development server wia webpack.

For development purposes, the frontend can be run using `webpack-dev-server`. After following the [Getting Started](#getting-started) section to initialize The Things Stack and doing an initial build of the frontend via `tools/bin/mage js:build`, and setting up the correct environment, it can be served using:
The Things Stack can be accessed at `http://localhost:8080`. The frontend is ready when you see:

```bash
$ export NODE_ENV=development
$ tools/bin/mage js:serve
[js:serve] <i> [webpack-dev-server] Project is running at:
[js:serve] <i> [webpack-dev-server] Loopback: http://localhost:8080/, http://[::1]:8080/
```

The development server runs on `http://localhost:8080` and will proxy all API calls to port `1885`. The serve command watches any changes inside `pkg/webui` and refreshes automatically.

#### Interactive development stack launcher tool

In order to easily launch development environments in different deployment contexts, this mage target configures and starts a development environment for The Things Stack, allowing users to choose between local and staging environments, enable branding, and configure cloud-hosted mock setups. You can launch it via:
The backend is ready when you see:

```bash
$ tools/bin/mage dev:serveDevWebui
[stack] DEBUG Creating listener {"address": ":8887"}
[stack] DEBUG Creating listener {"address": ":1889"}
DEBUG Creating listener {"address": ":1887"}
DEBUG Creating listener {"address": ":8881"}
INFO New patch version available {"current": "3.32.2-dev", "docs_url": "https://www.thethingsindustries.com/docs/getting-started/upgrading/", "latest": "3.32.3"}
DEBUG Creating listener {"address": ":8883"}
DEBUG Creating listener {"address": ":8889"}
DEBUG Creating listener {"address": ":1881"}
DEBUG Creating listener {"address": ":8882"}
DEBUG Creating listener {"address": ":1883"}
DEBUG Creating listener {"address": ":1882"}
```

It will interactively guide you through the desired setup and launches the The Things Stack Enterprise as well as a frontend development server wia webpack.

## Code Style

### Code Formatting
Expand Down Expand Up @@ -808,7 +718,33 @@ We use [Cypress](https://cypress.io) for running frontend-based end-to-end tests

#### Running frontend end-to-end tests locally

Make sure to [build the frontend assets](#building-the-frontend) and run `tools/bin/mage dev:initStack dev:sqlDump` to create a seed database which the tests can reset the database to in between runs. To run the stack when working on end-to-end tests, use the `tools/bin/mage dev:startDevStack` command. This will run the runs The Things Stack with proper configuration for the end-to-end tests. Note: this command does not output anything, but logs are written to `.cache/devStack.log`.
The preferred way to run the end-to-end tests is to use the [interactive launcher tool](#interactive-development-stack-launcher-tool).

1. Make sure to run `tools/bin/mage dev:dbStop dev:dbErase dev:dbCreate dev:initStack dev:sqlDump` to create a seed database which the tests can reset the database to in between runs.
2. Run `tools/bin/mage dev:serveDevWebui`
3. Select "Cypress" in the launcher tool
4. In a separate terminal, add the following environment variables:

```bash
export NODE_ENV="development"
export CYPRESS_BASE_URL="http://localhost:8080"
```

5. And run the end-to-end tests (`tools/bin/mage js:cypressInteractive`)

#### Optional: testing in development environment

Make sure to [build the frontend assets](#building-the-frontend) and run `tools/bin/mage dev:dbStop dev:dbErase dev:dbCreate dev:initStack dev:sqlDump` to create a seed database which the tests can reset the database to in between runs.

To run the stack when working on end-to-end tests, use the `tools/bin/mage dev:startDevStack` command. This will run the runs The Things Stack with proper configuration for the end-to-end tests. Note: this command does not output anything, but logs are written to `.cache/devStack.log`.

It is possible to run the tests while using the development environment. To do so, follow the guide on setting up the [development environment](#development-configuration). Once configured, do the following:

1. Run the stack with (`tools/bin/mage dev:startDevStack`)
2. Serve the frontend (`tools/bin/mage js:serve`)
3. Run the end-to-end tests (`tools/bin/mage js:cypressInteractive`)

##### Running the tests

[Cypress](https://www.cypress.io/) provides two modes for running tests: headless and interactive.
- **Headless mode** will not display any browser GUI and output test progress into your terminal instead. This is helpful when one just needs see the results of the tests.
Expand Down Expand Up @@ -1095,6 +1031,115 @@ $ go run ./cmd/ttn-lw-stack start

It is also possible to use `go build`, or release snapshots, as described below.

### Advanced Development Configuration

> The preffered way to set up the development environment is to use the [interactive development stack launcher tool](#interactive-development-stack-launcher-tool).

In order to set up The Things Stack to support running the frontend via `webpack-dev-server`, the following environment setup is needed:

```bash
# .dev.env
export NODE_ENV="development"
export TTN_LW_IS_ADMIN_RIGHTS_ALL="true"
export TTN_LW_IS_EMAIL_DIR=".dev/email"
export TTN_LW_IS_EMAIL_PROVIDER="dir"
export TTN_LW_LOG_LEVEL="debug"
export TTN_LW_NOC_ACCESS_EXTENDED="true"
export TTN_LW_PLUGINS_SOURCE="directory"
export TTN_LW_CONSOLE_UI_CANONICAL_URL="http://localhost:8080/console"
export TTN_LW_CONSOLE_OAUTH_AUTHORIZE_URL="http://localhost:8080/oauth/authorize"
export TTN_LW_CONSOLE_OAUTH_LOGOUT_URL="http://localhost:8080/oauth/logout"
export TTN_LW_CONSOLE_OAUTH_TOKEN_URL="http://localhost:8080/oauth/token"
export TTN_LW_CONSOLE_UI_ASSETS_BASE_URL="http://localhost:8080/assets"
export TTN_LW_CONSOLE_UI_AS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_EDTC_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_GCS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_GS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_IS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_JS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_JS_FILE="libs.bundle.js console.js"
export TTN_LW_CONSOLE_UI_NS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_QRG_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_IS_OAUTH_UI_IS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_IS_OAUTH_UI_JS_FILE="libs.bundle.js account.js"
export WEBPACK_DEV_BACKEND_API_PROXY_URL="http://localhost:1885"
export TTN_LW_CONSOLE_UI_ACCOUNT_URL="http://localhost:8080/oauth"
export TTN_LW_IS_EMAIL_NETWORK_IDENTITY_SERVER_URL="http://localhost:8080/oauth"
export TTN_LW_IS_OAUTH_UI_CANONICAL_URL="http://localhost:8080/oauth"
export CYPRESS_BASE_URL="http://localhost:8080"
```

We recommend saving this configuration as an `.dev.env` file and sourcing it like `source .dev.env`. This allows you to easily apply development configuration when needed.

The development server can also be run with a staging environment (`.staging.env`) with the following set up:

```bash
# .staging.env
export STAGING_URL="<STAGING URL>"
export NODE_ENV="development"
export TTN_LW_IS_ADMIN_RIGHTS_ALL="true"
export TTN_LW_IS_EMAIL_DIR=".dev/email"
export TTN_LW_IS_EMAIL_PROVIDER="dir"
export TTN_LW_LOG_LEVEL="debug"
export TTN_LW_NOC_ACCESS_EXTENDED="true"
export TTN_LW_PLUGINS_SOURCE="directory"
export TTN_LW_CONSOLE_UI_CANONICAL_URL="http://localhost:8080/console"
export TTN_LW_CONSOLE_OAUTH_AUTHORIZE_URL="${STAGING_URL}/oauth/authorize"
export TTN_LW_CONSOLE_OAUTH_CLIENT_ID="localhost-console"
export TTN_LW_CONSOLE_OAUTH_CLIENT_SECRET="console"
export TTN_LW_CONSOLE_OAUTH_LOGOUT_URL="${STAGING_URL}/oauth/logout"
export TTN_LW_CONSOLE_OAUTH_TOKEN_URL="${STAGING_URL}/oauth/token"
export TTN_LW_CONSOLE_UI_AS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_EDTC_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_GCS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_GS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_IS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_JS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_NS_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_QRG_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_NOC_BASE_URL="http://localhost:8080/api/v3"
export TTN_LW_CONSOLE_UI_NOC_URL="${STAGING_URL}/noc"
export WEBPACK_DEV_BACKEND_API_PROXY_URL="${STAGING_URL}"
export TTN_LW_CONSOLE_UI_ACCOUNT_URL="${STAGING_URL}/oauth"
export TTN_LW_IS_OAUTH_UI_CANONICAL_URL="${STAGING_URL}/oauth"
```

> Note: It is important to **source these environment variables in all terminal sessions** that run The Things Stack or the `tools/bin/mage` commands. Failing to do so will result in erros such as blank page renders. See also [troubleshooting](#troubleshooting).

#### Optional Configuration

##### Disable [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/)

If you experience trouble seeing the WebUIs updated after a code change, you can also disable hot module replacement and enforce a hard reload on code changes instead. This method is a bit slower but more robust. To do so apply the following variable:

```bash
WEBPACK_DEV_SERVER_DISABLE_HMR="true"
```

> Note: Webpack-related configuration can be loaded from environment variables only. It cannot be sourced from a config file.

##### Enable TLS in `webpack-dev-server`

```bash
WEBPACK_DEV_SERVER_USE_TLS="true"
```
This option uses the key and certificate set via `TTN_LW_TLS_KEY` and `TTN_LW_TLS_CERTIFICATE` environment variables. Useful when developing functionalities that rely on TLS.

> Note: To use this option, The Things Stack for LoRaWAN must be properly setup for TLS. You can obtain more information about this in the **Getting Started** section of the The Things Stack for LoRaWAN documentation.

#### Serving

For development purposes, the frontend can be run using `webpack-dev-server`. After following the [Getting Started](#getting-started) section to initialize The Things Stack and doing an initial build of the frontend via `tools/bin/mage js:build`, and [setting up the correct environment](#development-configuration), it can be served using:

```bash
$ tools/bin/mage js:serve
```

The development server runs on `http://localhost:8080` and will proxy all API calls to port `1885`. The serve command watches any changes inside `pkg/webui` and refreshes automatically.

## Releasing

The Things Stack uses [GoReleaser](https://goreleaser.com/) for releases. If you want to build a release (snapshot), you first need to install GoReleaser:
Expand Down
4 changes: 2 additions & 2 deletions cypress/plugins/tasks.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
// Copyright © 2024 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -79,7 +79,7 @@ const sqlTask = on => {
const exec = util.promisify(childProcess.exec)
await Promise.all([
exec('tools/bin/mage dev:sqlRestore', { cwd: '..' }),
exec('tools/bin/mage dev:redisFlush', { cwd: '..' }),
exec('tools/bin/mage -v dev:redisFlush', { cwd: '..' }),
])
return null
},
Expand Down
5 changes: 5 additions & 0 deletions tools/js/serve-dev-webui.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export TTN_LW_LOG_LEVEL="debug"
export TTN_LW_NOC_ACCESS_EXTENDED="true"
export TTN_LW_PLUGINS_SOURCE="directory"
export TTN_LW_CONSOLE_UI_CANONICAL_URL="http://localhost:8080/console"
export TTN_LW_TRACING_ENABLE="false"
export TTN_LW_TELEMETRY_ENABLE="false"
`

// Local configuration environment variables
Expand Down Expand Up @@ -136,6 +138,9 @@ if (relevantSetEnvs.length > 0) {
}
envConfig += stagingConfig
}
} else {
// Cypress setup
envConfig = `${baseConfig + localConfig}export CYPRESS_BASE_URL="http://localhost:8080"\n`
}

const envVars = envConfig
Expand Down
Loading

0 comments on commit c6cdc60

Please sign in to comment.