test: add e2e tests for service store install/uninstall flow
Unit Tests / test (push) Successful in 11m13s
Unit Tests / test (push) Successful in 11m13s
Tests verify: - /services page loads and lists all available services - Admin can install calendar, files, email, and webmail via the store UI - Install order respects dependencies (email before webmail) - Uninstall flow shows confirmation dialog before removing - Dashboard shows service links after install Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,175 @@
|
|||||||
|
"""
|
||||||
|
Service Store E2E tests.
|
||||||
|
|
||||||
|
Tests that the admin can install and remove store services via the /store page.
|
||||||
|
Requires a running PIC stack with access to the service store index and registry.
|
||||||
|
|
||||||
|
Run with:
|
||||||
|
pytest tests/e2e/ui/test_service_store.py -v --base-url http://<pic-host>
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.ui
|
||||||
|
|
||||||
|
STORE_ROUTE = '/services'
|
||||||
|
|
||||||
|
# Services to install in dependency order (webmail requires email)
|
||||||
|
INSTALL_ORDER = ['calendar', 'files', 'email', 'webmail']
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Helpers
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def _goto_store(page, webui_base):
|
||||||
|
page.goto(f"{webui_base}{STORE_ROUTE}")
|
||||||
|
page.wait_for_load_state('networkidle')
|
||||||
|
|
||||||
|
|
||||||
|
def _service_card(page, service_name):
|
||||||
|
"""Return the card element containing the named service."""
|
||||||
|
return page.locator('.card', has=page.get_by_text(service_name, exact=False)).first
|
||||||
|
|
||||||
|
|
||||||
|
def _is_installed(page, service_name):
|
||||||
|
card = _service_card(page, service_name)
|
||||||
|
return card.get_by_text('Installed', exact=False).is_visible()
|
||||||
|
|
||||||
|
|
||||||
|
def _install_service(page, webui_base, service_name, timeout_ms=180_000):
|
||||||
|
"""Click Install on a service card and wait until the card shows Installed."""
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
card = _service_card(page, service_name)
|
||||||
|
install_btn = card.get_by_role('button', name='Install')
|
||||||
|
install_btn.click()
|
||||||
|
# Wait for the Install button to disappear (replaced by Remove) or for
|
||||||
|
# the Installed badge to appear — whichever comes first.
|
||||||
|
card.get_by_text('Installed', exact=False).wait_for(state='visible', timeout=timeout_ms)
|
||||||
|
|
||||||
|
|
||||||
|
def _remove_service(page, webui_base, service_name, timeout_ms=60_000):
|
||||||
|
"""Click Uninstall on a service card and confirm, then wait until Install reappears."""
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
card = _service_card(page, service_name)
|
||||||
|
card.get_by_role('button', name='Uninstall').click()
|
||||||
|
# A confirmation dialog appears — click the confirm Uninstall button
|
||||||
|
page.get_by_role('button', name='Uninstall Service').wait_for(state='visible', timeout=5000)
|
||||||
|
page.get_by_role('button', name='Uninstall Service').click()
|
||||||
|
card.get_by_role('button', name='Install').wait_for(state='visible', timeout=timeout_ms)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Tests
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_store_page_loads(admin_page, webui_base):
|
||||||
|
"""Store page must load and list available services without errors."""
|
||||||
|
page = admin_page
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
|
||||||
|
# Should not show a generic error message
|
||||||
|
assert 'Could not load the service store' not in page.content(), (
|
||||||
|
'Store page showed error: could not load the service store'
|
||||||
|
)
|
||||||
|
|
||||||
|
# At least one service card should be visible
|
||||||
|
cards = page.locator('.card').all()
|
||||||
|
assert len(cards) > 0, 'No service cards found on the store page'
|
||||||
|
|
||||||
|
|
||||||
|
def test_store_shows_known_services(admin_page, webui_base):
|
||||||
|
"""Store page must list email, calendar, files, and webmail."""
|
||||||
|
page = admin_page
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
|
||||||
|
for name in ('Email Server', 'Calendar', 'File Storage', 'Webmail'):
|
||||||
|
assert page.get_by_text(name, exact=False).first.is_visible(), (
|
||||||
|
f"Expected service '{name}' not visible on store page"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_install_calendar(admin_page, webui_base):
|
||||||
|
"""Admin can install the calendar service."""
|
||||||
|
page = admin_page
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
|
||||||
|
if _is_installed(page, 'Calendar'):
|
||||||
|
pytest.skip('calendar already installed — skipping install test')
|
||||||
|
|
||||||
|
_install_service(page, webui_base, 'Calendar & Contacts', timeout_ms=180_000)
|
||||||
|
assert _is_installed(page, 'Calendar'), (
|
||||||
|
'Calendar service card did not show Installed after install'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_install_files(admin_page, webui_base):
|
||||||
|
"""Admin can install the file storage service."""
|
||||||
|
page = admin_page
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
|
||||||
|
if _is_installed(page, 'File Storage'):
|
||||||
|
pytest.skip('files already installed — skipping install test')
|
||||||
|
|
||||||
|
_install_service(page, webui_base, 'File Storage', timeout_ms=180_000)
|
||||||
|
assert _is_installed(page, 'File Storage'), (
|
||||||
|
'Files service card did not show Installed after install'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_install_email(admin_page, webui_base):
|
||||||
|
"""Admin can install the email service."""
|
||||||
|
page = admin_page
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
|
||||||
|
if _is_installed(page, 'Email Server'):
|
||||||
|
pytest.skip('email already installed — skipping install test')
|
||||||
|
|
||||||
|
_install_service(page, webui_base, 'Email Server', timeout_ms=300_000)
|
||||||
|
assert _is_installed(page, 'Email Server'), (
|
||||||
|
'Email service card did not show Installed after install'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_install_webmail(admin_page, webui_base):
|
||||||
|
"""Admin can install webmail after email is installed."""
|
||||||
|
page = admin_page
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
|
||||||
|
if not _is_installed(page, 'Email Server'):
|
||||||
|
pytest.skip('email not installed — webmail requires email first')
|
||||||
|
|
||||||
|
if _is_installed(page, 'Webmail'):
|
||||||
|
pytest.skip('webmail already installed — skipping install test')
|
||||||
|
|
||||||
|
_install_service(page, webui_base, 'Webmail', timeout_ms=180_000)
|
||||||
|
assert _is_installed(page, 'Webmail'), (
|
||||||
|
'Webmail service card did not show Installed after install'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_installed_services_appear_on_dashboard(admin_page, webui_base):
|
||||||
|
"""After installation, services should appear as links on the dashboard."""
|
||||||
|
page = admin_page
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
|
||||||
|
page.goto(f"{webui_base}/")
|
||||||
|
page.wait_for_load_state('networkidle')
|
||||||
|
|
||||||
|
# Check that at least the Cell Home link is present
|
||||||
|
assert page.get_by_text('Cell Home', exact=False).is_visible(), (
|
||||||
|
'Dashboard does not show the Cell Home service link'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_uninstall_webmail(admin_page, webui_base):
|
||||||
|
"""Admin can uninstall the webmail service."""
|
||||||
|
page = admin_page
|
||||||
|
_goto_store(page, webui_base)
|
||||||
|
|
||||||
|
if not _is_installed(page, 'Webmail'):
|
||||||
|
pytest.skip('webmail not installed — skipping uninstall test')
|
||||||
|
|
||||||
|
_remove_service(page, webui_base, 'Webmail')
|
||||||
|
assert not _is_installed(page, 'Webmail'), (
|
||||||
|
'Webmail service card still shows Installed after uninstall'
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user