URL: https://github.com/freeipa/freeipa/pull/1679 Author: Rezney Title: #1679: WebUI tests: test_service Action: opened
PR body: """ Extension of test_service WebUI tests. """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/1679/head:pr1679 git checkout pr1679
From e998332ac0f407a3421c137a7989e6f5df01e2c6 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 18:05:03 +0100 Subject: [PATCH 01/14] ui_tests: change get_http_pkey() function change get_http_pkey() function to more generic one in order to get pkey for different services https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/test_service.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ipatests/test_webui/test_service.py b/ipatests/test_webui/test_service.py index 602ae4d83b..b134b73e68 100644 --- a/ipatests/test_webui/test_service.py +++ b/ipatests/test_webui/test_service.py @@ -54,10 +54,11 @@ def load_file(self, path): content = file_d.read() return content - def get_http_pkey(self): - host = self.config.get('ipa_server') + def get_service_pkey(self, service, host=None): + if not host: + host = self.config.get('ipa_server') realm = self.config.get('ipa_realm') - pkey = 'HTTP/%s@%s' % (host, realm) + pkey = '{}/{}@{}'.format(service, host, realm) return pkey @@ -265,7 +266,7 @@ def test_kerberos_flags(self): Test Kerberos flags http://www.freeipa.org/page/V3/Kerberos_Flags """ - pkey = self.get_http_pkey() + pkey = self.get_service_pkey('HTTP') name = 'ipakrbokasdelegate' mod = {'mod': [('checkbox', name, None)]} checked = ['checked'] From c7bcc8e25aff32319b93b49f046df5a0330c8541 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 18:09:08 +0100 Subject: [PATCH 02/14] ui_tests: add_host() support func in test_service Add add_host() support func into test_service to create temp hosts. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/test_service.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ipatests/test_webui/test_service.py b/ipatests/test_webui/test_service.py index b134b73e68..cc7f8b1ccb 100644 --- a/ipatests/test_webui/test_service.py +++ b/ipatests/test_webui/test_service.py @@ -61,6 +61,14 @@ def get_service_pkey(self, service, host=None): pkey = '{}/{}@{}'.format(service, host, realm) return pkey + def add_host(self, hostname, dns_zone, force=False): + self.navigate_to_entity('host') + self.facet_button_click('add') + self.fill_textbox('hostname', hostname) + self.fill_textbox('dnszone', dns_zone) + if force: + self.check_option('force', 'checked') + self.dialog_button_click('add') @pytest.mark.tier1 class test_service(sevice_tasks): From d90def572873e0fe8b90889a8066158b1d99de78 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 18:17:18 +0100 Subject: [PATCH 03/14] ui_tests: add_service() support func in test_service Add add_service() support func into test_service. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/test_service.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ipatests/test_webui/test_service.py b/ipatests/test_webui/test_service.py index cc7f8b1ccb..ab88f865e0 100644 --- a/ipatests/test_webui/test_service.py +++ b/ipatests/test_webui/test_service.py @@ -70,6 +70,30 @@ def add_host(self, hostname, dns_zone, force=False): self.check_option('force', 'checked') self.dialog_button_click('add') + def add_service(self, service, + host=None, + textbox=None, + force=False, + cancel=False, + confirm=True): + + if not host: + host = self.config.get('ipa_server') + self.navigate_to_entity(ENTITY) + self.facet_button_click('add') + + self.select_combobox('service', service, combobox_input=textbox) + self.select_combobox('host', host) + if force: + self.check_option('force', 'checked') + if cancel: + self.dialog_button_click('cancel') + return + if not confirm: + return + self.dialog_button_click('add') + self.wait(0.3) + self.assert_no_error_dialog() @pytest.mark.tier1 class test_service(sevice_tasks): From e78b98e44715f714164a7761ef939608cc4595ec Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 18:23:11 +0100 Subject: [PATCH 04/14] ui_tests: add more test cases to test_certification Add cases for: "cancel_cert_request", "cancel_hold_cert", "cancel_remove_hold", "cancel_revoke_cert" and "revoke_cert" https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/test_service.py | 45 ++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/ipatests/test_webui/test_service.py b/ipatests/test_webui/test_service.py index ab88f865e0..75d668b776 100644 --- a/ipatests/test_webui/test_service.py +++ b/ipatests/test_webui/test_service.py @@ -111,8 +111,8 @@ def test_certificates(self): """ Test service certificate actions - Requires to have CA installed and 'service_csr_path' configuration option - set. + Requires to have CA installed and 'service_csr_path' configuration + option set. """ if not self.has_ca(): @@ -133,6 +133,9 @@ def test_certificates(self): # cert request self.action_list_action('request_cert', confirm=False) + # testing if cancel button works + self.dialog_button_click('cancel') + self.action_list_action('request_cert', confirm=False) self.assert_dialog() self.fill_text("textarea[name='csr'", csr) self.dialog_button_click('issue') @@ -166,7 +169,14 @@ def test_certificates(self): parents_css_sel=cert_widget_sel, facet_actions=False) - # cert revoke + # cert revoke/hold cancel + self.action_list_action('revoke', confirm=False, + parents_css_sel=cert_widget_sel) + self.wait() + self.select('select', '6') + self.dialog_button_click('cancel') + + # cert revoke/hold self.action_list_action('revoke', confirm=False, parents_css_sel=cert_widget_sel) self.wait() @@ -185,6 +195,11 @@ def test_certificates(self): parents_css_sel=cert_widget_sel, facet_actions=False) + # cert remove hold cancel + self.action_list_action('remove_hold', confirm=False, + parents_css_sel=cert_widget_sel) + self.dialog_button_click('cancel') + # cert remove hold self.action_list_action('remove_hold', confirm=False, parents_css_sel=cert_widget_sel) @@ -202,6 +217,30 @@ def test_certificates(self): parents_css_sel=cert_widget_sel, facet_actions=False) + # cert revoke cancel + self.action_list_action('revoke', confirm=False, + parents_css_sel=cert_widget_sel) + self.wait() + self.select('select', '1') + self.dialog_button_click('cancel') + + # cert revoke + self.action_list_action('revoke', confirm=False, + parents_css_sel=cert_widget_sel) + self.wait() + self.select('select', '1') + self.dialog_button_click('ok') + + # 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 not is 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')) From 397e932574c57506bfcabc2aac6008a6e050d5f5 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 18:24:48 +0100 Subject: [PATCH 05/14] ui_tests: add more test cases Add more test cases to test_services. Details in the ticket. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/test_service.py | 463 ++++++++++++++++++++++++++++++++++++ 1 file changed, 463 insertions(+) diff --git a/ipatests/test_webui/test_service.py b/ipatests/test_webui/test_service.py index 75d668b776..8a856984b6 100644 --- a/ipatests/test_webui/test_service.py +++ b/ipatests/test_webui/test_service.py @@ -23,6 +23,9 @@ from ipatests.test_webui.ui_driver import UI_driver from ipatests.test_webui.ui_driver import screenshot +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.common.action_chains import ActionChains import pytest ENTITY = 'service' @@ -352,3 +355,463 @@ def test_kerberos_flags(self): self.validate_fields([('checkbox', name, checked)]) self.mod_record(ENTITY, mod) self.validate_fields([('checkbox', name, [])]) + + @screenshot + def test_add_cifs_service(self): + """ + Test add CIFS service using combobox + """ + self.init_app() + pkey = self.get_service_pkey('cifs') + self.add_service('cifs') + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + @screenshot + def test_add_dns_service(self): + """ + Test add DNS service using combobox + """ + self.init_app() + temp_host = 'host-no-dns.ipa.test' + self.add_host('host-no-dns', 'ipa.test', force=True) + pkey = self.get_service_pkey('DNS', host=temp_host) + self.add_service('DNS', host=temp_host, force=True) + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + # host cleanup + self.navigate_to_entity('host') + self.delete_record(temp_host) + + @screenshot + def test_add_ftp_service(self): + """ + Test add FTP service using combobox + """ + self.init_app() + pkey = self.get_service_pkey('ftp') + self.add_service('ftp') + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + @screenshot + def test_add_http_service(self): + """ + Test add HTTP service using combobox + """ + self.init_app() + temp_host = 'host-no-dns.ipa.test' + self.add_host('host-no-dns', 'ipa.test', force=True) + pkey = self.get_service_pkey('HTTP', host=temp_host) + self.add_service('HTTP', host=temp_host, force=True) + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + # host cleanup + self.navigate_to_entity('host') + self.delete_record(temp_host) + + @screenshot + def test_add_imap_service(self): + """ + Test add IMAP service using combobox + """ + self.init_app() + pkey = self.get_service_pkey('imap') + self.add_service('imap') + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + @screenshot + def test_add_ldap_service(self): + """ + Test add LDAP service using combobox + """ + self.init_app() + temp_host = 'host-no-dns.ipa.test' + self.add_host('host-no-dns', 'ipa.test', force=True) + pkey = self.get_service_pkey('ldap', host=temp_host) + self.add_service('ldap', host=temp_host, force=True) + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + # host cleanup + self.navigate_to_entity('host') + self.delete_record(temp_host) + + @screenshot + def test_add_libvirt_service(self): + """ + Test add libvirt service using combobox + """ + self.init_app() + pkey = self.get_service_pkey('libvirt') + self.add_service('libvirt') + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + @screenshot + def test_add_nfs_service(self): + """ + Test add nfs service using combobox + """ + self.init_app() + pkey = self.get_service_pkey('nfs') + self.add_service('nfs') + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + @screenshot + def test_add_qpidd_service(self): + """ + Test add qpidd service using combobox + """ + self.init_app() + pkey = self.get_service_pkey('qpidd') + self.add_service('qpidd') + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + @screenshot + def test_add_smtp_service(self): + """ + Test add smtp service using combobox + """ + self.init_app() + pkey = self.get_service_pkey('smtp') + self.add_service('smtp') + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + @screenshot + def test_add_custom_service(self): + """ + Test add custom service using textbox + """ + self.init_app() + pkey = self.get_service_pkey('test_service') + self.add_service('test_service', textbox='service') + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + @screenshot + def test_cancel_adding_service(self): + """ + Test cancel when adding a service + """ + self.init_app() + pkey = self.get_service_pkey('cifs') + self.add_service('cifs', cancel=True) + assert not self.has_record(pkey) + + @screenshot + def test_force_add_service(self): + """ + Test force add service with host without DNS record + """ + temp_host = 'host-no-dns.ipa.test' + + self.init_app() + self.navigate_to_entity('host') + self.facet_button_click('add') + self.fill_textbox('hostname', 'host-no-dns') + self.fill_textbox('dnszone', 'ipa.test') + self.check_option('force', 'checked') + self.dialog_button_click('add') + + pkey = self.get_service_pkey('test-service-force', host=temp_host) + self.add_service('test-service-force', textbox='service', + host=temp_host, force=True) + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + + # host cleanup + self.navigate_to_entity('host') + self.delete_record(temp_host) + + @screenshot + def test_cancel_delete_service(self): + """ + Test cancel deleting a service + """ + self.init_app() + pkey = self.get_service_pkey('HTTP') + self.navigate_to_entity(ENTITY) + self.delete_record(pkey, cancel=True) + assert self.has_record(pkey) + + @screenshot + def test_delete_single_service(self): + """ + Test delete single service + """ + self.init_app() + pkey = self.get_service_pkey('single_service') + self.add_service('single_service', textbox='service') + assert self.has_record(pkey) + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + @screenshot + def test_delete_multiple_services(self): + """ + Test delete multiple services + """ + self.init_app() + cifs_pkey = self.get_service_pkey('cifs') + nfs_pkey = self.get_service_pkey('nfs') + smtp_pkey = self.get_service_pkey('smtp') + + for service in ('cifs', 'nfs', 'smtp'): + self.add_service(service) + + for service in (cifs_pkey, nfs_pkey, smtp_pkey): + self.delete_record(service) + self.wait(0.5) + assert not self.has_record(service) + + @screenshot + def test_cancel_add_delete_managedby_host(self): + """ + Test cancel/add/delete managed by host + """ + pkey = self.get_service_pkey('HTTP') + host = self.config.get('ipa_server') + temp_host = 'host-no-dns.ipa.test' + self.init_app() + + # add another host for "managedby" testing + self.add_host('host-no-dns', 'ipa.test', force=True) + + self.navigate_to_record(pkey, entity=ENTITY) + self.add_associations([temp_host], facet='managedby_host', + cancel=True) + self.add_associations([temp_host], facet='managedby_host', + delete=True) + self.delete_record(host, cancel=True) + + # host cleanup + self.navigate_to_entity('host') + self.delete_record(temp_host) + + @screenshot + def test_add_service_missing_hostname_field(self): + """ + Test add service "hostname" field required + """ + self.init_app() + self.navigate_to_entity(ENTITY) + self.facet_button_click('add') + self.select_combobox('service', 'cifs', combobox_input='service') + self.dialog_button_click('add') + host_elem = self.find(".widget[name='host']", By.CSS_SELECTOR) + self.assert_field_required(parent=host_elem) + + @screenshot + def test_add_service_missing_service_field(self): + """ + Test add service "service field required + """ + self.init_app() + host = self.config.get('ipa_server') + self.navigate_to_entity(ENTITY) + self.facet_button_click('add') + self.select_combobox('host', host, combobox_input='service') + self.dialog_button_click('add') + self.wait() + service_elem = self.find(".widget[name='service']", By.CSS_SELECTOR) + self.assert_field_required(parent=service_elem) + + @screenshot + def test_add_service_no_DNS_for_host(self): + """ + Add service for a host without dns + """ + self.init_app() + temp_host = 'host-no-dns.ipa.test' + pkey = self.get_service_pkey('cifs', host=temp_host) + self.add_host('host-no-dns', 'ipa.test', force=True) + self.add_service('cifs', temp_host, force=True) + + # service cleanup + self.delete_record(pkey) + self.assert_notification() + assert not self.has_record(pkey) + + # host cleanup + self.navigate_to_entity('host') + self.delete_record(temp_host) + + @screenshot + def test_search_services(self): + """ + Search different services + """ + # keywords to search (find_record accepts data dict) + http_search = {'pkey': self.get_service_pkey('HTTP')} + ldap_search = {'pkey': self.get_service_pkey('ldap')} + dns_search = {'pkey': self.get_service_pkey('DNS')} + self.init_app() + self.navigate_to_entity(ENTITY) + self.find_record('service', http_search) + self.find_record('service', ldap_search) + self.find_record('service', dns_search) + + @screenshot + def test_dropdown(self): + """ + Test service combobox dropdowns with UP/DOWN arrows + """ + self.init_app() + self.navigate_to_entity(ENTITY) + self.facet_button_click('add') + + actions = ActionChains(self.driver) + actions.send_keys(Keys.ARROW_DOWN) + # all actions are performed at once with perform() + actions.send_keys(Keys.ARROW_DOWN).perform() + actions.send_keys(Keys.ENTER) + actions.send_keys(Keys.TAB) + actions.send_keys(Keys.ARROW_DOWN) + actions.send_keys(Keys.ARROW_DOWN) + actions.send_keys(Keys.ENTER).perform() + + # evaluate value fields are not empty + service_cb = "input[name='service']" + service = self.find(service_cb, By.CSS_SELECTOR) + assert service.get_attribute('value') != "" + host_cb = "[name='host'].combobox-widget" + host = self.find(host_cb, By.CSS_SELECTOR) + assert host.get_attribute('value') != "" + + @screenshot + def test_add_service_using_enter(self): + """ + Add a service using enter key + """ + self.init_app() + pkey = self.get_service_pkey('smtp') + self.add_service('smtp', confirm=False) + actions = ActionChains(self.driver) + actions.send_keys(Keys.ENTER).perform() + self.wait(1) + assert self.has_record(pkey) + + # service cleanup + self.delete_record(pkey) + assert not self.has_record(pkey) + + @screenshot + def test_delete_service_using_enter(self): + """ + Delete a service using enter key + """ + self.init_app() + pkey = self.get_service_pkey('smtp') + self.add_service('smtp') + assert self.has_record(pkey) + self.delete_record(pkey, confirm=False) + actions = ActionChains(self.driver) + actions.send_keys(Keys.ENTER).perform() + self.wait(1) + assert not self.has_record(pkey) + + @screenshot + def test_provision_unprovision_keytab(self): + """ + Test provision / unprovision keytab + + Requires to run a ipa-get/rmkeytab on UI host. + """ + if not self.has_ca(): + self.skip('CA is not configured') + + csr_path = self.config.get('service_csr_path') + if not csr_path: + self.skip('CSR file is not configured') + + csr = self.load_file(csr_path) + + self.init_app() + pkey = self.get_service_pkey('cifs') + + self.navigate_to_entity(ENTITY) + + # provision service + self.add_service('cifs') + self.navigate_to_record(pkey, entity=ENTITY) + self.action_list_action('request_cert', confirm=False) + self.assert_dialog() + self.fill_text("textarea[name='csr'", csr) + self.dialog_button_click('issue') + self.run_keytab_on_host(pkey, 'get') + self.wait(1) + self.facet_button_click('refresh') + + # assert key present + no_key_selector = 'div[name="kerberos-key-valid"] label' + provisioned_assert = 'Kerberos Key Present, Service Provisioned' + self.assert_text(no_key_selector, provisioned_assert) + + # unprovision service + self.action_list_action('unprovision', confirm_btn='unprovision') + self.facet_button_click('refresh') + self.run_keytab_on_host(pkey, 'rm') + + # assert key not present + no_key_selector = 'div[name="kerberos-key-missing"] label' + provisioned_assert = 'Kerberos Key Not Present' + self.assert_text(no_key_selector, provisioned_assert) + + # service cleanup + self.navigate_to_entity(ENTITY) + self.delete_record(pkey) From a895f0d6d2c950fd53a0ba611a08f4ae7c7210a9 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 18:45:23 +0100 Subject: [PATCH 06/14] ui_tests: run ipa-get/rmkeytab command on UI host Run ipa-get/rmkeytab command on UI host in order to test whether we have the key un/provisioned. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/test_service.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/ipatests/test_webui/test_service.py b/ipatests/test_webui/test_service.py index 8a856984b6..286d4930c4 100644 --- a/ipatests/test_webui/test_service.py +++ b/ipatests/test_webui/test_service.py @@ -26,6 +26,7 @@ from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains + import pytest ENTITY = 'service' @@ -97,6 +98,27 @@ def add_service(self, service, self.dialog_button_click('add') self.wait(0.3) self.assert_no_error_dialog() + + def run_keytab_on_host(self, pkey, action): + """ + Run ipa-get/rmkeytab command on UI host in order to test whether + we have the key un/provisioned. + """ + + kt_path = '/tmp/test.keytab' + + if action == 'get': + cmd = '/usr/sbin/ipa-getkeytab -p {} -k {}'.format(pkey, kt_path) + self.run_cmd_on_ui_host(cmd) + elif action == 'rm': + cmd = '/usr/sbin/ipa-rmkeytab -p {} -k {}'.format(pkey, kt_path) + kt_rm_cmd = 'rm -f {}'.format(kt_path) + self.run_cmd_on_ui_host(cmd) + self.run_cmd_on_ui_host(kt_rm_cmd) + else: + raise ValueError("Bad action specified") + + @pytest.mark.tier1 class test_service(sevice_tasks): From c51d31b810c93947a1855c6ed42a6a8015548461 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 18:51:10 +0100 Subject: [PATCH 07/14] ui_tests: add assert_notification() Add assert_notification() function to check whether we have a notification of particular type/ https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/ui_driver.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py index 71efe6705c..b9c099e414 100644 --- a/ipatests/test_webui/ui_driver.py +++ b/ipatests/test_webui/ui_driver.py @@ -1875,3 +1875,21 @@ def assert_action_list_action(self, action, visible=True, enabled=True, is_enabled = not self.has_class(li, 'disabled') assert is_enabled == enabled, ('Invalid enabled state of action item %s. ' 'Expected: %s') % (action, str(visible)) + + def assert_notification(self, type='success', assert_text=None): + """ + Assert whether we have a notification of particular type + + type: type for assertion + assert_text: assert particular text when True + + Returns True if selector/text found + """ + + notification_type = 'div.notification-area .alert-{}'.format(type) + # wait for a half sec for notification to appear + self.wait(0.5) + is_present = self.find(notification_type, By.CSS_SELECTOR) + if assert_text: + assert assert_text in is_present.text + assert is_present, "Notification not present" From 30f6ea6c9637997a818bffebb28e8e73e1caf63a Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 18:52:45 +0100 Subject: [PATCH 08/14] ui_tests: add assert_field_required() Add assert_field_required() to check whether we got 'Required field' error message. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/ui_driver.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py index b9c099e414..27bf5fcb20 100644 --- a/ipatests/test_webui/ui_driver.py +++ b/ipatests/test_webui/ui_driver.py @@ -1876,6 +1876,19 @@ def assert_action_list_action(self, action, visible=True, enabled=True, assert is_enabled == enabled, ('Invalid enabled state of action item %s. ' 'Expected: %s') % (action, str(visible)) + def assert_field_required(self, parent=None): + """ + Assert we got 'Required field' error message + """ + + if not parent: + parent = self.get_form() + + req_field_css = '.help-block[name="error_link"]' + + res = self.find(req_field_css, By.CSS_SELECTOR, context=parent) + assert 'Required field' in res.text, 'No "Required field" error found' + def assert_notification(self, type='success', assert_text=None): """ Assert whether we have a notification of particular type From 7fe32a65181a1a32c33635f8eeda0aa20d2ab048 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 18:56:25 +0100 Subject: [PATCH 09/14] ui_tests: add funcs to add/remove users public SSH key Add funcs to add/remove users public SSH key. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/ui_driver.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py index 27bf5fcb20..6ef84266b6 100644 --- a/ipatests/test_webui/ui_driver.py +++ b/ipatests/test_webui/ui_driver.py @@ -1615,6 +1615,34 @@ def get_t_vals(t): # add multiple at once and test table delete button self.add_table_associations(table, keys, delete=True) + def add_sshkey_to_user(self, user, ssh_key): + """ + Add ssh public key to particular user + + user (str): user to add the key to + ssh_key (str): public ssh key + """ + self.navigate_to_entity('user') + self.navigate_to_record(user) + + ssh_pub = 'div[name="ipasshpubkey"] button[name="add"]' + self.find(ssh_pub, By.CSS_SELECTOR).click() + self.wait_for_request(n=5, d=2) + self.driver.switch_to.active_element.send_keys(ssh_key) + self.dialog_button_click('update') + self.facet_button_click('save') + + def delete_user_sshkey(self, user): + """ + Delete ssh public key of particular user + """ + self.navigate_to_entity('user') + self.navigate_to_record(user) + + ssh_pub = 'div[name="ipasshpubkey"] button[name="remove"]' + self.find(ssh_pub, By.CSS_SELECTOR).click() + self.facet_button_click('save') + def has_class(self, el, cls): """ Check if el has CSS class From 74a14d99be7165335878043b9566a0a2b681a028 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 19:02:45 +0100 Subject: [PATCH 10/14] ui_tests: add function to run cmd on UI host Run command on the UI system using "admin" user's passwd from conf. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/ui_driver.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py index 6ef84266b6..8283090f9b 100644 --- a/ipatests/test_webui/ui_driver.py +++ b/ipatests/test_webui/ui_driver.py @@ -30,6 +30,7 @@ import os from functools import wraps import unittest +import paramiko # pylint: disable=import-error from six.moves.urllib.error import URLError @@ -1643,6 +1644,31 @@ def delete_user_sshkey(self, user): self.find(ssh_pub, By.CSS_SELECTOR).click() self.facet_button_click('save') + def run_cmd_on_ui_host(self, cmd): + """ + Run command on the UI system using "admin" user's passwd from conf. + + cmd (str): command to run + """ + + login = self.config.get('ipa_admin') + hostname = self.config.get('ipa_server') + password = self.config.get('ipa_password') + + try: + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh.connect(hostname=hostname, username=login, password=password) + ssh.exec_command(cmd) + except paramiko.AuthenticationException: + self.skip('Authentication to server {} failed'.format(hostname)) + except paramiko.SSHException as e: + self.skip('Unable to establish SSH connection: {}'.format(e)) + except Exception as e: + self.skip('Unable to proceed: {}'.format(e)) + finally: + ssh.close() + def has_class(self, el, cls): """ Check if el has CSS class From 89c59a437cbdc6b534215faed994d27061f705c8 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 19:07:20 +0100 Subject: [PATCH 11/14] ui_tests: make associations cancelable Adjust associations functions to simulate "cancel" action. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/ui_driver.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py index 8283090f9b..2457b6659e 100644 --- a/ipatests/test_webui/ui_driver.py +++ b/ipatests/test_webui/ui_driver.py @@ -1415,7 +1415,8 @@ def add_table_record(self, name, data, parent=None): self.wait_for_request() def prepare_associations( - self, pkeys, facet=None, facet_btn='add', member_pkeys=None): + self, pkeys, facet=None, facet_btn='add', member_pkeys=None, + cancel=False): """ Helper function for add_associations and delete_associations """ @@ -1430,6 +1431,9 @@ def prepare_associations( self.select_record(key, table_name='available') self.button_click('add') + if cancel: + self.dialog_button_click('cancel') + return self.dialog_button_click('add') self.wait_for_request() @@ -1442,13 +1446,14 @@ def prepare_associations( def add_associations( self, pkeys, facet=None, delete=False, facet_btn='add', - member_pkeys=None): + member_pkeys=None, cancel=False): """ Add associations """ check_pkeys = self.prepare_associations( - pkeys, facet, facet_btn, member_pkeys) - + pkeys, facet, facet_btn, member_pkeys, cancel=cancel) + if cancel: + return for key in check_pkeys: self.assert_record(key) if delete: From 1a0fc09f2f23bb49f4b29a7ad3bd0ad9f4e4dcaf Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 22:04:07 +0100 Subject: [PATCH 12/14] ui_tests: test cancel and delete without button Add conditions to test cancel of delete record and confirmation with "Enter" key. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/ui_driver.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py index 2457b6659e..2ea06e9144 100644 --- a/ipatests/test_webui/ui_driver.py +++ b/ipatests/test_webui/ui_driver.py @@ -1072,7 +1072,7 @@ def navigate_to_record(self, pkey, parent=None, table_name=None, entity=None, fa def delete_record( self, pkeys, fields=None, parent=None, table_name=None, - facet_btn='remove'): + facet_btn='remove', cancel=False, confirm=True): """ Delete records with given pkeys in currently opened search table. """ @@ -1097,6 +1097,11 @@ def delete_record( self.facet_button_click(facet_btn) if fields: self.fill_fields(fields) + if cancel: + self.dialog_button_click('cancel') + return + if not confirm: + return self.dialog_button_click('ok') self.wait_for_request(n=2) self.wait() From 9847519ce4efa3d09d1f22fe311609289bcffdb0 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 22:14:49 +0100 Subject: [PATCH 13/14] ui_tests: select_combobox() fixes Move strict "search_btn" element finding to later so we do not fail when using combobox without search button. Also switch open_btn.click() before fill_textbox() as it is used to close the selection. https://pagure.io/freeipa/issue/7441 --- ipatests/test_webui/ui_driver.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py index 2ea06e9144..196f13fd31 100644 --- a/ipatests/test_webui/ui_driver.py +++ b/ipatests/test_webui/ui_driver.py @@ -872,19 +872,19 @@ def select_combobox(self, name, value, parent=None, combobox_input=None): self.wait_for_request() list_cnt = self.find('.combobox-widget-list', By.CSS_SELECTOR, cb, strict=True) - 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 combobox_input: if not option: - self.fill_textbox(combobox_input, value, cb) open_btn.click() + self.fill_textbox(combobox_input, value, cb) else: if not option: # try to search self.fill_textbox('filter', value, cb) - + search_btn = self.find('a[name=search] i', By.CSS_SELECTOR, cb, + strict=True) search_btn.click() self.wait_for_request() option = self.find(opt_s, By.CSS_SELECTOR, cb, strict=True) From ab77352ec7ce5a37081074fff6a2e2536a7cb701 Mon Sep 17 00:00:00 2001 From: Michal Reznik <mrez...@redhat.com> Date: Tue, 13 Mar 2018 22:28:46 +0100 Subject: [PATCH 14/14] freeipa-pr-ci: enable WebUI tests enable WebUI tests in PRCI --- .freeipa-pr-ci.yaml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.freeipa-pr-ci.yaml b/.freeipa-pr-ci.yaml index b98a27835c..154e2212b5 100644 --- a/.freeipa-pr-ci.yaml +++ b/.freeipa-pr-ci.yaml @@ -3,6 +3,10 @@ topologies: name: build cpu: 2 memory: 3800 + ipaserver: &ipaserver + name: ipaserver + cpu: 1 + memory: 2400 master_1repl: &master_1repl name: master_1repl cpu: 4 @@ -23,7 +27,7 @@ jobs: git_refspec: '{git_refspec}' template: &ci-master-f27 name: freeipa/ci-master-f27 - version: 1.0.2 + version: 1.0.3 timeout: 1800 topology: *build @@ -62,3 +66,15 @@ jobs: template: *ci-master-f27 timeout: 3600 topology: *master_1repl + + fedora-27/test_webui: + requires: [fedora-27/build] + priority: 50 + job: + class: RunWebuiTests + args: + build_url: '{fedora-27/build_url}' + test_suite: test_webui/ + template: *ci-master-f27 + timeout: 7200 + topology: *ipaserver
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org