def _visit_library(browser, name): """Open the page for the library.""" functional.visit(browser, '/calibre/') # Calibre interface will be available a short time after restarting the # service. def _service_available(): unavailable_xpath = '//h1[contains(text(), "Service Unavailable")]' available = not browser.find_by_xpath(unavailable_xpath) if not available: time.sleep(0.5) functional.visit(browser, '/calibre/') return available functional.eventually(_service_available) functional.eventually(browser.find_by_css, args=[f'.calibre-push-button[data-lid="{name}"]']) link = browser.find_by_css(f'.calibre-push-button[data-lid="{name}"]') if not link: raise ValueError('Library not found') link.first.click() functional.eventually(browser.find_by_css, ['.book-list-cover-grid'])
def _delete_main_page(browser, username, password): """Delete the mediawiki main page.""" _login(browser, username, password) functional.visit(browser, '/mediawiki/index.php?title=Main_Page&action=delete') with functional.wait_for_page_update(browser): browser.find_by_id('wpConfirmB').first.click()
def _set_language(browser, language_code): username = functional.config['DEFAULT']['username'] functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username)) browser.find_by_xpath('//select[@id="id_language"]//option[@value="' + language_code + '"]').first.click() browser.find_by_id('id_confirm_password').fill(_admin_password) functional.submit(browser)
def _visit_site(browser): """Visit WordPress and run the first setup wizard if needed.""" _load_site(browser) if '/install.php' in browser.url: browser.fill('weblog_title', 'Test Blog') browser.fill('user_name', functional.config['DEFAULT']['username']) # browser.fill() once does not work for some reason for password field browser.fill('admin_password', functional.config['DEFAULT']['password']) browser.fill('admin_password', functional.config['DEFAULT']['password']) browser.check('pw_weak') browser.fill('admin_email', '*****@*****.**') functional.submit(browser) if not browser.find_by_css('.install-success'): raise Exception('WordPress installation failed') functional.visit(browser, '/wordpress/wp-admin/') if not browser.find_by_id('wpadminbar'): functional.visit(browser, '/wordpress/wp-login.php') browser.fill('log', functional.config['DEFAULT']['username']) browser.fill('pwd', functional.config['DEFAULT']['password']) functional.submit(browser)
def _delete_image(browser, username, password, image): """Delete an image from MediaWiki.""" _login(browser, username, password) path = f'/mediawiki/index.php?title=File:{image}&action=delete' functional.visit(browser, path) delete_button = browser.find_by_id('mw-filedelete-submit') functional.submit(browser, element=delete_button)
def _add_password(browser): functional.visit(browser, '/plinth/apps/bepasty/add') for permission in ['read', 'create', 'list', 'delete', 'admin']: browser.find_by_css('#id_bepasty-permissions input[value="{}"]'.format( permission)).check() browser.fill('bepasty-comment', 'bepasty functional test') functional.submit(browser, form_class='form-add')
def _service_available(): unavailable_xpath = '//h1[contains(text(), "Service Unavailable")]' available = not browser.find_by_xpath(unavailable_xpath) if not available: time.sleep(0.5) functional.visit(browser, '/calibre/') return available
def _get_post(browser, title): """Return whether a blog post with a given title is available.""" _visit_site(browser) functional.visit(browser, '/wordpress/wp-admin/edit.php') xpath = '//tr[contains(@class, "type-post")][.//a[contains(@class, ' \ f'"row-title") and contains(text(), "{title}")]]' post = browser.find_by_xpath(xpath) return post[0] if post else None
def _add_share(browser, name, path, group): """Add a share in sharing app.""" functional.visit(browser, '/plinth/apps/sharing/add/') browser.fill('sharing-name', name) browser.fill('sharing-path', path) browser.find_by_css( '#id_sharing-groups input[value="{}"]'.format(group)).check() functional.submit(browser)
def _get_ssh_keys(browser, username=None): functional.visit(browser, '/plinth/') if username is None: browser.find_by_id('id_user_menu').click() browser.find_by_id('id_user_edit_menu').click() else: functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username)) return browser.find_by_id('id_ssh_keys').text
def _delete_all(browser): functional.visit(browser, '/plinth/sys/snapshot/manage/') delete_button = browser.find_by_name('delete_selected').first if not delete_button['disabled']: browser.find_by_id('select-all').check() functional.submit(browser, delete_button) confirm_button = browser.find_by_name('delete_confirm') if confirm_button: # Only if redirected to confirm page functional.submit(browser, confirm_button)
def _load_site(browser): """Visit WordPress site and wait until becomes available.""" functional.visit(browser, '/wordpress/wp-admin/') def loaded(): browser.reload() title_node = browser.find_by_css('title') return (not title_node or '404' not in title_node[0].text) functional.eventually(loaded)
def _verify_upload_password(browser, password): functional.visit(browser, '/coquelicot') # ensure the password form is scrolled into view browser.execute_script('window.scrollTo(100, 0)') browser.find_by_id('upload_password').fill(password) actions = ActionChains(browser.driver) actions.send_keys(Keys.RETURN) actions.perform() assert functional.eventually(browser.is_element_present_by_css, args=['div[style*="display: none;"]'])
def _image_exists(browser, image): """Check whether the given image exists.""" functional.visit(browser, '/mediawiki/Special:ListFiles') elements = browser.links.find_by_partial_href(image) if not elements: # Necessary but insufficient check. # Special:ListFiles also shows deleted images. return False # The second hyperlink is a direct link to the image. response = requests.get(elements[1]['href'], verify=False) return response.status_code != 404
def _upload_image(browser, username, password, image): """Upload an image to MediaWiki. Idempotent.""" functional.visit(browser, '/mediawiki') _login(browser, username, password) # Upload file functional.visit(browser, '/mediawiki/Special:Upload') file_path = pathlib.Path(__file__).parent file_path /= '../../../../static/themes/default/img/' + image browser.attach_file('wpUploadFile', str(file_path.resolve())) functional.submit(browser, element=browser.find_by_name('wpUpload')[0])
def _get_number_of_ed2k_files(browser): """Return the number of ed2k files currently in mldonkey.""" functional.visit(browser, '/mldonkey/') with browser.get_iframe('commands') as commands_frame: commands_frame.find_by_xpath( '//tr//td[contains(text(), "Transfers")]').click() with browser.get_iframe('output') as output_frame: functional.eventually(output_frame.find_by_css, ['.downloaded']) return len(output_frame.find_by_css('.dl-1')) + len( output_frame.find_by_css('.dl-2'))
def _upload_sample_torrent(browser): """Upload a sample torrent into transmission.""" functional.visit(browser, '/transmission') file_path = os.path.join(os.path.dirname(__file__), 'data', 'sample.torrent') browser.click_link_by_id('toolbar-open') functional.eventually(browser.is_element_not_present_by_css, args=['#upload-container[style="display: none;"]']) browser.attach_file('torrent_files[]', [file_path]) browser.click_link_by_id('upload_confirm_button') functional.eventually(browser.is_element_present_by_css, args=['#torrent_list .torrent'])
def _upload_image(browser, username, password, image, ignore_warnings=True): """Upload an image to MediaWiki. Idempotent.""" functional.visit(browser, '/mediawiki') _login(browser, username, password) # Upload file functional.visit(browser, '/mediawiki/Special:Upload') file_path = pathlib.Path(__file__).parent file_path /= '../../../../static/themes/default/img/' + image.lower() browser.attach_file('wpUploadFile', str(file_path.resolve())) if ignore_warnings: # allow uploading file with the same name browser.find_by_name('wpIgnoreWarning').first.click() functional.submit(browser, element=browser.find_by_name('wpUpload')[0])
def _write_post(browser, title): """Create a blog post in WordPress site.""" post = _get_post(browser, title) if post: _delete_post(browser, title) functional.visit(browser, '/wordpress/wp-admin/post-new.php') if browser.find_by_css('.edit-post-welcome-guide'): browser.find_by_css('.components-modal__header button')[0].click() browser.find_by_id('post-title-0').fill(title) browser.find_by_css('.editor-post-publish-button__button')[0].click() functional.eventually(browser.find_by_css, ['.editor-post-publish-button']) browser.find_by_css('.editor-post-publish-button')[0].click()
def _jsxc_login(browser): """Login to JSXC.""" username = functional.config['DEFAULT']['username'] password = functional.config['DEFAULT']['password'] functional.visit(browser, '/plinth/apps/jsxc/jsxc/') assert functional.eventually(browser.find_by_text, ['BOSH Server reachable.']) if browser.find_by_text('relogin'): browser.reload() browser.find_by_id('jsxc-username').fill(username) browser.find_by_id('jsxc-password').fill(password) browser.find_by_id('jsxc-submit').click() assert functional.eventually(browser.find_by_css, ['#jsxc_roster.jsxc_state_shown'])
def _set_ssh_keys(browser, ssh_keys, username=None): if username is None: browser.find_by_id('id_user_menu').click() browser.find_by_id('id_user_edit_menu').click() else: functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username)) current_user = browser.find_by_id('id_user_menu_link').text auth_password = functional.get_password(current_user) browser.find_by_id('id_ssh_keys').fill(ssh_keys) browser.find_by_id('id_confirm_password').fill(auth_password) functional.submit(browser)
def _remove_all_torrents(browser): """Remove all torrents from transmission.""" functional.visit(browser, '/transmission') while True: torrents = browser.find_by_css('#torrent_list .torrent') if not torrents: break torrents.first.click() functional.eventually(browser.is_element_not_present_by_css, args=['#toolbar-remove.disabled']) browser.click_link_by_id('toolbar-remove') functional.eventually( browser.is_element_not_present_by_css, args=['#dialog-container[style="display: none;"]']) browser.click_link_by_id('dialog_confirm_button') functional.eventually(browser.is_element_present_by_css, args=['#toolbar-remove.disabled'])
def _change_password(browser, new_password, current_password=None, username=None): if username is None: browser.find_by_id('id_user_menu').click() browser.find_by_id('id_change_password_menu').click() else: functional.visit( browser, '/plinth/sys/users/{}/change_password/'.format(username)) current_user = browser.find_by_id('id_user_menu_link').text auth_password = current_password or functional.get_password(current_user) browser.find_by_id('id_new_password1').fill(new_password) browser.find_by_id('id_new_password2').fill(new_password) browser.find_by_id('id_confirm_password').fill(auth_password) functional.submit(browser)
def _cannot_list_all(browser): functional.visit(browser, '/bepasty/+list') return functional.eventually(browser.is_text_present, ['Forbidden'], 5)
def _can_list_all(browser): functional.visit(browser, '/bepasty') return functional.eventually(browser.links.find_by_href, ['/bepasty/+list'], 5)
def _logout(browser): functional.visit(browser, '/bepasty') logout = browser.find_by_value('Logout') if logout: logout.click()
def transmission_assert_number_of_torrents(session_browser, torrents_number): functional.visit(session_browser, '/transmission') assert functional.eventually( lambda: torrents_number == _get_number_of_torrents(session_browser))
def _go_to_status_logs(browser): functional.visit(browser, '/plinth/help/status-log/')
def _modify_upload_password(browser, password): """Change the upload password for coquelicot to the given value""" functional.visit(browser, '/plinth/apps/coquelicot/') browser.find_by_id('id_upload_password').fill(password) functional.submit(browser, form_class='form-configuration')
def _get_max_file_size(browser): """Get the maximum file size of coquelicot""" functional.visit(browser, '/plinth/apps/coquelicot/') return int(browser.find_by_id('id_max_file_size').value)