Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/on-push.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: "On push"

on:
push:

jobs:
format:
uses: ./.github/workflows/reusable__format.yaml
with:
COMMIT_HASH: ${{ github.sha }}

tests:
uses: ./.github/workflows/reusable__tests.yaml
with:
COMMIT_HASH: ${{ github.sha }}

e2e-tests:
needs:
- format
- tests
uses: ./.github/workflows/reusable__e2e-testing.yaml
with:
COMMIT_HASH: ${{ github.sha }}
85 changes: 85 additions & 0 deletions .github/workflows/reusable__e2e-testing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
name: 'Reusable - Run E2E Tests (Matrix)'

on:
workflow_call:
inputs:
DOCKER_IMAGE_TAG:
type: string
description: 'The full Docker image tag being tested'
required: false
COMMIT_HASH:
type: string
description: 'The commit hash from which to check out the repository'
required: false

jobs:
get-e2e-files:
runs-on: ubuntu-latest
outputs:
file_list: ${{ steps.generate-file-list.outputs.file_list }}
steps:
- name: Checkout Target Repo Code (to find test files)
uses: actions/checkout@v5
with:
ref: ${{ inputs.COMMIT_HASH }}

- name: Install jq (JSON processor)
run: sudo apt-get update && sudo apt-get install -y jq

- name: Generate list of E2E test files
id: generate-file-list
env:
E2E_DIR: frontend/cypress/e2e
run: |
if [ -d "$E2E_DIR" ] && [ "$(ls -A $E2E_DIR)" ]; then
FILES=$(ls $E2E_DIR | jq -R . | jq -s . | jq -c)
echo "Found test files: $FILES"
else
echo "No test files found in $E2E_DIR or directory does not exist."
FILES="[]"
fi
echo "file_list=$FILES" >> $GITHUB_OUTPUT

e2e:
needs: get-e2e-files
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
file: ${{ fromJSON(needs.get-e2e-files.outputs.file_list) }}
env:
BRANCH_NAME: ${{ github.ref_name || github.base_ref }}
COMMIT_REF: ${{ inputs.COMMIT_HASH || github.ref_name }}

steps:
- name: Checkout repo
uses: actions/checkout@v5
with:
ref: ${{ env.COMMIT_REF }}

- name: Start application stack with Docker Compose
run: cd docker && docker compose -f docker-compose.yml -f docker-compose.e2e.yml up -d

- name: Set up node for Cypress
uses: actions/setup-node@v5
with:
node-version: ${{ vars.NODE_VERSION }}

- name: Cypress run e2e tests
uses: cypress-io/github-action@v6
with:
working-directory: frontend
install: true
wait-on: 'http://localhost:4200/'
wait-on-timeout: 300
browser: chrome
headed: false
config: baseUrl=http://localhost:4200/
spec: cypress/e2e/${{ matrix.file }}

- uses: actions/upload-artifact@v4
if: always()
with:
name: cypress-screenshots for ${{ matrix.file }}
path: frontend/cypress/screenshots
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
---
name: 'Format'
name: "Reusable - Format"

on: [push]
jobs:
on:
workflow_call:
inputs:
COMMIT_HASH:
type: string
required: false

jobs:
backend:
runs-on: ubuntu-24.04
defaults:
Expand All @@ -12,14 +17,16 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ inputs.COMMIT_HASH }}

- name: Set up JDK ${{vars.JAVA_VERSION}}
- name: Set up JDK ${{ vars.JAVA_VERSION }}
uses: actions/setup-java@v5
with:
java-version: ${{vars.JAVA_VERSION}}
distribution: 'adopt'
java-version: ${{ vars.JAVA_VERSION }}
distribution: adopt
server-id: github
settings-path: ${{github.workspace}}
settings-path: ${{ github.workspace }}

- name: Format backend
run: mvn spotless:check
Expand All @@ -32,11 +39,13 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ inputs.COMMIT_HASH }}

- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: ${{vars.NODE_VERSION}}
node-version: ${{ vars.NODE_VERSION }}

- name: Npm install
run: npm ci
Expand All @@ -52,6 +61,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ inputs.COMMIT_HASH }}

- name: Install Ruby
run: sudo apt-get install ruby-full
Expand All @@ -72,9 +83,11 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ inputs.COMMIT_HASH }}

- name: Install yamllint
run: sudo apt-get install yamllint
run: sudo apt-get install -y yamllint

- name: yaml linting
run: yamllint .
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
---
name: 'Tests'
name: "Reusable - Tests"

on:
push:
workflow_call:
inputs:
COMMIT_HASH:
type: string
required: false

jobs:
frontend-tests:
Expand All @@ -13,17 +17,20 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ inputs.COMMIT_HASH || github.head_ref }}

- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: ${{vars.NODE_VERSION}}
node-version: ${{ vars.NODE_VERSION }}

- name: Npm install
run: npm ci

- name: Run unit tests
run: npm test

backend-tests:
runs-on: ubuntu-24.04
defaults:
Expand All @@ -32,12 +39,14 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ inputs.COMMIT_HASH || github.head_ref }}

- name: Set up JDK ${{vars.JAVA_VERSION}}
- name: Set up JDK ${{ vars.JAVA_VERSION }}
uses: actions/setup-java@v5
with:
java-version: ${{vars.JAVA_VERSION}}
distribution: 'adopt'
java-version: ${{ vars.JAVA_VERSION }}
distribution: adopt

- name: Use Maven to run unit and integration tests
run: mvn clean verify
12 changes: 12 additions & 0 deletions backend/src/main/resources/application-e2e-test.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
spring.application.name=PCTS

spring.datasource.url=jdbc:postgresql://pcts-db:5432/pcts
spring.datasource.username=user
spring.datasource.password=pwd
spring.datasource.driver-class-name=org.postgresql.Driver

#Flyway
spring.flyway.locations=classpath:db/migration,classpath:db/e2e-data-migration
spring.flyway.schemas=public

springdoc.api-docs.enabled=true
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void shouldGetRoleById() throws Exception {
.andExpect(jsonPath("$.isManagement").value(false))
.andExpect(jsonPath("$.name").value("Role 1"));

verify(service, times(1)).getById(eq(1L));
verify(service, times(1)).getById((1L));
verify(mapper, times(1)).toDto(any(Role.class));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void shouldEstablishConnection() {
void shouldGetRoleById() {
Optional<Role> role = persistenceService.getById(2L);

assertThat(role.isPresent()).isTrue();
assertThat(role).isPresent();
assertThat(role.get().getId()).isEqualTo(2L);
}

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

assertThat(result.isPresent()).isTrue();
assertThat(result).isPresent();
assertThat(result.get().getId()).isEqualTo(id);
assertThat(role.getName()).isEqualTo("Updated role");
assertThat(role.getIsManagement()).isEqualTo(true);
assertThat(role.getIsManagement()).isTrue();
}

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

Optional<Role> result = persistenceService.getById(id);
assertThat(result.isPresent()).isFalse();
assertThat(result).isNotPresent();
}
}
6 changes: 6 additions & 0 deletions docker/docker-compose.e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
services:
pcts-backend:
container_name: pcts-e2e-backend
environment:
SPRING_PROFILE: e2e-test
1 change: 1 addition & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ services:
PCTS_SPRING_DATASOURCE_URL: pcts-db
SPRING_PROFILE: dev
profiles: ['', backend]

pcts-frontend:
container_name: pcts-frontend
build:
Expand Down
12 changes: 12 additions & 0 deletions docker/e2e-application-start
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
git_base_path=$(git rev-parse --show-toplevel)

echo "**Changing into the docker directory**"
cd "$git_base_path"/docker

echo "**Merging and running the docker-compose file**"
echo "----------------------------------------------------------------"
docker compose -f docker-compose.yml -f docker-compose.e2e.yml up

echo "**Stopping the docker containers**"
trap 'docker compose down' EXIT
27 changes: 22 additions & 5 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,30 @@ We use [Jest](https://jestjs.io/) for frontend testing.
npm run test
```

## Running end-to-end tests
## End-to-end tests

For end-to-end (e2e) testing, run:
We use [Cypress](https://www.cypress.io/) for running our end-to-end tests. Here is everything you need to know:

```bash
ng e2e
```
### Local setup

To run the backend for Cypress testing, you need to start the application with the correct Docker profile. To achieve this, make sure you're in the docker directory and execute this command: `./e2e-application-start`

### Running Tests

**To run all tests headless use:**

- `npm run cypress:run`

**To only run selected tests headfull use:**

- `npm run cypress:open`

### In case of failing tests

Comment thread
mmoeri marked this conversation as resolved.
- Make sure you do not have any additional or missing data in your database from a previous testrun
- Confirm that the application is healthy and running
- Restart the application and / or restart cypress
- Otherwise, check the logs

## Running formatters

Expand Down
17 changes: 17 additions & 0 deletions frontend/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defineConfig } from 'cypress';

export default defineConfig({
e2e: {
baseUrl: 'http://localhost:4200',
experimentalMemoryManagement: true,
testIsolation: true,
viewportWidth: 1920,
viewportHeight: 1080
},
retries: {
// Configure retry attempts for `cypress run`
runMode: 2,
// Configure retry attempts for `cypress open`
openMode: 0,
},
});
12 changes: 12 additions & 0 deletions frontend/cypress/e2e/example.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import HomePage from '../pages/homePage';

describe('example page', () => {
beforeEach(() => {
HomePage.visitDefaultPage();
});

it('should show html', () => {
cy.get('html')
.should('be.visible');
});
});
5 changes: 5 additions & 0 deletions frontend/cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
Loading
Loading