1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Functional, browser based tests for syncthing app.
"""
import time
import pytest
from plinth.tests import functional
pytestmark = [pytest.mark.apps, pytest.mark.syncthing, pytest.mark.sso]
class TestSyncthingApp(functional.BaseAppTests):
app_name = 'syncthing'
has_service = True
has_web = True
def test_notifications(self, session_browser):
"""Test that authentication and usage reporting notifications are not
shown."""
functional.app_enable(session_browser, self.app_name)
functional.access_url(session_browser, self.app_name)
_assert_usage_report_notification_not_shown(session_browser)
_assert_authentication_notification_not_shown(session_browser)
def test_add_remove_folder(self, session_browser):
"""Test adding and removing a folder."""
functional.app_enable(session_browser, self.app_name)
if _folder_is_present(session_browser, 'Test'):
_remove_folder(session_browser, 'Test')
_add_folder(session_browser, 'Test', '/tmp')
assert _folder_is_present(session_browser, 'Test')
_remove_folder(session_browser, 'Test')
assert not _folder_is_present(session_browser, 'Test')
@pytest.mark.backups
def test_backup_restore(self, session_browser):
"""Test backup and restore of app data."""
functional.app_enable(session_browser, self.app_name)
if _folder_is_present(session_browser, 'Test'):
_remove_folder(session_browser, 'Test')
_add_folder(session_browser, 'Test', '/tmp')
functional.backup_create(session_browser, self.app_name,
'test_syncthing')
_remove_folder(session_browser, 'Test')
time.sleep(1) # Helps with browsing away in next step
functional.backup_restore(session_browser, self.app_name,
'test_syncthing')
assert _folder_is_present(session_browser, 'Test')
def test_user_group_access(self, session_browser):
"""Test that only users in syncthing-access group can access syncthing
site."""
functional.app_enable(session_browser, self.app_name)
if not functional.user_exists(session_browser, 'syncthinguser'):
functional.create_user(session_browser, 'syncthinguser',
groups=['syncthing-access'])
if not functional.user_exists(session_browser, 'nogroupuser'):
functional.create_user(session_browser, 'nogroupuser')
functional.login_with_account(session_browser, functional.base_url,
'syncthinguser')
assert functional.is_available(session_browser, self.app_name)
functional.login_with_account(session_browser, functional.base_url,
'nogroupuser')
assert not functional.is_available(session_browser, self.app_name)
functional.login(session_browser)
def _assert_usage_report_notification_not_shown(session_browser):
_load_main_interface(session_browser)
assert session_browser.find_by_id('ur').visible is False
def _assert_authentication_notification_not_shown(session_browser):
_load_main_interface(session_browser)
assert bool(session_browser.find_by_css(
'#authenticationUserAndPassword *')) is False
def _load_main_interface(browser):
"""Close the dialog boxes that many popup after visiting the URL."""
functional.access_url(browser, 'syncthing')
def service_is_available():
if browser.is_element_present_by_xpath(
'//h1[text()="Service Unavailable"]'):
functional.access_url(browser, 'syncthing')
return False
return True
# After a backup restore, service may not be available immediately
functional.eventually(service_is_available)
# Wait for javascript loading process to complete
functional.eventually(lambda: browser.evaluate_script(
'angular.element("[ng-controller=SyncthingController]").scope()'
'.thisDevice().name'))
# Give browser additional time to setup site
time.sleep(1)
def _folder_is_present(browser, folder_name):
"""Return whether a folder is present in Syncthing."""
_load_main_interface(browser)
folder_names = browser.find_by_css('#folders .panel-title-text span')
folder_names = [folder_name.text for folder_name in folder_names]
return folder_name in folder_names
def _add_folder(browser, folder_name, folder_path):
"""Add a new folder to Synthing."""
_load_main_interface(browser)
add_folder_xpath = '//button[contains(@ng-click, "addFolder")]'
browser.find_by_xpath(add_folder_xpath).click()
folder_dialog = browser.find_by_id('editFolder').first
functional.eventually(lambda: folder_dialog.visible)
browser.find_by_id('folderLabel').fill(folder_name)
browser.find_by_id('folderPath').fill(folder_path)
save_folder_xpath = './/button[contains(@ng-click, "saveFolder")]'
folder_dialog.find_by_xpath(save_folder_xpath).first.click()
functional.eventually(lambda: not folder_dialog.visible)
def _remove_folder(browser, folder_name):
"""Remove a folder from Synthing."""
_load_main_interface(browser)
# Find folder
folder = None
for current_folder in browser.find_by_css('#folders > .panel'):
name = current_folder.find_by_css('.panel-title-text span').first.text
if name == folder_name:
folder = current_folder
break
# Edit folder button
folder.find_by_css('button.panel-heading').first.click()
functional.eventually(lambda: folder.find_by_css('div.collapse.in'))
edit_folder_xpath = './/button[contains(@ng-click, "editFolder")]'
edit_folder_button = folder.find_by_xpath(edit_folder_xpath).first
edit_folder_button.scroll_to()
edit_folder_button.click()
# Edit folder dialog
folder_dialog = browser.find_by_id('editFolder').first
functional.eventually(lambda: folder_dialog.visible)
remove_button_xpath = './/button[contains(@data-target, "remove-folder")]'
folder_dialog.find_by_xpath(remove_button_xpath).first.click()
# Remove confirmation dialog
remove_folder_dialog = browser.find_by_id('remove-folder-confirmation')
functional.eventually(lambda: remove_folder_dialog.visible)
remove_button_xpath = './/button[contains(@ng-click, "deleteFolder")]'
remove_folder_dialog.find_by_xpath(remove_button_xpath).first.click()
functional.eventually(lambda: not folder_dialog.visible)
|