Skip to content
146 changes: 146 additions & 0 deletions .github/workflows/web-integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
name: Web Integration Tests

on:
workflow_dispatch:

permissions:
issues: write

jobs:
web-integration-tests:
name: Web Integration Tests
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python 3.9.25
uses: actions/setup-python@v5
with:
python-version: '3.9.25'

- name: Create virtual environment and install dependencies
working-directory: python
run: |
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements_dev.txt

- name: Use webserver log configuration
working-directory: python
run: |
ln -s logconf_webserver.json pifinder_logconf.json

- name: Initialize tetra3
working-directory: python
run: |
git submodule sync
git submodule update --init --recursive
ln -s PiFinder/tetra3/tetra3 tetra3

- name: Use cache of hip_main.dat star catalog

id: cache-hip-main
uses: actions/cache@v4
with:
path: astro_data/hip_main.dat
key: hip_main-dat-v1
# Bump this key, to force redownloading the catalog if it changes or if we want to refresh the cache

- name: Download hip_main.dat star catalog
if: steps.cache-hip-main.outputs.cache-hit != 'true'
run: |
wget -q -O astro_data/hip_main.dat \
https://cdsarc.cds.unistra.fr/ftp/cats/I/239/hip_main.dat

- name: Set up PiFinder_data directory
run: |
mkdir -p ~/PiFinder_data/obslists
mkdir -p ~/PiFinder_data/captures
cp default_config.json ~/PiFinder_data/config.json

- name: Start PiFinder with fake hardware
working-directory: python
run: |
source .venv/bin/activate
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy python -m PiFinder.main -fh --camera debug --keyboard local \
> /tmp/pifinder.log 2>&1 &
echo $! > /tmp/pifinder.pid
echo "PiFinder started with PID $(cat /tmp/pifinder.pid)"

- name: Wait for PiFinder web server (port 8080)
run: |
for i in $(seq 1 30); do
if curl -sf http://localhost:8080/ > /dev/null 2>&1; then
echo "PiFinder web server is ready"
break
fi
if [ "$i" -eq 30 ]; then
echo "ERROR: server did not start within 150s"
cat /tmp/pifinder.log
exit 1
fi
echo "Attempt $i/30, sleeping 5s..."
sleep 5
done

- name: Run web tests
id: pytest_first
continue-on-error: true
working-directory: python
env:
PIFINDER_HOMEPAGE: http://localhost:8080
run: |
source .venv/bin/activate
pytest -ra -m web --local -v

- name: Rerun failed tests with --lf
id: pytest_rerun
if: steps.pytest_first.outcome == 'failure'
continue-on-error: true
working-directory: python
env:
PIFINDER_HOMEPAGE: http://localhost:8080
run: |
source .venv/bin/activate
pytest -ra -m web --local -v --lf

- name: Alert maintainers via GitHub Issue
if: steps.pytest_rerun.outcome == 'failure'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh issue create \
--title "Web Integration Tests failed — $(date -u '+%Y-%m-%d %H:%M UTC')" \
--body "Web integration tests failed on both the initial run and the --lf rerun.

**Workflow run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
**Triggered by:** ${{ github.actor }}
**Branch:** ${{ inputs.branch }}" \
--label "bug"

- name: Fail job after persistent test failure
if: steps.pytest_first.outcome == 'failure' && steps.pytest_rerun.outcome != 'failure'
run: |
echo "First run failed but --lf rerun passed — treating as flaky, not failing job."

- name: Fail job if rerun also failed
if: steps.pytest_rerun.outcome == 'failure'
run: exit 1

- name: Upload PiFinder log on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: pifinder-log
path: /tmp/pifinder.log

- name: Stop PiFinder
if: always()
run: |
if [ -f /tmp/pifinder.pid ]; then
kill "$(cat /tmp/pifinder.pid)" || true
fi
Loading