Skip to content

Commit dffb797

Browse files
committed
implement e2e testing for the webui
1 parent a87c67b commit dffb797

File tree

12 files changed

+271
-17
lines changed

12 files changed

+271
-17
lines changed

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,3 +1851,10 @@ go-mod-tidy-all:
18511851
dump-preset-roles:
18521852
GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go run ./build.assets/dump-preset-roles/main.go
18531853
pnpm test web/packages/teleport/src/Roles/RoleEditor/StandardEditor/standardmodel.test.ts
1854+
1855+
.PHONY: test-web-e2e
1856+
test-web-e2e: ensure-webassets
1857+
@if [[ "${WEBASSETS_SKIP_BUILD}" -eq 1 ]]; then mkdir -p webassets/teleport && mkdir -p webassets/teleport/app && cp web/packages/teleport/index.html webassets/teleport/index.html; \
1858+
else MAKE="$(MAKE)" "$(MAKE_DIR)/build.assets/build-webassets-if-changed.sh" OSS webassets/oss-sha build-ui web; fi
1859+
1860+
$(CGOFLAG) go test -tags=webassets_embed ./integration/web-e2e_test.go

integration/helpers/helpers.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import (
5050
"github.com/gravitational/teleport/lib"
5151
"github.com/gravitational/teleport/lib/auth"
5252
"github.com/gravitational/teleport/lib/auth/authclient"
53+
"github.com/gravitational/teleport/lib/auth/testauthority"
5354
"github.com/gravitational/teleport/lib/backend"
5455
"github.com/gravitational/teleport/lib/client"
5556
"github.com/gravitational/teleport/lib/client/identityfile"
@@ -547,3 +548,43 @@ func UpsertAuthPrefAndWaitForCache(
547548
assert.Empty(t, cmp.Diff(&pref, &p))
548549
}, 5*time.Second, 100*time.Millisecond)
549550
}
551+
552+
// CreateTeleportTestInstance creates a new Teleport instance to be used for Web UI e2e tests.
553+
func CreateTeleportTestInstance(t *testing.T) (instance *TeleInstance, ctx context.Context) {
554+
privateKey, publicKey, err := testauthority.New().GenerateKeyPair()
555+
require.NoError(t, err)
556+
557+
cfg := InstanceConfig{
558+
ClusterName: "test-cluster",
559+
HostID: uuid.New().String(),
560+
NodeName: Host,
561+
Logger: utils.NewSlogLoggerForTests(),
562+
Priv: privateKey,
563+
Pub: publicKey,
564+
}
565+
cfg.Listeners = SingleProxyPortSetupOn(Host)(t, &cfg.Fds)
566+
rc := NewInstance(t, cfg)
567+
568+
rcConf := servicecfg.MakeDefaultConfig()
569+
rcConf.DataDir = t.TempDir()
570+
rcConf.Auth.Enabled = true
571+
rcConf.Auth.Preference.SetSecondFactor("webauthn")
572+
rcConf.Auth.Preference.SetWebauthn(&types.Webauthn{RPID: Host})
573+
rcConf.Proxy.Enabled = true
574+
rcConf.SSH.Enabled = false
575+
rcConf.Proxy.DisableWebInterface = false
576+
rcConf.Version = "v3"
577+
578+
ctx, contextCancel := context.WithCancel(context.Background())
579+
580+
err = rc.CreateEx(t, nil, rcConf)
581+
require.NoError(t, err)
582+
err = rc.Start()
583+
require.NoError(t, err)
584+
t.Cleanup(func() {
585+
assert.NoError(t, rc.StopAll())
586+
contextCancel()
587+
})
588+
589+
return rc, ctx
590+
}

integration/web-e2e_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package integration
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"testing"
8+
9+
"github.com/gravitational/teleport/api/types"
10+
"github.com/gravitational/teleport/integration/helpers"
11+
"github.com/gravitational/teleport/lib/auth/authclient"
12+
"github.com/gravitational/teleport/lib/services"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
// TestSignup sets up a test instance of Teleport and runs a playwright test against it to test the signup flow.
17+
func TestSignup(t *testing.T) {
18+
rc, ctx := helpers.CreateTeleportTestInstance(t)
19+
20+
as := rc.Process.GetAuthServer()
21+
22+
accessRole := services.NewPresetAccessRole()
23+
24+
// Create a test user.
25+
testUser, err := types.NewUser("testuser")
26+
require.NoError(t, err)
27+
testUser.SetRoles([]string{accessRole.GetName()})
28+
user, err := as.UpsertUser(ctx, testUser)
29+
30+
inviteToken, err := as.CreateResetPasswordToken(ctx, authclient.CreateUserTokenRequest{
31+
Name: user.GetName(),
32+
})
33+
require.NoError(t, err)
34+
35+
// Generate the URL the playwright test will start from.
36+
startUrl := fmt.Sprintf("START_URL=https://%s/web/invite/%s", rc.Web, inviteToken.GetName())
37+
38+
// Start the playwright test
39+
cmd := exec.Command("pnpm", "test-e2e", "signup.spec.ts")
40+
cmd.Env = append(os.Environ(), startUrl)
41+
cmd.Stdout = os.Stdout
42+
cmd.Stderr = os.Stderr
43+
require.NoError(t, cmd.Run())
44+
}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"test": "jest",
1818
"test-coverage": "jest --coverage && web/scripts/print-coverage-link.sh",
1919
"test-update-snapshot": "pnpm run test --updateSnapshot",
20+
"test-e2e": "pnpm --dir=./web/e2e test",
2021
"tdd": "jest --watch",
2122
"lint": "pnpm eslint && pnpm prettier-check",
2223
"lint-fix": "pnpm eslint --fix && pnpm prettier-write",
@@ -112,4 +113,4 @@
112113
"engines": {
113114
"node": "^22"
114115
}
115-
}
116+
}

pnpm-lock.yaml

Lines changed: 19 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
packages:
22
- web/packages/*
33
- e/web/*
4+
- web/e2e
45
onlyBuiltDependencies:
56
- '@swc/core'
67
- electron

web/e2e/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
test-results/
3+
playwright-report/
4+
playwright/.cache/

web/e2e/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# E2E Testing with Playwright
2+
3+
This directory contains the configuration and tests for end-to-end testing against a real Teleport instance using Playwright.
4+
5+
E2E tests should be run by a corresponding Go test in `integration/web-e2e_test.go` and run
6+
using `make test-web-e2e`. To run only the Playwright test directly, you'll need a Teleport instance running locally.
7+
8+
### Setup
9+
10+
Before being able to run any tests, you'll need to install the playwright package and the chromium browser.
11+
12+
```bash
13+
# Install packages
14+
pnpm install
15+
16+
# Install the Chromium browser
17+
pnpm exec playwright install chromium
18+
```
19+
20+
## Running Tests
21+
22+
### Basic Commands
23+
24+
```bash
25+
# Run all tests with the default START_URL (https://localhost:3080/web/login)
26+
pnpm test
27+
28+
# Run a specific test file.
29+
pnpm test signup.spec.ts
30+
31+
# Run tests against a specific START_URL.
32+
START_URL=https://teleport.dev pnpm test
33+
34+
# Run tests with the Playwright UI, useful for debugging.
35+
pnpm test --ui
36+
37+
# Start the Playwright codegen to generate tests by recording your browser interactions.
38+
pnpm exec playwright codegen
39+
40+
# View past test reports.
41+
pnpm report
42+
```

web/e2e/package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "playwright-e2e-testing",
3+
"version": "1.0.0",
4+
"description": "Playwright tests for e2e testing.",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "playwright test --project=chromium",
8+
"report": "playwright show-report"
9+
},
10+
"author": "",
11+
"license": "ISC",
12+
"devDependencies": {
13+
"@playwright/test": "^1.51.1"
14+
}
15+
}

web/e2e/playwright.config.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
3+
// Default to localhost:3080/web/login if START_URL is not defined.
4+
const baseURL = process.env.START_URL || 'http://localhost:3080/web/login';
5+
6+
export default defineConfig({
7+
testDir: './tests',
8+
fullyParallel: true,
9+
forbidOnly: !!process.env.CI,
10+
retries: process.env.CI ? 2 : 0,
11+
workers: process.env.CI ? 1 : undefined,
12+
reporter: [['html', { open: 'never' }]],
13+
14+
use: {
15+
ignoreHTTPSErrors: true,
16+
baseURL,
17+
trace: 'on-first-retry',
18+
screenshot: 'only-on-failure',
19+
},
20+
21+
projects: [
22+
{
23+
name: 'chromium',
24+
use: { ...devices['Desktop Chrome'] },
25+
},
26+
],
27+
});

0 commit comments

Comments
 (0)