Providing the correct access token grants access to the upload zone.
1
wrong_token_shows_error
Providing a wrong access token shows an error.
0
upload_zone_visible_without_gate
If no gate is configured, upload zone is immediately visible.
1
Screenshots
03 Wrong Token
Wrong token response
02 After Token
After entering access token
Deterministic view (non-dynamic areas only)

01 Landing
Landing page (may show gate or upload zone)
Deterministic view (non-dynamic areas only)

04 No Gate
Upload zone without gate
Deterministic view (non-dynamic areas only)

View test source โ tests/qa/v030/p1__access_gate/test__access_gate.py
```python
"""UC-10: Access token gate โ browser tests (P1).
Test flow:
- Navigate to /en-gb/ (upload page)
- If access gate is active, verify token entry UI appears
- Enter the valid access token โ verify upload zone becomes visible
- Verify wrong token shows an error
API-level tests (token counter) live in via__httpx/test__access_gate.py.
v0.3.1 notes:
- CR-001: Use body[data-ready] instead of networkidle.
- CR-002: Use data-testid selectors for access gate elements:
[data-testid="access-gate-input"] (was #access-token-input)
[data-testid="access-gate-submit"] (was #access-token-submit)
[data-testid="access-gate-error"] (was generic text search)
ID selectors (#access-token-input) are preserved for backward compatibility
and still work, but data-testid is the preferred stable selector.
"""
import pytest
pytestmark = pytest.mark.p1
class TestAccessGate:
"""Verify the access token gate on the upload page."""
def _load_upload_page(self, page, ui_url):
"""Navigate to the upload page and wait for it to be ready."""
page.goto(f"{ui_url}/en-gb/", wait_until="commit")
page.wait_for_selector("body[data-ready]", timeout=10_000)
def test_upload_accessible_with_token(self, page, ui_url, send_server, screenshots):
"""Providing the correct access token grants access to the upload zone."""
self._load_upload_page(page, ui_url)
screenshots.capture(page, "01_landing", "Landing page (may show gate or upload zone)")
# Use explicit IDs โ the combined selector with .first can hit the language
# dropdown button which appears before #access-token-submit in the DOM.
# See bugs/test__bug__generic_button_opens_language_dropdown.py for details.
gate_input = page.locator('[data-testid="access-gate-input"], #access-token-input').first
if gate_input.is_visible(timeout=3_000):
gate_input.fill(send_server.access_token)
page.locator('#access-token-submit').click()
page.wait_for_selector("body[data-ready]", timeout=10_000)
page.wait_for_timeout(800)
screenshots.capture(page, "02_after_token", "After entering access token")
# Upload zone should now be visible
file_input = page.locator("#file-input, [data-testid='file-input']").first
page_text = page.text_content("body") or ""
has_upload = file_input.count() > 0
has_keyword = any(kw in page_text.lower() for kw in [
"upload", "drop", "browse", "choose"
])
assert has_upload or has_keyword, \
"Upload zone not visible after providing valid access token"
def test_wrong_token_shows_error(self, page, ui_url, send_server, screenshots):
"""Providing a wrong access token shows an error."""
self._load_upload_page(page, ui_url)
gate_input = page.locator('[data-testid="access-gate-input"], #access-token-input').first
if gate_input.is_visible(timeout=3_000):
gate_input.fill("wrong-token-12345-xxxxx")
page.locator('#access-token-submit').click()
page.wait_for_timeout(1_000)
screenshots.capture(page, "03_wrong_token", "Wrong token response")
# CR-002: data-testid="access-gate-error" is the error element
error_el = page.locator('[data-testid="access-gate-error"]').first
if error_el.is_visible(timeout=2_000):
error_text = error_el.text_content() or ""
assert error_text.strip(), "access-gate-error element is visible but empty"
else:
# Fallback: check body text or that gate is still visible
page_text = page.text_content("body") or ""
assert any(kw in page_text.lower() for kw in [
"error", "invalid", "wrong", "incorrect", "denied"
]) or gate_input.is_visible(), \
"No error shown for wrong access token"
def test_upload_zone_visible_without_gate(self, page, ui_url, send_server, screenshots):
"""If no gate is configured, upload zone is immediately visible."""
self._load_upload_page(page, ui_url)
gate_input = page.locator('[data-testid="access-gate-input"], #access-token-input').first
if gate_input.is_visible(timeout=2_000):
pytest.skip("Access gate is active; testing gated flow in other tests")
# No gate โ upload zone should be directly visible
file_input = page.locator("#file-input, [data-testid='file-input']").first
screenshots.capture(page, "04_no_gate", "Upload zone without gate")
page_text = page.text_content("body") or ""
assert file_input.count() > 0 or any(kw in page_text.lower() for kw in [
"upload", "drop", "browse"
]), "Upload zone not visible (and no gate present)"
```