test: improve E2E test robustness and prevent orphaned emulators #347
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright 2026 Firebase | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| name: Tests | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Check license headers on all source files | |
| check-license-header: | |
| name: Check License Headers | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download addlicense | |
| run: | | |
| curl -sL https://github.com/google/addlicense/releases/download/v1.2.0/addlicense_v1.2.0_Linux_x86_64.tar.gz | tar xz -C /usr/local/bin addlicense | |
| chmod +x /usr/local/bin/addlicense | |
| - name: Check license headers | |
| run: | | |
| addlicense -f header_template.txt \ | |
| --check \ | |
| --ignore "**/*.yml" \ | |
| --ignore "**/*.yaml" \ | |
| --ignore "**/*.xml" \ | |
| --ignore "**/*.g.dart" \ | |
| --ignore "**/*.sh" \ | |
| --ignore "**/*.html" \ | |
| --ignore "**/*.js" \ | |
| --ignore "**/*.ts" \ | |
| --ignore "**/*.txt" \ | |
| --ignore "**/.dart_tool/**" \ | |
| --ignore "**/test/fixtures/nodejs_reference/**" \ | |
| --ignore "**/test/fixtures/with_options_nodejs/**" \ | |
| . | |
| # Dart package analysis and formatting | |
| lint-analyze: | |
| name: Format & Analyze (${{ matrix.sdk }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| sdk: [stable, beta] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Dart SDK | |
| uses: dart-lang/setup-dart@v1 | |
| with: | |
| sdk: ${{ matrix.sdk }} | |
| - name: Print Dart version | |
| run: dart --version | |
| - name: Install dependencies | |
| run: dart pub upgrade | |
| - name: Verify formatting | |
| run: dart format --output=none --set-exit-if-changed . | |
| if: matrix.sdk == 'stable' | |
| - name: Analyze all packages | |
| run: | | |
| dart analyze --fatal-infos | |
| for dir in example/*/; do | |
| if [ -f "$dir/pubspec.yaml" ]; then | |
| echo "Analyzing $dir..." | |
| dart analyze --fatal-infos "$dir" | |
| fi | |
| done | |
| dart analyze --fatal-infos test/fixtures/dart_reference | |
| # TODO: Re-enable when unit tests are added | |
| # - name: Run unit tests | |
| # run: dart test --exclude-tags=snapshot,integration,e2e | |
| # Builder tests - generate and verify functions.yaml | |
| builder-tests: | |
| name: Builder Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Dart SDK | |
| uses: dart-lang/setup-dart@v1 | |
| with: | |
| sdk: stable | |
| - name: Install dependencies (root) | |
| run: dart pub upgrade | |
| - name: Install dependencies (fixture) | |
| working-directory: test/fixtures/dart_reference | |
| run: dart pub upgrade | |
| - name: Run build_runner | |
| working-directory: test/fixtures/dart_reference | |
| run: dart run build_runner build --delete-conflicting-outputs | |
| - name: Verify functions.yaml was generated | |
| run: | | |
| if [ ! -f "test/fixtures/dart_reference/functions.yaml" ]; then | |
| echo "Error: functions.yaml was not generated" | |
| exit 1 | |
| fi | |
| echo "✓ functions.yaml generated successfully" | |
| - name: Display generated manifest | |
| run: | | |
| echo "Generated Dart manifest:" | |
| cat test/fixtures/dart_reference/functions.yaml | |
| - name: Upload generated manifest | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dart-manifest | |
| path: test/fixtures/dart_reference/functions.yaml | |
| retention-days: 7 | |
| # Snapshot tests - compare Dart manifest with Node.js reference | |
| snapshot-tests: | |
| name: Snapshot Tests | |
| runs-on: ubuntu-latest | |
| needs: builder-tests | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Dart SDK | |
| uses: dart-lang/setup-dart@v1 | |
| with: | |
| sdk: stable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: test/fixtures/nodejs_reference/package-lock.json | |
| - name: Install Dart dependencies | |
| run: dart pub upgrade | |
| - name: Download Dart manifest from builder-tests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dart-manifest | |
| path: test/fixtures/dart_reference | |
| - name: Install Node.js dependencies (nodejs_reference) | |
| working-directory: test/fixtures/nodejs_reference | |
| run: npm ci | |
| - name: Generate Node.js manifest | |
| working-directory: test/fixtures/nodejs_reference | |
| run: | | |
| echo "Starting firebase-functions server..." | |
| GCLOUD_PROJECT="test-project" \ | |
| PORT="8080" \ | |
| FUNCTIONS_CONTROL_API="true" \ | |
| npx firebase-functions > /tmp/ff.log 2>&1 & | |
| FF_PID=$! | |
| echo "Server PID: $FF_PID" | |
| # Wait for server to be ready | |
| echo "Waiting for server to start..." | |
| for i in {1..30}; do | |
| if curl -s http://localhost:8080/__/functions.yaml > /dev/null 2>&1; then | |
| echo "✓ Server is ready" | |
| break | |
| fi | |
| if [ $i -eq 30 ]; then | |
| echo "Error: Server failed to start" | |
| cat /tmp/ff.log | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| # Fetch manifest | |
| echo "Fetching manifest..." | |
| curl -s http://localhost:8080/__/functions.yaml | python3 -m json.tool > nodejs_manifest.json | |
| # Stop server | |
| kill $FF_PID 2>/dev/null || true | |
| echo "Node.js manifest generated:" | |
| cat nodejs_manifest.json | |
| - name: Display all manifests | |
| run: | | |
| echo "========== DART MANIFEST ==========" | |
| cat test/fixtures/dart_reference/functions.yaml | |
| echo "" | |
| echo "========== NODE.JS MANIFEST ==========" | |
| cat test/fixtures/nodejs_reference/nodejs_manifest.json | |
| - name: Run snapshot comparison tests | |
| run: dart test test/snapshots/manifest_snapshot_test.dart --reporter=expanded | |
| - name: Upload manifests on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: manifests-comparison | |
| path: | | |
| test/fixtures/dart_reference/functions.yaml | |
| test/fixtures/nodejs_reference/nodejs_manifest.json | |
| retention-days: 30 | |
| # E2E tests with Firebase Emulator | |
| e2e-tests: | |
| name: E2E Tests (Emulator) | |
| runs-on: ubuntu-latest | |
| needs: builder-tests | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Checkout custom firebase-tools | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: invertase/firebase-tools | |
| ref: '@invertase/dart' | |
| path: custom-firebase-tools | |
| - name: Setup Dart SDK | |
| uses: dart-lang/setup-dart@v1 | |
| with: | |
| sdk: stable | |
| - name: Setup Java 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Link custom firebase-tools | |
| working-directory: custom-firebase-tools | |
| run: npm i && npm link | |
| - name: Verify Firebase CLI | |
| run: firebase --version | |
| - name: Install dependencies (root) | |
| run: dart pub upgrade | |
| - name: Download Dart manifest from builder-tests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dart-manifest | |
| path: test/fixtures/dart_reference | |
| - name: Create .env.local for params | |
| run: | | |
| cat > test/fixtures/dart_reference/.env.local << 'EOF' | |
| WELCOME_MESSAGE=Hello from Dart Functions! | |
| MIN_INSTANCES=0 | |
| IS_PRODUCTION=false | |
| EOF | |
| echo "✓ Created .env.local with default param values" | |
| - name: Run E2E tests | |
| run: dart test test/e2e/e2e_test.dart --reporter=expanded | |
| timeout-minutes: 5 | |
| - name: Upload test logs on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: e2e-test-logs | |
| path: | | |
| test/fixtures/dart_reference/functions.yaml | |
| test/fixtures/dart_reference/firebase-debug.log | |
| retention-days: 7 | |
| # Test result summary | |
| test-summary: | |
| name: Test Summary | |
| runs-on: ubuntu-latest | |
| needs: [check-license-header, lint-analyze, builder-tests, snapshot-tests, e2e-tests] | |
| if: always() | |
| steps: | |
| - name: Check test results | |
| run: | | |
| if [ "${{ needs.check-license-header.result }}" != "success" ]; then | |
| echo "❌ License header check failed" | |
| exit 1 | |
| fi | |
| if [ "${{ needs.lint-analyze.result }}" != "success" ]; then | |
| echo "❌ Format & Analyze failed" | |
| exit 1 | |
| fi | |
| if [ "${{ needs.builder-tests.result }}" != "success" ]; then | |
| echo "❌ Builder tests failed" | |
| exit 1 | |
| fi | |
| if [ "${{ needs.snapshot-tests.result }}" != "success" ]; then | |
| echo "❌ Snapshot tests failed" | |
| exit 1 | |
| fi | |
| if [ "${{ needs.e2e-tests.result }}" != "success" ]; then | |
| echo "❌ E2E tests failed" | |
| exit 1 | |
| fi | |
| echo "✅ All tests passed!" |