Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 46 additions & 41 deletions .github/workflows/end2end_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,16 @@ env:

jobs:
end-to-end-test:
name: End2End Test
name: End2End Test (shard ${{ matrix.shard.index }}/${{ matrix.shard.total }})
strategy:
fail-fast: false
matrix:
# Run each Playwright shard on its own runner to split the suite by file.
shard:
- index: 1
total: 2
- index: 2
total: 2
runs-on: ubuntu-latest
steps:
- name: Checkout Code
Expand Down Expand Up @@ -52,29 +61,13 @@ jobs:
path: lightly_studio/datasets/coco-128
key: coco-example-dataset

- name: Cache lightly_studio app build
id: cache-python-build
uses: actions/cache@v4
with:
path: lightly_studio/dist
key: python-build-${{ hashFiles('lightly_studio/src/**', 'lightly_studio/pyproject.toml', 'lightly_studio_view/src/**', 'lightly_studio_view/public/**', 'lightly_studio_view/package.json', 'lightly_studio_view/package-lock.json') }}

- name: Cache e2e-tests
id: cache-e2e-tests
uses: actions/cache@v4
with:
path: lightly_studio_view/playwright-report
key: python-build-${{ hashFiles('lightly_studio/e2e-tests/index_dataset_for_end2end_ui_tests.py', 'lightly_studio/src/**', 'lightly_studio/pyproject.toml', 'lightly_studio_view/e2e/**', 'lightly_studio_view/src/**', 'lightly_studio_view/public/**', 'lightly_studio_view/package.json', 'lightly_studio_view/package-lock.json') }}

### Setup steps for the workflow ###
- name: Set Up Python
if: steps.cache-python-build.outputs.cache-hit != 'true' || steps.cache-e2e-tests.outputs.cache-hit != 'true'
uses: actions/setup-python@v5
with:
python-version: "3.8"

- name: Set Up uv
if: steps.cache-python-build.outputs.cache-hit != 'true' || steps.cache-e2e-tests.outputs.cache-hit != 'true'
uses: astral-sh/setup-uv@v6
with:
version: "0.8.17"
Expand All @@ -87,8 +80,9 @@ jobs:
cache: 'npm'
cache-dependency-path: lightly_studio_view/package-lock.json

- name: Install dependencies
if: steps.cache-e2e-tests.outputs.cache-hit != 'true' || steps.cache-python-build.outputs.cache-hit != 'true'
# Always install npm dependencies (needed for npx playwright commands)
# The setup-node npm cache makes this fast even on repeated runs
- name: Install npm dependencies
working-directory: lightly_studio_view
run: npm ci

Expand All @@ -102,13 +96,12 @@ jobs:

# Always ensure system packages for browsers are present on Ubuntu
- name: Install Playwright system dependencies
if: steps.cache-e2e-tests.outputs.cache-hit != 'true'
working-directory: lightly_studio_view
run: npx playwright install-deps chromium

# Only download browser binaries when cache misses; otherwise reuse cache
- name: Install Playwright browsers
if: steps.cache-e2e-tests.outputs.cache-hit != 'true' && steps.cache-playwright-browsers.outputs.cache-hit != 'true'
if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
working-directory: lightly_studio_view
run: npx playwright install chromium

Expand All @@ -119,33 +112,26 @@ jobs:
git clone --depth=1 https://github.com/lightly-ai/dataset_examples_studio.git tmp_dataset_repo
cp -r tmp_dataset_repo/coco_subset_128_images/* lightly_studio/datasets/coco-128/
rm -rf tmp_dataset_repo

- name: Install lightly_studio python dependencies
if: steps.cache-python-build.outputs.cache-hit != 'true'
working-directory: lightly_studio
run: make install-optional-deps

- name: Export schema from backend
if: steps.cache-python-build.outputs.cache-hit != 'true'
working-directory: lightly_studio
run: make export-schema

### Buildging and steps for the workflow ###
### Building steps for the workflow ###
- name: Build the ui application
if: steps.cache-ui-build.outputs.cache-hit != 'true' || steps.cache-python-build.outputs.cache-hit != 'true'
if: steps.cache-ui-build.outputs.cache-hit != 'true'
working-directory: lightly_studio_view
run: |
rm -rf build
npm run build

- name: Copy the built ui app to lightly_studio source folder
if: steps.cache-ui-build.outputs.cache-hit != 'true' || steps.cache-python-build.outputs.cache-hit != 'true'
if: steps.cache-ui-build.outputs.cache-hit != 'true'
run: |
rm -rf lightly_studio/src/lightly_studio/dist_lightly_studio_view_app
cp -r lightly_studio_view/build/ lightly_studio/src/lightly_studio/dist_lightly_studio_view_app

- name: Index dataset with using lightly_studio pypi package
if: steps.cache-e2e-tests.outputs.cache-hit != 'true'
- name: Start lightly_studio server with test dataset
working-directory: lightly_studio
# TODO(Michal, 10/2025): Starting up the server redownloads the embedding model. Consider caching it.
run: |
Expand All @@ -154,14 +140,13 @@ jobs:
id: server

- name: Wait for the server to start
if: steps.cache-e2e-tests.outputs.cache-hit != 'true'
timeout-minutes: 5
run: |
echo "Waiting for the server to become available..."
timeout=360
elapsed=0
interval=5

while [ $elapsed -lt $timeout ]; do
if curl -s -f ${E2E_BASE_URL}/healthz > /dev/null 2>&1; then
echo "✅ Server is up and running after ${elapsed} seconds!"
Expand All @@ -171,22 +156,26 @@ jobs:
sleep $interval
elapsed=$((elapsed + interval))
done

if [ $elapsed -ge $timeout ]; then
echo "❌ Timed out waiting for server to become available"
exit 1
fi

### Running end-to-end tests ###
# Shard Playwright specs across runners for parallel execution.
- name: Run end-to-end tests for indexed dataset
if: steps.cache-e2e-tests.outputs.cache-hit != 'true'
working-directory: lightly_studio_view
run: npx playwright test --reporter=html --trace=on
run: |
npx playwright test \
--reporter=html \
--trace=on \
--shard=${{ matrix.shard.index }}/${{ matrix.shard.total }}
timeout-minutes: 10

### Cleanup steps for the workflow ###
- name: Show server logs after failure
if: failure() && steps.cache-e2e-tests.outputs.cache-hit != 'true'
if: failure()
working-directory: lightly_studio
run: |
echo "Server logs:"
Expand All @@ -196,11 +185,27 @@ jobs:
uses: actions/upload-artifact@v4
if: failure()
with:
name: Upload Playwright Report
# Each shard uploads its own Playwright HTML report.
name: playwright-report-shard-${{ matrix.shard.index }}-of-${{ matrix.shard.total }}
path: lightly_studio_view/playwright-report
retention-days: 5

- name: Stop lightly_studio application running in background
if: always() && steps.cache-e2e-tests.outputs.cache-hit != 'true'
if: always()
run: |
kill ${{ env.SERVER_PID }} || true

# Summary job that reports overall test status
end-to-end-test-summary:
name: End2End Test
needs: end-to-end-test
runs-on: ubuntu-latest
if: always()
steps:
- name: Check test results
run: |
if [[ "${{ needs.end-to-end-test.result }}" != "success" ]]; then
echo "❌ One or more test shards failed"
exit 1
fi
echo "✅ All end-to-end test shards passed successfully"