name: End-to-End Tests on: pull_request: types: [opened, synchronize, reopened, labeled] branches: - main - develop workflow_dispatch: jobs: e2e-tests: if: contains(github.event.pull_request.labels.*.name, 'end-to-end') || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 60 env: GITHUB_REPO_NAME: ${{ github.repository }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Install poetry via pipx uses: abatilo/actions-poetry@v4 with: poetry-version: 2.1.3 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.12' cache: 'poetry' - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y libgtk-3-0 libnotify4 libnss3 libxss1 libxtst6 xauth xvfb libgbm1 libasound2t64 netcat-openbsd - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' cache-dependency-path: 'frontend/package-lock.json' - name: Setup environment for end-to-end tests run: | # Create test results directory mkdir -p test-results # Create downloads directory for OpenHands (use a directory in the home folder) mkdir -p $HOME/downloads sudo chown -R $USER:$USER $HOME/downloads sudo chmod -R 755 $HOME/downloads - name: Build OpenHands env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} LLM_MODEL: ${{ secrets.LLM_MODEL || 'gpt-4o' }} LLM_API_KEY: ${{ secrets.LLM_API_KEY || 'test-key' }} LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }} INSTALL_DOCKER: 1 RUNTIME: docker FRONTEND_PORT: 12000 FRONTEND_HOST: 0.0.0.0 BACKEND_HOST: 0.0.0.0 BACKEND_PORT: 3000 ENABLE_BROWSER: true INSTALL_PLAYWRIGHT: 1 run: | # Fix poetry.lock file if needed echo "Fixing poetry.lock file if needed..." poetry lock # Build OpenHands using make build echo "Running make build..." make build # Install Chromium Headless Shell for Playwright (needed for pytest-playwright) echo "Installing Chromium Headless Shell for Playwright..." poetry run playwright install chromium-headless-shell # Verify Playwright browsers are installed (for e2e tests only) echo "Verifying Playwright browsers installation for e2e tests..." BROWSER_CHECK=$(poetry run python tests/e2e/check_playwright.py 2>/dev/null) if [ "$BROWSER_CHECK" != "chromium_found" ]; then echo "ERROR: Chromium browser not found or not working for e2e tests" echo "$BROWSER_CHECK" exit 1 else echo "Playwright browsers are properly installed for e2e tests." fi # Docker runtime will handle workspace directory creation # Start the application using make run with custom parameters and reduced logging echo "Starting OpenHands using make run..." # Set environment variables to reduce logging verbosity export PYTHONUNBUFFERED=1 export LOG_LEVEL=WARNING export UVICORN_LOG_LEVEL=warning export OPENHANDS_LOG_LEVEL=WARNING FRONTEND_PORT=12000 FRONTEND_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0 make run > /tmp/openhands-e2e-test.log 2>&1 & # Store the PID of the make run process MAKE_PID=$! echo "OpenHands started with PID: $MAKE_PID" # Wait for the application to start echo "Waiting for OpenHands to start..." max_attempts=15 attempt=1 while [ $attempt -le $max_attempts ]; do echo "Checking if OpenHands is running (attempt $attempt of $max_attempts)..." # Check if the process is still running if ! ps -p $MAKE_PID > /dev/null; then echo "ERROR: OpenHands process has terminated unexpectedly" echo "Last 50 lines of the log:" tail -n 50 /tmp/openhands-e2e-test.log exit 1 fi # Check if frontend port is open if nc -z localhost 12000; then # Verify we can get HTML content if curl -s http://localhost:12000 | grep -q "