name: Playwright test reusable workflow on: workflow_call: inputs: shard: description: 'Shard number' required: true type: string db: required: true type: string jobs: playwright: runs-on: [self-hosted, v2] timeout-minutes: 100 steps: - name: Checkout uses: actions/checkout@v3 - name: pre-requisite checks shell: bash run: | node_version=$(node --version || echo "error") pnpm_version=$(pnpm -v || echo "error") echo "node version: $node_version" echo "pnpm version: $pnpm_version" if [[ $node_version != v18* ]] || [[ $pnp_version != 8* ]]; then echo "version mismatch: expected node v18 and pnpm v8" RUN_PRERQUISITE_STEPS="true" elif [[ ${FORCE_RUN_PRERQUISITE_STEPS} == "true" ]]; # || [[ ! -f ${PRE_REQ_CHECK_FILE_PATH} ]]; then echo "FORCE_RUN_PRERQUISITE_STEPS is true" RUN_PRERQUISITE_STEPS="true" else RUN_PRERQUISITE_STEPS="false" fi echo "RUN_PRERQUISITE_STEPS=${RUN_PRERQUISITE_STEPS}" >> $GITHUB_ENV - name: Setup Node if: env.RUN_PRERQUISITE_STEPS == 'true' uses: actions/setup-node@v3 with: node-version: 18.14.0 - name: Setup pnpm if: env.RUN_PRERQUISITE_STEPS == 'true' uses: pnpm/action-setup@v2 with: version: 8 - name: Get pnpm store directory shell: bash run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - uses: actions/cache@v3 if: env.RUN_PRERQUISITE_STEPS == 'true' name: Setup pnpm cache with: path: ${{ env.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - name: setup pg if: ${{ inputs.db == 'pg' || ( inputs.db == 'sqlite' && inputs.shard == '1' ) }} working-directory: ./ run: | service postgresql start cd /var/lib/postgresql/ && sudo -u postgres psql -c "SELECT 'dropdb '||datname||'' FROM pg_database WHERE datistemplate = false AND datallowconn = true And datname NOT IN ('postgres')" |grep ' dropdb ' | sudo -u postgres /bin/bash ; cd sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'password';" sudo -u postgres psql -c "ALTER USER postgres WITH SUPERUSER;" service postgresql restart - name: Kill stale servers run: | # export NODE_OPTIONS=\"--max_old_space_size=16384\"; kill -9 $(lsof -t -i:8080) || echo "no process running on 8080" kill -9 $(lsof -t -i:3000) || echo "no process running on 3000" - name: Set CI env run: export CI=true - name: Set NC Edition run: export EE=false - name: install dependencies run: pnpm bootstrap - name: Setup mysql if: ${{ inputs.db == 'mysql' }} working-directory: ./packages/nocodb/tests/mysql-sakila-db run: | # Get a list of non-system databases and construct the DROP DATABASE statement for each service mysql start mysql -u'root' -p'password' -e "SHOW DATABASES" --skip-column-names | grep -Ev "(information_schema|mysql|performance_schema|sys)" | while read db; do mysql -u'root' -p'password' -e "DROP DATABASE IF EXISTS \`$db\`"; done # keep sql_mode default except remove "STRICT_TRANS_TABLES" mysql -u'root' -p'password' -e "SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';" # this is only needed for connecting to sakila db as its refeferred in multiple places in test code mysql -u'root' -p'password' < 01-mysql-sakila-schema.sql mysql -u'root' -p'password' < 02-mysql-sakila-insert-data.sql - name: Setup pg for quick tests if: ${{ inputs.db == 'sqlite' && inputs.shard == '1' }} working-directory: ./packages/nocodb/tests/pg-cy-quick/ run: | sudo -u postgres psql -U postgres -f 01-cy-quick.sql - name: Run backend if: ${{ inputs.db == 'sqlite' }} working-directory: ./packages/nocodb run: | pnpm run watch:run:playwright &> ${{ inputs.db }}_${{ inputs.shard }}_test_backend.log & - name: Run backend:mysql if: ${{ inputs.db == 'mysql' }} working-directory: ./packages/nocodb run: | pnpm run watch:run:playwright:mysql &> ${{ inputs.db }}_${{ inputs.shard }}_test_backend.log & - name: Run backend:pg if: ${{ inputs.db == 'pg' }} working-directory: ./packages/nocodb run: | pnpm run watch:run:playwright:pg &> ${{ inputs.db }}_${{ inputs.shard }}_test_backend.log & - name: copy built output and start frontend if: always() working-directory: ./ run: | # expects the variables to be available in runner context. path="gh-artifacts/runs/${GITHUB_RUN_ID}/ui-build/.output" target_dir="/mnt/${path}" mkdir -p ${target_dir} if [[ -d ${target_dir} ]]; then echo "Directory ${target_dir} exists." cp -r ${target_dir} ./packages/nc-gui/ || echo "playwright reports directory does not exists" >> ${target_dir}/playwright-report/index.html else echo "Error: Directory ${target_dir} does not exists." exit 1 fi cd ./packages/nc-gui/ pnpm run ci:start - name: Install Playwright Browsers working-directory: ./tests/playwright run: pnpm exec playwright install --with-deps chromium - name: Wait for frontend and backend run: | while ! curl --output /dev/null --silent --head --fail http://localhost:3000; do printf '.' sleep 2 done echo "Frontend is up" while ! curl --output /dev/null --silent --head --fail http://localhost:8080; do printf '.' sleep 2 done echo "Backend is up" timeout-minutes: 2 - name: Run Playwright Tests working-directory: ./tests/playwright run: E2E_DB_TYPE=${{ inputs.db }} npm run ci:test:shard:${{ inputs.shard }} timeout-minutes: 60 # Stress test added/modified tests - name: Fetch develop branch working-directory: ./tests/playwright run: git fetch origin develop - name: Stress test working-directory: ./tests/playwright run: E2E_DB_TYPE=${{ inputs.db }} node ./scripts/stressTestNewlyAddedTest.js # # Quick tests (pg on sqlite shard 0 and sqlite on sqlite shard 1) # - name: Run quick server and tests (pg) # if: ${{ inputs.db == 'sqlite' && inputs.shard == '1' }} # working-directory: ./packages/nocodb # run: | # kill -9 $(lsof -t -i:8080) # npm run watch:run:playwright:pg:cyquick > quick_${{ inputs.shard }}_test_backend.log & # - name: Run quick server and tests (sqlite) # if: ${{ inputs.db == 'sqlite' && inputs.shard == '2' }} # working-directory: ./packages/nocodb # run: | # kill -9 $(lsof -t -i:8080) # npm run watch:run:playwright:quick > quick_${{ inputs.shard }}_test_backend.log & # - name: Wait for backend for sqlite-tests # if: ${{ inputs.db == 'sqlite' }} # working-directory: ./tests/playwright # run: | # while ! curl --output /dev/null --silent --head --fail http://localhost:8080; do # printf '.' # sleep 2 # done # timeout-minutes: 1 # - name: Run quick tests # if: ${{ inputs.db == 'sqlite' }} # working-directory: ./tests/playwright # run: PLAYWRIGHT_HTML_REPORT=playwright-report-quick npm run test:quick - uses: actions/upload-artifact@v3 if: ${{ inputs.db == 'sqlite' }} with: name: quick-backend-log-${{ inputs.shard }} path: ./packages/nocodb/quick_${{ inputs.shard }}_test_backend.log retention-days: 2 - uses: actions/upload-artifact@v3 if: ${{ inputs.db == 'sqlite' }} with: name: playwright-report-quick-${{ inputs.shard }} path: ./tests/playwright/playwright-report-quick/ retention-days: 2 - uses: actions/upload-artifact@v3 if: always() with: name: playwright-report-${{ inputs.db }}-${{ inputs.shard }} path: ./tests/playwright/playwright-report/ retention-days: 2 - uses: actions/upload-artifact@v3 if: always() with: name: playwright-report-stress-${{ inputs.db }}-${{ inputs.shard }} path: ./tests/playwright/playwright-report-stress/ retention-days: 2 - uses: actions/upload-artifact@v3 if: always() with: name: backend-logs-${{ inputs.db }}-${{ inputs.shard }} path: ./packages/nocodb/${{ inputs.db }}_${{ inputs.shard }}_test_backend.log retention-days: 2 - name: stop database servers if: always() working-directory: ./packages/nocodb run: | service postgresql stop service mysql stop - name: Copy Artifacts to Local Artifacts Dir if: always() working-directory: ./ run: | # expects the variables to be available in runner context. path="gh-artifacts/runs/${GITHUB_RUN_ID}/run-attempt/${GITHUB_RUN_ATTEMPT}/job_name/"${GITHUB_JOB}"-${{ inputs.shard }}/${RANDOM}-$(date +%s)" target_dir="/mnt/${path}" mkdir -p ${target_dir} mkdir -p ${target_dir}/playwright-report # start : add any artifacts to be copied here cp -r ./tests/playwright/playwright-report ${target_dir}/ || echo "playwright reports directory does not exists" >> ${target_dir}/playwright-report/index.html cp ./packages/nocodb/*_test_backend.log ${target_dir}/ || echo "backend logs file does not exists" >> ${target_dir}/index.html # end: artifacts copy SUMMARY='[Artifacts](http://135.181.48.96/'${path}') [playwright-report](http://135.181.48.96/'${path}'/playwright-report)' echo "$SUMMARY" >> $GITHUB_STEP_SUMMARY