From 2aeacd7d14d51abe556590927f6cb9afefc5c3e6 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 25 Apr 2023 20:16:26 +0200 Subject: [PATCH] ci: create playwright tests workflow ci: make db and redis as github action services --- .github/workflows/ci.yml | 4 +- .github/workflows/playwright.yml | 59 +++++++++++++++++++++++++ docker-compose.e2e.yml | 6 +-- docker-compose.test.yml | 2 + e2e/0001-register.spec.ts | 7 ++- e2e/0003-apps.spec.ts | 2 +- e2e/helpers/db.ts | 2 +- e2e/helpers/global-setup.ts | 3 ++ package.json | 8 ++-- pnpm-lock.yaml | 25 +++++++---- scripts/start-dev.sh | 3 +- scripts/start-prod.sh | 74 ++++++++++++++++++++++++++++++++ 12 files changed, 171 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/playwright.yml create mode 100755 scripts/start-prod.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 444da65d..fdb5b7c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,13 +36,13 @@ jobs: - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - uses: pnpm/action-setup@v2.2.4 name: Install pnpm id: pnpm-install with: - version: 7 + version: 8 run_install: false - name: Get pnpm store directory diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 00000000..5d7274d6 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,59 @@ +name: Playwright Tests +on: + push: + branches: [develop, master, test/e2e-playwright] + pull_request: + branches: [develop, master] + +jobs: + e2e: + timeout-minutes: 60 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + + - uses: pnpm/action-setup@v2.2.2 + name: Install pnpm + id: pnpm-install + with: + version: 8 + run_install: false + + - name: Install fswatch + run: sudo apt-get update && sudo apt-get install fswatch + + - name: Get pnpm store directory + id: pnpm-cache + run: | + echo "::set-output name=pnpm_cache_dir::$(pnpm store path)" + + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install + + - name: Install Playwright Browsers + run: npx playwright install --with-deps + + - name: Build and run the app + run: npm run start:e2e + + - name: Run Playwright tests + run: npm run test:e2e + + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/docker-compose.e2e.yml b/docker-compose.e2e.yml index afdc8731..52c6becb 100644 --- a/docker-compose.e2e.yml +++ b/docker-compose.e2e.yml @@ -6,8 +6,8 @@ services: image: traefik:v2.8 restart: unless-stopped ports: - - 8080:8080 - ${NGINX_PORT-80}:80 + - ${NGINX_PORT_SSL-443}:443 command: --providers.docker volumes: - /var/run/docker.sock:/var/run/docker.sock:ro @@ -25,8 +25,8 @@ services: - 5432:5432 environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_USER: ${POSTGRES_USERNAME} - POSTGRES_DB: ${POSTGRES_DBNAME} + POSTGRES_USER: tipi + POSTGRES_DB: tipi healthcheck: test: ['CMD-SHELL', 'pg_isready -d tipi -U tipi'] interval: 5s diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 546be642..2923e1d1 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -21,6 +21,8 @@ services: image: postgres:14 restart: unless-stopped stop_grace_period: 1m + ports: + - 5432:5432 volumes: - pgdata:/var/lib/postgresql/data environment: diff --git a/e2e/0001-register.spec.ts b/e2e/0001-register.spec.ts index 37cccad8..a17e9d52 100644 --- a/e2e/0001-register.spec.ts +++ b/e2e/0001-register.spec.ts @@ -3,8 +3,11 @@ import { test, expect } from '@playwright/test'; import { testUser } from './helpers/constants'; import { clearDatabase } from './helpers/db'; -test('user should be redirected to /register', async ({ page }) => { +test.beforeEach(async () => { await clearDatabase(); +}); + +test('user should be redirected to /register', async ({ page }) => { await page.goto('/'); await page.waitForURL(/register/); @@ -18,7 +21,7 @@ test('user can register a new account', async ({ page }) => { await page.getByPlaceholder('you@example.com').click(); await page.getByPlaceholder('you@example.com').fill(testUser.email); - await page.getByPlaceholder('Your password', { exact: true }).fill(testUser.password); + await page.getByPlaceholder('Enter your password', { exact: true }).fill(testUser.password); await page.getByPlaceholder('Confirm your password').fill(testUser.password); await page.getByRole('button', { name: 'Register' }).click(); diff --git a/e2e/0003-apps.spec.ts b/e2e/0003-apps.spec.ts index c33871c3..6a69ff6b 100644 --- a/e2e/0003-apps.spec.ts +++ b/e2e/0003-apps.spec.ts @@ -42,7 +42,7 @@ test('user can install and uninstall app', async ({ page, context }) => { // Uninstall app await page.getByRole('button', { name: 'Remove' }).click(); - await expect(page.getByText('Uninstall Hello World ?')).toBeVisible(); + await expect(page.getByText('Uninstall Hello World?')).toBeVisible(); await page.getByRole('button', { name: 'Uninstall' }).click(); diff --git a/e2e/helpers/db.ts b/e2e/helpers/db.ts index e8d2a44a..b19ace0d 100644 --- a/e2e/helpers/db.ts +++ b/e2e/helpers/db.ts @@ -4,7 +4,7 @@ import { getConfig } from '../../src/server/core/TipiConfig'; export const clearDatabase = async () => { const pgClient = new pg.Client({ user: getConfig().postgresUsername, - host: 'localhost', + host: '127.0.0.1', database: getConfig().postgresDatabase, password: getConfig().postgresPassword, port: getConfig().postgresPort, diff --git a/e2e/helpers/global-setup.ts b/e2e/helpers/global-setup.ts index 0d102d5d..e70b8c69 100644 --- a/e2e/helpers/global-setup.ts +++ b/e2e/helpers/global-setup.ts @@ -1,7 +1,10 @@ +import { clearDatabase } from './db'; + /** * */ async function globalSetup() { + await clearDatabase(); console.log('Global setup...'); } diff --git a/package.json b/package.json index b45b8010..cb2a80c4 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,8 @@ "scripts": { "copy:migrations": "mkdir -p dist/migrations && cp -r ./src/server/migrations dist", "test": "dotenv -e .env.test -- jest --colors", - "test:e2e": "NODE_ENV=test dotenv -e .env.e2e -- playwright test", - "test:e2e:ui": "NODE_ENV=test dotenv -e .env.e2e -- playwright test --ui", + "test:e2e": "NODE_ENV=test dotenv -e .env -- playwright test", + "test:e2e:ui": "NODE_ENV=test dotenv -e .env -- playwright test --ui", "test:client": "jest --colors --selectProjects client --", "test:server": "jest --colors --selectProjects server --", "dev": "npm run copy:migrations && nodemon", @@ -16,10 +16,10 @@ "build": "npm run copy:migrations && node ./esbuild.js build", "build:server": "node ./esbuild.js build", "build:next": "next build", - "start:dev": "./scripts/start-dev.sh", "start:dev-container": "./.devcontainer/filewatcher.sh && npm run start:dev", "start:rc": "docker-compose -f docker-compose.rc.yml --env-file .env up --build", - "start:prod": "docker-compose -f docker-compose.test.yml --env-file .env up --build", + "start:dev": "./scripts/start-dev.sh", + "start:prod": "./scripts/start-prod.sh", "start:e2e": "./scripts/start-e2e.sh", "start:pg": "docker run --name test-db -p 5433:5432 -d --rm -e POSTGRES_PASSWORD=postgres postgres:14", "version": "echo $npm_package_version", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ba2a1250..55639293 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -171,8 +171,11 @@ devDependencies: '@faker-js/faker': specifier: ^8.0.1 version: 8.0.1 + '@playwright/test': + specifier: ^1.32.3 + version: 1.32.3 '@testing-library/dom': - specifier: ^9.3.0 + specifier: ^9.0.1 version: 9.3.0 '@testing-library/jest-dom': specifier: ^5.16.5 @@ -350,13 +353,6 @@ packages: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.17 - /@babel/code-frame@7.18.6: - resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.18.6 - dev: true - /@babel/code-frame@7.21.4: resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} engines: {node: '>=6.9.0'} @@ -1617,6 +1613,17 @@ packages: tslib: 2.5.2 dev: true + /@playwright/test@1.32.3: + resolution: {integrity: sha512-BvWNvK0RfBriindxhLVabi8BRe3X0J9EVjKlcmhxjg4giWBD/xleLcg2dz7Tx0agu28rczjNIPQWznwzDwVsZQ==} + engines: {node: '>=14'} + hasBin: true + dependencies: + '@types/node': 20.2.1 + playwright-core: 1.32.3 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /@popperjs/core@2.11.7: resolution: {integrity: sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==} dev: false @@ -2228,7 +2235,7 @@ packages: resolution: {integrity: sha512-Dffe68pGwI6WlLRYR2I0piIkyole9cSBH5jGQKCGMRpHW5RHCqAUaqc2Kv0tUyd4dU4DLPKhJIjyKOnjv4tuUw==} engines: {node: '>=14'} dependencies: - '@babel/code-frame': 7.18.6 + '@babel/code-frame': 7.21.4 '@babel/runtime': 7.20.13 '@types/aria-query': 5.0.1 aria-query: 5.1.3 diff --git a/scripts/start-dev.sh b/scripts/start-dev.sh index 48c497ec..1796f4ba 100755 --- a/scripts/start-dev.sh +++ b/scripts/start-dev.sh @@ -40,12 +40,11 @@ env_variables_json=$(cat <"${ROOT_FOLDER}/state/system-info.json" +fi + +chmod -R a+rwx "${ROOT_FOLDER}/state/events" +chmod -R a+rwx "${ROOT_FOLDER}/state/system-info.json" +kill_watcher +"${ROOT_FOLDER}/scripts/watcher.sh" & + +### -------------------------------- +### env file generation +### -------------------------------- +generate_env_file "${env_variables_json}" + +### -------------------------------- +### Start the project +### -------------------------------- +docker compose -f docker-compose.test.yml up --build