Source code for univention.testing.browser.appcenter
#!/usr/bin/python3
# SPDX-FileCopyrightText: 2023-2025 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only
import json
import logging
import re
from playwright.sync_api import Page, Response, expect
from univention.lib.i18n import Translation
from univention.testing.browser.lib import MIN, UMCBrowserTest
logger = logging.getLogger(__name__)
_ = Translation('ucs-test-framework').translate
[docs]
def wait_for_final_query(response: Response):
if not re.fullmatch('.*/univention/command/appcenter/query.*', response.url):
return False
request = response.request
if request.post_data is None:
return False
json_body = json.loads(request.post_data)
if 'options' in json_body and 'quick' in json_body['options'] and not json_body['options']['quick']:
logger.debug('URL: %s', response.url)
logger.debug('JSON content: %s', json_body)
logger.debug('TRUE')
return True
return False
[docs]
class AppCenter:
def __init__(self, tester: UMCBrowserTest):
self.tester: UMCBrowserTest = tester
self.page: Page = tester.page
self.module_name = _('App Center')
[docs]
def navigate(self, username='Administrator', password='univention'):
self.tester.login(username, password)
self.tester.open_module(self.module_name)
self.handle_first_open_dialog()
[docs]
def handle_first_open_dialog(self):
first_open_dialog = self.page.get_by_role('dialog', name='Univention App Center')
only_visible_when_no_dialog = self.page.get_by_role('heading', name=_('Available'))
expect(first_open_dialog.or_(only_visible_when_no_dialog)).to_be_visible(timeout=2 * MIN)
if first_open_dialog.is_visible():
first_open_dialog.get_by_label(_('Do not show this message again')).check()
first_open_dialog.get_by_role('button', name='Continue').click()
[docs]
def open_app(self, app_name: str):
"""Click on an app in the AppCenter overview"""
self.page.locator('.umcTile').get_by_text(app_name).first.click()
[docs]
def return_to_app_module_from_app_view(self):
"""Return to the app center overview from an opened app"""
back_to_overview = self.page.get_by_role('button', name=_('Back to overview'))
expect(back_to_overview).to_be_visible()
back_to_overview.click()
[docs]
def install_app(self, app_name: str):
"""Install an app. The AppCenter needs to be on the overview screen"""
self.open_app(app_name)
logger.info('Starting installation of %s', app_name)
install_button = self.page.get_by_role('button', name=_('Install'), exact=True)
expect(install_button).to_be_visible()
install_button.click()
self.handle_installation_dialog()
self.return_to_app_module_from_app_view()
logger.info('App installation done')
[docs]
def handle_installation_dialog(self):
start_installation = self.page.get_by_role('button', name=_('Start installation'))
continue_button = self.page.get_by_role('button', name=_('Continue'))
expect(start_installation.or_(continue_button)).to_be_visible()
if continue_button.is_visible():
continue_button.click()
start_installation.click()
expect(self.page.get_by_role('progressbar')).to_be_hidden(timeout=10 * MIN)
[docs]
def uninstall_app(self, app_name: str):
"""Uninstall an app. The AppCenter needs to be on the overview screen"""
self.open_app(app_name)
manage_installations = self.page.get_by_role('button', name=_('Manage installation'))
expect(manage_installations).to_be_visible(timeout=2 * MIN)
manage_installations.click()
uninstall_button = self.page.get_by_role('button', name=_('Uninstall'))
grid = self.page.get_by_role('grid')
expect(uninstall_button.or_(grid)).to_be_visible()
logger.info('Starting uninstall of %s', app_name)
if grid.is_visible():
self.tester.check_checkbox_in_grid_by_name(_('this computer'))
self.page.get_by_role('button', name=_('More')).click()
self.page.get_by_role('cell', name=_('Uninstall')).click()
else:
uninstall_button.click()
self.page.get_by_role('button', name=_('Start removal')).click()
expect(self.page.get_by_role('progressbar')).to_be_hidden(timeout=10 * MIN)
self.return_to_app_module_from_app_view()
logger.info('Uninstall done')