Skip to content

Commit 388894d

Browse files
authored
replace puppeteer with testim (#472)
* wip: replace puppeteer with testim * updates for embedded cluster testim project * update testim test names * add e2e README section for Testim * add note about version control in testim
1 parent 31a6602 commit 388894d

14 files changed

+141
-736
lines changed

.github/actions/e2e/action.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ inputs:
1313
license:
1414
description: 'license (b64) to use for e2e tests'
1515
required: true
16+
testim-access-token:
17+
description: 'testim access token'
18+
required: true
19+
testim-branch:
20+
description: 'testim branch'
21+
required: true
1622

1723
runs:
1824
using: composite
@@ -52,4 +58,6 @@ runs:
5258
export LICENSE_ID=${{ inputs.license-id }}
5359
export AIRGAP_LICENSE_ID=${{ inputs.airgap-license-id }}
5460
echo "${{ inputs.license }}" | base64 --decode > e2e/license.yaml
61+
export TESTIM_ACCESS_TOKEN=${{ inputs.testim-access-token }}
62+
export TESTIM_BRANCH=${{ inputs.testim-branch }}
5563
make e2e-test TEST_NAME=${{ inputs.test-name }}

.github/workflows/pull-request.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,5 @@ jobs:
167167
airgap-license-id: ${{ secrets.STAGING_EMBEDDED_CLUSTER_AIRGAP_LICENSE_ID }}
168168
license-id: ${{ secrets.STAGING_EMBEDDED_CLUSTER_LICENSE_ID }}
169169
license: ${{ secrets.STAGING_EMBEDDED_CLUSTER_LICENSE }}
170+
testim-access-token: ${{ secrets.TESTIM_ACCESS_TOKEN }}
171+
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }}

.github/workflows/release-dev.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,5 @@ jobs:
144144
airgap-license-id: ${{ secrets.STAGING_EMBEDDED_CLUSTER_AIRGAP_LICENSE_ID }}
145145
license-id: ${{ secrets.STAGING_EMBEDDED_CLUSTER_LICENSE_ID }}
146146
license: ${{ secrets.STAGING_EMBEDDED_CLUSTER_LICENSE }}
147+
testim-access-token: ${{ secrets.TESTIM_ACCESS_TOKEN }}
148+
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }}

e2e/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,21 @@ https://vendor.staging.replicated.com/apps/embedded-cluster-smoke-test-staging-a
6666
Make sure to update the application yaml files under kots-release-onmerge
6767
and kots-release-onpr directories if you create a new release of the remote
6868
application.
69+
70+
### Testim
71+
72+
We use [Testim](https://www.testim.io/) to run end to end tests on the UI. The tests live within the
73+
"Embedded Cluster" Testim project.
74+
75+
When a git branch is pushed to GitHub, a cooresponding branch is created in
76+
Testim. The on-PR tests will run against the matching branch in Testim, so if you need
77+
to make changes to the tests as part of your PR, you should make those updates in your
78+
Testim branch.
79+
80+
When a PR is merged, the on-merge tests will run against the master branch in Testim.
81+
If you have made changes to the tests in your Testim branch, you should merge those changes
82+
to the master branch in Testim when merging your PR. Similarly, if you rebase your git
83+
branch from main, you may need to "rebase" your Testim branch (merge changes from master)
84+
if there have been changes to the tests.
85+
86+
For more details on version control in Testim, refer to the [Testim documentation](https://help.testim.io/docs/version-control-branches).

e2e/install_test.go

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package e2e
22

33
import (
4-
"encoding/json"
54
"fmt"
65
"net/http"
76
"os"
@@ -12,15 +11,6 @@ import (
1211
"github.com/replicatedhq/embedded-cluster/e2e/cluster"
1312
)
1413

15-
type clusterStatusResponse struct {
16-
App string `json:"app"`
17-
Cluster string `json:"cluster"`
18-
}
19-
20-
type nodeJoinResponse struct {
21-
Command string `json:"command"`
22-
}
23-
2414
func TestSingleNodeInstallation(t *testing.T) {
2515
t.Parallel()
2616
tc := cluster.NewTestCluster(&cluster.Input{
@@ -37,7 +27,7 @@ func TestSingleNodeInstallation(t *testing.T) {
3727
t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err)
3828
}
3929

40-
runPuppeteerAppStatusCheck(t, 0, tc)
30+
installTestimAndDeploy(t, 0, tc)
4131

4232
t.Logf("%s: checking installation state after upgrade", time.Now().Format(time.RFC3339))
4333
line = []string{"check-postupgrade-state.sh", os.Getenv("SHORT_SHA")}
@@ -217,39 +207,35 @@ func TestMultiNodeInstallation(t *testing.T) {
217207
t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err)
218208
}
219209

220-
runPuppeteerAppStatusCheck(t, 0, tc)
210+
installTestimAndDeploy(t, 0, tc)
221211

222212
// generate all node join commands (2 for controllers and 1 for worker).
223213
t.Logf("%s: generating two new controller token commands", time.Now().Format(time.RFC3339))
224214
controllerCommands := []string{}
225215
for i := 0; i < 2; i++ {
226-
line := []string{"puppeteer.sh", "generate-controller-join-token.js", "10.0.0.2"}
216+
line := []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "get-join-controller-command"}
227217
stdout, stderr, err := RunCommandOnNode(t, tc, 0, line)
228218
if err != nil {
229-
t.Fatalf("fail to generate controller join token: %s", stdout)
219+
t.Fatalf("fail to generate controller join token:\nstdout: %s\nstderr: %s", stdout, stderr)
230220
}
231-
var r nodeJoinResponse
232-
if err := json.Unmarshal([]byte(stdout), &r); err != nil {
233-
t.Logf("stdout: %s\nstderr: %s", stdout, stderr)
234-
t.Fatalf("fail to parse script response: %v", err)
221+
command, err := findJoinCommandInOutput(stdout)
222+
if err != nil {
223+
t.Fatalf("fail to find the join command in the output: %v", err)
235224
}
236-
// trim down the "./" and the "sudo" command as those are not needed. we run as
237-
// root and the embedded-cluster binary is on the PATH.
238-
command := strings.TrimPrefix(r.Command, "sudo ./")
239225
controllerCommands = append(controllerCommands, command)
240226
t.Log("controller join token command:", command)
241227
}
242228
t.Logf("%s: generating a new worker token command", time.Now().Format(time.RFC3339))
243-
line := []string{"puppeteer.sh", "generate-worker-join-token.js", "10.0.0.2"}
229+
line := []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "get-join-worker-command"}
244230
stdout, stderr, err := RunCommandOnNode(t, tc, 0, line)
245231
if err != nil {
246-
t.Fatalf("fail to generate controller join token: %s", stdout)
232+
t.Fatalf("fail to generate controller join token:\nstdout: %s\nstderr: %s", stdout, stderr)
247233
}
248-
var jr nodeJoinResponse
249-
if err := json.Unmarshal([]byte(stdout), &jr); err != nil {
250-
t.Logf("stdout: %s\nstderr: %s", stdout, stderr)
251-
t.Fatalf("fail to parse script response: %v", err)
234+
command, err := findJoinCommandInOutput(stdout)
235+
if err != nil {
236+
t.Fatalf("fail to find the join command in the output: %v", err)
252237
}
238+
t.Log("worker join token command:", command)
253239

254240
// join the nodes.
255241
for i, cmd := range controllerCommands {
@@ -267,8 +253,6 @@ func TestMultiNodeInstallation(t *testing.T) {
267253
t.Logf("node %d joined, sleeping...", node)
268254
time.Sleep(30 * time.Second)
269255
}
270-
command := strings.TrimPrefix(jr.Command, "sudo ./")
271-
t.Log("worker join token command:", command)
272256
t.Logf("%s: joining node 3 to the cluster as a worker", time.Now().Format(time.RFC3339))
273257
if _, _, err := RunCommandOnNode(t, tc, 3, strings.Split(command, " ")); err != nil {
274258
t.Fatalf("fail to join node 3 to the cluster as a worker: %v", err)
@@ -479,14 +463,15 @@ func TestSingleNodeAirgapInstallationUbuntuJammy(t *testing.T) {
479463
t.Logf("%s: test complete", time.Now().Format(time.RFC3339))
480464
}
481465

482-
func runPuppeteerAppStatusCheck(t *testing.T, node int, tc *cluster.Output) {
483-
t.Logf("%s: installing puppeteer on node %d", time.Now().Format(time.RFC3339), node)
484-
line := []string{"install-puppeteer.sh"}
466+
func installTestimAndDeploy(t *testing.T, node int, tc *cluster.Output) {
467+
t.Logf("%s: installing testim on node %d", time.Now().Format(time.RFC3339), node)
468+
line := []string{"install-testim.sh"}
485469
if _, _, err := RunCommandOnNode(t, tc, 0, line); err != nil {
486-
t.Fatalf("fail to install puppeteer on node %s: %v", tc.Nodes[0], err)
470+
t.Fatalf("fail to install testim on node %s: %v", tc.Nodes[0], err)
487471
}
472+
488473
t.Logf("%s: accessing kotsadm interface and deploying app", time.Now().Format(time.RFC3339))
489-
line = []string{"puppeteer.sh", "deploy-kots-application.js", "10.0.0.2"}
474+
line = []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "deploy-kots-application"}
490475
if _, _, err := RunCommandOnNode(t, tc, 0, line); err != nil {
491476
t.Fatalf("fail to access kotsadm interface and state: %v", err)
492477
}

e2e/reset_test.go

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package e2e
22

33
import (
4-
"encoding/json"
4+
"os"
55
"strings"
66
"testing"
77
"time"
@@ -28,39 +28,35 @@ func TestMultiNodeReset(t *testing.T) {
2828
t.Fatalf("fail to install embedded-cluster on node %s: %v", tc.Nodes[0], err)
2929
}
3030

31-
runPuppeteerAppStatusCheck(t, 0, tc)
31+
installTestimAndDeploy(t, 0, tc)
3232

3333
// generate all node join commands (2 for controllers and 1 for worker).
3434
t.Logf("%s: generating two new controller token commands", time.Now().Format(time.RFC3339))
3535
controllerCommands := []string{}
3636
for i := 0; i < 2; i++ {
37-
line := []string{"puppeteer.sh", "generate-controller-join-token.js", "10.0.0.2"}
37+
line := []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "get-join-controller-command"}
3838
stdout, stderr, err := RunCommandOnNode(t, tc, 0, line)
3939
if err != nil {
40-
t.Fatalf("fail to generate controller join token: %s", stdout)
40+
t.Fatalf("fail to generate controller join token:\nstdout: %s\nstderr: %s", stdout, stderr)
4141
}
42-
var r nodeJoinResponse
43-
if err := json.Unmarshal([]byte(stdout), &r); err != nil {
44-
t.Logf("stdout: %s\nstderr: %s", stdout, stderr)
45-
t.Fatalf("fail to parse script response: %v", err)
42+
command, err := findJoinCommandInOutput(stdout)
43+
if err != nil {
44+
t.Fatalf("fail to find the join command in the output: %v", err)
4645
}
47-
// trim down the "./" and the "sudo" command as those are not needed. we run as
48-
// root and the embedded-cluster binary is on the PATH.
49-
command := strings.TrimPrefix(r.Command, "sudo ./")
5046
controllerCommands = append(controllerCommands, command)
5147
t.Log("controller join token command:", command)
5248
}
5349
t.Logf("%s: generating a new worker token command", time.Now().Format(time.RFC3339))
54-
line := []string{"puppeteer.sh", "generate-worker-join-token.js", "10.0.0.2"}
50+
line := []string{"testim.sh", os.Getenv("TESTIM_ACCESS_TOKEN"), os.Getenv("TESTIM_BRANCH"), "get-join-worker-command"}
5551
stdout, stderr, err := RunCommandOnNode(t, tc, 0, line)
5652
if err != nil {
57-
t.Fatalf("fail to generate controller join token: %s", stdout)
53+
t.Fatalf("fail to generate worker join token:\nstdout: %s\nstderr: %s", stdout, stderr)
5854
}
59-
var jr nodeJoinResponse
60-
if err := json.Unmarshal([]byte(stdout), &jr); err != nil {
61-
t.Logf("stdout: %s\nstderr: %s", stdout, stderr)
62-
t.Fatalf("fail to parse script response: %v", err)
55+
command, err := findJoinCommandInOutput(stdout)
56+
if err != nil {
57+
t.Fatalf("fail to find the join command in the output: %v", err)
6358
}
59+
t.Log("worker join token command:", command)
6460

6561
// join the nodes.
6662
for i, cmd := range controllerCommands {
@@ -78,8 +74,6 @@ func TestMultiNodeReset(t *testing.T) {
7874
t.Logf("node %d joined, sleeping...", node)
7975
time.Sleep(30 * time.Second)
8076
}
81-
command := strings.TrimPrefix(jr.Command, "sudo ./")
82-
t.Log("worker join token command:", command)
8377
t.Logf("%s: joining node 3 to the cluster as a worker", time.Now().Format(time.RFC3339))
8478
if _, _, err := RunCommandOnNode(t, tc, 3, strings.Split(command, " ")); err != nil {
8579
t.Fatalf("fail to join node 3 to the cluster as a worker: %v", err)

0 commit comments

Comments
 (0)