Imported Upstream version 4.0.5

This commit is contained in:
Mario Fetka
2021-07-25 07:50:50 +02:00
parent 8ff3be4216
commit 3bfaa6e020
2049 changed files with 317193 additions and 1632423 deletions

View File

@@ -20,8 +20,3 @@
"""
Sub-package containing Web UI integration tests
"""
import ipatests.util
ipatests.util.check_ipaclient_unittests()
ipatests.util.check_no_ipaapi() # also ignore in make fasttest

View File

@@ -26,7 +26,7 @@ DATA = {
'add': [
('textbox', 'cn', PKEY),
('textarea', 'description', 'test-group desc'),
('radio', 'type', 'nonposix'),
('radio', 'type', 'normal'),
],
'mod': [
('textarea', 'description', 'test-group desc modified'),
@@ -68,13 +68,3 @@ DATA5 = {
('textarea', 'description', 'test-group5 desc'),
]
}
PKEY6 = 'itest-group6'
DATA6 = {
'pkey': PKEY6,
'add': [
('textbox', 'cn', PKEY6),
('textarea', 'description', 'test-group6 desc'),
('textbox', 'gidnumber', '77777'),
]
}

View File

@@ -1,20 +0,0 @@
#
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
#
ENTITY = 'idview'
USER_FACET = 'idoverrideuser'
GROUP_FACET = 'idoverridegroup'
HOST_FACET = 'appliedtohosts'
PKEY = 'itest-view'
DATA = {
'pkey': PKEY,
'add': [
('textbox', 'cn', PKEY),
('textarea', 'description', 'Description of ID view'),
],
'mod': [
('textarea', 'description', 'Different description'),
],
}

View File

@@ -17,6 +17,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
ENTITY = 'user'
PKEY = 'itest-user'
@@ -62,26 +63,3 @@ DATA2 = {
('textbox', 'sn', 'OtherSurname2'),
],
}
PKEY3 = 'itest-user3'
DATA3 = {
'pkey': PKEY3,
'add': [
('textbox', 'uid', PKEY3),
('textbox', 'givenname', 'Name3'),
('textbox', 'sn', 'Surname3'),
('checkbox', 'noprivate', None),
]
}
PKEY4 = 'itest-user4'
DATA4 = {
'pkey': PKEY4,
'add': [
('textbox', 'uid', PKEY4),
('textbox', 'givenname', 'Name4'),
('textbox', 'sn', 'Surname4'),
('checkbox', 'noprivate', None),
('combobox', 'gidnumber', '77777'),
]
}

View File

@@ -1,63 +0,0 @@
# Authors:
# Pavel Vomacka <pvomacka@redhat.com>
#
# Copyright (C) 2016 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
ENTITY = 'vault'
PKEY = 'itest-user-vault'
DATA = {
'pkey': PKEY,
'facet': 'user_search',
'add': [
('radio', 'type', 'user'),
('textbox', 'cn', PKEY),
('textbox', 'description', 'test-desc')
],
'mod': [
('textbox', 'description', 'test-desc-mod'),
],
}
PKEY2 = 'itest-service-vault'
DATA2 = {
'pkey': PKEY2,
'facet': 'service_search',
'add': [
('radio', 'type', 'service'),
# service
('textbox', 'cn', PKEY2),
('textbox', 'description', 'test-desc')
],
'mod': [
('textbox', 'description', 'test-desc-mod'),
],
}
PKEY3 = 'itest-shared-vault'
DATA3 = {
'pkey': PKEY3,
'facet': 'shared_search',
'add': [
('radio', 'type', 'shared'),
('textbox', 'cn', PKEY3),
('textbox', 'description', 'test-desc')
],
'mod': [
('textbox', 'description', 'test-desc-mod'),
],
}

View File

@@ -59,13 +59,13 @@ class range_tasks(UI_driver):
self.max_id = max_id
self.max_rid = max_rid
def get_domain(self):
def get_sid(self):
result = self.execute_api_from_ui('trust_find', [], {})
trusts = result['result']['result']
domain = None
sid = None
if trusts:
domain = trusts[0]['cn']
return domain
sid = trusts[0]['ipanttrusteddomainsid']
return sid
def get_data(self, pkey, size=50, add_data=None):
@@ -81,7 +81,7 @@ class range_tasks(UI_driver):
}
return data
def get_add_data(self, pkey, range_type='ipa-local', size=50, shift=100, domain=None):
def get_add_data(self, pkey, range_type='ipa-local', size=50, shift=100, sid=None):
base_id = self.max_id + shift
self.max_id = base_id + size
@@ -98,19 +98,19 @@ class range_tasks(UI_driver):
('callback', self.check_range_type_mod, range_type)
]
if not domain:
if not sid:
base_rid = self.max_rid + shift
self.max_rid = base_rid + size
add.append(('textbox', 'ipasecondarybaserid', str(base_rid)))
if domain:
add.append(('textbox', 'ipanttrusteddomainname', domain))
if sid:
add.append(('textbox', 'ipanttrusteddomainsid', sid))
return add
def check_range_type_mod(self, range_type):
if range_type == 'ipa-local':
self.assert_disabled("[name=ipanttrusteddomainname]")
self.assert_disabled("[name=ipanttrusteddomainsid]")
self.assert_disabled("[name=ipasecondarybaserid]", negative=True)
elif range_type == 'ipa-ad-trust':
self.assert_disabled("[name=ipanttrusteddomainname]", negative=True)
self.assert_disabled("[name=ipanttrusteddomainsid]", negative=True)
self.assert_disabled("[name=ipasecondarybaserid]")

View File

@@ -25,7 +25,6 @@ from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import ipatests.test_webui.data_hostgroup as hostgroup
from ipatests.test_webui.test_host import host_tasks
import pytest
ENTITY = 'automember'
@@ -51,7 +50,6 @@ HOST_GROUP_DATA = {
}
@pytest.mark.tier1
class test_automember(UI_driver):
@screenshot
@@ -95,7 +93,6 @@ class test_automember(UI_driver):
self.init_app()
host_util = host_tasks()
host_util.setup(self.driver, self.config)
domain = self.config.get('ipa_domain')
host1 = 'web1.%s' % domain
host2 = 'web2.%s' % domain
@@ -110,8 +107,8 @@ class test_automember(UI_driver):
})
# Add hosts
self.add_record('host', host_util.get_data("web1", domain))
self.add_record('host', host_util.get_data("web2", domain))
self.add_record('host', host_util.get_data("web1", domain));
self.add_record('host', host_util.get_data("web2", domain));
# Add an automember rule
self.add_record(
@@ -159,6 +156,7 @@ class test_automember(UI_driver):
# Rebuild membership for all hosts, using action on hosts search facet
self.navigate_by_menu('identity/host')
self.navigate_by_breadcrumb('Hosts')
self.action_list_action('automember_rebuild')
# Assert that hosts are now members of hostgroup
@@ -255,7 +253,8 @@ class test_automember(UI_driver):
self.assert_record('dev2', negative=True)
# Rebuild membership for all users, using action on users search facet
self.navigate_by_menu('identity/user_search')
self.navigate_by_menu('identity/user')
self.navigate_by_breadcrumb('Users')
self.action_list_action('automember_rebuild')
# Assert that users are now members of group

View File

@@ -23,7 +23,6 @@ Automount tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
LOC_ENTITY = 'automountlocation'
MAP_ENTITY = 'automountmap'
@@ -62,7 +61,6 @@ KEY_DATA = {
}
@pytest.mark.tier1
class test_automount(UI_driver):
@screenshot

View File

@@ -23,16 +23,14 @@ Cert tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ENTITY = 'cert'
@pytest.mark.tier1
class test_cert(UI_driver):
def setup(self, *args, **kwargs):
super(test_cert, self).setup(*args, **kwargs)
def __init__(self, *args, **kwargs):
super(test_cert, self).__init__(args, kwargs)
if not self.has_ca():
self.skip('CA not configured')

View File

@@ -23,7 +23,6 @@ Config tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ENTITY = 'config'
@@ -42,7 +41,6 @@ DATA2 = {
}
@pytest.mark.tier1
class test_config(UI_driver):
@screenshot

View File

@@ -23,7 +23,6 @@ Delegation tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ENTITY = 'delegation'
PKEY = 'itest-delegation-rule'
@@ -43,7 +42,6 @@ DATA = {
}
@pytest.mark.tier1
class test_delegation(UI_driver):
@screenshot

View File

@@ -23,7 +23,6 @@ DNS tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ZONE_ENTITY = 'dnszone'
FORWARD_ZONE_ENTITY = 'dnsforwardzone'
@@ -38,6 +37,9 @@ ZONE_DATA = {
'pkey': ZONE_PKEY,
'add': [
('textbox', 'idnsname', ZONE_PKEY),
('textbox', 'idnssoamname', 'ns'),
('textbox', 'ip_address', '192.168.1.1'),
('checkbox', 'force', 'checked'),
],
'mod': [
('checkbox', 'idnsallowsyncptr', 'checked'),
@@ -86,11 +88,10 @@ CONFIG_MOD_DATA = {
}
@pytest.mark.tier1
class test_dns(UI_driver):
def setup(self, *args, **kwargs):
super(test_dns, self).setup(*args, **kwargs)
def __init__(self, *args, **kwargs):
super(test_dns, self).__init__(args, kwargs)
if not self.has_dns():
self.skip('DNS not configured')

View File

@@ -29,10 +29,8 @@ import ipatests.test_webui.data_netgroup as netgroup
import ipatests.test_webui.data_hbac as hbac
import ipatests.test_webui.test_rbac as rbac
import ipatests.test_webui.data_sudo as sudo
import pytest
@pytest.mark.tier1
class test_group(UI_driver):
@screenshot

View File

@@ -25,10 +25,8 @@ from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import ipatests.test_webui.data_hbac as hbac
import ipatests.test_webui.data_hostgroup as hostgroup
import pytest
@pytest.mark.tier1
class test_hbac(UI_driver):
@screenshot

View File

@@ -28,16 +28,14 @@ import ipatests.test_webui.data_netgroup as netgroup
import ipatests.test_webui.data_hbac as hbac
import ipatests.test_webui.test_rbac as rbac
import ipatests.test_webui.data_sudo as sudo
import pytest
ENTITY = 'host'
@pytest.mark.tier1
class host_tasks(UI_driver):
def setup(self, *args, **kwargs):
super(host_tasks, self).setup(*args, **kwargs)
def __init__(self, *args, **kwargs):
super(host_tasks, self).__init__(args, kwargs)
self.prep_data()
self.prep_data2()
@@ -98,13 +96,13 @@ class host_tasks(UI_driver):
ip.append(str(last + 1))
return '.'.join(ip)
def load_file(self, path):
with open(path, 'r') as file_d:
content = file_d.read()
return content
def load_csr(self, path):
# ENHANCEMENT: generate csr dynamically
with open(path, 'r') as csr_file:
csr = csr_file.read()
return csr
@pytest.mark.tier1
class test_host(host_tasks):
@screenshot
@@ -132,147 +130,49 @@ class test_host(host_tasks):
self.skip('CSR file is not configured')
self.init_app()
# ENHANCEMENT: generate csr dynamically
csr = self.load_file(csr_path)
cert_widget_sel = "div.certificate-widget"
csr = self.load_csr(csr_path)
panel = 'cert_actions'
realm = self.config.get('ipa_realm')
self.add_record(ENTITY, self.data)
self.navigate_to_record(self.pkey)
self.assert_visible("div[name='certificate-missing']")
# cert request
self.action_list_action('request_cert', confirm=False)
self.assert_dialog()
self.fill_text("textarea[name='csr']", csr)
self.fill_text('textarea.certificate', csr)
self.dialog_button_click('issue')
self.wait_for_request(n=2, d=3)
self.assert_visible(cert_widget_sel)
self.wait_for_request(n=2, d=0.5)
self.assert_visible("div[name='certificate-valid']")
# cert view
self.action_list_action('view', confirm=False,
parents_css_sel=cert_widget_sel)
self.assert_dialog()
self.action_list_action('view_cert', confirm=False)
self.wait()
self.assert_text("tbody tr:nth-child(2) td:nth-child(2)", self.pkey)
self.assert_text("tbody tr:nth-child(3) td:nth-child(2)", realm)
self.dialog_button_click('close')
# cert get
self.action_list_action('get', confirm=False,
parents_css_sel=cert_widget_sel)
self.assert_dialog()
# check that the textarea is not empty
self.assert_empty_value('textarea.certificate', negative=True)
self.action_list_action('get_cert', confirm=False)
self.wait()
# We don't know the cert text, so at least open and close the dialog
self.dialog_button_click('close')
# cert download - we can only try to click the download action
self.action_list_action('download', confirm=False,
parents_css_sel=cert_widget_sel)
# check that revoke action is enabled
self.assert_action_list_action('revoke',
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is not enabled
self.assert_action_list_action('remove_hold', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# cert revoke
self.action_list_action('revoke', confirm=False,
parents_css_sel=cert_widget_sel)
self.action_list_action('revoke_cert', confirm=False)
self.wait()
self.select('select', '6')
self.dialog_button_click('ok')
self.wait_for_request(n=2, d=3)
self.assert_visible(cert_widget_sel + " div.watermark")
self.wait_for_request(n=2)
self.assert_visible("div[name='certificate-revoked']")
# check that revoke action is not enabled
self.assert_action_list_action('revoke', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is enabled
self.assert_action_list_action('remove_hold',
parents_css_sel=cert_widget_sel,
facet_actions=False)
# cert remove hold
self.action_list_action('remove_hold', confirm=False,
parents_css_sel=cert_widget_sel)
# cert restore
self.action_list_action('restore_cert', confirm=False)
self.wait()
self.dialog_button_click('ok')
self.wait_for_request(n=2)
# check that revoke action is enabled
self.assert_action_list_action('revoke',
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is not enabled
self.assert_action_list_action('remove_hold', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# cleanup
self.navigate_to_entity(ENTITY, 'search')
self.delete_record(self.pkey, self.data.get('del'))
@screenshot
def test_arbitrary_certificates(self):
"""
Test managing host arbitrary certificate.
Requires to have 'arbitrary_cert_path' configuration set.
"""
cert_path = self.config.get('arbitrary_cert_path')
if not cert_path:
self.skip('Arbitrary certificate file is not configured')
self.init_app()
cert = self.load_file(cert_path)
self.add_record(ENTITY, self.data)
self.navigate_to_record(self.pkey)
# check whether certificate section is present
self.assert_visible("div[name='certificate']")
# add certificate
self.button_click('add', parents_css_sel="div[name='certificate']")
self.assert_dialog()
self.fill_textarea('new_cert', cert)
self.dialog_button_click('add')
self.assert_visible("div.certificate-widget")
# cert view
self.action_list_action('view', confirm=False,
parents_css_sel="div.certificate-widget")
self.assert_dialog()
self.dialog_button_click('close')
# cert get
self.action_list_action('get', confirm=False,
parents_css_sel="div.certificate-widget")
self.assert_dialog()
# check that the textarea is not empty
self.assert_empty_value('textarea.certificate', negative=True)
self.dialog_button_click('close')
# cert download - we can only try to click the download action
self.action_list_action('download', confirm=False,
parents_css_sel="div.certificate-widget")
# check that revoke action is not enabled
self.assert_action_list_action(
'revoke', enabled=False,
parents_css_sel="div.certificate-widget",
facet_actions=False)
# check that remove_hold action is not enabled
self.assert_action_list_action(
'remove_hold', enabled=False,
parents_css_sel="div.certificate-widget",
facet_actions=False)
self.assert_visible("div[name='certificate-valid']")
# cleanup
self.navigate_to_entity(ENTITY, 'search')
@@ -292,6 +192,11 @@ class test_host(host_tasks):
self.navigate_to_record(self.pkey)
self.assert_action_list_action('request_cert', visible=False)
self.assert_action_list_action('revoke_cert', visible=False)
self.assert_action_list_action('restore_cert', visible=False)
self.assert_action_list_action('view_cert', enabled=False)
self.assert_action_list_action('get_cert', enabled=False)
self.navigate_by_breadcrumb('Hosts')
self.delete_record(self.pkey, self.data.get('del'))

View File

@@ -27,11 +27,10 @@ import ipatests.test_webui.data_hostgroup as hostgroup
from ipatests.test_webui.test_host import host_tasks, ENTITY as HOST_ENTITY
import ipatests.test_webui.data_netgroup as netgroup
import ipatests.test_webui.data_hbac as hbac
import ipatests.test_webui.test_rbac as rbac
import ipatests.test_webui.data_sudo as sudo
import pytest
@pytest.mark.tier1
class test_hostgroup(UI_driver):
@screenshot
@@ -49,8 +48,7 @@ class test_hostgroup(UI_driver):
Hostgroup associations
"""
self.init_app()
host = host_tasks()
host.setup(self.driver, self.config)
host = host_tasks(self.driver, self.config)
# prepare
# -------
@@ -91,8 +89,7 @@ class test_hostgroup(UI_driver):
Hostgroup indirect associations
"""
self.init_app()
host = host_tasks()
host.setup(self.driver, self.config)
host = host_tasks(self.driver, self.config)
# add
# ---

View File

@@ -1,126 +0,0 @@
#
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
#
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import ipatests.test_webui.data_idviews as idview
import ipatests.test_webui.data_user as user
import ipatests.test_webui.data_group as group
import ipatests.test_webui.data_hostgroup as hostgroup
from ipatests.test_webui.test_host import host_tasks, ENTITY as HOST_ENTITY
import pytest
DATA_USER = {
'pkey': user.PKEY,
'add': [
('combobox', 'ipaanchoruuid', user.PKEY),
('textbox', 'uid', 'iduser'),
('textbox', 'gecos', 'id user'),
('textbox', 'uidnumber', 1),
('textbox', 'gidnumber', 1),
('textbox', 'loginshell', 'shell'),
('textbox', 'homedirectory', 'home'),
('textarea', 'description', 'desc'),
],
'mod': [
('textbox', 'uid', 'moduser'),
('textbox', 'uidnumber', 3),
],
}
DATA_GROUP = {
'pkey': group.PKEY,
'add': [
('combobox', 'ipaanchoruuid', group.PKEY),
('textbox', 'cn', 'idgroup'),
('textbox', 'gidnumber', 2),
('textarea', 'description', 'desc'),
],
'mod': [
('textbox', 'cn', 'modgroup'),
('textbox', 'gidnumber', 3),
],
}
@pytest.mark.tier1
class test_idviews(UI_driver):
@screenshot
def test_crud(self):
"""
Basic CRUD: ID view
"""
self.init_app()
self.basic_crud(
idview.ENTITY, idview.DATA, default_facet=idview.USER_FACET)
@screenshot
def test_overrides(self):
"""
User and group overrides
"""
self.init_app()
self.add_record(user.ENTITY, user.DATA, navigate=False)
self.add_record(group.ENTITY, group.DATA)
self.add_record(idview.ENTITY, idview.DATA)
self.navigate_to_record(idview.PKEY)
parent_entity = 'idview'
# user override
self.add_record(parent_entity, DATA_USER, facet=idview.USER_FACET)
self.navigate_to_record(user.PKEY)
self.mod_record(idview.USER_FACET, DATA_USER)
self.delete_action(idview.ENTITY, user.PKEY)
# group override
self.navigate_to_record(idview.PKEY)
self.switch_to_facet(idview.GROUP_FACET)
self.add_record(parent_entity, DATA_GROUP, facet=idview.GROUP_FACET)
self.navigate_to_record(group.PKEY)
self.mod_record(idview.GROUP_FACET, DATA_GROUP)
self.delete_action(idview.ENTITY, group.PKEY)
# cleanup
self.delete(idview.ENTITY, [idview.DATA])
self.delete(user.ENTITY, [user.DATA])
self.delete(group.ENTITY, [group.DATA])
@screenshot
def test_hosts(self):
"""
Apply to hosts and host groups
"""
self.init_app()
host = host_tasks()
host.setup(self.driver, self.config)
self.add_record(HOST_ENTITY, host.data)
self.add_record(hostgroup.ENTITY, hostgroup.DATA)
self.navigate_to_record(hostgroup.PKEY)
self.add_associations([host.pkey])
self.add_record(idview.ENTITY, idview.DATA)
self.navigate_to_record(idview.PKEY)
self.switch_to_facet(idview.HOST_FACET)
# apply to host
self.add_associations(
[host.pkey], facet='appliedtohosts', facet_btn='idview_apply')
self.delete_record([host.pkey], facet_btn='idview_unapply')
# apply to hostgroup
self.add_associations(
[hostgroup.PKEY], facet_btn='idview_apply_hostgroups',
member_pkeys=[host.pkey])
self.delete_associations(
[hostgroup.PKEY], facet_btn='idview_unapply_hostgroups',
member_pkeys=[host.pkey])
# cleanup
self.delete(idview.ENTITY, [idview.DATA])
self.delete(hostgroup.ENTITY, [hostgroup.DATA])
self.delete(HOST_ENTITY, [host.data])

View File

@@ -23,7 +23,6 @@ Kerberos policy tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ENTITY = 'krbtpolicy'
@@ -42,7 +41,6 @@ DATA2 = {
}
@pytest.mark.tier1
class test_krbtpolicy(UI_driver):
@screenshot

View File

@@ -23,7 +23,6 @@ Basic ui tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ENTITIES = [
@@ -66,7 +65,6 @@ ENTITIES = [
]
@pytest.mark.tier1
class test_navigation(UI_driver):
@screenshot
@@ -107,7 +105,7 @@ class test_navigation(UI_driver):
# Identity
# don't start by users (default)
self.navigate_by_menu('identity/group', False)
self.navigate_by_menu('identity/user_search', False)
self.navigate_by_menu('identity/user', False)
self.navigate_by_menu('identity/host', False)
self.navigate_by_menu('identity/hostgroup', False)
self.navigate_by_menu('identity/netgroup', False)
@@ -136,9 +134,9 @@ class test_navigation(UI_driver):
self.navigate_by_menu('authentication/radiusproxy', False)
self.navigate_by_menu('authentication/otptoken', False)
if self.has_ca():
self.navigate_by_menu('authentication/cert_search', False)
self.navigate_by_menu('authentication/cert', False)
else:
self.assert_menu_item('authentication/cert_search', False)
self.assert_menu_item('authentication/cert', False)
# Network Services
self.navigate_by_menu('network_services')

View File

@@ -28,10 +28,8 @@ import ipatests.test_webui.data_user as user
import ipatests.test_webui.data_group as group
import ipatests.test_webui.data_hostgroup as hostgroup
from ipatests.test_webui.test_host import host_tasks, ENTITY as HOST_ENTITY
import pytest
@pytest.mark.tier1
class test_netgroup(UI_driver):
@screenshot
@@ -48,8 +46,7 @@ class test_netgroup(UI_driver):
Mod: netgroup
"""
self.init_app()
host = host_tasks()
host.setup(self.driver, self.config)
host = host_tasks(self.driver, self.config)
self.add_record(netgroup.ENTITY, netgroup.DATA2)
self.add_record(user.ENTITY, user.DATA)

View File

@@ -23,7 +23,6 @@ Password policy tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ENTITY = 'pwpolicy'
DATA = {
@@ -45,7 +44,6 @@ DATA = {
}
@pytest.mark.tier1
class test_pwpolicy(UI_driver):
@screenshot

View File

@@ -24,13 +24,11 @@ Range tests
import ipatests.test_webui.test_trust as trust_mod
from ipatests.test_webui.ui_driver import screenshot
from ipatests.test_webui.task_range import range_tasks
import pytest
ENTITY = 'idrange'
PKEY = 'itest-range'
@pytest.mark.tier1
class test_range(range_tasks):
@screenshot
@@ -59,6 +57,9 @@ class test_range(range_tasks):
pkey_local = 'itest-local'
pkey_ad = 'itest-ad'
pkey_posix = 'itest-ad-posix'
pkey_winsync = 'itest-ad-winsync'
pkey_trust = 'itest-ipa-trust'
column = 'iparangetype'
add = self.get_add_data(pkey_local)
@@ -73,11 +74,11 @@ class test_range(range_tasks):
self.add_record(trust_mod.ENTITY, trust_data)
domain = self.get_domain()
sid = self.get_sid()
self.navigate_to_entity(ENTITY)
add = self.get_add_data(pkey_ad, range_type='ipa-ad-trust', domain=domain)
add = self.get_add_data(pkey_ad, range_type='ipa-ad-trust', sid=sid)
data = self.get_data(pkey_ad, add_data=add)
self.add_record(ENTITY, data, navigate=False)
self.assert_record_value('Active Directory domain range', pkey_ad, column)

View File

@@ -23,7 +23,6 @@ RBAC tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ROLE_ENTITY = 'role'
ROLE_DEF_FACET = 'member_user'
@@ -71,7 +70,6 @@ PERMISSION_DATA = {
}
@pytest.mark.tier1
class test_rbac(UI_driver):
@screenshot

View File

@@ -23,12 +23,10 @@ Realm domains tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ENTITY = 'realmdomains'
@pytest.mark.tier1
class test_realmdomains(UI_driver):
@screenshot
@@ -41,13 +39,13 @@ class test_realmdomains(UI_driver):
# add
self.add_multivalued('associateddomain', 'itest.bar')
self.facet_button_click('save')
self.facet_button_click('update')
self.dialog_button_click('force')
self.wait_for_request()
# delete
self.del_multivalued('associateddomain', 'itest.bar')
self.facet_button_click('save')
self.facet_button_click('update')
self.dialog_button_click('force')
self.wait_for_request()
self.wait_for_request()

View File

@@ -23,7 +23,6 @@ Selfservice tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ENTITY = 'selfservice'
PKEY = 'itest-selfservice-rule'
@@ -40,7 +39,6 @@ DATA = {
}
@pytest.mark.tier1
class test_selfservice(UI_driver):
@screenshot

View File

@@ -27,7 +27,6 @@ import ipatests.test_webui.data_user as user
import ipatests.test_webui.data_group as group
import ipatests.test_webui.data_hostgroup as hostgroup
from ipatests.test_webui.test_host import host_tasks, ENTITY as HOST_ENTITY
import pytest
ENTITY = 'selinuxusermap'
PKEY = 'itest-selinuxusermap'
@@ -43,7 +42,6 @@ DATA = {
}
@pytest.mark.tier1
class test_selinuxusermap(UI_driver):
@screenshot
@@ -60,8 +58,7 @@ class test_selinuxusermap(UI_driver):
Mod: selinuxusermap
"""
self.init_app()
host = host_tasks()
host.setup(self.driver, self.config)
host = host_tasks(self.driver, self.config)
self.add_record(user.ENTITY, user.DATA)
self.add_record(user.ENTITY, user.DATA2, navigate=False)

View File

@@ -23,12 +23,10 @@ Service tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import pytest
ENTITY = 'service'
@pytest.mark.tier1
class sevice_tasks(UI_driver):
def prep_data(self):
@@ -48,11 +46,11 @@ class sevice_tasks(UI_driver):
],
}
def load_file(self, path):
def load_csr(self, path):
# ENHANCEMENT: generate csr dynamically
with open(path, 'r') as file_d:
content = file_d.read()
return content
with open(path, 'r') as csr_file:
csr = csr_file.read()
return csr
def get_http_pkey(self):
host = self.config.get('ipa_server')
@@ -61,7 +59,6 @@ class sevice_tasks(UI_driver):
return pkey
@pytest.mark.tier1
class test_service(sevice_tasks):
@screenshot
@@ -92,146 +89,49 @@ class test_service(sevice_tasks):
self.init_app()
data = self.prep_data()
pkey = data.get('pkey')
csr = self.load_file(csr_path)
cert_widget_sel = "div.certificate-widget"
csr = self.load_csr(csr_path)
host = self.config.get('ipa_server')
realm = self.config.get('ipa_realm')
self.add_record(ENTITY, data)
self.navigate_to_record(pkey)
self.assert_visible("div[name='certificate-missing']")
# cert request
self.action_list_action('request_cert', confirm=False)
self.assert_dialog()
self.fill_text("textarea[name='csr'", csr)
self.fill_text('textarea.certificate', csr)
self.dialog_button_click('issue')
self.wait_for_request(n=2, d=3)
self.assert_visible(cert_widget_sel)
self.wait_for_request(n=2, d=0.5)
self.assert_visible("div[name='certificate-valid']")
# cert view
self.action_list_action('view', confirm=False,
parents_css_sel=cert_widget_sel)
self.assert_dialog()
self.action_list_action('view_cert', confirm=False)
self.wait()
self.assert_text("tbody tr:nth-child(2) td:nth-child(2)", host)
self.assert_text("tbody tr:nth-child(3) td:nth-child(2)", realm)
self.dialog_button_click('close')
# cert get
self.action_list_action('get', confirm=False,
parents_css_sel=cert_widget_sel)
self.assert_dialog()
# check that text area is not empty
self.assert_empty_value('textarea.certificate', negative=True)
self.action_list_action('get_cert', confirm=False)
self.wait()
# We don't know the cert text, so at least open and close the dialog
self.dialog_button_click('close')
# cert download - we can only try to click the download action
self.action_list_action('download', confirm=False,
parents_css_sel=cert_widget_sel)
# check that revoke action is enabled
self.assert_action_list_action('revoke',
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is not enabled
self.assert_action_list_action('remove_hold', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# cert revoke
self.action_list_action('revoke', confirm=False,
parents_css_sel=cert_widget_sel)
self.action_list_action('revoke_cert', confirm=False)
self.wait()
self.select('select', '6')
self.dialog_button_click('ok')
self.wait_for_request(n=2, d=3)
self.assert_visible(cert_widget_sel + " div.watermark")
self.wait_for_request(n=2)
self.assert_visible("div[name='certificate-revoked']")
# check that revoke action is not enabled
self.assert_action_list_action('revoke', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is enabled
self.assert_action_list_action('remove_hold',
parents_css_sel=cert_widget_sel,
facet_actions=False)
# cert remove hold
self.action_list_action('remove_hold', confirm=False,
parents_css_sel=cert_widget_sel)
# cert restore
self.action_list_action('restore_cert', confirm=False)
self.wait()
self.dialog_button_click('ok')
self.wait_for_request(n=2)
# check that revoke action is enabled
self.assert_action_list_action('revoke',
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is not enabled
self.assert_action_list_action('remove_hold', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# cleanup
self.navigate_to_entity(ENTITY, 'search')
self.delete_record(pkey, data.get('del'))
@screenshot
def test_arbitrary_certificates(self):
"""
Test managing service arbitrary certificate.
Requires to have 'arbitrary_cert_path' configuration set.
"""
cert_path = self.config.get('arbitrary_cert_path')
if not cert_path:
self.skip('Arbitrary certificate file is not configured')
self.init_app()
data = self.prep_data()
pkey = data.get('pkey')
cert = self.load_file(cert_path)
cert_widget_sel = "div.certificate-widget"
self.add_record(ENTITY, data)
self.navigate_to_record(pkey)
# check whether certificate section is present
self.assert_visible("div[name='certificate']")
# add certificate
self.button_click('add', parents_css_sel="div[name='certificate']")
self.assert_dialog()
self.fill_textarea('new_cert', cert)
self.dialog_button_click('add')
self.assert_visible(cert_widget_sel)
# cert view
self.action_list_action('view', confirm=False,
parents_css_sel=cert_widget_sel)
self.assert_dialog()
self.dialog_button_click('close')
# cert get
self.action_list_action('get', confirm=False,
parents_css_sel=cert_widget_sel)
self.assert_dialog()
# check that the textarea is not empty
self.assert_empty_value('textarea.certificate', negative=True)
self.dialog_button_click('close')
# cert download - we can only try to click the download action
self.action_list_action('download', confirm=False,
parents_css_sel=cert_widget_sel)
# check that revoke action is not enabled
self.assert_action_list_action('revoke', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is not enabled
self.assert_action_list_action('remove_hold', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
self.assert_visible("div[name='certificate-valid']")
# cleanup
self.navigate_to_entity(ENTITY, 'search')
@@ -255,10 +155,23 @@ class test_service(sevice_tasks):
self.navigate_to_record(pkey)
self.assert_action_list_action('request_cert', visible=False)
self.assert_action_list_action('revoke_cert', visible=False)
self.assert_action_list_action('restore_cert', visible=False)
self.assert_action_list_action('view_cert', enabled=False)
self.assert_action_list_action('get_cert', enabled=False)
self.navigate_by_breadcrumb('Services')
self.delete_record(pkey, data.get('del'))
# test HTTP, which should have cert set by default and so 'view' and 'get'
# actions visible and enabled
pkey = self.get_http_pkey()
self.navigate_to_record(pkey)
self.assert_action_list_action('view_cert')
self.assert_action_list_action('get_cert')
@screenshot
def test_kerberos_flags(self):
"""

View File

@@ -29,10 +29,8 @@ import ipatests.test_webui.data_user as user
import ipatests.test_webui.data_group as group
import ipatests.test_webui.data_hostgroup as hostgroup
from ipatests.test_webui.test_host import host_tasks, ENTITY as HOST_ENTITY
import pytest
@pytest.mark.tier1
class test_sudo(UI_driver):
@screenshot
@@ -52,8 +50,7 @@ class test_sudo(UI_driver):
Mod: sudo
"""
self.init_app()
host = host_tasks()
host.setup(self.driver, self.config)
host = host_tasks(self.driver, self.config)
self.add_record(netgroup.ENTITY, netgroup.DATA2)

View File

@@ -24,7 +24,6 @@ Trust tests
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
from ipatests.test_webui.task_range import range_tasks
import pytest
ENTITY = 'trust'
CONFIG_ENTITY = 'trustconfig'
@@ -42,7 +41,6 @@ CONFIG_DATA2 = {
}
@pytest.mark.tier1
class trust_tasks(UI_driver):
def get_data(self, add_data=None):
@@ -95,11 +93,11 @@ class trust_tasks(UI_driver):
return domain.upper() + '_id_range'
@pytest.mark.tier1
class test_trust(trust_tasks):
def setup(self, *args, **kwargs):
super(test_trust, self).setup(*args, **kwargs)
def __init__(self, *args, **kwargs):
super(test_trust, self).__init__(args, kwargs)
if not self.has_trusts():
self.skip('Trusts not configured')
@@ -123,8 +121,7 @@ class test_trust(trust_tasks):
self.init_app()
r_tasks = range_tasks()
r_tasks.setup(self.driver, self.config)
r_tasks = range_tasks(self.driver, self.config)
r_tasks.get_shifts()
range_add = r_tasks.get_add_data('')
base_id = range_add[2][2]

View File

@@ -29,7 +29,6 @@ import ipatests.test_webui.data_netgroup as netgroup
import ipatests.test_webui.data_hbac as hbac
import ipatests.test_webui.test_rbac as rbac
import ipatests.test_webui.data_sudo as sudo
import pytest
try:
from selenium.webdriver.common.by import By
@@ -37,16 +36,7 @@ except ImportError:
pass
@pytest.mark.tier1
class user_tasks(UI_driver):
def load_file(self, path):
with open(path, 'r') as file_d:
content = file_d.read()
return content
@pytest.mark.tier1
class test_user(user_tasks):
class test_user(UI_driver):
@screenshot
def test_crud(self):
@@ -169,107 +159,7 @@ class test_user(user_tasks):
self.action_list_action('unlock')
# delete
self.delete_action(user.ENTITY, user.PKEY, action='delete_active_user')
@screenshot
def test_certificates(self):
"""
Test user certificate actions
Requires to have CA installed and 'user_csr_path' configuration option
set.
"""
if not self.has_ca():
self.skip('CA is not configured')
csr_path = self.config.get('user_csr_path')
if not csr_path:
self.skip('CSR file is not configured')
self.init_app()
# ENHANCEMENT: generate csr dynamically
csr = self.load_file(csr_path)
cert_widget_sel = "div.certificate-widget"
self.add_record(user.ENTITY, user.DATA)
self.navigate_to_record(user.PKEY)
# cert request
self.action_list_action('request_cert', confirm=False)
self.assert_dialog()
self.fill_text("textarea[name='csr']", csr)
self.dialog_button_click('issue')
self.wait_for_request(n=2, d=3)
self.assert_visible(cert_widget_sel)
# cert view
self.action_list_action('view', confirm=False,
parents_css_sel=cert_widget_sel)
self.assert_dialog()
self.dialog_button_click('close')
# cert get
self.action_list_action('get', confirm=False,
parents_css_sel=cert_widget_sel)
self.assert_dialog()
# check that the textarea is not empty
self.assert_empty_value('textarea.certificate', negative=True)
self.dialog_button_click('close')
# cert download - we can only try to click the download action
self.action_list_action('download', confirm=False,
parents_css_sel=cert_widget_sel)
# check that revoke action is enabled
self.assert_action_list_action('revoke',
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is not enabled
self.assert_action_list_action('remove_hold', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# cert revoke
self.action_list_action('revoke', confirm=False,
parents_css_sel=cert_widget_sel)
self.wait()
self.select('select', '6')
self.dialog_button_click('ok')
self.wait_for_request(n=2, d=3)
self.assert_visible(cert_widget_sel + " div.watermark")
# check that revoke action is not enabled
self.assert_action_list_action('revoke', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is enabled
self.assert_action_list_action('remove_hold',
parents_css_sel=cert_widget_sel,
facet_actions=False)
# cert remove hold
self.action_list_action('remove_hold', confirm=False,
parents_css_sel=cert_widget_sel)
self.wait()
self.dialog_button_click('ok')
self.wait_for_request(n=2)
# check that revoke action is enabled
self.assert_action_list_action('revoke',
parents_css_sel=cert_widget_sel,
facet_actions=False)
# check that remove_hold action is not enabled
self.assert_action_list_action('remove_hold', enabled=False,
parents_css_sel=cert_widget_sel,
facet_actions=False)
# cleanup
self.navigate_to_entity(user.ENTITY, 'search')
self.delete_record(user.PKEY, user.DATA.get('del'))
self.delete_action(user.ENTITY, user.PKEY)
@screenshot
def test_password_expiration_notification(self):
@@ -369,42 +259,3 @@ class test_user(user_tasks):
self.dialog_button_click('confirm')
self.wait_for_request(n=3)
self.assert_no_error_dialog()
@pytest.mark.tier1
class test_user_no_private_group(UI_driver):
@screenshot
def test_noprivate_nonposix(self):
"""
User without private group and without specified GID
"""
self.init_app()
with pytest.raises(AssertionError) as e:
self.add_record(user.ENTITY, user.DATA3)
assert (str(e.value) == 'Unexpected error: Default group for new '
'users is not POSIX')
@screenshot
def test_noprivate_posix(self):
"""
User without private group and specified existing posix GID
"""
self.init_app()
self.add_record(group.ENTITY, group.DATA6)
self.add_record(user.ENTITY, user.DATA4)
self.delete(user.ENTITY, [user.DATA4])
self.delete(group.ENTITY, [group.DATA6])
@screenshot
def test_noprivate_gidnumber(self):
"""
User without private group and specified unused GID
"""
self.init_app()
self.add_record(user.ENTITY, user.DATA4, combobox_input='gidnumber')
self.delete(user.ENTITY, [user.DATA4])

View File

@@ -1,184 +0,0 @@
# Authors:
# Pavel Vomacka <pvomacka@redhat.com>
#
# Copyright (C) 2013 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Vault tests
"""
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import ipatests.test_webui.data_vault as vault
import ipatests.test_webui.data_user as user
import ipatests.test_webui.data_group as group
import pytest
@pytest.mark.tier1
class vault_tasks(UI_driver):
def prep_service_data(self):
host = self.config.get('ipa_server')
realm = self.config.get('ipa_realm')
pkey = 'itest'
return {
'entity': 'service',
'pkey': '%s/%s@%s' % (pkey, host, realm),
'add': [
('textbox', 'service', pkey),
('combobox', 'host', host)
]
}
def prepare_vault_service_data(self, data):
s_data = self.prep_service_data()
service = s_data['pkey']
serv_field = [('combobox', 'service', service)]
data['add'].extend(serv_field)
def prepare_vault_user_data(self, data, user='admin'):
user_field = [('combobox', 'username', user)]
data['add'].extend(user_field)
@pytest.mark.tier1
class test_vault(vault_tasks):
def setup(self, *args, **kwargs):
super(test_vault, self).setup(*args, **kwargs)
if not self.has_kra():
self.skip('KRA not configured')
@screenshot
def test_crud(self):
"""
Basic basic CRUD: user vault
"""
self.init_app()
self.prepare_vault_user_data(vault.DATA)
self.basic_crud(vault.ENTITY, vault.DATA)
@screenshot
def test_add_service_vault(self):
"""
Add Service vault
"""
self.init_app()
# Add itest service
s_data = self.prep_service_data()
self.add_record(s_data['entity'], s_data)
self.prepare_vault_service_data(vault.DATA2)
# Add and remove service vault
self.add_record(vault.ENTITY, vault.DATA2, facet=vault.DATA2['facet'],
delete=True)
# Remove test service
self.navigate_to_entity(s_data['entity'])
self.delete_record(s_data['pkey'])
@screenshot
def test_add_shared_vault(self):
"""
Add Shared vault
"""
self.init_app()
# Add shared vault
self.add_record(vault.ENTITY, vault.DATA3, facet=vault.DATA3['facet'],
delete=True)
@screenshot
def test_member_owner_vault(self):
"""
Add User Vault and try to add member and owner
"""
def fill_tables():
self.add_table_associations('member_user', [user.PKEY])
self.add_table_associations('member_group', [group.PKEY])
self.add_table_associations('member_service', [s_data['pkey']])
self.add_table_associations('owner_user', [user.PKEY])
self.add_table_associations('owner_group', [group.PKEY])
self.add_table_associations('owner_service', [s_data['pkey']])
# Add user
self.init_app()
self.add_record(user.ENTITY, user.DATA)
# Prepare items - user already exists
s_data = self.prep_service_data()
self.add_record(s_data['entity'], s_data)
self.add_record(group.ENTITY, group.DATA)
# USER
# Add user vault
self.add_record(vault.ENTITY, vault.DATA, facet='user_search')
# Navigate to record
self.navigate_to_record(vault.DATA['pkey'])
# Try add values into table
fill_tables()
# Remove user vault record
self.navigate_to_entity(vault.ENTITY, vault.DATA['facet'])
self.delete_record(vault.PKEY)
# SERVICE
# Add service vault
self.prepare_vault_service_data(vault.DATA2)
self.add_record(vault.ENTITY, vault.DATA2, facet=vault.DATA2['facet'])
# Navigate to record
self.navigate_to_record(vault.DATA2['pkey'])
# Try add values into table
fill_tables()
# Remove service vault record
self.navigate_to_entity(vault.ENTITY, vault.DATA2['facet'])
self.delete_record(vault.DATA2['pkey'])
# SHARED
# Add shared vault
self.add_record(vault.ENTITY, vault.DATA3, facet=vault.DATA3['facet'])
# Navigate to record
self.navigate_to_record(vault.DATA3['pkey'])
# Try add values into table
fill_tables()
# Remove shared vault record
self.navigate_to_entity(vault.ENTITY, vault.DATA3['facet'])
self.delete_record(vault.DATA3['pkey'])
# Clean up
self.navigate_to_entity(s_data['entity'])
self.delete_record(s_data['pkey'])
self.navigate_to_entity(user.ENTITY)
self.delete_record(user.PKEY)
self.navigate_to_entity(group.ENTITY)
self.delete_record(group.PKEY)

View File

@@ -22,7 +22,6 @@ Base class for UI integration tests.
Contains browser driver and common tasks.
"""
from __future__ import print_function
import nose
from datetime import datetime
@@ -32,10 +31,6 @@ import os
from functools import wraps
from nose.plugins.skip import SkipTest
# pylint: disable=import-error
from six.moves.urllib.error import URLError
# pylint: enable=import-error
try:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
@@ -57,9 +52,9 @@ try:
NO_YAML = False
except ImportError:
NO_YAML = True
from urllib2 import URLError
from ipaplatform.paths import paths
ENV_MAP = {
'MASTER': 'ipa_server',
'ADMINID': 'ipa_admin',
@@ -70,7 +65,6 @@ ENV_MAP = {
'IPA_NO_CA': 'no_ca',
'IPA_NO_DNS': 'no_dns',
'IPA_HAS_TRUSTS': 'has_trusts',
'IPA_HAS_KRA': 'has_kra',
'IPA_HOST_CSR_PATH': 'host_csr_path',
'IPA_SERVICE_CSR_PATH': 'service_csr_path',
'AD_DOMAIN': 'ad_domain',
@@ -119,22 +113,16 @@ class UI_driver(object):
"""
@classmethod
def setup_class(cls):
def setUpClass(cls):
if NO_SELENIUM:
raise nose.SkipTest('Selenium not installed')
def setup(self, driver=None, config=None):
def __init__(self, driver=None, config=None):
self.request_timeout = 30
self.driver = driver
self.config = config
if not config:
self.load_config()
if not self.driver:
self.driver = self.get_driver()
self.driver.maximize_window()
def teardown(self):
self.driver.quit()
def load_config(self):
"""
@@ -150,9 +138,9 @@ class UI_driver(object):
try:
with open(path, 'r') as conf:
self.config = yaml.load(conf)
except yaml.YAMLError as e:
except yaml.YAMLError, e:
raise nose.SkipTest("Invalid Web UI config.\n%s" % e)
except IOError as e:
except IOError, e:
raise nose.SkipTest("Can't load Web UI test config: %s" % e)
else:
self.config = {}
@@ -160,7 +148,7 @@ class UI_driver(object):
c = self.config
# override with environmental variables
for k, v in ENV_MAP.items():
for k, v in ENV_MAP.iteritems():
val = os.environ.get(k)
if val is not None:
c[v] = val
@@ -173,6 +161,20 @@ class UI_driver(object):
if 'type' not in c:
c['type'] = DEFAULT_TYPE
def setUp(self):
"""
Test setup
"""
if not self.driver:
self.driver = self.get_driver()
self.driver.maximize_window()
def tearDown(self):
"""
Test clean up
"""
self.driver.quit()
def get_driver(self):
"""
Get WebDriver according to configuration
@@ -188,7 +190,7 @@ class UI_driver(object):
options.binary_location = paths.CHROMIUM_BROWSER
if driver_type == 'remote':
if 'host' not in self.config:
if not 'host' in self.config:
raise nose.SkipTest('Selenium server host not configured')
host = self.config["host"]
@@ -204,9 +206,9 @@ class UI_driver(object):
driver = webdriver.Remote(
command_executor='http://%s:%d/wd/hub' % (host, port),
desired_capabilities=capabilities)
except URLError as e:
except URLError, e:
raise nose.SkipTest('Error connecting to selenium server: %s' % e)
except RuntimeError as e:
except RuntimeError, e:
raise nose.SkipTest('Error while establishing webdriver: %s' % e)
else:
try:
@@ -219,9 +221,9 @@ class UI_driver(object):
if "ff_profile" in self.config:
fp = webdriver.FirefoxProfile(self.config["ff_profile"])
driver = webdriver.Firefox(fp)
except URLError as e:
except URLError, e:
raise nose.SkipTest('Error connecting to selenium server: %s' % e)
except RuntimeError as e:
except RuntimeError, e:
raise nose.SkipTest('Error while establishing webdriver: %s' % e)
return driver
@@ -285,12 +287,6 @@ class UI_driver(object):
"""
return self.config.get('has_trusts')
def has_kra(self):
"""
FreeIPA server was installed with Kra.
"""
return self.config.get('has_kra')
def has_active_request(self):
"""
Check if there is running AJAX request
@@ -317,7 +313,7 @@ class UI_driver(object):
"""
runner = self
for _i in range(n):
for i in range(n):
self.wait(implicit)
WebDriverWait(self.driver, self.request_timeout).until_not(lambda d: runner.has_active_request())
self.wait()
@@ -452,18 +448,8 @@ class UI_driver(object):
Click on tab with given name
"""
facet = self.get_facet()
tabs = "div.facet-tabs"
sidebar = "div.sidebar-pf"
facets_container = self.find(tabs, By.CSS_SELECTOR, facet)
# handle sidebar instead of facet-tabs
# the webui facet can have only the facet-tabs OR sidebar, not both
if not facets_container:
facets_container = self.find(sidebar, By.CSS_SELECTOR, facet)
s = "li[name='%s'] a" % name
link = self.find(s, By.CSS_SELECTOR, facets_container, strict=True)
s = "div.facet-tabs li[name='%s'] a" % name
link = self.find(s, By.CSS_SELECTOR, facet, strict=True)
link.click()
# double wait because of facet's paging
self.wait_for_request(0.5)
@@ -636,17 +622,12 @@ class UI_driver(object):
s = "a[name='%s'].action-button" % name
self._button_click(s, parent, name)
def button_click(self, name, parent=None,
parents_css_sel=None):
def button_click(self, name, parent=None):
"""
Click on .ui-button
"""
if not parent:
if parents_css_sel:
parent = self.find(parents_css_sel, By.CSS_SELECTOR,
strict=True)
else:
parent = self.get_form()
parent = self.get_form()
s = "[name='%s'].btn" % name
self._button_click(s, parent, name)
@@ -804,7 +785,7 @@ class UI_driver(object):
assert label is not None, "Option not found: %s" % name
label.click()
def select_combobox(self, name, value, parent=None, combobox_input=None):
def select_combobox(self, name, value, parent=None):
"""
Select value in a combobox. Search if not found.
"""
@@ -821,20 +802,15 @@ class UI_driver(object):
search_btn = self.find('a[name=search] i', By.CSS_SELECTOR, cb, strict=True)
opt_s = "select[name=list] option[value='%s']" % value
option = self.find(opt_s, By.CSS_SELECTOR, cb)
if not option:
# try to search
self.fill_textbox('filter', value, cb)
if combobox_input:
if not option:
self.fill_textbox(combobox_input, value, cb)
else:
if not option:
# try to search
self.fill_textbox('filter', value, cb)
search_btn.click()
self.wait_for_request()
option = self.find(opt_s, By.CSS_SELECTOR, cb, strict=True)
search_btn.click()
self.wait_for_request()
option = self.find(opt_s, By.CSS_SELECTOR, cb, strict=True)
option.click()
option.click()
# Chrome does not close search area on click
if list_cnt.is_displayed():
@@ -964,8 +940,12 @@ class UI_driver(object):
s = self.get_table_selector(table_name)
input_s = s + " tbody td input[value='%s']" % pkey
checkbox = self.find(input_s, By.CSS_SELECTOR, parent, strict=True)
checkbox_id = checkbox.get_attribute('id')
label_s = s + " tbody td label[for='%s']" % checkbox_id
print label_s
label = self.find(label_s, By.CSS_SELECTOR, parent, strict=True)
try:
ActionChains(self.driver).move_to_element(checkbox).click().perform()
ActionChains(self.driver).move_to_element(label).click().perform()
except WebDriverException as e:
assert False, 'Can\'t click on checkbox label: %s \n%s' % (s, e)
self.wait()
@@ -1014,9 +994,7 @@ class UI_driver(object):
link.click()
self.wait_for_request()
def delete_record(
self, pkeys, fields=None, parent=None, table_name=None,
facet_btn='remove'):
def delete_record(self, pkeys, fields=None, parent=None, table_name=None):
"""
Delete records with given pkeys in currently opened search table.
"""
@@ -1036,9 +1014,9 @@ class UI_driver(object):
if table_name and parent:
s = self.get_table_selector(table_name)
table = self.find(s, By.CSS_SELECTOR, parent, strict=True)
self.button_click(facet_btn, table)
self.button_click('remove', table)
else:
self.facet_button_click(facet_btn)
self.facet_button_click('remove')
if fields:
self.fill_fields(fields)
self.dialog_button_click('ok')
@@ -1056,8 +1034,7 @@ class UI_driver(object):
fields = data.get('del')
self.delete_record(pkey, fields)
def fill_fields(
self, fields, parent=None, undo=False, combobox_input=None):
def fill_fields(self, fields, parent=None, undo=False):
"""
Fill dialog or facet inputs with give data.
@@ -1092,8 +1069,7 @@ class UI_driver(object):
elif widget_type == 'selectbox':
self.select('select[name=%s]' % key, val, parent)
elif widget_type == 'combobox':
self.select_combobox(
key, val, parent, combobox_input=combobox_input)
self.select_combobox(key, val, parent)
elif widget_type == 'add_table_record':
self.add_table_record(key, val, parent)
elif widget_type == 'add_table_association':
@@ -1182,7 +1158,7 @@ class UI_driver(object):
def add_record(self, entity, data, facet='search', facet_btn='add',
dialog_btn='add', delete=False, pre_delete=True,
dialog_name='add', navigate=True, combobox_input=None):
dialog_name='add', navigate=True):
"""
Add records.
@@ -1217,7 +1193,7 @@ class UI_driver(object):
self.assert_dialog(dialog_name)
# fill dialog
self.fill_fields(data['add'], combobox_input=combobox_input)
self.fill_fields(data['add'])
# confirm dialog
self.dialog_button_click(dialog_btn)
@@ -1250,7 +1226,7 @@ class UI_driver(object):
new_count = len(self.get_rows())
self.assert_row_count(count, new_count)
def mod_record(self, entity, data, facet='details', facet_btn='save'):
def mod_record(self, entity, data, facet='details', facet_btn='update'):
"""
Mod record
@@ -1275,7 +1251,7 @@ class UI_driver(object):
add_facet_btn='add',
add_dialog_btn='add',
add_dialog_name='add',
update_btn='save',
update_btn='update',
breadcrumb=None,
navigate=True,
delete=True):
@@ -1315,6 +1291,7 @@ class UI_driver(object):
)
# Find
self.find_record(parent_entity, data, search_facet)
# 3. Navigate to details facet
@@ -1357,15 +1334,14 @@ class UI_driver(object):
self.dialog_button_click('add')
self.wait_for_request()
def prepare_associations(
self, pkeys, facet=None, facet_btn='add', member_pkeys=None):
def add_associations(self, pkeys, facet=None, delete=False):
"""
Helper function for add_associations and delete_associations
Add associations
"""
if facet:
self.switch_to_facet(facet)
self.facet_button_click(facet_btn)
self.facet_button_click('add')
self.wait()
self.wait_for_request()
@@ -1376,39 +1352,12 @@ class UI_driver(object):
self.dialog_button_click('add')
self.wait_for_request()
if member_pkeys:
check_pkeys = member_pkeys
else:
check_pkeys = pkeys
return check_pkeys
def add_associations(
self, pkeys, facet=None, delete=False, facet_btn='add',
member_pkeys=None):
"""
Add associations
"""
check_pkeys = self.prepare_associations(
pkeys, facet, facet_btn, member_pkeys)
for key in check_pkeys:
for key in pkeys:
self.assert_record(key)
if delete:
self.delete_record(key)
self.assert_record(key, negative=True)
def delete_associations(
self, pkeys, facet=None, facet_btn='remove', member_pkeys=None):
"""
Remove associations
"""
check_pkeys = self.prepare_associations(
pkeys, facet, facet_btn, member_pkeys)
for key in check_pkeys:
self.assert_record(key, negative=True)
def add_table_associations(self, table_name, pkeys, parent=False, delete=False):
"""
Add value to table (association|rule|...)
@@ -1439,25 +1388,14 @@ class UI_driver(object):
for key in pkeys:
self.assert_record(key, parent, table_name, negative=True)
def action_list_action(self, name, confirm=True, confirm_btn="ok",
parents_css_sel=None):
def action_list_action(self, name, confirm=True, confirm_btn="ok"):
"""
Execute action list action
"""
context = None
if not parents_css_sel:
context = self.find(".active-facet .facet-actions",
By.CSS_SELECTOR, strict=True)
else:
context = self.find(parents_css_sel, By.CSS_SELECTOR,
strict=True)
expand = self.find(".dropdown-toggle", By.CSS_SELECTOR, context,
strict=True)
cont = self.find(".active-facet .facet-actions", By.CSS_SELECTOR, strict=True)
expand = self.find(".dropdown-toggle", By.CSS_SELECTOR, cont, strict=True)
expand.click()
action_link = self.find("li[data-name=%s] a" % name, By.CSS_SELECTOR,
context, strict=True)
action_link = self.find("li[data-name=%s] a" % name, By.CSS_SELECTOR, cont, strict=True)
action_link.click()
if confirm:
self.wait(0.5) # wait for dialog
@@ -1494,11 +1432,11 @@ class UI_driver(object):
self.assert_no_error_dialog()
self.assert_class(title, 'disabled')
def delete_action(self, entity, pkey, action='delete', facet='search'):
def delete_action(self, entity, pkey, facet='search'):
"""
Execute and test 'delete' action panel action.
"""
self.action_list_action(action)
self.action_list_action('delete')
self.wait_for_request(n=4)
self.assert_no_error_dialog()
self.assert_facet(entity, facet)
@@ -1520,7 +1458,7 @@ class UI_driver(object):
# add values
for t in tables:
table, keys, _exts = get_t_vals(t)
table, keys, exts = get_t_vals(t)
# add one by one to test for #3711
for key in keys:
self.add_table_associations(table, [key])
@@ -1531,14 +1469,14 @@ class UI_driver(object):
# update
self.assert_rule_tables_enabled(t_list, False)
self.facet_button_click('save')
self.facet_button_click('update')
self.wait_for_request(n=3, d=0.3)
self.assert_rule_tables_enabled(t_list, False)
p = self.get_form()
# now tables in categories should be empty, check it
for t in tables:
table, keys, _exts = get_t_vals(t)
table, keys, exts = get_t_vals(t)
if table in no_categories:
# clear the rest
self.delete_record(keys, None, p, table)
@@ -1550,12 +1488,12 @@ class UI_driver(object):
for cat in categories:
self.check_option(cat, '')
self.assert_rule_tables_enabled(t_list, True)
self.facet_button_click('save')
self.facet_button_click('update')
self.wait_for_request(n=3, d=0.3)
self.assert_rule_tables_enabled(t_list, True)
for t in tables:
table, keys, _exts = get_t_vals(t)
table, keys, exts = get_t_vals(t)
# add multiple at once and test table delete button
self.add_table_associations(table, keys, delete=True)
@@ -1587,17 +1525,6 @@ class UI_driver(object):
s = "div[name='%s'] %s[name='%s']" % (name, element, name)
self.assert_text(s, value, parent)
def assert_empty_value(self, selector, parent=None, negative=False):
"""
Assert empty value of some field in details page or in a form
"""
value = self.get_value(selector, parent)
if negative:
assert not value == ''
else:
assert value == ''
def assert_no_dialog(self):
"""
Assert that no dialog is opened
@@ -1699,7 +1626,7 @@ class UI_driver(object):
"""
if not parent:
parent = self.get_form()
self.find(selector, By.CSS_SELECTOR, parent, strict=True)
el = self.find(selector, By.CSS_SELECTOR, parent, strict=True)
dis = self.find(selector+"[disabled]", By.CSS_SELECTOR, parent)
if negative:
assert dis is None, "Element is disabled: %s" % selector
@@ -1787,26 +1714,17 @@ class UI_driver(object):
assert is_enabled == enabled, ('Invalid enabled state of action button %s. '
'Expected: %s') % (action, str(visible))
def assert_action_list_action(self, action, visible=True, enabled=True,
parent=None, parents_css_sel=None,
facet_actions=True):
def assert_action_list_action(self, action, visible=True, enabled=True, parent=None):
"""
Assert that action dropdown action is visible/hidden, and enabled/disabled
Enabled is checked only if action is visible.
"""
li_s = " li[data-name='%s']" % action
if not parent:
parent = self.get_form()
if facet_actions:
li_s = ".facet-actions" + li_s
else:
li_s = parents_css_sel + li_s
li = self.find(li_s, By.CSS_SELECTOR, parent)
s = ".facet-actions li[data-name='%s']" % action
li = self.find(s, By.CSS_SELECTOR, parent)
link = self.find("a", By.CSS_SELECTOR, li)
is_visible = li is not None and link is not None