name: ocelot.social end-to-end test CI on: push: paths: - 'webapp/**' - 'backend/**' - 'neo4j/**' - 'cypress/**' - '.github/workflows/test-e2e.yml' jobs: build_images: name: Build Docker Images runs-on: ubuntu-latest strategy: matrix: include: - service: backend dockerfile: backend/Dockerfile context: backend target: build - service: webapp dockerfile: webapp/Dockerfile context: webapp target: build - service: neo4j dockerfile: neo4j/Dockerfile context: neo4j target: community steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - name: Build ${{ matrix.service }} image uses: docker/build-push-action@v5 with: context: ./${{ matrix.context }} file: ./${{ matrix.dockerfile }} target: ${{ matrix.target }} tags: ocelotsocialnetwork/${{ matrix.service }}:test push: false outputs: type=docker,dest=/tmp/${{ matrix.service }}.tar - name: Upload Docker image tarball uses: actions/upload-artifact@v4 with: name: ${{ matrix.service }}-image path: /tmp/${{ matrix.service }}.tar prepare_backend: name: Prepare backend runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - name: Generate backend cache key id: backend-key run: echo "key=node-modules-${{ runner.os }}-${{ hashFiles('backend/yarn.lock') }}" >> $GITHUB_OUTPUT - name: Cache backend node_modules uses: actions/cache@v4 with: path: backend/node_modules key: ${{ steps.backend-key.outputs.key }} restore-keys: | node-modules-${{ runner.os }}- node-modules- - name: Setup .env and backend deps run: | cp backend/.env.test_e2e backend/.env || touch backend/.env cd backend if [ ! -d "node_modules" ]; then yarn install; fi yarn build - name: Upload backend build uses: actions/upload-artifact@v4 with: name: backend-build path: backend/build prepare_webapp: name: Prepare webapp runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - name: Generate webapp cache key id: webapp-key run: echo "key=node-modules-${{ runner.os }}-${{ hashFiles('webapp/yarn.lock') }}" >> $GITHUB_OUTPUT - name: Cache webapp node_modules uses: actions/cache@v4 with: path: webapp/node_modules key: ${{ steps.webapp-key.outputs.key }} restore-keys: | node-modules-${{ runner.os }}- node-modules- - name: Setup .env and webapp deps run: | cp webapp/.env.template webapp/.env || touch webapp/.env if [ ! -d "webapp/node_modules" ]; then (cd webapp && yarn install || true); fi prepare_cypress: name: Prepare Cypress runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Generate cypress cache key id: cypress-key run: echo "key=cypress-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}" >> $GITHUB_OUTPUT - name: Cache cypress and dependencies uses: actions/cache@v4 with: path: | /opt/cucumber-json-formatter ~/.cache/Cypress node_modules backend/node_modules key: ${{ steps.cypress-key.outputs.key }} restore-keys: | cypress-${{ runner.os }}- cypress- - name: Copy env files run: | cp webapp/.env.template webapp/.env cp backend/.env.test_e2e backend/.env - name: Install cypress requirements run: | wget --no-verbose -O /opt/cucumber-json-formatter "https://github.com/cucumber/json-formatter/releases/download/v19.0.0/cucumber-json-formatter-linux-386" chmod +x /opt/cucumber-json-formatter cd backend && yarn install && yarn build && cd .. yarn install fullstack_tests: name: Run Fullstack E2E Tests needs: [build_images, prepare_backend, prepare_webapp, prepare_cypress] runs-on: ubuntu-latest env: jobs: 8 strategy: matrix: job: [1, 2, 3, 4, 5, 6, 7, 8] steps: - name: Restore node_modules cache uses: actions/cache@v4 with: path: | backend/node_modules webapp/node_modules key: node-modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} restore-keys: | node-modules-${{ runner.os }}- node-modules- - name: Download Docker image tarballs uses: actions/download-artifact@v4 with: name: backend-image path: /tmp - uses: actions/download-artifact@v4 with: name: webapp-image path: /tmp - uses: actions/download-artifact@v4 with: name: neo4j-image path: /tmp - name: Load Docker images run: | docker load < /tmp/neo4j.tar docker load < /tmp/backend.tar docker load < /tmp/webapp.tar - name: Download backend build uses: actions/download-artifact@v4 with: name: backend-build path: backend/build - uses: actions/checkout@v4 - name: Add node_modules/.bin to PATH run: echo "$(pwd)/node_modules/.bin" >> $GITHUB_PATH - name: Ensure Cypress CLI is available run: | if ! command -v cypress >/dev/null; then echo "⚠️ Cypress CLI missing — installing now..." yarn install else echo "✅ Cypress CLI is present" fi - name: Setup .env files run: | mkdir -p webapp backend cp webapp/.env.template webapp/.env || touch webapp/.env cp backend/.env.test_e2e backend/.env || touch backend/.env - name: Start system run: | set -e docker compose -f docker-compose.yml -f docker-compose.test.yml up --detach webapp mailserver - name: Wait for webapp run: | for i in {1..30}; do curl -sf http://localhost:3000 && exit 0 || sleep 2; done; exit 1 - name: Run Cypress tests run: | yarn run cypress:run --spec $(cypress/parallel-features.sh ${{ matrix.job }} ${{ env.jobs }})