Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4245 - E2E Testing framework and test runner in Github Actions #4246

Open
wants to merge 46 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
2e38cfb
4245 - dont start reporter server
Jan 24, 2025
2f07f8c
4245 - run tests inside container
Jan 24, 2025
9000403
4245 - partial-backup: support excluding schemas and tables outside s…
Jan 24, 2025
ec8b132
Merge branch 'development' of github.com:openforis/fra-platform into …
Jan 24, 2025
10031e6
4245 - workflow: test: partial db copy
Jan 24, 2025
3af2082
4245 - workflow: test: cleanup
Jan 24, 2025
4304cd1
4245 - Dockerfile.playwright remove unnecessary ls
Jan 24, 2025
3f797b0
4245 - debug
Jan 24, 2025
b70d598
4245 - use exact name
Jan 24, 2025
7a9c61f
4245 - Disable whisper
Jan 24, 2025
1134e7e
Merge branch 'development' of github.com:openforis/fra-platform into …
Jan 27, 2025
5220022
4245 - Google authentication env var placeholder
Jan 27, 2025
75cc78c
4245 - token_secret env var placeholder
Jan 27, 2025
fb103e6
4245 - Remove unknown opt
Jan 27, 2025
e6d5e04
4245 - Disable tmate
Jan 27, 2025
3d71634
4245 - use latest cycle
Jan 27, 2025
4ac0126
4245 - Mount test results folder and upload artifact
Jan 27, 2025
50d89bb
debug
Jan 27, 2025
2bf1825
4245 - Zipped results and one drive db
Jan 27, 2025
4a0f7f4
4245 - Backup from s3
Jan 28, 2025
4ca5758
4245 - Fix failing title test
Jan 28, 2025
5345b18
4245 - Disable tmate
Jan 28, 2025
3ed3c00
4245 - add db caching
Jan 28, 2025
54bfe1f
Merge branch 'development' into 4245-use-docker-compose-for-ci-e2e
sorja Jan 28, 2025
bfa995c
4245 - Fix indentation
Jan 28, 2025
f9a5672
Merge branch '4245-use-docker-compose-for-ci-e2e' of github.com:openf…
Jan 28, 2025
c640837
Empty-Commit
Jan 28, 2025
ac50925
Empty-Commit
sorja Jan 28, 2025
cfba008
Merge branch 'development' into 4245-use-docker-compose-for-ci-e2e
mergify[bot] Jan 28, 2025
5208761
Merge branch 'development' into 4245-use-docker-compose-for-ci-e2e
mergify[bot] Jan 28, 2025
88405f5
Merge branch 'development' into 4245-use-docker-compose-for-ci-e2e
mergify[bot] Jan 29, 2025
b73b853
4245 - split CI workflows into build, test, and e2e
sorja Jan 29, 2025
e4ee133
4245 - separate unit and integration test configs
sorja Jan 29, 2025
0972240
4245 - run unit and integration tests parallel
sorja Jan 29, 2025
223984e
Merge branch '4245-use-docker-compose-for-ci-e2e' of github.com:openf…
sorja Jan 29, 2025
803a67c
4245 - remove deprecated workflow
sorja Jan 29, 2025
bcfdd28
4245 - fix typo
sorja Jan 29, 2025
0b1b562
4245 - Cache and parallel
sorja Jan 29, 2025
ee4a088
4245 - fix typo
sorja Jan 29, 2025
ea7e903
4245 - Remove separate build wf
sorja Jan 29, 2025
fa679f8
4245 - Fix typo
sorja Jan 29, 2025
4cb2f98
4245 - cache only db
sorja Jan 29, 2025
fa49967
4245 - run migrations
sorja Jan 29, 2025
2c93d06
4245 - default false
sorja Jan 29, 2025
b8c85b6
4245 - boolean
sorja Jan 29, 2025
6c88ad1
4245 - remove jest prefix
sorja Jan 29, 2025
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
91 changes: 91 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Run E2E Tests

on:
pull_request:
branches:
- 'development'
workflow_dispatch:
inputs:
force_refresh:
description: 'Force database refresh'
required: false
default: false
type: boolean

jobs:
tests:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_DEV }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEV }}
aws-region: eu-west-1

- name: Cache test database
id: cache-db
uses: actions/cache@v3
with:
path: ./db/backup
key: test-db-${{ runner.os }}-v1-${{ hashFiles('src/test/e2e/docker-compose.test.yml') }}
restore-keys: |
test-db-${{ runner.os }}-v1-
test-db-${{ runner.os }}-

- name: Download and decrypt test database
if: steps.cache-db.outputs.cache-hit != 'true' || ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.force_refresh == true }}
run: |
mkdir -p ./db
aws s3 cp s3://fra-platform-s3-developer-assets/test-assets/database/backup.gpg ./db/backup.gpg
./src/tools/heroku/decrypt.sh ./db/backup.gpg
env:
BACKUP_PASSPHRASE: ${{ secrets.BACKUP_PASSPHRASE }}

- name: Build and start containers
run: docker compose -f src/test/e2e/docker-compose.test.yml up -d
env:
NPM_GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}

- name: Wait for services to be ready
run: |
timeout 300 bash -c 'until docker compose -f src/test/e2e/docker-compose.test.yml ps web | grep -q "healthy"; do sleep 5; done'

- name: Create test results directory
run: mkdir -p playwright-report

- name: Run database migrations
run: docker compose -f src/test/e2e/docker-compose.test.yml exec -T web yarn migration-steps:run

- name: Run E2E tests
if: always()
run: |
docker compose -f src/test/e2e/docker-compose.test.yml run \
playwright npm run test:e2e
env:
NPM_GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}

- name: Zip test results
if: always()
run: |
cd src/test/e2e
zip -r ../../../playwright-results.zip test-results/

- name: Upload test results
if: always() && !env.ACT
uses: actions/upload-artifact@v4
with:
name: playwright-results
path: playwright-results.zip
retention-days: 30

- name: Stop containers
if: always()
run: docker compose -f src/test/e2e/docker-compose.test.yml down -v

- name: Cleanup database backup
if: always()
run: |
rm -rf ./db
86 changes: 0 additions & 86 deletions .github/workflows/test.js.yml

This file was deleted.

72 changes: 72 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Run Tests

minotogna marked this conversation as resolved.
Show resolved Hide resolved
on:
pull_request:
branches-ignore:
- 'master'
- 'production'
Comment on lines +6 to +7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we run this action on ALL branches, except development ?
What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean like so?

on:
  pull_request:
    branches-ignore:
      - 'development'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

workflow_dispatch:
inputs:
force_refresh:
description: 'Force database refresh'
required: false
default: false
type: boolean

jobs:
tests:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_DEV }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEV }}
aws-region: eu-west-1

- name: Cache test database
id: cache-db
uses: actions/cache@v3
with:
path: ./db/backup
key: test-db-${{ runner.os }}-v1-${{ hashFiles('src/test/e2e/docker-compose.test.yml') }}
restore-keys: |
test-db-${{ runner.os }}-v1-
test-db-${{ runner.os }}-

- name: Download and decrypt test database
if: steps.cache-db.outputs.cache-hit != 'true' || ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.force_refresh == 'true' }}
run: |
mkdir -p ./db
aws s3 cp s3://fra-platform-s3-developer-assets/test-assets/database/backup.gpg ./db/backup.gpg
./src/tools/heroku/decrypt.sh ./db/backup.gpg
env:
BACKUP_PASSPHRASE: ${{ secrets.BACKUP_PASSPHRASE }}

- name: Build and start containers
run: docker compose -f src/test/e2e/docker-compose.test.yml up -d
env:
NPM_GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}

- name: Wait for services to be ready
run: |
timeout 300 bash -c 'until docker compose -f src/test/e2e/docker-compose.test.yml ps web | grep -q "healthy"; do sleep 5; done'

- name: Run database migrations
run: docker compose -f src/test/e2e/docker-compose.test.yml exec -T web yarn migration-steps:run

- name: Run unit and integration tests
run: docker compose -f src/test/e2e/docker-compose.test.yml exec -T web yarn test
env:
NPM_GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}

- name: Stop containers
if: always()
run: docker compose -f src/test/e2e/docker-compose.test.yml down -v

- name: Cleanup database backup
if: always()
run: |
rm -rf ./db
2 changes: 0 additions & 2 deletions jest.config.js → jest.config.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,5 @@ module.exports = {
rootDir: 'src',
roots: ['<rootDir>'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testPathIgnorePatterns: ['/node_modules/'],
verbose: true,
}
7 changes: 7 additions & 0 deletions jest.config.integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const baseConfig = require('./jest.config.base')

module.exports = {
...baseConfig,
testMatch: ['**/integration.test.ts'],
}
minotogna marked this conversation as resolved.
Show resolved Hide resolved
8 changes: 8 additions & 0 deletions jest.config.unit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const baseConfig = require('./jest.config.base')

module.exports = {
...baseConfig,
testMatch: ['**/?(*.)+(test).ts'],
testPathIgnorePatterns: ['/node_modules/', '/dist/', '/src/test/integration/', '/src/test/e2e/'],
}
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@
"run:prod:server": "node dist/server/start",
"start": "run-s migration-public:run run:prod:server",
"//test": "mochapack --webpack-config webpack.config.babel.test.js",
"test": "run-s test:integration",
"test:integration": "yarn jest --no-cache --detectOpenHandles --setupFiles dotenv/config",
"test:e2e": "playwright test --config ./src/test/e2e/jest-playwright.config.ts",
"test:e2e:dev": "playwright test --config ./src/test/e2e/jest-playwright.config.local.ts --debug --headed --ui",
"test": "run-p test:unit test:integration",
"test:unit": "yarn jest --no-cache --detectOpenHandles --setupFiles dotenv/config --config jest.config.unit.js",
"test:integration": "yarn jest --no-cache --detectOpenHandles --setupFiles dotenv/config --config jest.config.integration.js src/test/integration/integration.test.ts",
minotogna marked this conversation as resolved.
Show resolved Hide resolved
"test:e2e": "playwright test --config ./src/test/e2e/playwright.config.ts",
"test:e2e:dev": "playwright test --config ./src/test/e2e/playwright.config.local.ts --debug --headed --ui",
"test:e2e:docker": "docker-compose -f src/test/e2e/docker-compose.test.yml up --build --exit-code-from playwright",
"test:watch": "yarn jest --no-cache --detectOpenHandles --watchAll --setupFiles dotenv/config",
"test:watch": "yarn jest --no-cache --detectOpenHandles --watchAll --setupFiles dotenv/config --config jest.config.unit.js",
"preversion": "git diff --quiet || { echo \"Working directory is dirty\"; exit 1; };",
"postversion": "git push --tags && echo \"Successfully released version $npm_package_version!\"",
"prepare": "husky install",
Expand Down Expand Up @@ -295,4 +296,4 @@
"prettier --write"
]
}
}
}
2 changes: 0 additions & 2 deletions src/test/e2e/Dockerfile.playwright
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ RUN yarn playwright install --with-deps chromium

COPY . .

RUN ls -la src/test/e2e

EXPOSE 9323

CMD ["yarn", "test:e2e"]
4 changes: 4 additions & 0 deletions src/test/e2e/docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ services:
- REDIS_QUEUE_URL=redis://redis-queue:6379
- REDIS_DATA_URL=redis://redis-data:6379
- PORT=9001
- WWWHISPER_DISABLE=true
- FRA_GOOGLE_CLIENT_ID=google-client-id
- FRA_GOOGLE_CLIENT_SECRET=goggle-client-secret
- TOKEN_SECRET=1234567890
ports:
- '9001:9001'
healthcheck:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PlaywrightTestConfig } from '@playwright/test'

import baseConfig from './jest-playwright.config'
import baseConfig from './playwright.config'

const config: PlaywrightTestConfig = {
...baseConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,7 @@ const config: PlaywrightTestConfig = {
},
],

reporter: [
['list'],
[
'html',
{
outputFolder: 'test-results',
port: 9323,
host: '0.0.0.0',
open: 'always', // Remove this or change to 'on-failure'
},
],
],
reporter: [['list'], ['html', { outputFolder: 'test-results', open: 'never' }]],
}

export default config
4 changes: 2 additions & 2 deletions src/test/e2e/tests/01-example.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { expect, test } from '@playwright/test'

test('homepage has title and links to intro page', async ({ page }) => {
await page.goto('/')

await expect(page).toHaveTitle(/FRA platform/, { timeout: 10000 })
const title = /FRA Platform | Global Forest Resources Data | Food and Agriculture Organization of the United Nations/
await expect(page).toHaveTitle(title, { timeout: 10000 })
const headerLogo = await page.getByRole('img', { name: 'FAO' })
await expect(headerLogo).toBeVisible()
const headerTitle = await page.getByText('Global Forest Resources Assessment').first()
Expand Down
6 changes: 3 additions & 3 deletions src/test/e2e/tests/03-login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'

test.describe('Login', () => {
test('should login with test user credentials', async ({ page }) => {
await page.goto('/assessments/fra/2025/login')
await page.goto('/assessments/fra/latest/login')

await page.click('button:has-text("Sign in with FRA")')

Expand All @@ -11,13 +11,13 @@ test.describe('Login', () => {

await page.click('button.btn:has-text("Login")')

await expect(page).toHaveURL('/assessments/fra/2025')
await expect(page).toHaveURL('/assessments/fra/latest')

await expect(page.getByText('Test User')).toBeVisible()
})

test('should show error with invalid credentials', async ({ page }) => {
await page.goto('/assessments/fra/2025/login')
await page.goto('/assessments/fra/latest/login')

await page.click('button:has-text("Sign in with FRA")')

Expand Down
Loading