Skip to content
Open
Show file tree
Hide file tree
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
19 changes: 19 additions & 0 deletions .github/actions/setup-python-env/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: 'Setup Python Environment'
description: 'Sets up Python and installs dependencies'
runs:
using: "composite"
steps:
- name: "Install uv"
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"

- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version-file: ".python-version"

- name: "Install dependencies"
run: make install
shell: bash
75 changes: 46 additions & 29 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,8 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: "Install uv"
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"

- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version-file: ".python-version"

- name: "Install dependencies"
run: |
make install
- name: "Setup Python environment"
uses: ./.github/actions/setup-python-env

- name: "Lint with ruff"
run: |
Expand All @@ -51,20 +39,8 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: "Install uv"
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"

- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version-file: ".python-version"

- name: "Install dependencies"
run: |
make install
- name: "Setup Python environment"
uses: ./.github/actions/setup-python-env

# api client version should be committed in the repository
# so re-generating it in the CI is skipped unless explicitly requested
Expand All @@ -79,7 +55,48 @@ jobs:
run: |
make test-api

# TODO add e2e ui tests
test-ui:
name: "Run UI tests"
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright/python:v1.55.0-noble
options: --ipc=host --user 1001

steps:
- uses: actions/checkout@v4

- name: "Install uv"
run: |
pip install --user uv

- name: "Install project dependencies"
# TODO sync only frontend package group
run: |
uv sync --all-extras --dev --all-packages

- uses: actions/setup-node@v4
with:
node-version: lts/*

- name: Install dependencies
run: |
npm ci

- name: "Install chromium and dependencies"
run: |
npx playwright install --with-deps chromium

- name: "Run UI tests"
run: |
uv run --package frontend -- pytest -v packages/frontend/tests
env:
PLAYWRIGHT_TRACING: True

- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-traces
path: /tmp/playwright_traces/

# TODO add security checks

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ test-api:

test-ui: start-playwright-server
@echo "Running UI E2E tests..."
uv run --package frontend -- pytest -v packages/frontend/tests
PLAYWRIGHT_WS_ENDPOINT=ws://0.0.0.0:19323 uv run --package frontend -- pytest -v packages/frontend/tests

start-playwright-server:
@echo "Starting Playwright server..."
Expand Down
30 changes: 20 additions & 10 deletions packages/frontend/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,39 @@
from typing import Generator
import os

# TODO the value should be fetched from a configuration file
# expects playwright browser server to run in a container
PLAYWRIGHT_WS_ENDPOINT = "ws://0.0.0.0:19323"
PLAYWRIGHT_TRACING = True
# If PLAYWRIGHT_WS_ENDPOINT is set, we connect to a remote server (for local)
# otherwise launch a local browser instance (used in CI)
PLAYWRIGHT_WS_ENDPOINT = os.environ.get("PLAYWRIGHT_WS_ENDPOINT")
# tracing is disabled by default
PLAYWRIGHT_TRACING = os.environ.get("PLAYWRIGHT_TRACING", "False").lower() == "True"


@pytest.fixture(scope="session")
def chromium_browser() -> Generator[Browser, None, None]:
"""
Main browser fixture that connects to the running browser server in container.
Main browser fixture.

This fixture establishes a connection to a Playwright browser server running
in a container and provides a Browser instance for the entire test session.
If the PLAYWRIGHT_WS_ENDPOINT environment variable is set, this fixture
connects to a remote Playwright browser server. This is used for local
testing with the 'make test-ui' command.

The browser is closed when the session ends.
If the environment variable is not set, it launches a new local browser
instance, used in CI container where the browsers are available directly.

The browser is closed automatically when the session ends.

Returns:
Generator[Browser, None, None]: A generator yielding a Playwright Browser
instance connected to the remote server.
instance.
"""
with sync_playwright() as p:
browser = p.chromium.connect(PLAYWRIGHT_WS_ENDPOINT)
if PLAYWRIGHT_WS_ENDPOINT:
browser = p.chromium.connect(PLAYWRIGHT_WS_ENDPOINT)
else:
browser = p.chromium.launch()

yield browser

browser.close()


Expand Down
Loading