Skip to content

Commit 696c225

Browse files
committed
Add a Docker Compose script to run the browser tests
1 parent d8bb33d commit 696c225

File tree

5 files changed

+104
-28
lines changed

5 files changed

+104
-28
lines changed

atr/docs/running-and-creating-tests.html

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,23 @@ <h1 id="running-and-creating-tests">3.7. Running and creating tests</h1>
99
</ul>
1010
<h2 id="running-tests">Running tests</h2>
1111
<p>We currently only have end-to-end browser tests, but we plan to expand these as part of <a href="https://github.com/apache/tooling-trusted-releases/issues/209">Issue #209</a>. Meanwhile, these browser tests serve as a simple consistency check when developing ATR.</p>
12-
<p>To run the tests, you will need Docker. Other OCI runtimes should work, but you will need to edit the <a href="/ref/Makefile"><code>Makefile</code></a> or run your own command. The simple way to run the tests is:</p>
12+
<p>To run the tests, you will need Docker. Other OCI runtimes should work, but you will need to edit the test scripts accordingly.</p>
13+
<h3 id="using-docker-compose">Using Docker Compose</h3>
14+
<p>The simplest way to run the tests is using Docker Compose, which starts both ATR and the Playwright test container:</p>
15+
<pre><code class="language-shell">sh tests/run-tests.sh
16+
</code></pre>
17+
<p>This uses <a href="/ref/tests/docker-compose.yml"><code>tests/docker-compose.yml</code></a> to orchestrate the test environment. The ATR server runs in one container and the Playwright tests run in another, connected via a Docker network.</p>
18+
<h3 id="using-host-networking">Using host networking</h3>
19+
<p>If you already have ATR running locally with <code>make serve-local</code>, you can run the Playwright tests directly against it instead of using Docker Compose:</p>
1320
<pre><code class="language-shell">make build-playwright &amp;&amp; make run-playwright
1421
</code></pre>
1522
<p>Where the two <code>make</code> invocations correspond to:</p>
1623
<pre><code class="language-shell">docker build -t atr-playwright -f tests/Dockerfile.playwright playwright
1724
docker run --net=host -it atr-playwright python3 test.py --skip-slow
1825
</code></pre>
19-
<p>In other words, we build <a href="/ref/tests/Dockerfile.playwright"><code>tests/Dockerfile.playwright</code></a>, and then run <a href="/ref/playwright/test.py"><code>playwright/test.py</code></a> inside that container. The container is called <code>atr-playwright</code>; if you want to give the container a different name, then you'll need to run the manual <code>docker</code> commands. Replace <code>docker</code> with the name of your Docker-compatible OCI runtime to use an alternative runtime.</p>
20-
<p>The tests should, as of 14 Oct 2025, take about 20 to 25 seconds to run. The last line should be <code>Tests finished successfully</code>, and if the tests do not complete successfully there should be an obvious Python backtrace.</p>
26+
<p>In other words, we build <a href="/ref/tests/Dockerfile.playwright"><code>tests/Dockerfile.playwright</code></a>, and then run <a href="/ref/playwright/test.py"><code>playwright/test.py</code></a> inside that container using host networking to access your locally running ATR instance. Replace <code>docker</code> with the name of your Docker-compatible OCI runtime to use an alternative runtime.</p>
27+
<h3 id="test-duration">Test duration</h3>
28+
<p>The tests should, as of 14 Oct 2025, take about 40 to 50 seconds to run in Docker Compose, and 20 to 25 seconds to run on the host. The last line of the test output should be <code>Tests finished successfully</code>, and if the tests do not complete successfully there should be an obvious Python backtrace.</p>
2129
<h2 id="creating-tests">Creating tests</h2>
2230
<p>You can add tests to <code>playwright/test.py</code>. If you're feeling particularly adventurous, you can add separate unit tests etc., but it's okay to add tests only to the Playwright test script until <a href="https://github.com/apache/tooling-trusted-releases/issues/209">Issue #209</a> is resolved.</p>
2331
<h3 id="how-the-tests-work">How the tests work</h3>

atr/docs/running-and-creating-tests.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,21 @@
1515

1616
We currently only have end-to-end browser tests, but we plan to expand these as part of [Issue #209](https://github.com/apache/tooling-trusted-releases/issues/209). Meanwhile, these browser tests serve as a simple consistency check when developing ATR.
1717

18-
To run the tests, you will need Docker. Other OCI runtimes should work, but you will need to edit the [`Makefile`](/ref/Makefile) or run your own command. The simple way to run the tests is:
18+
To run the tests, you will need Docker. Other OCI runtimes should work, but you will need to edit the test scripts accordingly.
19+
20+
### Using Docker Compose
21+
22+
The simplest way to run the tests is using Docker Compose, which starts both ATR and the Playwright test container:
23+
24+
```shell
25+
sh tests/run-tests.sh
26+
```
27+
28+
This uses [`tests/docker-compose.yml`](/ref/tests/docker-compose.yml) to orchestrate the test environment. The ATR server runs in one container and the Playwright tests run in another, connected via a Docker network.
29+
30+
### Using host networking
31+
32+
If you already have ATR running locally with `make serve-local`, you can run the Playwright tests directly against it instead of using Docker Compose:
1933

2034
```shell
2135
make build-playwright && make run-playwright
@@ -28,9 +42,11 @@ docker build -t atr-playwright -f tests/Dockerfile.playwright playwright
2842
docker run --net=host -it atr-playwright python3 test.py --skip-slow
2943
```
3044

31-
In other words, we build [`tests/Dockerfile.playwright`](/ref/tests/Dockerfile.playwright), and then run [`playwright/test.py`](/ref/playwright/test.py) inside that container. The container is called `atr-playwright`; if you want to give the container a different name, then you'll need to run the manual `docker` commands. Replace `docker` with the name of your Docker-compatible OCI runtime to use an alternative runtime.
45+
In other words, we build [`tests/Dockerfile.playwright`](/ref/tests/Dockerfile.playwright), and then run [`playwright/test.py`](/ref/playwright/test.py) inside that container using host networking to access your locally running ATR instance. Replace `docker` with the name of your Docker-compatible OCI runtime to use an alternative runtime.
46+
47+
### Test duration
3248

33-
The tests should, as of 14 Oct 2025, take about 20 to 25 seconds to run. The last line should be `Tests finished successfully`, and if the tests do not complete successfully there should be an obvious Python backtrace.
49+
The tests should, as of 14 Oct 2025, take about 40 to 50 seconds to run in Docker Compose, and 20 to 25 seconds to run on the host. The last line of the test output should be `Tests finished successfully`, and if the tests do not complete successfully there should be an obvious Python backtrace.
3450

3551
## Creating tests
3652

playwright/test.py

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import playwright.sync_api as sync_api
3535
import rich.logging
3636

37+
ATR_BASE_URL: Final[str] = os.environ.get("ATR_BASE_URL", "https://localhost.apache.org:8080")
3738
OPENPGP_TEST_UID: Final[str] = "<apache-tooling@example.invalid>"
3839
SSH_KEY_COMMENT: Final[str] = "atr-playwright-test@127.0.0.1"
3940
SSH_KEY_PATH: Final[str] = "/root/.ssh/id_ed25519"
@@ -92,7 +93,7 @@ def get_default_gateway_ip() -> str | None:
9293

9394

9495
def go_to_path(page: sync_api.Page, path: str, wait: bool = True) -> None:
95-
page.goto(f"https://localhost.apache.org:8080{path}")
96+
page.goto(f"{ATR_BASE_URL}{path}")
9697
if wait:
9798
wait_for_path(page, path)
9899

@@ -313,21 +314,22 @@ def main() -> None:
313314
)
314315

315316
logging.debug(f"Log level set to {args.log.upper()}")
316-
# Add localhost.apache.org to /etc/hosts
317-
default_gateway_ip = get_default_gateway_ip()
318-
if default_gateway_ip is not None:
319-
with open("/etc/hosts", "a") as f:
320-
f.write(f"{default_gateway_ip} localhost.apache.org\n")
321-
logging.info(f"Added localhost.apache.org to /etc/hosts with IP {default_gateway_ip}")
322-
else:
323-
logging.warning("Could not determine default gateway IP, skipping /etc/hosts modification")
317+
if "ATR_BASE_URL" not in os.environ:
318+
# Add localhost.apache.org to /etc/hosts
319+
default_gateway_ip = get_default_gateway_ip()
320+
if default_gateway_ip is not None:
321+
with open("/etc/hosts", "a") as f:
322+
f.write(f"{default_gateway_ip} localhost.apache.org\n")
323+
logging.info(f"Added localhost.apache.org to /etc/hosts with IP {default_gateway_ip}")
324+
else:
325+
logging.warning("Could not determine default gateway IP, skipping /etc/hosts modification")
324326

325327
run_tests(args.skip_slow, args.tidy)
326328

327329

328330
def poll_for_tasks_completion(page: sync_api.Page, project_name: str, version_name: str, revision: str) -> None:
329331
rev_path = f"{project_name}/{version_name}/{revision}"
330-
polling_url = f"https://localhost.apache.org:8080/admin/ongoing-tasks/{rev_path}"
332+
polling_url = f"{ATR_BASE_URL}/admin/ongoing-tasks/{rev_path}"
331333
logging.info(f"Polling URL: {polling_url}")
332334

333335
max_wait_seconds = 18
@@ -930,17 +932,17 @@ def test_projects_02_check_directory(page: sync_api.Page, credentials: Credentia
930932
go_to_path(page, "/projects")
931933
logging.info("Project directory page loaded")
932934

933-
logging.info("Checking for the Apache Tooling project card")
934-
h3_locator = page.get_by_text("Apache Tooling", exact=True)
935-
tooling_card_locator = h3_locator.locator("xpath=ancestor::div[contains(@class, 'project-card')]")
936-
sync_api.expect(tooling_card_locator).to_be_visible()
937-
logging.info("Apache Tooling project card found successfully")
935+
logging.info("Checking for the Apache Test project card")
936+
h3_locator = page.get_by_text("Apache Test", exact=True)
937+
test_card_locator = h3_locator.locator("xpath=ancestor::div[contains(@class, 'project-card')]")
938+
sync_api.expect(test_card_locator).to_be_visible()
939+
logging.info("Apache Test project card found successfully")
938940

939941

940942
def test_projects_03_add_project(page: sync_api.Page, credentials: Credentials) -> None:
941-
base_project_label = "tooling"
942-
project_name = "Apache Tooling Test Example"
943-
project_label = "tooling-test-example"
943+
base_project_label = "test"
944+
project_name = "Apache Test Example"
945+
project_label = "test-example"
944946

945947
logging.info("Navigating to the add derived project page")
946948
go_to_path(page, f"/project/add/{base_project_label}")
@@ -1040,14 +1042,18 @@ def test_ssh_02_rsync_upload(page: sync_api.Page, credentials: Credentials) -> N
10401042

10411043
logging.info(f"Starting rsync upload test for {project_name}-{version_name}")
10421044

1043-
gateway_ip = get_default_gateway_ip()
1044-
if not gateway_ip:
1045-
raise RuntimeError("Cannot proceed without gateway IP")
1045+
if "ATR_BASE_URL" in os.environ:
1046+
ssh_host = os.environ.get("ATR_BASE_URL", "").replace("https://", "").replace(":8080", "")
1047+
else:
1048+
gateway_ip = get_default_gateway_ip()
1049+
if not gateway_ip:
1050+
raise RuntimeError("Cannot proceed without gateway IP")
1051+
ssh_host = gateway_ip
10461052

10471053
username = credentials.username
10481054
ssh_command = "ssh -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
10491055
source_path = f"{source_dir_abs}/"
1050-
destination = f"{username}@{gateway_ip}:/{project_name}/{version_name}/"
1056+
destination = f"{username}@{ssh_host}:/{project_name}/{version_name}/"
10511057

10521058
rsync_cmd = [
10531059
"rsync",

tests/docker-compose.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
services:
2+
atr:
3+
build:
4+
context: ..
5+
dockerfile: Dockerfile.alpine
6+
environment:
7+
- ALLOW_TESTS=1
8+
- APP_HOST=atr:8080
9+
- BIND=0.0.0.0:8080
10+
- SECRET_KEY=insecure-test-key
11+
- SSH_HOST=0.0.0.0
12+
networks:
13+
- test-network
14+
healthcheck:
15+
test: ["CMD", "curl", "-k", "-f", "https://localhost:8080/"]
16+
interval: 2s
17+
timeout: 1s
18+
retries: 30
19+
start_period: 10s
20+
21+
playwright:
22+
build:
23+
context: ../playwright
24+
dockerfile: ../tests/Dockerfile.playwright
25+
depends_on:
26+
atr:
27+
condition: service_healthy
28+
networks:
29+
- test-network
30+
command: python3 test.py --skip-slow
31+
environment:
32+
- ATR_BASE_URL=https://atr:8080
33+
34+
networks:
35+
test-network:
36+
driver: bridge

tests/run-tests.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/sh
2+
set -eu
3+
4+
cd "$(dirname "$0")"
5+
6+
echo "Building and running ATR integration tests..."
7+
docker compose up --build --abort-on-container-exit --exit-code-from playwright
8+
9+
# Clean up
10+
docker compose down -v

0 commit comments

Comments
 (0)