Skip to content

Commit d3184c1

Browse files
Miguel7373Manuel
andauthored
test(e2e): Add E2E test setup #12
* feat(frontend): Add e2e test setup and write a example test #12 * test(e2e): Add page model with abstraction for more reuseability in the future #12 * docs(frontend): Add troubleshooting steps for e2e tests #12 * ci(frontend): Use newest node setup version and rename file to have .yaml ending #12 --------- Co-authored-by: Manuel <moeri@puzzle.ch>
1 parent 5189856 commit d3184c1

24 files changed

Lines changed: 1746 additions & 111 deletions

.github/workflows/on-push.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
name: "On push"
3+
4+
on:
5+
push:
6+
7+
jobs:
8+
format:
9+
uses: ./.github/workflows/reusable__format.yaml
10+
with:
11+
COMMIT_HASH: ${{ github.sha }}
12+
13+
tests:
14+
uses: ./.github/workflows/reusable__tests.yaml
15+
with:
16+
COMMIT_HASH: ${{ github.sha }}
17+
18+
e2e-tests:
19+
needs:
20+
- format
21+
- tests
22+
uses: ./.github/workflows/reusable__e2e-testing.yaml
23+
with:
24+
COMMIT_HASH: ${{ github.sha }}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
name: 'Reusable - Run E2E Tests (Matrix)'
3+
4+
on:
5+
workflow_call:
6+
inputs:
7+
DOCKER_IMAGE_TAG:
8+
type: string
9+
description: 'The full Docker image tag being tested'
10+
required: false
11+
COMMIT_HASH:
12+
type: string
13+
description: 'The commit hash from which to check out the repository'
14+
required: false
15+
16+
jobs:
17+
get-e2e-files:
18+
runs-on: ubuntu-latest
19+
outputs:
20+
file_list: ${{ steps.generate-file-list.outputs.file_list }}
21+
steps:
22+
- name: Checkout Target Repo Code (to find test files)
23+
uses: actions/checkout@v5
24+
with:
25+
ref: ${{ inputs.COMMIT_HASH }}
26+
27+
- name: Install jq (JSON processor)
28+
run: sudo apt-get update && sudo apt-get install -y jq
29+
30+
- name: Generate list of E2E test files
31+
id: generate-file-list
32+
env:
33+
E2E_DIR: frontend/cypress/e2e
34+
run: |
35+
if [ -d "$E2E_DIR" ] && [ "$(ls -A $E2E_DIR)" ]; then
36+
FILES=$(ls $E2E_DIR | jq -R . | jq -s . | jq -c)
37+
echo "Found test files: $FILES"
38+
else
39+
echo "No test files found in $E2E_DIR or directory does not exist."
40+
FILES="[]"
41+
fi
42+
echo "file_list=$FILES" >> $GITHUB_OUTPUT
43+
44+
e2e:
45+
needs: get-e2e-files
46+
runs-on: ubuntu-24.04
47+
strategy:
48+
fail-fast: false
49+
matrix:
50+
file: ${{ fromJSON(needs.get-e2e-files.outputs.file_list) }}
51+
env:
52+
BRANCH_NAME: ${{ github.ref_name || github.base_ref }}
53+
COMMIT_REF: ${{ inputs.COMMIT_HASH || github.ref_name }}
54+
55+
steps:
56+
- name: Checkout repo
57+
uses: actions/checkout@v5
58+
with:
59+
ref: ${{ env.COMMIT_REF }}
60+
61+
- name: Start application stack with Docker Compose
62+
run: cd docker && docker compose -f docker-compose.yml -f docker-compose.e2e.yml up -d
63+
64+
- name: Set up node for Cypress
65+
uses: actions/setup-node@v5
66+
with:
67+
node-version: ${{ vars.NODE_VERSION }}
68+
69+
- name: Cypress run e2e tests
70+
uses: cypress-io/github-action@v6
71+
with:
72+
working-directory: frontend
73+
install: true
74+
wait-on: 'http://localhost:4200/'
75+
wait-on-timeout: 300
76+
browser: chrome
77+
headed: false
78+
config: baseUrl=http://localhost:4200/
79+
spec: cypress/e2e/${{ matrix.file }}
80+
81+
- uses: actions/upload-artifact@v4
82+
if: always()
83+
with:
84+
name: cypress-screenshots for ${{ matrix.file }}
85+
path: frontend/cypress/screenshots
Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
---
2-
name: 'Format'
2+
name: "Reusable - Format"
33

4-
on: [push]
5-
jobs:
4+
on:
5+
workflow_call:
6+
inputs:
7+
COMMIT_HASH:
8+
type: string
9+
required: false
610

11+
jobs:
712
backend:
813
runs-on: ubuntu-24.04
914
defaults:
@@ -12,14 +17,16 @@ jobs:
1217
steps:
1318
- name: Checkout
1419
uses: actions/checkout@v5
20+
with:
21+
ref: ${{ inputs.COMMIT_HASH }}
1522

16-
- name: Set up JDK ${{vars.JAVA_VERSION}}
23+
- name: Set up JDK ${{ vars.JAVA_VERSION }}
1724
uses: actions/setup-java@v5
1825
with:
19-
java-version: ${{vars.JAVA_VERSION}}
20-
distribution: 'adopt'
26+
java-version: ${{ vars.JAVA_VERSION }}
27+
distribution: adopt
2128
server-id: github
22-
settings-path: ${{github.workspace}}
29+
settings-path: ${{ github.workspace }}
2330

2431
- name: Format backend
2532
run: mvn spotless:check
@@ -32,11 +39,13 @@ jobs:
3239
steps:
3340
- name: Checkout
3441
uses: actions/checkout@v5
42+
with:
43+
ref: ${{ inputs.COMMIT_HASH }}
3544

3645
- name: Setup Node.js
3746
uses: actions/setup-node@v5
3847
with:
39-
node-version: ${{vars.NODE_VERSION}}
48+
node-version: ${{ vars.NODE_VERSION }}
4049

4150
- name: Npm install
4251
run: npm ci
@@ -52,6 +61,8 @@ jobs:
5261
steps:
5362
- name: Checkout
5463
uses: actions/checkout@v5
64+
with:
65+
ref: ${{ inputs.COMMIT_HASH }}
5566

5667
- name: Install Ruby
5768
run: sudo apt-get install ruby-full
@@ -72,9 +83,11 @@ jobs:
7283
steps:
7384
- name: Checkout
7485
uses: actions/checkout@v5
86+
with:
87+
ref: ${{ inputs.COMMIT_HASH }}
7588

7689
- name: Install yamllint
77-
run: sudo apt-get install yamllint
90+
run: sudo apt-get install -y yamllint
7891

7992
- name: yaml linting
8093
run: yamllint .
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
---
2-
name: 'Tests'
2+
name: "Reusable - Tests"
33

44
on:
5-
push:
5+
workflow_call:
6+
inputs:
7+
COMMIT_HASH:
8+
type: string
9+
required: false
610

711
jobs:
812
frontend-tests:
@@ -13,17 +17,20 @@ jobs:
1317
steps:
1418
- name: Checkout
1519
uses: actions/checkout@v5
20+
with:
21+
ref: ${{ inputs.COMMIT_HASH || github.head_ref }}
1622

1723
- name: Setup Node.js
1824
uses: actions/setup-node@v5
1925
with:
20-
node-version: ${{vars.NODE_VERSION}}
26+
node-version: ${{ vars.NODE_VERSION }}
2127

2228
- name: Npm install
2329
run: npm ci
2430

2531
- name: Run unit tests
2632
run: npm test
33+
2734
backend-tests:
2835
runs-on: ubuntu-24.04
2936
defaults:
@@ -32,12 +39,14 @@ jobs:
3239
steps:
3340
- name: Checkout
3441
uses: actions/checkout@v5
42+
with:
43+
ref: ${{ inputs.COMMIT_HASH || github.head_ref }}
3544

36-
- name: Set up JDK ${{vars.JAVA_VERSION}}
45+
- name: Set up JDK ${{ vars.JAVA_VERSION }}
3746
uses: actions/setup-java@v5
3847
with:
39-
java-version: ${{vars.JAVA_VERSION}}
40-
distribution: 'adopt'
48+
java-version: ${{ vars.JAVA_VERSION }}
49+
distribution: adopt
4150

4251
- name: Use Maven to run unit and integration tests
4352
run: mvn clean verify
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
spring.application.name=PCTS
2+
3+
spring.datasource.url=jdbc:postgresql://pcts-db:5432/pcts
4+
spring.datasource.username=user
5+
spring.datasource.password=pwd
6+
spring.datasource.driver-class-name=org.postgresql.Driver
7+
8+
#Flyway
9+
spring.flyway.locations=classpath:db/migration,classpath:db/e2e-data-migration
10+
spring.flyway.schemas=public
11+
12+
springdoc.api-docs.enabled=true

backend/src/test/java/ch/puzzle/pcts/controller/RoleControllerIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void shouldGetRoleById() throws Exception {
9292
.andExpect(jsonPath("$.isManagement").value(false))
9393
.andExpect(jsonPath("$.name").value("Role 1"));
9494

95-
verify(service, times(1)).getById(eq(1L));
95+
verify(service, times(1)).getById((1L));
9696
verify(mapper, times(1)).toDto(any(Role.class));
9797
}
9898

backend/src/test/java/ch/puzzle/pcts/service/persistence/RolePersistenceServiceIT.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ void shouldEstablishConnection() {
4949
void shouldGetRoleById() {
5050
Optional<Role> role = persistenceService.getById(2L);
5151

52-
assertThat(role.isPresent()).isTrue();
52+
assertThat(role).isPresent();
5353
assertThat(role.get().getId()).isEqualTo(2L);
5454
}
5555

@@ -88,10 +88,10 @@ void shouldUpdate() {
8888
persistenceService.update(id, role);
8989
Optional<Role> result = persistenceService.getById(id);
9090

91-
assertThat(result.isPresent()).isTrue();
91+
assertThat(result).isPresent();
9292
assertThat(result.get().getId()).isEqualTo(id);
9393
assertThat(role.getName()).isEqualTo("Updated role");
94-
assertThat(role.getIsManagement()).isEqualTo(true);
94+
assertThat(role.getIsManagement()).isTrue();
9595
}
9696

9797
@DisplayName("Should delete role")
@@ -104,6 +104,6 @@ void shouldDelete() {
104104
persistenceService.delete(id);
105105

106106
Optional<Role> result = persistenceService.getById(id);
107-
assertThat(result.isPresent()).isFalse();
107+
assertThat(result).isNotPresent();
108108
}
109109
}

docker/docker-compose.e2e.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
services:
3+
pcts-backend:
4+
container_name: pcts-e2e-backend
5+
environment:
6+
SPRING_PROFILE: e2e-test

docker/docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ services:
2222
PCTS_SPRING_DATASOURCE_URL: pcts-db
2323
SPRING_PROFILE: dev
2424
profiles: ['', backend]
25+
2526
pcts-frontend:
2627
container_name: pcts-frontend
2728
build:

docker/e2e-application-start

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
git_base_path=$(git rev-parse --show-toplevel)
3+
4+
echo "**Changing into the docker directory**"
5+
cd "$git_base_path"/docker
6+
7+
echo "**Merging and running the docker-compose file**"
8+
echo "----------------------------------------------------------------"
9+
docker compose -f docker-compose.yml -f docker-compose.e2e.yml up
10+
11+
echo "**Stopping the docker containers**"
12+
trap 'docker compose down' EXIT

0 commit comments

Comments
 (0)