diff options
author | Edan Binshtok <eb578m@intl.att.com> | 2017-10-04 09:33:23 +0300 |
---|---|---|
committer | Edan Binshtok <eb578m@intl.att.com> | 2017-10-04 09:36:04 +0300 |
commit | f8907f0c4fc0ba4bb97a1d636a50c5b40c2642f2 (patch) | |
tree | 3d04d86910c93e42c055e5ed699ab1919482d5be /services/frontend | |
parent | 733e00df0a6fa19dd92ec7392966340345dd1885 (diff) |
Initial seed
Initial upload of django test framework
Change-Id: I643a7f4efc52cfafe4cc6d92e3178f36a0c1837c
Issue-Id: VVP-1
Signed-off-by: Edan Binshtok <eb578m@intl.att.com>
Diffstat (limited to 'services/frontend')
34 files changed, 4142 insertions, 0 deletions
diff --git a/services/frontend/__init__.py b/services/frontend/__init__.py new file mode 100644 index 0000000..30d7152 --- /dev/null +++ b/services/frontend/__init__.py @@ -0,0 +1,38 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. diff --git a/services/frontend/__pycache__/__init__.cpython-36.pyc b/services/frontend/__pycache__/__init__.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..bd6d49d --- /dev/null +++ b/services/frontend/__pycache__/__init__.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_checklist.cpython-36.pyc b/services/frontend/__pycache__/fe_checklist.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..d743311 --- /dev/null +++ b/services/frontend/__pycache__/fe_checklist.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_checklist_template.cpython-36.pyc b/services/frontend/__pycache__/fe_checklist_template.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..c781628 --- /dev/null +++ b/services/frontend/__pycache__/fe_checklist_template.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_cms.cpython-36.pyc b/services/frontend/__pycache__/fe_cms.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..b1c3fbe --- /dev/null +++ b/services/frontend/__pycache__/fe_cms.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_dashboard.cpython-36.pyc b/services/frontend/__pycache__/fe_dashboard.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..5222e8e --- /dev/null +++ b/services/frontend/__pycache__/fe_dashboard.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_detailed_view.cpython-36.pyc b/services/frontend/__pycache__/fe_detailed_view.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..6247ca3 --- /dev/null +++ b/services/frontend/__pycache__/fe_detailed_view.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_general.cpython-36.pyc b/services/frontend/__pycache__/fe_general.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..9b19b20 --- /dev/null +++ b/services/frontend/__pycache__/fe_general.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_invite.cpython-36.pyc b/services/frontend/__pycache__/fe_invite.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..2a94d33 --- /dev/null +++ b/services/frontend/__pycache__/fe_invite.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_overview.cpython-36.pyc b/services/frontend/__pycache__/fe_overview.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..eee24cc --- /dev/null +++ b/services/frontend/__pycache__/fe_overview.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_user.cpython-36.pyc b/services/frontend/__pycache__/fe_user.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..54cb26d --- /dev/null +++ b/services/frontend/__pycache__/fe_user.cpython-36.pyc diff --git a/services/frontend/__pycache__/fe_wizard.cpython-36-PYTEST.pyc b/services/frontend/__pycache__/fe_wizard.cpython-36-PYTEST.pyc Binary files differnew file mode 100755 index 0000000..630c015 --- /dev/null +++ b/services/frontend/__pycache__/fe_wizard.cpython-36-PYTEST.pyc diff --git a/services/frontend/__pycache__/fe_wizard.cpython-36.pyc b/services/frontend/__pycache__/fe_wizard.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..ca7c26f --- /dev/null +++ b/services/frontend/__pycache__/fe_wizard.cpython-36.pyc diff --git a/services/frontend/base_actions/__init__.py b/services/frontend/base_actions/__init__.py new file mode 100644 index 0000000..30d7152 --- /dev/null +++ b/services/frontend/base_actions/__init__.py @@ -0,0 +1,38 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. diff --git a/services/frontend/base_actions/__pycache__/__init__.cpython-36.pyc b/services/frontend/base_actions/__pycache__/__init__.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..567e40e --- /dev/null +++ b/services/frontend/base_actions/__pycache__/__init__.cpython-36.pyc diff --git a/services/frontend/base_actions/__pycache__/click.cpython-36.pyc b/services/frontend/base_actions/__pycache__/click.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..7848aff --- /dev/null +++ b/services/frontend/base_actions/__pycache__/click.cpython-36.pyc diff --git a/services/frontend/base_actions/__pycache__/enter.cpython-36.pyc b/services/frontend/base_actions/__pycache__/enter.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..df5e175 --- /dev/null +++ b/services/frontend/base_actions/__pycache__/enter.cpython-36.pyc diff --git a/services/frontend/base_actions/__pycache__/get.cpython-36.pyc b/services/frontend/base_actions/__pycache__/get.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..a95dc14 --- /dev/null +++ b/services/frontend/base_actions/__pycache__/get.cpython-36.pyc diff --git a/services/frontend/base_actions/__pycache__/wait.cpython-36.pyc b/services/frontend/base_actions/__pycache__/wait.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..29b73ba --- /dev/null +++ b/services/frontend/base_actions/__pycache__/wait.cpython-36.pyc diff --git a/services/frontend/base_actions/click.py b/services/frontend/base_actions/click.py new file mode 100644 index 0000000..00470b7 --- /dev/null +++ b/services/frontend/base_actions/click.py @@ -0,0 +1,108 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from selenium.webdriver.common.action_chains import ActionChains + +from services.frontend.base_actions.wait import Wait +from services.session import session + + +class Click: + + @staticmethod + def id(element_id, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + Wait.id(element_id) + session.ice_driver.find_element_by_id(element_id).click() + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to click_on on ID " + element_id + raise Exception(errorMsg, e) + + @staticmethod + def name(element_name, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + Wait.name(element_name) + session.ice_driver.find_element_by_name(element_name).click() + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to click_on on ID " + element_name + raise Exception(errorMsg, e) + + @staticmethod + def link_text(link_inner_text, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + Wait.link_text(link_inner_text) + session.ice_driver.find_element_by_link_text(link_inner_text).click() + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to click_on on LINK TEXT " + link_inner_text + raise Exception(errorMsg, e) + + @staticmethod + def css(element_css, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + Wait.css(element_css) + session.ice_driver.find_element_by_css_selector(element_css).click() + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to click_on on CSS Selector " + element_css + raise Exception(errorMsg, e) + + @staticmethod + def xpath(element_xpath, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + Wait.xpath(element_xpath) + session.ice_driver.find_element_by_xpath(element_xpath).click() + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to click_on on XPATH " + element_xpath + raise Exception(errorMsg, e) + + @staticmethod + def drag_and_drop_by_css(source_css, xoffset, yoffset): + ns = session.ice_driver.find_element_by_id("step-description-1") + ActionChains(session.ice_driver).move_to_element(ns).perform() + Wait.css(source_css) + source_element = session.ice_driver.find_element_by_css_selector(source_css) + ActionChains(session.ice_driver).drag_and_drop_by_offset(source_element, xoffset, yoffset).perform() diff --git a/services/frontend/base_actions/enter.py b/services/frontend/base_actions/enter.py new file mode 100644 index 0000000..4577a3d --- /dev/null +++ b/services/frontend/base_actions/enter.py @@ -0,0 +1,139 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from datetime import datetime +import time + +from services.frontend.base_actions.wait import Wait +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() +class Enter: + + @staticmethod + def text_by_name(attr_name_value, typed_text, wait_for_page=False): + try: # Send keys to element in UI, by name locator (e.g. type something in text box). + if wait_for_page: + Wait.page_has_loaded() + Wait.name(attr_name_value) + session.ice_driver.find_element_by_name(attr_name_value).clear() + session.ice_driver.find_element_by_name(attr_name_value).send_keys(typed_text[:-1]) + time.sleep(session.wait_until_time_pause) + session.ice_driver.find_element_by_name(attr_name_value).send_keys(typed_text[-1:]) + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to type " + typed_text + " in text box" + raise Exception(errorMsg, e) + + @staticmethod + def text_by_xpath(attr_xpath_value, typed_text, wait_for_page=False): + try: # Send keys to element in UI, by name locator (e.g. type something in text box). + if wait_for_page: + Wait.page_has_loaded() + Wait.xpath(attr_xpath_value) + session.ice_driver.find_element_by_xpath(attr_xpath_value).clear() + session.ice_driver.find_element_by_xpath(attr_xpath_value).send_keys(typed_text[:-1]) + time.sleep(session.wait_until_time_pause) + session.ice_driver.find_element_by_xpath(attr_xpath_value).send_keys(typed_text[-1:]) + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to type " + typed_text + " in text box" + raise Exception(errorMsg, attr_xpath_value) + + @staticmethod + def text_by_id(attr_id_value, typed_text, wait_for_page=False): + try: # Send keys to element in UI, by ID locator (e.g. type something in text box). + if wait_for_page: + Wait.page_has_loaded() + Wait.id(attr_id_value) + session.ice_driver.find_element_by_id(attr_id_value).clear() + session.ice_driver.find_element_by_id(attr_id_value).send_keys(typed_text[:-1]) + time.sleep(session.wait_until_time_pause) + session.ice_driver.find_element_by_id(attr_id_value).send_keys(typed_text[-1:]) + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to type " + typed_text + " in text box" + raise Exception(errorMsg, attr_id_value) + + @staticmethod + def clear(attr_id_value): + try: + Wait.id(attr_id_value) + session.ice_driver.find_element_by_id(attr_id_value).clear() + except Exception as e: + errorMsg = "Failed to clear text box" + raise Exception(errorMsg, attr_id_value) + + @staticmethod + def text_by_css(attr_css_value, typed_text, wait_for_page=False): + try: # Send keys to element in UI, by CSS locator (e.g. type something in text box). + if wait_for_page: + Wait.page_has_loaded() + Wait.css(attr_css_value) + session.ice_driver.find_element_by_css_selector(attr_css_value).clear() + session.ice_driver.find_element_by_css_selector(attr_css_value).send_keys(typed_text[:-1]) + time.sleep(session.wait_until_time_pause) + session.ice_driver.find_element_by_css_selector(attr_css_value).send_keys(typed_text[-1:]) + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to type " + typed_text + " in text box" + raise Exception(errorMsg, attr_css_value) + + @staticmethod + def text_by_link_text(attr_link_text_value, typed_text, wait_for_page=False): + try: # Send keys to element in UI, by name locator (e.g. type something in text box). + if wait_for_page: + Wait.page_has_loaded() + Wait.link_text(attr_link_text_value) + session.ice_driver.find_element_by_link_text(attr_link_text_value).clear() + session.ice_driver.find_element_by_link_text(attr_link_text_value).send_keys(typed_text[:-1]) + time.sleep(session.wait_until_time_pause) + session.ice_driver.find_element_by_link_text(attr_link_text_value).send_keys(typed_text[-1:]) + except Exception as e: # If failed - count the failure and add the error to list of errors. + errorMsg = "Failed to type " + typed_text + " in text box" + raise Exception(errorMsg, attr_link_text_value) + + @staticmethod + def date_picker(selector, property_name, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + session.ice_driver.execute_script( + "var element = angular.element(document.querySelector('" + selector + "')); element.scope()." + + property_name + " = new Date('" + str(datetime.today().isoformat()) + "')") + except Exception as e: + errorMsg = "Failed to select date with datePicker." + raise Exception(errorMsg, str(e)) diff --git a/services/frontend/base_actions/get.py b/services/frontend/base_actions/get.py new file mode 100644 index 0000000..8735c1b --- /dev/null +++ b/services/frontend/base_actions/get.py @@ -0,0 +1,127 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from services.frontend.base_actions.wait import Wait +from services.session import session + + +class Get: + + @staticmethod + def by_id(attr_id_value, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + Wait.id(attr_id_value) + return session.ice_driver.find_element_by_id(attr_id_value).text + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Failed to get text of element " + attr_id_value + raise Exception(errorMsg, attr_id_value) + + @staticmethod + def by_css(attr_css_value, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + Wait.css(attr_css_value) + return session.ice_driver.find_element_by_css_selector(attr_css_value).text + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Failed to get text of element " + attr_css_value + raise Exception(errorMsg, attr_css_value) + + @staticmethod + def wysiwyg_element_by_id(attr_id_value): + try: + Wait.id(attr_id_value) + return session.ice_driver.find_element_by_css_selector( + "#" + attr_id_value + ".wysiwyg-textarea") + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Failed to get element by id " + attr_id_value + raise Exception(errorMsg, attr_id_value) + + @staticmethod + def by_name(attr_name_value): + try: + Wait.name(attr_name_value) + return session.ice_driver.find_element_by_name(attr_name_value).text + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Failed to get text of element " + attr_name_value + raise Exception(errorMsg, attr_name_value) + + @staticmethod + def by_xpath(attr_name_value): + try: + Wait.xpath(attr_name_value) + return session.ice_driver.find_element_by_xpath(attr_name_value).text + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Failed to get text of element " + attr_name_value + raise Exception(errorMsg, attr_name_value) + + @staticmethod + def value_by_name(attr_name_value): + try: + Wait.name(attr_name_value) + return session.ice_driver.find_element_by_name(attr_name_value).get_attribute("value") + except Exception as e: + errorMsg = "Failed to get value by name:" + attr_name_value + raise Exception(errorMsg, attr_name_value) + + @staticmethod + def meta_order_by_id(attr_id_value): + try: + Wait.id(attr_id_value) + return session.ice_driver.find_element_by_id(attr_id_value).get_attribute("meta-order") + except Exception as e: + errorMsg = "Failed to get meta order by id:" + attr_id_value + raise Exception(errorMsg, attr_id_value) + + @staticmethod + def is_selected_by_id(attr_id_value, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + Wait.id(attr_id_value) + return session.ice_driver.find_element_by_id(attr_id_value).is_selected() + except Exception as e: + errorMsg = "Failed to get if it's selected by id:" + attr_id_value + raise Exception(errorMsg, attr_id_value) diff --git a/services/frontend/base_actions/wait.py b/services/frontend/base_actions/wait.py new file mode 100644 index 0000000..50eff08 --- /dev/null +++ b/services/frontend/base_actions/wait.py @@ -0,0 +1,317 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +import time + +from selenium.common.exceptions import NoSuchElementException +from selenium.webdriver.common.by import By +from selenium.webdriver.support import expected_conditions +from selenium.webdriver.support.wait import WebDriverWait + +from services.constants import Constants +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() + + +class Wait: + + @staticmethod + def text_by_xpath(xpath, text, wait_for_page=False): + try: # Wait 4 seconds for element and compare to expected result. + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_retires).until( + expected_conditions.text_to_be_present_in_element( + (By.XPATH, xpath), text) + ) + # If failed - count the failure and add the error to list of errors. + except: + error_msg = "Text - " + text + " not found in xPath " + xpath + raise Exception(error_msg, xpath) + + @staticmethod + def text_by_id(element_id, text, wait_for_page=False): + try: # Wait 4 seconds for element and compare to expected result. + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_retires).until( + expected_conditions.text_to_be_present_in_element( + (By.ID, element_id), text) + ) + # If failed - count the failure and add the error to list of errors. + except: + error_msg = "Text - " + text + " not found in ID " + element_id + raise Exception(error_msg, element_id) + + @staticmethod + def text_by_css(css, text, wait_for_page=False): + try: # Wait 4 seconds for element and compare to expected result. + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_retires).until( + expected_conditions.text_to_be_present_in_element( + (By.CSS_SELECTOR, css), text) + ) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + error_msg = "Text - " + text + " not found in CSS - " + css + raise Exception(error_msg, e) + + @staticmethod + def text_by_name(name, text, wait_for_page=False): + try: # Wait 4 seconds for element and compare to expected result. + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_retires).until( + expected_conditions.text_to_be_present_in_element( + (By.NAME, name), text) + ) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + error_msg = "Text - " + text + " not found by NAME - " + name + raise Exception(error_msg, e) + + @staticmethod + def id(element_id, wait_for_page=False): + try: # Wait 4 seconds for element and compare to expected result. + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_retires).until( + expected_conditions.visibility_of_element_located( + (By.ID, element_id)) + ) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + error_msg = "Didn't find ID " + element_id + raise Exception(error_msg, e) + + @staticmethod + def css(element_css, wait_for_page=False): + try: # Wait 4 seconds for element and compare to expected result. + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_retires).until( + expected_conditions.visibility_of_element_located( + (By.CSS_SELECTOR, element_css)) + ) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + error_msg = "Didn't find CSS Selector " + element_css + raise Exception(error_msg, e) + + @staticmethod + def is_css_exists(element_css, wait_for_page=False): + try: # Wait 4 seconds for element and compare to expected result. + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_implicit_time).until( + expected_conditions.visibility_of_element_located( + (By.CSS_SELECTOR, element_css)) + ) + return True + # If failed - count the failure and add the error to list of errors. + except Exception as e: + error_msg = "Didn't find CSS Selector " + element_css + return False + + @staticmethod + def link_text(link_inner_text, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_retires).until( + expected_conditions.visibility_of_element_located( + (By.LINK_TEXT, link_inner_text)) + ) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + error_msg = "Didn't find LINK TEXT " + link_inner_text + raise Exception(error_msg, e) + + @staticmethod + def name(element_name, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_retires).until( + expected_conditions.visibility_of_element_located( + (By.NAME, element_name)) + ) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + error_msg = "Didn't find NAME " + element_name + raise Exception(error_msg, e) + + @staticmethod + def xpath(element_xpath, wait_for_page=False): + try: + if wait_for_page: + Wait.page_has_loaded() + WebDriverWait(session.ice_driver, session.wait_until_retires).until( + expected_conditions.visibility_of_element_located( + (By.XPATH, element_xpath)) + ) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + error_msg = "Didn't find XPath " + element_xpath + raise Exception(error_msg, e) + + @staticmethod + def page_has_loaded(): + countwait_untilelement_to_be_presented_by_id = 0 + for _ in range(Constants.FEConstants.RETRIES_NUMBER): + httpRequests = session.ice_driver.execute_script( + 'return window.angular ? window.angular.element("body").injector().get("$http").pendingRequests.length : 1;') + if(str(httpRequests) == "0"): + time.sleep(session.wait_until_time_pause) + return + logger.debug( + "Checking if {} page is loaded. ".format(session.ice_driver.current_url)) + time.sleep(session.wait_until_time_pause) + countwait_untilelement_to_be_presented_by_id += 1 + + raise Exception("Page loading took too much time") + + @staticmethod + def modal_to_dissappear(): + session.ice_driver.implicitly_wait(0) + i = 0 + not_found = False + while i < session.wait_until_retires: + try: + session.ice_driver.find_element_by_css_selector( + Constants.Dashboard.Wizard.Open.CSS) + except NoSuchElementException: + not_found = True + try: + session.ice_driver.find_element_by_class_name( + Constants.Dashboard.Wizard.Open.CLASS_NAME) + not_found = False + except NoSuchElementException: + not_found = True + + if not_found: + break + + else: + time.sleep(session.wait_until_time_pause) + i += 1 + + session.ice_driver.implicitly_wait(session.wait_until_implicit_time) + if not_found: + return True + else: + raise Exception("waitForModalToDissapper") + + @staticmethod + def id_to_dissappear(id_element, wait_for_page=False): + if wait_for_page: + Wait.page_has_loaded() + session.ice_driver.implicitly_wait(0) + i = 0 + not_found = False + while i < session.wait_until_retires: + try: + session.ice_driver.find_element_by_id(id_element) + except NoSuchElementException: + not_found = True + + if not_found: + break + else: + time.sleep(session.wait_until_time_pause) + i += 1 + + session.ice_driver.implicitly_wait(session.wait_until_implicit_time) + if not_found: + return True + else: + raise Exception( + "id_to_dissappear " + id_element + " num of retries = " + str(i)) + + @staticmethod + def name_to_dissappear(name_element, wait_for_page=False): + if wait_for_page: + Wait.page_has_loaded() + session.ice_driver.implicitly_wait(0) + i = 0 + not_found = False + while i < session.wait_until_retires: + try: + session.ice_driver.find_element_by_name(name_element) + except NoSuchElementException: + not_found = True + + if not_found: + break + else: + time.sleep(session.wait_until_time_pause) + i += 1 + + session.ice_driver.implicitly_wait(session.wait_until_implicit_time) + if not_found: + return True + else: + raise Exception( + "name_to_dissappear " + name_element + " num of retries = " + str(i)) + + @staticmethod + def css_to_dissappear(css_element): + session.ice_driver.implicitly_wait(0) + i = 0 + not_found = False + while i < session.wait_until_retires: + try: + session.ice_driver.find_element_by_css_selector(css_element) + except NoSuchElementException: + not_found = True + + if not_found: + break + else: + time.sleep(session.wait_until_time_pause) + i += 1 + + session.ice_driver.implicitly_wait(session.wait_until_implicit_time) + if not_found: + return True + else: + raise Exception("css_to_dissappear" + css_element) diff --git a/services/frontend/fe_checklist.py b/services/frontend/fe_checklist.py new file mode 100644 index 0000000..75f957a --- /dev/null +++ b/services/frontend/fe_checklist.py @@ -0,0 +1,755 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from django.conf import settings +from selenium.webdriver.support.ui import Select +from wheel.signatures import assertTrue + +from services.database.db_checklist import DBChecklist +from services.database.db_user import DBUser +from services.database.db_virtual_function import DBVirtualFunction +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.get import Get +from services.frontend.base_actions.wait import Wait +from services.frontend.fe_general import FEGeneral +from services.frontend.fe_overview import FEOverview +from services.frontend.fe_user import FEUser +from services.frontend.fe_wizard import FEWizard +from services.helper import Helper +from services.logging_service import LoggingServiceFactory +from tests.uiTests.test_ui_base import * + + +logger = LoggingServiceFactory.get_logger() + + +class FEChecklist: + + assocciatedFileName = None + + @staticmethod + def go_to_checklist(engagement_id, cl_uuid): + try: + Click.id(engagement_id) + Click.id("checklist-" + cl_uuid) + Wait.id("line-item-description") + except Exception as e: + errorMsg = "Failed to go to checklist page." + raise Exception(errorMsg, e) + + @staticmethod + def create_new_checklist(newObj): + try: + newObjWithChecklist = None + vfName = newObj[0] + uuid = newObj[1] + inviteEmail = newObj[2] + # Fetch one AT&T user ID. + vfuuid = DBGeneral.select_where( + "uuid", "ice_vf", "name", vfName, 1) + engagement_id = DBVirtualFunction.select_eng_uuid(vfName) + engLeadEmail = DBUser.select_el_email(vfName) + logger.debug("EL email: " + engLeadEmail) + engagement_manual_id = DBGeneral.select_where("engagement_manual_id", "ice_engagement", "uuid", + engagement_id, 1) + # Click on all default next steps + myVfName = engagement_manual_id + ": " + vfName + actualVfNameid = "clickable-" + myVfName + actualVfName = Get.by_id(actualVfNameid) + Helper.internal_assert(myVfName, actualVfName) + # NEXT STEP ID + Click.id(actualVfNameid, wait_for_page=True) + FEOverview.complete_defaults_nextsteps(engagement_id) + inviterURL = Constants.Default.InviteURL.Signup.TEXT + \ + vfuuid + "&inviter_uuid=" + uuid + "&email=" + inviteEmail +# time.sleep(2) + FEGeneral.re_open(inviterURL) + FEGeneral.form_validate_email(inviteEmail) + # Login with EL role + FEGeneral.re_open(Constants.Default.LoginURL.TEXT) + FEUser.login(engLeadEmail, Constants.Default.Password.TEXT) + Wait.id(Constants.Dashboard.Statuses.Title.ID) + Wait.id(engagement_manual_id) # cheklist + # VALIDATE SCROLLING + actualVfName = Get.by_id(actualVfNameid) + myVfName = engagement_manual_id + ": " + vfName +# Wait.id(actualVfNameid) + Wait.id(engagement_manual_id, wait_for_page=True) + Click.id(actualVfNameid, wait_for_page=True) + # Create new checklist + checklistName = FEChecklist.create_checklist( + engagement_id, vfName, actualVfName, engagement_manual_id) + checklistUuid = DBGeneral.select_where( + "uuid", "ice_checklist", "name", checklistName, 1) + newObjWithChecklist = [checklistUuid, engLeadEmail, engagement_manual_id, actualVfNameid, myVfName, + checklistName] + return newObjWithChecklist + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Failed to create checklist." + str(e) + raise Exception(errorMsg, "create_new_checklist") + + @staticmethod + def create_checklist(engagement_id, vfName, actualVfName, engagement_manual_id): + try: + checklistName = Helper.rand_string("randomString") + Wait.id("checklist-plus-" + engagement_id, wait_for_page=True) + + Click.id("checklist-plus-" + engagement_id, wait_for_page=True) + + Helper.internal_assert( + "Create Checklist", Get.by_id("modal-header-checklist-15")) + # vm.checkListName + Enter.text_by_name( + "checkListName", checklistName, wait_for_page=True) + Wait.xpath("//select") + + Select(session.ice_driver.find_element_by_id(Constants.Template.Subtitle.SelectTemplateTitle.TEXT) + ).select_by_visible_text(Constants.Template.Heat.TEXT) + Click.id(Constants.Template.Heat.TEXT, wait_for_page=True) +# Click.css("option.ng-binding.ng-scope") + Helper.internal_assert( + "Associate Files", Get.by_id("associated-files-title", wait_for_page=True)) + Click.xpath("//multiselect/div/button", wait_for_page=True) + Click.link_text("file0", wait_for_page=True) + Click.link_text("file1") + Wait.text_by_css(Constants.SubmitButton.CSS, "Create Checklist") + Click.id(Constants.Dashboard.LeftPanel.CreateChecklist.ID) + Wait.modal_to_dissappear() + Wait.id(engagement_manual_id) + return checklistName + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Failed to create checklist." + str(e) + raise Exception(errorMsg, "create_checklist") + + @staticmethod + def update_cl_name_and_associated_files(engagement_manual_id): + Click.id("edit-checklist", True) + Wait.text_by_id("modal-header-checklist-15", "Update Checklist") + newfileName = "file" + Helper.rand_string("randomString") + Enter.text_by_xpath("//div[3]/div/div/input", newfileName) + updatedFileName = "file2" + # Select associated files from multi-select drop-down. + Click.xpath("//multiselect/div/button") + Click.link_text("file2") + Click.css(Constants.SubmitButton.CSS) + Wait.id(engagement_manual_id) + newFileNames = [newfileName, updatedFileName] + return newFileNames + + @staticmethod + def update_cl_associated_files(engagement_manual_id): + Click.id("edit-checklist", True) + Wait.text_by_id("modal-header-checklist-15", "Update Checklist") + # Select associated files from multi-select drop-down. + Click.xpath("//multiselect/div/button") + Click.link_text("file2") + Click.xpath("//multiselect/div/button") + Click.css(Constants.SubmitButton.CSS) + Wait.id(engagement_manual_id, True) + + @staticmethod + def add_next_step(checklistName, newObj): + Click.id(Constants.Dashboard.Checklist.AddNS.ID, wait_for_page=True) + Wait.text_by_css("span.font_header", "Checklist:") + Helper.internal_assert("Checklist:", Get.by_css("span.font_header")) + Helper.internal_assert("Add Next Steps", Get.by_css("h2")) + # First NS + Click.id("description") + Enter.text_by_id("description", "description of NS") + Click.css("div.modal-content") + Click.xpath("(//button[@type='button'])[10]") + FEChecklist.assocciatedFileName = "file0" + Click.link_text(FEChecklist.assocciatedFileName) + Click.css("div.modal-content") + Click.xpath("(//button[@type='button'])[11]") + try: + Click.xpath("//div[3]/multiselect/div/ul/li/a") + except: + Click.link_text("Homer Simpson") + Click.css("div.modal-content") + count = 0 + FEWizard.date_picker_add_ns(count) + count = +1 + Click.css("span.add-text") + Click.xpath("(//div[@id='description'])[2]") + Enter.text_by_xpath( + "(//div[@id='description'])[2]", "description of NS2") + Click.css("div.modal-content") + Click.xpath("(//button[@type='button'])[14]") + Click.xpath("(//button[@type='button'])[22]") + Click.xpath("//div[3]/div/div[2]/multiselect/div/ul/li[2]/a") + Click.css("div.modal-content") + Click.xpath("(//button[@type='button'])[23]") + Click.css( + "div.btn-group.open > ul.dropdown-menu > li.ng-scope > a.ng-binding") + Click.link_text("Add Another Next Step") + Click.xpath("(//button[@type='button'])[25]") + FEWizard.date_picker_add_ns(count) + Click.xpath("//div[4]/div/span") + Helper.internal_assert("Submit Next Steps", Get.by_id("btn-submit")) + Click.id("btn-submit", wait_for_page=True) + + @staticmethod + def add_next_step_updated(checklistName, newFileName): + Click.id(Constants.Dashboard.Checklist.AddNS.ID) + Wait.id(Constants.Dashboard.Modal.CLOSE_BUTTON_ID) + Wait.text_by_css("span.font_header.ng-binding", "Checklist:") + Wait.text_by_css("h2.ng-binding", "Add Next Steps") + # First NS + Click.id("description") + Enter.text_by_id("description", "description of NS") + Click.css("div.modal-content") + Click.xpath("(//button[@type='button'])[10]") + Click.link_text(newFileName) + Click.css("div.modal-content") + Click.xpath("(//button[@type='button'])[11]") + try: + Click.xpath("//div[3]/multiselect/div/ul/li/a") + except: + Wait.link_text("Homer Simpson") + Click.link_text("Homer Simpson") + Wait.css("div.modal-content") + Click.css("div.modal-content") + Wait.xpath("(//button[@type='button'])[12]") + count = 0 + FEWizard.date_picker_add_ns(count) + count = +1 + Click.css("span.add-text") + Click.xpath("(//div[@id='description'])[2]") + Enter.text_by_xpath( + "(//div[@id='description'])[2]", "description of NS2") + Click.css("div.modal-content") + Click.xpath("(//button[@type='button'])[14]") + Click.xpath("(//button[@type='button'])[22]") + Click.xpath("//div[3]/div/div[2]/multiselect/div/ul/li[2]/a") + Click.css("div.modal-content") + Click.xpath("(//button[@type='button'])[23]") + Click.css( + "div.btn-group.open > ul.dropdown-menu > li.ng-scope > a.ng-binding") + Click.link_text("Add Another Next Step") + Wait.xpath("(//button[@type='button'])[25]") + Click.xpath("(//button[@type='button'])[25]") + Wait.xpath("(//button[@type='button'])[24]") + FEWizard.date_picker_add_ns(count) + Wait.xpath("//div[4]/div/span") + Click.xpath("//div[4]/div/span") + Wait.id("btn-submit") + Wait.text_by_id("btn-submit", "Submit Next Steps") +# Helper.internal_assert("Submit Next Steps", Get.by_id("btn-submit")) + Click.id("btn-submit") + + @staticmethod + def approval_state_actions_and_validations(checklistName, newObj, state): + # REWVIEW STEPS AND VALIDATIONS + try: + Wait.id("checklist-main-section") + Wait.text_by_id( + Constants.Dashboard.Checklist.Name.ID, checklistName) + try: + if settings.DATABASE_TYPE == 'local': + Wait.text_by_css( + "h2.ng-binding", "Section 1: Parameter Specification") + Helper.internal_assert( + "Parameters", Get.by_css("span.col-md-9.ng-binding")) + Helper.internal_assert( + "String parameters", Get.by_xpath("//li[2]/span[2]")) + Helper.internal_assert( + "Numeric parameters", Get.by_xpath("//li[3]/span[2]")) + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert("Section 2: External References", + Get.by_xpath("//li[2]/h2")) + # //li[2]/ul/li/span[2] #//ul[@id='line-item-list']/li[2]/ul/li/span[2] + Helper.internal_assert( + "Normal references", Get.by_xpath("//li[2]/ul/li/span[2]")) + Helper.internal_assert( + "VF image", Get.by_xpath("//li[2]/ul/li[2]/span[2]")) + except: + if settings.DATABASE_TYPE == 'local': + Wait.text_by_css( + "h2.ng-binding", "Section 1: External References") + try: + Helper.internal_assert( + "Normal references", Get.by_css("span.col-md-9.ng-binding")) + except: + if "VF image" in Get.by_xpath("//li[2]/span[2]"): + logger.debug("All Ok") + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Section 2: Parameter Specification", Get.by_xpath("//li[2]/h2")) + try: + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "1.1 - Parameters", Get.by_xpath("//header/h2")) + except: + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "1.1 - Normal References", Get.by_xpath("//header/h2")) + if settings.DATABASE_TYPE == 'local': + elementTxt = Get.by_id("line-item-description") + Helper.internal_assert( + "Numeric parameters should include range and/or allowed values.", elementTxt) + Helper.internal_assert("Audit Logs", Get.by_css("h3.col-md-12")) + localLogText = "local log" + Enter.text_by_id("new-audit-log-text", localLogText) + Helper.internal_assert( + "Add Log Entry", Get.by_id("submit-new-audit-lop-text")) + Click.id("submit-new-audit-lop-text") + vfName = newObj[0] + engLeadFullName = DBUser.get_el_name(vfName) + Helper.internal_assert(localLogText, Get.by_css( + Constants.Dashboard.Checklist.AuditLog.LastLocalAuditLog.CSS)) + try: + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Parameters", Get.by_xpath("//li[2]/ul/li/span[2]")) + except: + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Numeric parameters", Get.by_xpath("//li[2]/ul/li/span[2]")) + +# if Wait.css(Constants.Dashboard.Checklist.LineItem.Deny.CSS) or +# Wait.css(Constants.Dashboard.Checklist.LineItem.Approve.CSS): + session.run_negative(lambda: Wait.css(Constants.Dashboard.Checklist.LineItem.Deny.CSS) or Wait.css( + Constants.Dashboard.Checklist.LineItem.Approve.CSS), "Buttons displayed for Admin it's NOT work") +# logger.debug("Buttons displayed for Admin it's NOT work") +# else: +# print("Buttons not displayed for Admin it's work") + if state == "APPROVAL": + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Audit Log (6)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + else: + Helper.internal_assert( + "Audit Log (7)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + if state == "HANDOFF": + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Audit Log (8)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + else: + Helper.internal_assert( + "Audit Log (9)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + Click.id(Constants.Dashboard.Checklist.AuditLog.ID) + Wait.text_by_xpath("//span[2]", checklistName) + engLeadFullName = DBUser.select_el_email(vfName) + Enter.text_by_xpath("//textarea", "zdfgsdyh") + Click.css(Constants.SubmitButton.CSS) + Wait.modal_to_dissappear() + if state == "APPROVAL": + if settings.DATABASE_TYPE == 'local': + Wait.text_by_id( + Constants.Dashboard.Checklist.AuditLog.ID, "Audit Log (7)") + else: + Wait.text_by_id( + Constants.Dashboard.Checklist.AuditLog.ID, "Audit Log (8)") + if state == "HANDOFF": + if settings.DATABASE_TYPE == 'local': + Wait.text_by_id( + Constants.Dashboard.Checklist.AuditLog.ID, "Audit Log (9)") + else: + Wait.text_by_id( + Constants.Dashboard.Checklist.AuditLog.ID, "Audit Log (10)") + if state == "APPROVAL": + Wait.text_by_xpath("//button[3]", "Add Next Steps") + Wait.text_by_id(Constants.Dashboard.Checklist.Reject.ID, + Constants.Dashboard.Checklist.Reject.Modal.Button.TEXT) + Wait.text_by_xpath( + "//div[@id='state-actions']/button", "Approve") + if state == "HANDOFF": + Wait.text_by_xpath( + "//div[@id='state-actions']/button", "Handoff complete?") + logger.debug("ALL VALIDATION PASS FOR STATE : " + state) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + logger.error( + state + " state FAILED CONNECT TO STAGING MANUAL AND VERIFY WHY! ") + errorMsg = "approval_state_actions_and_validations FAILED because : " + \ + str(e) + raise Exception(errorMsg, "approval_state_actions_and_validations") + + @staticmethod + def review_state_actions_and_validations(checklistName, vfName, state): + try: + # REWVIEW STEPS AND VALIDATIONS + Wait.id("checklist-main-section") + Wait.text_by_id( + Constants.Dashboard.Checklist.Name.ID, checklistName) + try: + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Section 1: Parameter Specification", Get.by_css("h2.ng-binding")) + Helper.internal_assert( + "Parameters", Get.by_css("span.col-md-9.ng-binding")) + Helper.internal_assert( + "String parameters", Get.by_xpath("//li[2]/span[2]")) + Helper.internal_assert( + "Numeric parameters", Get.by_xpath("//li[3]/span[2]")) + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Section 2: External References", Get.by_xpath("//li[2]/h2")) + Helper.internal_assert( + "Normal references", Get.by_name("Normal references")) + Helper.internal_assert( + "VF image", Get.by_name("Normal references")) + except: + try: + Helper.internal_assert( + "Section 1: External References", Get.by_css("h2.ng-binding")) + except: + Helper.internal_assert( + "Section 1: Scaling Considerations", Get.by_css("h2.ng-binding")) + try: + Helper.internal_assert( + "Normal references", Get.by_css("span.col-md-9.ng-binding")) + except: + if "VF image" in Get.by_xpath("//li[2]/span[2]"): + logger.debug("All Ok") + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Section 2: Parameter Specification", Get.by_xpath("//li[2]/h2")) + Click.name("VF image") + Click.name("Normal references") + try: + Helper.internal_assert( + "1.1 - Parameters", Get.by_xpath("//header/h2")) + except: + text = Get.by_name("Normal references") + Helper.internal_assert("Normal references", text) + Helper.internal_assert("Audit Logs", Get.by_css("h3.col-md-12")) + localLogText = "local log" + Enter.text_by_id("new-audit-log-text", localLogText) + Helper.internal_assert( + "Add Log Entry", Get.by_id("submit-new-audit-lop-text")) + Click.id("submit-new-audit-lop-text") + # Validate Local AuditLog + engLeadFullName = DBUser.get_el_name(vfName) + Helper.internal_assert( + engLeadFullName, Get.by_xpath("//ul[@id='audit-log-list']/li/h4")) + Helper.internal_assert(localLogText, Get.by_css( + Constants.Dashboard.Checklist.AuditLog.LastLocalAuditLog.CSS)) + if settings.DATABASE_TYPE == 'local': + try: + Helper.internal_assert( + "Parameters", Get.by_xpath("//li[2]/ul/li/span[2]")) + except: + Helper.internal_assert( + "Numeric parameters", Get.by_xpath("//li[2]/ul/li/span[2]")) + Click.name("Normal references") + Wait.css(Constants.Dashboard.Checklist.LineItem.Deny.CSS) + Wait.css(Constants.Dashboard.Checklist.LineItem.Approve.CSS) + Click.css(Constants.Dashboard.Checklist.LineItem.Approve.CSS) + # NOT LOCAL + if settings.DATABASE_TYPE != 'local': + checklistUuid = DBChecklist.get_recent_checklist_uuid( + checklistName)[0] + DBChecklist.update_all_decisions_to_approve(checklistUuid) + # NOT LOCAL + + Click.css(".line-item-row span.manual") + print("click on V button approve of decision in state = " + state) + try: + Wait.css("li.not-relevant-btn") + except: + Wait.xpath("//aside/header/ul/li") + if state == "review": + Wait.id("edit-checklist") + if state == "PEER": + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Audit Log (4)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + else: + Helper.internal_assert( + "Audit Log (5)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + if state == "review": + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Audit Log (2)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + else: + Helper.internal_assert( + "Audit Log (3)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + if state == "APPROVAL": + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Audit Log (8)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + else: + Helper.internal_assert( + "Audit Log (9)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + Click.id( + Constants.Dashboard.Checklist.AuditLog.ID, wait_for_page=True) + Wait.text_by_xpath("//span[2]", checklistName) + Enter.text_by_xpath("//textarea", "zdfgsdyh") + Click.css(Constants.SubmitButton.CSS) + Wait.modal_to_dissappear() + if state == "review": + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Audit Log (3)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + else: + Helper.internal_assert( + "Audit Log (4)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + if state == "PEER": + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Audit Log (5)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + else: + Helper.internal_assert( + "Audit Log (6)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + if state == "APPROVAL": + if settings.DATABASE_TYPE == 'local': + Helper.internal_assert( + "Audit Log (9)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + else: + Helper.internal_assert( + "Audit Log (10)", Get.by_id(Constants.Dashboard.Checklist.AuditLog.ID)) + # Validate Buttons + if settings.DATABASE_TYPE != 'local': + FEGeneral.refresh() + engagement_id = DBVirtualFunction.select_eng_uuid(vfName) + engLeadEmail = DBUser.select_el_email(vfName) + logger.debug("EL email: " + engLeadEmail) + engagement_manual_id = DBGeneral.select_where("engagement_manual_id", "ice_engagement", + "uuid", engagement_id, 1) + # Click on all default next steps + myVfName = engagement_manual_id + ": " + vfName + actualVfNameid = "clickable-" + myVfName + Click.id(actualVfNameid) + Click.id("checklist-" + checklistUuid) + Helper.internal_assert( + "Add Next Steps", Get.by_xpath("//button[3]")) + Wait.text_by_id(Constants.Dashboard.Checklist.Reject.ID, + Constants.Dashboard.Checklist.Reject.Modal.Button.TEXT, wait_for_page=True) + Helper.internal_assert( + "Approve", Get.by_xpath("//div[@id='state-actions']/button")) + logger.debug("ALL VALIDATION PASS FOR STATE: " + state) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "review_state_actions_and_validations FAILED because: " + \ + str(e) + raise Exception(errorMsg, "review_state_actions_and_validations") + logger.error( + state + " state FAILED CONNECT TO STAGING MANUAL AND VERIFY WHY!") + raise + + @staticmethod + def reject(rejectMsg=None): + try: + Click.id( + Constants.Dashboard.Checklist.Reject.ID, wait_for_page=True) + if rejectMsg: + Enter.text_by_name( + Constants.Dashboard.Checklist.Reject.Modal.Comment.NAME, rejectMsg, wait_for_page=True) + Click.id( + Constants.Dashboard.Checklist.Reject.Modal.Button.ID, wait_for_page=True) + except Exception as e: + errorMsg = "Failed to reject checklist." + raise Exception(errorMsg, e) + + @staticmethod + def add_line_item_audit_log(): + try: + log_txt = Helper.rand_string("randomString") + Enter.text_by_id("new-audit-log-text", log_txt, wait_for_page=True) + Click.id("submit-new-audit-lop-text") + Wait.text_by_css( + Constants.Dashboard.Checklist.AuditLog.LastLocalAuditLog.CSS, log_txt, wait_for_page=True) + return log_txt + except Exception as e: + errorMsg = "Failed to add audit log to line item." + raise Exception(errorMsg, e) + + @staticmethod + def click_on_checklist(user_content, checklistName, checklist_uuid=None): + FEOverview.click_on_vf(user_content) + if checklist_uuid is None: + checklist_uuid = DBGeneral.select_where_not_and_order_by_desc( + 'uuid', Constants.DBConstants.IceTables.CHECKLIST, 'name', checklistName, 'state', Constants.ChecklistStates.Archive.TEXT, 'create_time')[0] + Click.id("checklist-" + checklist_uuid) + + @staticmethod + def validate_reject_is_enabled(): + return Wait.id(Constants.Dashboard.Checklist.Reject.ID, wait_for_page=True) + + @staticmethod + def cl_to_next_stage(actualVfNameid): + Click.xpath("//div[@id='state-actions']/button", wait_for_page=True) + Wait.id(actualVfNameid, wait_for_page=True) + session.run_negative(lambda: Wait.css( + Constants.Default.BlockUI.CSS), "Error: CL to next stage failed.") + + @staticmethod + def search_by_vfname_for_not_local(user_content): + vfFullName = user_content[ + 'engagement_manual_id'] + ": " + user_content['vfName'] + if settings.DATABASE_TYPE != 'local': + Enter.text_by_id( + Constants.Dashboard.LeftPanel.SearchBox.ID, user_content['vfName']) + Click.css(Constants.Dashboard.LeftPanel.SearchBox.Results.CSS) + Wait.text_by_id( + Constants.Dashboard.Overview.Title.ID, vfFullName) + + @staticmethod + def search_by_manual_id(manual_id): + Enter.text_by_id( + Constants.Dashboard.LeftPanel.SearchBox.ID, manual_id, wait_for_page=True) + Click.css( + Constants.Dashboard.LeftPanel.SearchBox.Results.CSS, wait_for_page=True) + Wait.id(Constants.Dashboard.Overview.Title.ID) + + @staticmethod + def reject_checklist(newObj, checklistName): + Click.xpath("//button[2]") + vfName = newObj[0] + engLeadFullName = DBUser.get_el_name(vfName) + Enter.text_by_name( + Constants.Dashboard.Checklist.Reject.Modal.Comment.NAME, "Reject state By :" + engLeadFullName) + Helper.internal_assert( + "Checklist: " + checklistName, Get.by_css("span.state-title.ng-binding")) + Wait.text_by_id(Constants.Dashboard.Checklist.Reject.Modal.Button.ID, + Constants.Dashboard.Checklist.Reject.Modal.Button.TEXT) + Click.id(Constants.Dashboard.Checklist.Reject.Modal.Button.ID) + Wait.modal_to_dissappear() + + @staticmethod + def add_nsteps(checklistUuid, actualVfNameid, myVfName, checklistName, newFileNames): + Click.id(actualVfNameid, wait_for_page=True) + checklistUuid = DBChecklist.select_where_cl_not_archive( + "uuid", "ice_checklist", "name", newFileNames[0], 1) + Click.id("checklist-" + checklistUuid, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.Checklist.Name.ID, newFileNames[0]) + FEChecklist.add_next_step_updated(checklistName, newFileNames[1]) + # vALIDATE SCROLLING + actualVfNameid = "clickable-" + myVfName + actualVfName = Get.by_id(actualVfNameid, wait_for_page=True) + if actualVfName != '': + Helper.internal_assert(myVfName, actualVfName) + + @staticmethod + def validate_multi_eng(user_content, checklist_content, newEL_content, actualVfNameid): + query = "UPDATE ice_user_profile SET role_id=2 WHERE email = '" + \ + str(newEL_content['email']) + "';" + DBGeneral.update_by_query(query) + FEWizard.invite_team_members_modal(newEL_content['email']) + # Fetch one AT&T user ID. + enguuid = DBGeneral.select_where( + "uuid", "ice_engagement", "engagement_manual_id", user_content['engagement_manual_id'], 1) + invitation_token = DBUser.select_invitation_token( + "invitation_token", "ice_invitation", "engagement_uuid", enguuid, newEL_content['email'], 1) + URL = Constants.Default.InviteURL.Login.TEXT + invitation_token + FEGeneral.re_open(URL) + FEUser.login(newEL_content[ + 'email'], Constants.Default.Password.TEXT, expected_element=actualVfNameid) + Click.id(actualVfNameid, wait_for_page=True) + count = None + try: + session.ice_driver.find_element_by_id( + "checklist-" + checklist_content['uuid']) + count += 1 + except: + logger.debug( + "check list not visible for EL invited : " + str(newEL_content['email'])) + assertTrue(count == None) + query = "UPDATE ice_user_profile SET role_id=1 WHERE email = '" + \ + str(newEL_content['email']) + "';" + DBGeneral.update_by_query(query) + + @staticmethod + def create_cl_without_files(user_content): + FEOverview.click_on_vf(user_content) + Click.id("checklist-plus-" + user_content['engagement_uuid']) + Wait.id(Constants.Dashboard.Modal.CLOSE_BUTTON_ID) + checklistName = "NoAssociatedFiles" + \ + Helper.rand_string("randomString") + Enter.text_by_name("checkListName", checklistName) + Wait.xpath("//select") + if settings.DATABASE_TYPE == 'local': + Select(session.ice_driver.find_element_by_xpath("//select") + ).select_by_visible_text(Constants.Template.Heat.TEXT) + else: + Click.xpath("//select") + Click.xpath("//option[2]") + Click.id(Constants.Dashboard.LeftPanel.CreateChecklist.ID) + Wait.text_by_id(Constants.Dashboard.Checklist.Name.ID, checklistName) + + @staticmethod + def validate_audit_log(log_txt): + audit_log_list_text = Get.by_id( + Constants.Dashboard.Checklist.AuditLog.AuditLogList.ID, wait_for_page=True) + try: + log_txt in audit_log_list_text + logger.debug("validate_audit_log PASS") + except Exception as e: + errorMsg = "Failed in validate_audit_log" + raise Exception(errorMsg) + + @staticmethod + def get_to_create_new_ns_modal(): + Click.id(Constants.Dashboard.Checklist.AddNS.ID, + wait_for_page=True) + Wait.text_by_css(Constants.Dashboard.Checklist.AddNS.CSS, + Constants.Dashboard.Checklist.TITLE) + Helper.internal_assert(Constants.Dashboard.Checklist.TITLE, Get.by_css( + Constants.Dashboard.Checklist.AddNS.CSS)) + Helper.internal_assert( + Constants.Dashboard.Checklist.AddNS.TITLE, + Get.by_css(Constants.FEGeneral.CSS.H2)) + + @staticmethod + def get_to_create_new_ns_modal_via_overview(): + Click.id(Constants.Dashboard.Overview.NextSteps.Add.ID, + wait_for_page=True) + Wait.text_by_css(Constants.Dashboard.Checklist.AddNS.CSS, + Constants.Dashboard.Overview.NextSteps.Add.TITLE) + Helper.internal_assert( + Constants.Dashboard.Checklist.AddNS.TITLE, + Get.by_css(Constants.FEGeneral.CSS.H2)) + + @staticmethod + def get_jenkins_log(): + Click.id(Constants.Dashboard.Checklist.JenkinsLog.ID, True) + Wait.text_by_id( + Constants.Dashboard.Checklist.JenkinsLog.Modal.Title.ID, + Constants.Dashboard.Checklist.JenkinsLog.Modal.Title.TEXT, True) + log = Get.by_id( + Constants.Dashboard.Checklist.JenkinsLog.Modal.Body.ID, True) + Helper.assertTrue(Constants.Dashboard.Checklist.JenkinsLog.Modal.Body.TEXT_SAMPLE in log, + "Jenkins log could not be viewed.") + Click.id(Constants.Dashboard.Modal.CLOSE_BUTTON_ID) + return log + diff --git a/services/frontend/fe_checklist_template.py b/services/frontend/fe_checklist_template.py new file mode 100644 index 0000000..19e91aa --- /dev/null +++ b/services/frontend/fe_checklist_template.py @@ -0,0 +1,254 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.common.keys import Keys + +from services.api.api_virtual_function import APIVirtualFunction +from services.constants import Constants +from services.database.db_checklist import DBChecklist +from services.database.db_user import DBUser +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.get import Get +from services.frontend.base_actions.wait import Wait +from services.frontend.fe_checklist import FEChecklist +from services.frontend.fe_general import FEGeneral +from services.frontend.fe_overview import FEOverview +from services.frontend.fe_user import FEUser +from services.helper import Helper +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() + +class FEChecklistTemplate: + + @staticmethod + def basic_admin_navigation(): + FEUser.login( + Constants.Users.Admin.EMAIL, Constants.Default.Password.TEXT) + FEUser.go_to_admin() + + @staticmethod + def click_on_template_name_on_navigation(template_name, text): + Wait.text_by_name(template_name, text, wait_for_page=True) + Click.name(template_name, wait_for_page=True) + + @staticmethod + def click_on_save_and_assert_success_msg(): + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.SAVE_BTN_ID, wait_for_page=True) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.APPROVE_BTN_ID, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.SUCCESS_ID, + Constants.Dashboard.LeftPanel.EditChecklistTemplate.SUCCESS_SAVE_MSG) + + @staticmethod + def click_on_disabled_save_and_assert_for_promp_msg(): + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.SAVE_BTN_ID) + session.run_negative(lambda: Click.id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.APPROVE_BTN_ID), + "Ooops modal window is opened although 'Save' button should have been disabled") + + @staticmethod + def save_with_no_changes(): + Wait.text_by_id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.SAVE_BTN_ID, + Constants.Dashboard.LeftPanel.EditChecklistTemplate.SAVE_BTN) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.SAVE_BTN_ID, wait_for_page=True) + Wait.text_by_name(Constants.Dashboard.LeftPanel.EditChecklistTemplate.HEAT, + Constants.Dashboard.LeftPanel.EditChecklistTemplate.HEAT) + Wait.text_by_id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.APPROVE_BTN_TITLE_ID, + Constants.Dashboard.LeftPanel.EditChecklistTemplate.APPROVE_BTN_TITLE_TEXT) + Wait.text_by_id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.APPROVE_BTN_ID, "Yes") + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.APPROVE_BTN_ID, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.SUCCESS_ID, + Constants.Dashboard.LeftPanel.EditChecklistTemplate.CL_TEMPLATE_SAVED_TXT) + + @staticmethod + def discard_checklist_after_modification(): + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_ID, wait_for_page=True) + Enter.text_by_id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_INPUT_ID, "ttttttt", wait_for_page=True) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_ID) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.REJECT_BTN_ID) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.APPROVE_BTN_ID, wait_for_page=True) + Wait.text_by_id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.SUCCESS_ID, "All changes discarded.") + + @staticmethod + def edit_template_and_save(): + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_ID) + Enter.text_by_id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_INPUT_ID, "Ros Is My Mentor") + FEChecklistTemplate.click_on_save_and_assert_success_msg() + + @staticmethod + def del_lineitem_and_save(): + Click.id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_ID, wait_for_page=True) + Enter.text_by_id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_INPUT_ID, + "Ros Is My Mentor", wait_for_page=True) + Click.id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_ID) + FEChecklistTemplate.click_on_save_and_assert_success_msg() + + @staticmethod + def add_lineitem_and_save(): + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.ADD_LINE_ITEM_BTN, wait_for_page=True) + Click.xpath("//li[@id='select-lineitem-btn-0.1']/span[2]") + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_BTN) + Enter.text_by_id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_NAME, "xxx") + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_BTN, wait_for_page=True) + FEChecklistTemplate.click_on_save_and_assert_success_msg() + + @staticmethod + def edit_description_lineitem_and_save(): + isBold = False + desc = Helper.rand_string("randomString") + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_LINE_ITEM_ID) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_BTN) + Enter.text_by_id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_NAME, + Helper.rand_string("randomString")) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_DESC) + editor_element = Get.wysiwyg_element_by_id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.LINE_ITEM_DESC_TEXT_BOX) + editor_element.clear() + editor_element.send_keys(desc) + Wait.page_has_loaded() + actionChains = ActionChains(session.ice_driver) + actionChains.double_click(editor_element).perform() + Wait.page_has_loaded() + Click.xpath( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.WYSIWYG_BUTTON_BOLD) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_BTN, wait_for_page=True) + isBold = Wait.is_css_exists("b") + while not isBold: + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_BTN, wait_for_page=True) + actionChains.double_click(editor_element).perform() + Click.xpath( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.WYSIWYG_BUTTON_BOLD, wait_for_page=True) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_BTN, wait_for_page=True) + isBold = Wait.is_css_exists("b") + if isBold: + FEChecklistTemplate.click_on_save_and_assert_success_msg() + FEGeneral.refresh() + Click.name( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.HEAT, wait_for_page=True) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_LINE_ITEM_ID, wait_for_page=True) + Wait.css("b") + Wait.text_by_css("b", desc, wait_for_page=True) + + @staticmethod + def rollback_add_lineitem_and_save(): + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.DELETE_LINE_ITEM) + FEChecklistTemplate.click_on_save_and_assert_success_msg() + FEChecklistTemplate.rollback_to_heat_teampleate() + + @staticmethod + def add_lineitem_and_check_db(): + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_ID) + Enter.text_by_id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.FIRST_SECTION_INPUT_ID, "Ros Is My Mentor") + FEChecklistTemplate.click_on_save_and_assert_success_msg() + result = DBChecklist.checkChecklistIsUpdated() + Helper.internal_not_equal(result, None) + + @staticmethod + def check_cl_after_lineitem_added(): + template_name = Constants.Dashboard.LeftPanel.EditChecklistTemplate.HEAT + user_content = APIVirtualFunction.create_engagement() + FEUser.login( + Constants.Users.Admin.EMAIL, Constants.Default.Password.TEXT) + vfName = user_content['vfName'] + engagement_id = DBChecklist.fetchEngByVfName(vfName) + engLeadEmail = DBUser.select_el_email(vfName) + engagement_manual_id = DBChecklist.fetchEngManIdByEngUuid( + engagement_id) + myVfName = engagement_manual_id + ": " + vfName + FEOverview.click_on_vf(user_content) + FEGeneral.re_open(Constants.Default.LoginURL.TEXT) + FEUser.login( + engLeadEmail, Constants.Default.Password.TEXT, engagement_manual_id) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.DASHBOARD_ID) + Enter.text_by_id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.SEARCH_ENG_ID, vfName) + Click.id("test_" + vfName) + checklistName = FEChecklist.create_checklist( + engagement_id, vfName, None, engagement_manual_id) + FEUser.go_to_admin() + result = DBChecklist.fetchChecklistByName(checklistName) + FEUser.go_to_admin() + FEChecklistTemplate.click_on_template_name_on_navigation( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.HEAT, template_name) + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_BTN) + Enter.text_by_id(Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_NAME, + "test_lineitem_added_and_audit_log_on_dupl_cl-NAME") + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.EDIT_LINE_ITEM_BTN) + FEChecklistTemplate.click_on_save_and_assert_success_msg() + Click.id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.DASHBOARD_ID) + Enter.text_by_id( + Constants.Dashboard.LeftPanel.EditChecklistTemplate.SEARCH_ENG_ID, vfName) + Click.id("test_" + vfName) + Click.id("checklist-" + str(result)) + Helper.internal_assert( + "1. automation", session.ice_driver.find_element_by_xpath("//li[@id='']").text) diff --git a/services/frontend/fe_cms.py b/services/frontend/fe_cms.py new file mode 100644 index 0000000..a86626e --- /dev/null +++ b/services/frontend/fe_cms.py @@ -0,0 +1,157 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from services.constants import Constants +from services.database.db_cms import DBCMS +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.wait import Wait +from services.frontend.fe_dashboard import FEDashboard +from services.frontend.fe_general import FEGeneral +from services.frontend.fe_user import FEUser +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() + +class FECms: + + @staticmethod + def validate_5_last_announcement_displayed(listOfTitleAnDescriptions, user_content, last_title): + last_description = listOfTitleAnDescriptions[ + len(listOfTitleAnDescriptions) - 1][1] + Wait.text_by_id(Constants.Toast.CMS_ID, last_title + ".") + FEDashboard.open_announcement() + Wait.text_by_id(Constants.Cms.Toast_title_id, last_title) + Wait.text_by_id(Constants.Cms.Toast_description, last_description) + DBCMS.update_X_days_back_post(last_title, xdays=3) + Click.id(Constants.Cms.Test_addDT_close_modal_button) + FEUser.logout() + # Validate Announcement TOAST not displayed + FEUser.login(user_content['email'], Constants.Default.Password.TEXT) + session.run_negative(lambda: Wait.text_by_id(Constants.Cms.Toast_title_id, last_title), + "Last Announcement displayed in News & Announcements sections %s" % last_title) + + @staticmethod + def validate_grandchild_page(parent_title, child_title, grand_child_title, description): + Click.id(Constants.Cms.Documentation) + Click.id(parent_title) + Click.id(child_title) + Click.id(grand_child_title) + Wait.text_by_id("center-" + grand_child_title, grand_child_title) + page_id = DBCMS.get_last_inserted_page_id() + Wait.text_by_id(page_id, description) + + @staticmethod + def announcement_validate_toast(title, description, user_content): + Wait.text_by_id(Constants.Toast.CMS_ID, title + ".") + FEDashboard.open_announcement() + Wait.text_by_id(Constants.Cms.Toast_title_id, title) + Wait.text_by_id(Constants.Cms.Toast_description, description) + Click.id(Constants.Cms.Test_addDT_close_modal_button) + Click.css("button.close") + FEUser.logout() + FEUser.login(user_content['email'], Constants.Default.Password.TEXT) + # Validate Announcement displayed in News & Announcements sections + session.run_negative(lambda: FEDashboard.open_announcement( + ), "Announcement toast disappear after 2 days %s" % title) + Wait.text_by_id(title, title) + Wait.text_by_id(description, description) + + @staticmethod + def search_documentation_title(title, user_content): + FEDashboard.open_documentation(title) + Wait.text_by_id(title, title) + logger.debug("Search Documentation by title") + Enter.text_by_id(Constants.Cms.SearchDocumentation, title, wait_for_page=True) + Wait.text_by_id(title, title) + Click.id(title, wait_for_page=True) + Wait.text_by_id(title, title) + logger.debug("Documentation found (searched by title)") + + @staticmethod + def search_documentation_content(title, content): + FEDashboard.open_documentation(title) + Wait.text_by_id(title, title) + logger.debug("Search Documentation by content") + Enter.text_by_id(Constants.Cms.SearchDocumentation, content, wait_for_page=True) + Wait.text_by_id(title, title) + Click.id(title, wait_for_page=True) + Wait.text_by_css(Constants.Cms.DocumentationPageContent, content) + logger.debug("Documentation found (searched by content)") + + @staticmethod + def validate_expired_post_Announcement(title, description): + Wait.text_by_id(Constants.Toast.CMS_ID, title + ".") + FEDashboard.open_announcement() + Wait.text_by_id(Constants.Cms.Toast_title_id, title) + Wait.text_by_id(Constants.Cms.Toast_description, description) + DBCMS.update_X_days_back_post(title, xdays=3) + Click.id(Constants.Cms.Test_addDT_close_modal_button) + FEGeneral.refresh() + session.run_negative(lambda: Wait.text_by_id( + Constants.Toast.CMS_ID, title + "."), "Announcement toast not disappear after 2 days %s" % title) + + @staticmethod + def validate_page(title, description): + Click.id(Constants.Cms.Documentation) + Click.id(title) + Wait.text_by_id("center-" + title, title) + page_id = DBCMS.get_last_inserted_page_id() + Wait.text_by_id(page_id, description) + + @staticmethod + def validate_FAQ(description): + Wait.text_by_id(Constants.Cms.Tooltip_title, "Did you know?") + Wait.text_by_id(Constants.Cms.Tooltip_description, description) + + @staticmethod + def validate_news(title, description): + Wait.text_by_id(title, title) + Wait.text_by_id(description, description) + Click.id(title) + Wait.text_by_id(Constants.Cms.Toast_title_id, title) + Wait.text_by_id(Constants.Cms.Toast_description, description) + + @staticmethod + def validae_announcement(title, description): + Wait.text_by_id(Constants.Toast.CMS_ID, title + ".") + FEDashboard.open_announcement() + Wait.text_by_id(Constants.Cms.Toast_title_id, title) + Wait.text_by_id(Constants.Cms.Toast_description, description) diff --git a/services/frontend/fe_dashboard.py b/services/frontend/fe_dashboard.py new file mode 100644 index 0000000..0df66d4 --- /dev/null +++ b/services/frontend/fe_dashboard.py @@ -0,0 +1,289 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from selenium.webdriver.support.ui import Select + +from services.constants import Constants +from services.database.db_user import DBUser +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.get import Get +from services.frontend.base_actions.wait import Wait +from services.frontend.fe_general import FEGeneral +from services.frontend.fe_overview import FEOverview +from services.frontend.fe_user import FEUser +from services.helper import Helper +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() + + +class FEDashboard: + + @staticmethod + def open_announcement(): + try: + Click.id("read-more-button") + except Exception as e: + errorMsg = "Failed to go to Announcement page." + raise Exception(errorMsg, e) + + @staticmethod + def open_documentation(title): + try: + Click.id("documentation", wait_for_page=True) + Wait.id("search-doc") + Wait.text_by_id(title, title, wait_for_page=True) + except Exception as e: + errorMsg = "Failed to go to Announcement page." + raise Exception(errorMsg, e) + + @staticmethod + def validate_filtering_by_stage(user_content, stage): + FEGeneral.re_open(Constants.Default.LoginURL.TEXT) + # Validate Scrolling # + FEUser.login(user_content['el_email'], Constants.Default.Password.TEXT) + FEOverview.click_on_vf(user_content) + Click.id(Constants.Dashboard.Statuses.ID, wait_for_page=True) + Wait.text_by_id("dashboard-title", "Statuses", wait_for_page=True) + Wait.id("search-filter-stage") + Select(session.ice_driver.find_element_by_id( + "search-filter-stage")).select_by_visible_text(stage) + Wait.id( + Constants.Dashboard.Statuses.ExportExcel.ID, wait_for_page=True) + engLeadID = DBUser.select_user_native_id(user_content['el_email']) + # Query for fetching count of rows per stage. + countOfEngInStagePerUser = DBUser.select_user_engagements_by_stage( + stage, engLeadID) + # Calculate number of pages # + NUM_OF_RESULTS_PER_PAGES = 8 + number_of_pages = countOfEngInStagePerUser // NUM_OF_RESULTS_PER_PAGES + logger.debug("Number of pages: " + str(number_of_pages)) + if (countOfEngInStagePerUser % NUM_OF_RESULTS_PER_PAGES != 0): + number_of_pages += 1 + logger.debug("number_of_pages " + str(number_of_pages)) # Scroll # + Wait.id("engagements-pagination", wait_for_page=True) + element = session.ice_driver.find_element_by_id( + "engagements-pagination") + element.location_once_scrolled_into_view + Click.link_text(str(number_of_pages), wait_for_page=True) + + @staticmethod + def validate_filtering_by_stage_with_page_ids(user_content, stage): + FEOverview.click_on_vf(user_content) + Click.id(Constants.Dashboard.Statuses.ID) + # Stage Active Validation # + Wait.text_by_id("dashboard-title", "Statuses") + Wait.id(Constants.Dashboard.Statuses.FilterDropdown.ID) + Select(session.ice_driver.find_element_by_id( + Constants.Dashboard.Statuses.FilterDropdown.ID)).select_by_visible_text("Intake") + Wait.page_has_loaded() + Select(session.ice_driver.find_element_by_id( + Constants.Dashboard.Statuses.FilterDropdown.ID)).select_by_visible_text(stage) + Wait.id( + Constants.Dashboard.Statuses.ExportExcel.ID, wait_for_page=True) + countIdsActive = 0 + engLeadID = DBUser.select_user_native_id(user_content['el_email']) + countOfEngInStagePerUser = DBUser.select_user_engagements_by_stage( + stage, engLeadID) # Calculate number of pages # + NUM_OF_RESULTS_PER_PAGES = 8 + number_of_pages = countOfEngInStagePerUser // NUM_OF_RESULTS_PER_PAGES + if countOfEngInStagePerUser <= NUM_OF_RESULTS_PER_PAGES: + number_of_pages = 1 + if number_of_pages == 1: + # Count all engagements on current page + logger.debug("Number of pages: " + str(number_of_pages)) + ids = session.ice_driver.find_elements_by_xpath('//*[@id]') + for ii in ids: + if "starred-" in ii.get_attribute('id'): + # Print ii.tag_name (id name as string). + logger.debug(ii.get_attribute('id')) + countIdsActive += 1 + Wait.id(Constants.Dashboard.Statuses.ExportExcel.ID) + if countIdsActive == countOfEngInStagePerUser: + logger.debug("result right") + else: + if countOfEngInStagePerUser % NUM_OF_RESULTS_PER_PAGES != 0: + number_of_pages += 1 + logger.debug("number_of_pages " + str(number_of_pages)) + # Scroll # + Wait.id("engagements-pagination") + element = session.ice_driver.find_element_by_id( + "engagements-pagination") + element.location_once_scrolled_into_view + if number_of_pages > 1: + Click.link_text(str(number_of_pages), wait_for_page=True) + + @staticmethod + def validate_statistics_by_stages(user_content): + # Validate Scrolling # + FEOverview.click_on_vf(user_content) + Click.id(Constants.Dashboard.Statuses.ID) + Wait.text_by_id("dashboard-title", "Statuses") + Wait.css(Constants.Dashboard.Statuses.Statistics.FilterDropdown.CSS) + Select(session.ice_driver.find_element_by_css_selector( + Constants.Dashboard.Statuses.Statistics.FilterDropdown.CSS)).select_by_visible_text("All") + engLeadID = DBUser.select_user_native_id(user_content['el_email']) + countOfEngInStagePerUser = DBUser.select_all_user_engagements( + engLeadID) # Scroll # + Wait.text_by_id( + Constants.Dashboard.Statuses.Statistics.EngagementsNumber.ID, + str(countOfEngInStagePerUser), wait_for_page=True) + element = session.ice_driver.find_element_by_id( + Constants.Dashboard.Statuses.Statistics.EngagementsNumber.ID) + # Stage Active Validation # + element.location_once_scrolled_into_view + Wait.css( + Constants.Dashboard.Statuses.Statistics.FilterDropdown.CSS, wait_for_page=True) + Select(session.ice_driver.find_element_by_css_selector( + Constants.Dashboard.Statuses.Statistics.FilterDropdown.CSS)).select_by_visible_text("Active") + countOfEngInStagePerUser = DBUser.select_user_engagements_by_stage( + "Active", engLeadID) + Wait.text_by_id( + Constants.Dashboard.Statuses.Statistics.EngagementsNumber.ID, str(countOfEngInStagePerUser), wait_for_page=True) + + @staticmethod + def search_by_vf(user_content): + engName = user_content[ + 'engagement_manual_id'] + ": " + user_content['vfName'] + engSearchID = "eng-" + engName + FEGeneral.re_open_not_clean_cache(Constants.Default.DashbaordURL.TEXT) + logger.debug("Search engagement by engagement_manual_id") + Enter.text_by_id(Constants.Dashboard.Statuses.SearchBox.ID, + user_content['engagement_manual_id'], wait_for_page=True) + eng_manual_id = user_content['engagement_manual_id'] + ":" + Wait.text_by_id(engSearchID, eng_manual_id) + + @staticmethod + def search_in_left_searchbox_by_param(manual_id, vf_name, param): + myVfName = manual_id + ": " + vf_name + Enter.text_by_xpath( + Constants.Dashboard.LeftPanel.SearchBox.Results.XPATH, param) + Wait.text_by_css( + Constants.Dashboard.LeftPanel.SearchBox.Results.CSS, myVfName) + Click.css(Constants.Dashboard.LeftPanel.SearchBox.Results.CSS) + + @staticmethod + def check_vnf_version(user_content): + current_vnf_value = Get.by_css( + "#progress_bar_" + user_content['engagement_manual_id'] + " ." + Constants.Dashboard.Overview.Progress.VnfVersion.CLASS, wait_for_page=True) + Helper.internal_assert(current_vnf_value, user_content['vnf_version']) + + @staticmethod + def search_in_dashboard(user_content, vfcName, users): + engName = user_content[ + 'engagement_manual_id'] + ": " + user_content['vfName'] + engSearchID = "eng-" + engName + for user in users: + FEGeneral.re_open(Constants.Default.LoginURL.TEXT) + logger.debug("Login with user " + user) + FEUser.login(user, Constants.Default.Password.TEXT) + logger.debug("Search engagement by engagement_manual_id") + Enter.text_by_id( + Constants.Dashboard.Statuses.SearchBox.ID, user_content['engagement_manual_id']) + eng_manual_id = user_content['engagement_manual_id'] + ":" + Wait.text_by_id(engSearchID, eng_manual_id) + logger.debug("Engagement found (searched by engagement_manual_id)") + FEGeneral.refresh() + logger.debug("Search engagement by VF name") + # Search by VF name. + Enter.text_by_id( + Constants.Dashboard.Statuses.SearchBox.ID, user_content['vfName']) + Wait.text_by_id(engSearchID, eng_manual_id) + logger.debug("Engagement found (searched by VF name)") + FEGeneral.refresh() + logger.debug("Search engagement by VFC") + # Search by VFC. + Enter.text_by_id( + Constants.Dashboard.Statuses.SearchBox.ID, vfcName) + Wait.text_by_id(engSearchID, eng_manual_id) + logger.debug("Engagement found (searched by VFC)") + FEGeneral.refresh() + logger.debug("Negative search: search by random string") + # Search by VFC. + Enter.text_by_id(Constants.Dashboard.Statuses.SearchBox.ID, + "RND_STR_" + Helper.rand_string("randomString")) + Wait.text_by_id("search-results", "Export to Excel >>") + + @staticmethod + def check_if_the_eng_of_NS_is_the_correct_one(user_content): + logger.debug(" > Check if the engagement of NS is the correct one") + engName = user_content[ + 'engagement_manual_id'] + ": " + user_content['vfName'] + Wait.text_by_name( + user_content['engagement_manual_id'], "Engagement - " + engName) + return engName + + @staticmethod + def check_if_creator_of_NS_is_the_EL(user_content): + logger.debug( + " > Check if creator of NS is the EL " + user_content['el_name']) + if (user_content['el_name'] not in Get.by_name("creator-full-name-" + user_content['el_name'])): + logger.error("EL is not the creator of the NS according to UI.") + raise + + @staticmethod + def statuses_search_vf(engagement_manual_id, vf_name): + engName = engagement_manual_id + ": " + vf_name + # Search by VF name. + Enter.text_by_id( + Constants.Dashboard.Statuses.SearchBox.ID, vf_name, wait_for_page=True) + Wait.id("eng-" + engName, wait_for_page=True) + Click.id("eng-" + engName, wait_for_page=True) + Wait.text_by_id( + Constants.Dashboard.Overview.Title.ID, engName, wait_for_page=True) + + @staticmethod + def go_to_main_dashboard(): + Click.id(Constants.Dashboard.Statuses.ID) + + @staticmethod + def click_on_dashboard_and_validate_statistics(is_negative): + # Click.id(Constants.Dashboard.Default.DASHBOARD_ID) + Wait.page_has_loaded() + if is_negative: + session.run_negative(lambda: Wait.id( + Constants.Dashboard.Default.STATISTICS), "Negative test failed at Statistics appears") + else: + Wait.id(Constants.Dashboard.Default.STATISTICS) + + @staticmethod + def click_on_create_vf(): + Click.id(Constants.Dashboard.LeftPanel.AddEngagement.ID) diff --git a/services/frontend/fe_detailed_view.py b/services/frontend/fe_detailed_view.py new file mode 100644 index 0000000..bf9a5bf --- /dev/null +++ b/services/frontend/fe_detailed_view.py @@ -0,0 +1,359 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +import time + +from selenium.webdriver.support.ui import Select + +from services.constants import Constants +from services.database.db_general import DBGeneral +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.get import Get +from services.frontend.base_actions.wait import Wait +from services.frontend.fe_dashboard import FEDashboard +from services.frontend.fe_general import FEGeneral +from services.frontend.fe_user import FEUser +from services.helper import Helper +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() + + +class FEDetailedView: + + @staticmethod + def search_vf_and_go_to_detailed_view(engagement_manual_id, vf_name): + engName = engagement_manual_id + ": " + vf_name + detailed_view_id = Constants.Dashboard.DetailedView.ID + engName + FEDashboard.statuses_search_vf(engagement_manual_id, vf_name) + Click.id(detailed_view_id, wait_for_page=True) + return detailed_view_id + + @staticmethod + def update_aic_version(): + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.PLUS, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.Modal.TITLE_ID, + Constants.Dashboard.DetailedView.ValidationDetails.TITLE, wait_for_page=True) + Select(session.ice_driver.find_element_by_id(Constants.Dashboard.DetailedView.AIC.Dropdown.ID) + ).select_by_visible_text(Constants.Dashboard.DetailedView.ValidationDetails.TargetAICVersion.AIC3) + Click.xpath("//option[3]", wait_for_page=True) + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.SAVE, wait_for_page=True) + + @staticmethod + def open_validation_details(): + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.PLUS, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.Modal.TITLE_ID, + Constants.Dashboard.DetailedView.ValidationDetails.TITLE, wait_for_page=True) + + @staticmethod + def save_validation_details(): + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.SAVE, wait_for_page=True) + + @staticmethod + def update_target_lab_entry(): + Click.id( + Constants.Dashboard.DetailedView.TargetLabEntry.CHANGE, wait_for_page=True) + Enter.date_picker( + '#lab-entry-date', 'vm.targetLabDate', wait_for_page=True) + Click.css( + Constants.Dashboard.DetailedView.TargetLabEntry.INPUT_CSS, wait_for_page=True) + Click.css(Constants.SubmitButton.CSS, wait_for_page=True) + actualDate = Get.by_css( + Constants.Dashboard.DetailedView.TargetLabEntry.CONTENT_CSS, wait_for_page=True) + return str(actualDate) + + @staticmethod + def validate_target_lab_entry(date): + Wait.text_by_css(Constants.Dashboard.DetailedView.TargetLabEntry.CSS, + Constants.Dashboard.DetailedView.TargetLabEntry.TEXT, wait_for_page=True) + actualDate = Get.by_css( + Constants.Dashboard.DetailedView.TargetLabEntry.CONTENT_CSS) + Helper.internal_assert(actualDate, date) + + @staticmethod + def update_ecomp_release(EcompName): + count = 0 + try: + Click.id(Constants.Dashboard.DetailedView.ValidationDetails.PLUS) + Wait.text_by_id(Constants.Dashboard.Modal.TITLE_ID, + Constants.Dashboard.DetailedView.ValidationDetails.TITLE, wait_for_page=True) + Click.id( + Constants.Dashboard.DetailedView.ECOMP.Dropdown.ID, wait_for_page=True) + Select(session.ice_driver.find_element_by_id( + Constants.Dashboard.DetailedView.ECOMP.Dropdown.ID)).select_by_visible_text(EcompName) + Click.id(Constants.Dashboard.DetailedView.ValidationDetails.ECOMPRelease.ID_ECOMP + + EcompName, wait_for_page=True) + count += 1 + Wait.id(Constants.Dashboard.DetailedView.ValidationDetails.ECOMPRelease.ID_ECOMP + + Constants.Dashboard.DetailedView.ValidationDetails.ECOMPRelease.UNKNOW, wait_for_page=True) + Select(session.ice_driver.find_element_by_id(Constants.Dashboard.DetailedView.ECOMP.Dropdown.ID) + ).select_by_visible_text(Constants.Dashboard.DetailedView.ValidationDetails.ECOMPRelease.UNKNOW) + Click.id(Constants.Dashboard.DetailedView.ValidationDetails.ECOMPRelease.ID_ECOMP + + Constants.Dashboard.DetailedView.ValidationDetails.ECOMPRelease.UNKNOW, wait_for_page=True) + count += 1 + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.SAVE, wait_for_page=True) + Helper.internal_assert(count, 2) + # If failed - count the failure and add the error to list of errors. + except: + errorMsg = "Failed in update_ecomp_release ." + raise Exception(errorMsg) + + @staticmethod + def update_vf_version(): + try: + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.PLUS, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.Modal.TITLE_ID, + Constants.Dashboard.DetailedView.ValidationDetails.TITLE, wait_for_page=True) + newVFVersionName = "newVFVersionName-" + \ + Helper.rand_string("randomString") + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.VFVersion.ID_VERSION) + Enter.text_by_id( + Constants.Dashboard.DetailedView.ValidationDetails.VFVersion.ID_VERSION, newVFVersionName, wait_for_page=True) + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.SAVE, wait_for_page=True) + return newVFVersionName + # If failed - count the failure and add the error to list of errors. + except: + errorMsg = "Failed in update_ecomp_release ." + raise Exception(errorMsg) + + @staticmethod + def validate_aic_version(): + FEGeneral.refresh() + Wait.id( + Constants.Dashboard.DetailedView.AIC.ID + "3.0", wait_for_page=True) + + @staticmethod + def validate_ecomp_version(): + FEGeneral.refresh() + Wait.id(Constants.Dashboard.DetailedView.ECOMP.ID + + Constants.Dashboard.DetailedView.ValidationDetails.ECOMPRelease.UNKNOW, wait_for_page=True) + + @staticmethod + def validate_vf_version(newVFVersionName): + FEGeneral.refresh() + Wait.id(Constants.Dashboard.DetailedView.ValidationDetails.VFVersion.VF_VERSION_ID + + newVFVersionName, wait_for_page=True) + + @staticmethod + def validate_all_titles_on_dv_form(): + Wait.text_by_id(Constants.Dashboard.DetailedView.DeploymentTarget.ID, + Constants.Dashboard.DetailedView.DeploymentTarget.TEXT, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.DetailedView.VirtualFunctionComponents.ID, + Constants.Dashboard.DetailedView.VirtualFunctionComponents.TEXT) + Wait.text_by_id(Constants.Dashboard.DetailedView.TargetLabEntry.ID, + Constants.Dashboard.DetailedView.TargetLabEntry.TEXT) + Wait.text_by_id(Constants.Dashboard.DetailedView.ValidationDetails.ID, + Constants.Dashboard.DetailedView.ValidationDetails.TEXT) + Wait.text_by_id(Constants.Dashboard.DetailedView.ValidationDetails.TargetAICVersion.ID, + Constants.Dashboard.DetailedView.ValidationDetails.TargetAICVersion.TEXT) + Wait.text_by_id(Constants.Dashboard.DetailedView.ValidationDetails.ECOMPRelease.ID, + Constants.Dashboard.DetailedView.ValidationDetails.ECOMPRelease.TEXT) + Wait.text_by_id(Constants.Dashboard.DetailedView.ValidationDetails.VFVersion.ID, + Constants.Dashboard.DetailedView.ValidationDetails.VFVersion.TEXT, wait_for_page=True) + + @staticmethod + def add_deployment_target(user_content): + Click.id(Constants.Dashboard.DetailedView.TargetLabEntry.Add.ID) + Wait.text_by_id(Constants.Dashboard.Modal.TITLE_ID, + Constants.Dashboard.DetailedView.DeploymentTarget.TITLE) + # FIXME: empty drop-down, tests will fail. + Select(session.ice_driver.find_element_by_xpath( + "//select")).select_by_visible_text("Lisle (DPA3)") + Click.id( + Constants.Dashboard.DetailedView.DeploymentTarget.SAVE, wait_for_page=True) + Wait.text_by_css( + Constants.Dashboard.DetailedView.DeploymentTarget.CSS, "Lisle (DPA3)", wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.DetailedView.AIC.ID + + user_content['target_aic'], user_content['target_aic']) + e2edate = FEGeneral.date_short_formatter() + Wait.text_by_css( + Constants.Dashboard.DetailedView.TargetLabEntry.CONTENT_CSS, e2edate) + + @staticmethod + def remove_deployment_target(user_content): + Wait.text_by_id( + "visible-dts-Lisle (DPA3)", "Lisle (DPA3)", wait_for_page=True) + dt_site_id = DBGeneral.select_query( + "SELECT uuid FROM public.ice_deployment_target_site where name = 'Lisle (DPA3)'") + Click.id("visible-dts-Lisle (DPA3)") + Wait.id( + Constants.Dashboard.DetailedView.DeploymentTarget.ID_REMOVE_DTS + dt_site_id) + Click.id(Constants.Dashboard.DetailedView.DeploymentTarget.ID_REMOVE_DTS + + dt_site_id, wait_for_page=True) + session.run_negative(lambda: Wait.text_by_id( + "visible-dts-Lisle (DPA3)", "Lisle (DPA3)", wait_for_page=True), "Negative test failed at wait text Lisle (DPA3)") + + @staticmethod + def add_vfc(): + vfcName = "VFC-" + Helper.rand_string("randomString") + Click.id(Constants.Dashboard.DetailedView.VFC.Add.ID) + Enter.text_by_name("name", vfcName) + session.ice_driver.find_element_by_name("extRefID").click() + Enter.text_by_name("extRefID", Helper.rand_string("randomNumber")) + Select(session.ice_driver.find_element_by_id( + Constants.Dashboard.DetailedView.VFC.Choose_Company.ID)).select_by_visible_text("AT&T") + Click.id(Constants.Dashboard.DetailedView.VFC.Save_button.ID) + return vfcName + + @staticmethod + def add_vfcs(name, extRefID): + Click.id( + Constants.Dashboard.DetailedView.VFC.Add.ID, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.Modal.TITLE_ID, + "Add Virtual Function Components (VFCs)") + Enter.text_by_name("name", name) + Click.name("extRefID", wait_for_page=True) + Enter.text_by_name("extRefID", extRefID, wait_for_page=True) + Select(session.ice_driver.find_element_by_id( + Constants.Dashboard.DetailedView.VFC.Choose_Company.ID)).select_by_visible_text("Amdocs") + Wait.text_by_css("span.add-text", "Add VFC", wait_for_page=True) + Click.css("span.add-text", wait_for_page=True) + logger.debug("Add VFC no.2") + Enter.text_by_xpath( + "//div[2]/ng-form/div/input", "djoni2", wait_for_page=True) + Enter.text_by_xpath("//div[2]/ng-form/div[2]/input", "loka2") + Enter.text_by_xpath("//div[2]/ng-form/div[4]/input", "companyManual2") + Click.id( + Constants.Dashboard.DetailedView.VFC.Save_button.ID, wait_for_page=True) + + @staticmethod + def remove_vfc(user_content): + vf_id = DBGeneral.select_where( + "uuid", "ice_vf", "name", user_content['vfName'], 1) + djoni_uuid = None + counter = 0 + while not djoni_uuid and counter <= Constants.DBConstants.RETRIES_NUMBER: + time.sleep(session.wait_until_time_pause_long) + djoni_uuid = DBGeneral.select_where_and( + "uuid", "ice_vfc", "vf_id", vf_id, "name", "djoni", 1) + logger.debug("Checklist state not changed yet (%s of %s)" % ( + counter, Constants.DBConstants.RETRIES_NUMBER)) + counter += 1 + logger.debug("VFC_UUID was successfully selecteded : " + + djoni_uuid + ", and was verified over the DB") + Wait.text_by_id(Constants.Dashboard.DetailedView.VFC.ID + + "djoni", "djoni (loka)", wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.DetailedView.VFC.ID + + "djoni2", "djoni2 (loka2)", wait_for_page=True) + Click.id( + Constants.Dashboard.DetailedView.VFC.ID + "djoni", wait_for_page=True) + Click.id(Constants.Dashboard.DetailedView.VFC.Remove.ID + + djoni_uuid, wait_for_page=True) + + @staticmethod + def validate_deployment_targets(user_content, users): + for user in users: + FEGeneral.re_open(Constants.Default.LoginURL.TEXT) + logger.debug("Login with user " + user) + FEUser.login(user, Constants.Default.Password.TEXT) + FEDetailedView.search_vf_and_go_to_detailed_view( + user_content['engagement_manual_id'], user_content['vfName']) + Wait.id( + Constants.Dashboard.DetailedView.DeploymentTarget.AddDeploymentTargetButton.ID) + + @staticmethod + def add_remove_deployment_targets(user_content, users): + for user in users: + FEGeneral.re_open(Constants.Default.LoginURL.TEXT) + logger.debug("Login with user " + user) + FEUser.login(user, Constants.Default.Password.TEXT) + FEDetailedView.search_vf_and_go_to_detailed_view( + user_content['engagement_manual_id'], user_content['vfName']) + FEDetailedView.add_deployment_target(user_content) + FEDetailedView.remove_deployment_target(user_content) + + @staticmethod + def validate_negative_role_for_deployment_targets(user_content, users): + for user in users: + FEGeneral.re_open(Constants.Default.LoginURL.TEXT) + logger.debug("Login with user " + user) + FEUser.login(user, Constants.Default.Password.TEXT) + FEDetailedView.search_vf_and_go_to_detailed_view( + user_content['engagement_manual_id'], user_content['vfName']) + session.run_negative(lambda: Click.id(Constants.Dashboard.DetailedView.DeploymentTarget.AddDeploymentTargetButton.ID), + "Negative test failed at click_on_ deployment-targets with user %s" % user) + + @staticmethod + def click_on_update_aic_version(): + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.PLUS, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.Modal.TITLE_ID, + Constants.Dashboard.DetailedView.ValidationDetails.TITLE, wait_for_page=True) + + @staticmethod + def click_on_update_ecomp_release(): + Click.id( + Constants.Dashboard.DetailedView.ValidationDetails.PLUS, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.Modal.TITLE_ID, + Constants.Dashboard.DetailedView.ValidationDetails.TITLE, wait_for_page=True) + + @staticmethod + def select_aic_version_from_list(aic_version): + Select(session.ice_driver.find_element_by_id( + Constants.Dashboard.DetailedView.AIC.Dropdown.ID)).select_by_visible_text(aic_version) + + @staticmethod + def compare_aic_selected_version(expected_aic_version): + Helper.internal_assert(Get.by_id( + Constants.Dashboard.DetailedView.AIC.ID + expected_aic_version), expected_aic_version) + + @staticmethod + def compare_selected_ecomp_release(expected_ecomp_release): + Helper.internal_assert(Get.by_id( + Constants.Dashboard.DetailedView.ECOMP.ID + expected_ecomp_release), expected_ecomp_release) + + @staticmethod + def validate_deprecated_aic_version_in_dropdown(expected_aic_version): + Helper.internal_assert(Get.by_id(Constants.Dashboard.DetailedView.AIC.Dropdown.UniversalVersion.ID % + expected_aic_version), "AIC " + expected_aic_version + " - Deprecated") + + @staticmethod + def validate_deprecated_ecomp_release_in_dropdown(expected_ecomp_release): + Helper.internal_assert(Get.by_id(Constants.Dashboard.DetailedView.ECOMP.Dropdown.UniversalRelease.ID % + expected_ecomp_release), expected_ecomp_release + " - Deprecated") diff --git a/services/frontend/fe_general.py b/services/frontend/fe_general.py new file mode 100644 index 0000000..c6832cb --- /dev/null +++ b/services/frontend/fe_general.py @@ -0,0 +1,261 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +import json +import time + +from django.conf import settings +from selenium.webdriver.support.select import Select + +from services.constants import Constants +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.get import Get +from services.frontend.base_actions.wait import Wait +from services.helper import Helper +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() + +class FEGeneral(Helper): + + @staticmethod + def date_formatter(): + d = int(time.strftime("%d")) + if (d == 1 or d == 21 or d == 31): + d = str(d) + "st" + elif (d == 2 or d == 22): + d = str(d) + "nd" + elif (d == 3 or d == 23): + d = str(d) + "rd" + else: + d = str(d) + "th" + return time.strftime("%A %B " + d + " %Y") + + @staticmethod + def date_short_formatter(): + return time.strftime("%-m" + "/" + "%-d" + "/" + "%y") + + @staticmethod + def re_open(reopen_url): + try: + logger.debug("Reopen URL: " + reopen_url) + session.ice_driver.get('javascript:localStorage.clear();') + session.ice_driver.get('javascript:sessionStorage.clear();') + session.ice_driver.delete_all_cookies() + # Open FireFox with requested URL. + session.ice_driver.get("about:blank") + # Open FireFox with requested URL. + session.ice_driver.get(reopen_url) + session.ice_driver.maximize_window() + Wait.page_has_loaded() + except Exception as e: + errorMsg = "Could not reopen requested page" + raise Exception(errorMsg, reopen_url) + + @staticmethod + def re_open_not_clean_cache(url): + try: + # Open FireFox with requested URL. + session.ice_driver.get(url) + session.ice_driver.maximize_window() + except: + errorMsg = "Could not reopen requested page" + raise Exception(errorMsg, url) + logger.debug("Moving to next test case") + + @staticmethod + def refresh(): + try: # Click on element in UI, by CSS locator. + session.ice_driver.refresh() + Wait.page_has_loaded() + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Could not refresh the page." + logger.error(errorMsg) + raise Exception(errorMsg, e) + + @staticmethod + def select_vendor_from_list(vendor): + Wait.name(Constants.Signup.Company.NAME) + Select(session.ice_driver.find_element_by_name( + Constants.Signup.Company.NAME)).select_by_visible_text(vendor) + + @staticmethod + def go_to_signup_from_login(): + Click.link_text(Constants.Login.Signup.LINK_TEXT, wait_for_page=True) + Wait.text_by_css( + Constants.Signup.Title.CSS, Constants.Signup.Title.TEXT, wait_for_page=True) + + @staticmethod + def form_enter_name(name): + Enter.text_by_name(Constants.Signup.FullName.NAME, name) + + @staticmethod + def form_enter_email(email): + Enter.text_by_name(Constants.Signup.Email.NAME, email) + + @staticmethod + def form_enter_phone(phone): + Enter.text_by_name(Constants.Signup.Phone.NAME, phone) + + @staticmethod + def form_enter_password(password): + Enter.text_by_name(Constants.Signup.Password.NAME, password) + + @staticmethod + def form_check_checkbox(xpath): + Click.xpath(xpath) + + @staticmethod + def click_on_submit(): + Click.css(Constants.SubmitButton.CSS) + + @staticmethod + def go_to_login_from_signup(): + Click.link_text(Constants.Signup.HaveAccount.LINK_TEXT) + Wait.text_by_css(Constants.Login.Title.CSS, Constants.Login.Title.TEXT) + + @staticmethod + def verify_toast_message(expected_message): + Wait.text_by_id( + Constants.Toast.ID, expected_message, wait_for_page=True) + + @staticmethod + def form_validate_name(name): + name_in_ui = Get.value_by_name( + Constants.Dashboard.Avatar.Account.FullName.NAME) + Helper.internal_assert(name, name_in_ui) + + @staticmethod + def form_validate_email(email): + email_in_ui = Get.value_by_name( + Constants.Dashboard.Avatar.Account.Email.NAME) + Helper.internal_assert(email, email_in_ui) + + @staticmethod + def form_validate_phone(phone): + phone_in_ui = Get.value_by_name( + Constants.Dashboard.Avatar.Account.Phone.NAME) + Helper.internal_assert(phone, phone_in_ui) + + @staticmethod + def form_validate_company(company): + company_in_ui = Get.value_by_name( + Constants.Dashboard.Avatar.Account.Company.NAME) + Helper.internal_assert(company, company_in_ui) + + @staticmethod + def form_validate_ssh(key): + key_in_ui = Get.value_by_name( + Constants.Dashboard.Avatar.Account.SSHKey.NAME) + Helper.internal_assert(key, key_in_ui) + + @staticmethod + def go_to_reset_password_from_login(): + Click.link_text(Constants.Login.ResetPassword.LINK_TEXT) + + @staticmethod + def send_reset_password(email): + FEGeneral.go_to_reset_password_from_login() + Wait.text_by_css( + Constants.ResetPassword.Title.CSS, Constants.ResetPassword.Title.TEXT) + Enter.text_by_name(Constants.ResetPassword.Email.NAME, email) + Wait.text_by_css( + Constants.SubmitButton.CSS, Constants.ResetPassword.Button.TEXT) + Click.css(Constants.SubmitButton.CSS) + Wait.text_by_id( + Constants.Toast.ID, Constants.ResetPassword.Toast.Success.TEXT) + logger.debug(Constants.ResetPassword.Toast.Success.TEXT) + + @staticmethod + def verify_home_elements(): + Wait.text_by_id(Constants.Home.Title.ID, Constants.Home.Title.TEXT) + element = session.ice_driver.find_element_by_id( + Constants.Home.Collaborate.ID) + element.location_once_scrolled_into_view + Wait.text_by_xpath( + Constants.Home.Collaborate.XPATH, Constants.Home.Collaborate.TEXT) + Wait.text_by_xpath( + Constants.Home.Validate.XPATH, Constants.Home.Validate.TEXT) + Wait.text_by_xpath( + Constants.Home.Incubate.XPATH, Constants.Home.Incubate.TEXT) + element = session.ice_driver.find_element_by_id(Constants.Home.Logo.ID) + element.location_once_scrolled_into_view + Wait.text_by_id(Constants.Home.Title.ID, Constants.Home.Title.TEXT) + + @staticmethod + def go_to_signup_from_homepage(): + Click.link_text(Constants.Home.GetStarted.LINK_TEXT) + Wait.text_by_css( + Constants.Signup.Title.CSS, Constants.Signup.Title.TEXT) + + @staticmethod + def get_meta_order_of_element(element_id): + return Get.meta_order_by_id(element_id) + + @staticmethod + def verify_num_of_existing_ids(requested_num_of_ids, id_prefix): + existing_id_objects_in_page = 0 + ids = session.ice_driver.find_elements_by_xpath('//*[@id]') + for id in ids: + if id_prefix in id.get_attribute('id'): + # Print id.tag_name (id name as string). + logger.debug(id.get_attribute('id')) + existing_id_objects_in_page += 1 + Helper.internal_assert( + existing_id_objects_in_page, requested_num_of_ids) + logger.debug("verify_num_of_existing_ids succeeded") + + @staticmethod + def verify_existing_files_in_list(items_list, id_to_search_for): + element = session.ice_driver.find_elements_by_id(id_to_search_for) + element_attribute_items = json.loads(element[0].get_attribute('name')) + Helper.internal_assert( + len(items_list), len(element_attribute_items) - 1) + extracted_files_list = list() + for file in element_attribute_items: + extracted_files_list.append(file['File']) + for item in items_list: + if item not in extracted_files_list: + Helper.assertTrue( + False, "%s does not exist over the client's side" % item) + logger.debug( + "verify_existing_files_in_list succeeded, All vf repo files are available for choosing.") diff --git a/services/frontend/fe_invite.py b/services/frontend/fe_invite.py new file mode 100644 index 0000000..405581c --- /dev/null +++ b/services/frontend/fe_invite.py @@ -0,0 +1,198 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from asyncio.tasks import wait + +from selenium.webdriver.support.select import Select + +from services.api.api_user import APIUser +from services.api.api_virtual_function import APIVirtualFunction +from services.constants import Constants, ServiceProvider +from services.database.db_general import DBGeneral +from services.database.db_user import DBUser +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.get import Get +from services.frontend.base_actions.wait import Wait +from services.frontend.fe_general import FEGeneral +from services.frontend.fe_user import FEUser +from services.frontend.fe_wizard import FEWizard +from services.helper import Helper +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() + +class FEInvite: + + @staticmethod + def invite_users(user_content): + engName = user_content[0][ + 'engagement_manual_id'] + ": " + user_content[0]['vfName'] + vf_left_nav_id = "clickable-" + engName + Click.id(vf_left_nav_id) + FEWizard.invite_team_members_modal(user_content[1]['email']) + # self.sleep(1) # TODO need to wait until modal window is closed. + invitation_token = DBUser.select_invitation_token("invitation_token", "ice_invitation", "engagement_uuid", + user_content[0]['engagement_uuid'], user_content[1]['email'], 1) + inviterURL = Constants.Default.InviteURL.Login.TEXT + invitation_token + FEGeneral.re_open(inviterURL) + # Login with 2nd user # + title_id = "title-id-" + engName + FEUser.login( + user_content[1]['email'], Constants.Default.Password.TEXT, title_id) + Click.id(vf_left_nav_id) + actualVfName = Get.by_id(vf_left_nav_id) + Helper.internal_assert(engName, actualVfName) + Wait.text_by_id(Constants.Dashboard.Overview.Title.ID, engName) + FEUser.logout() + return vf_left_nav_id + + @staticmethod + def invite_x_users(user_content, vf_left_nav_id, x): + for _ in range(x): # Invites 2-5 + Click.id(vf_left_nav_id) + Click.id(Constants.Dashboard.LeftPanel.AddEngagement.ID) + FEWizard.add_vf() + Click.id( + Constants.Dashboard.Wizard.CloseButton.ID, wait_for_page=True) + FEWizard.invite_team_members_modal(user_content[1]['email']) + FEGeneral.refresh() + + @staticmethod + def invite_and_validate_limit(user_content, vf_left_nav_id): + Click.id(Constants.Dashboard.LeftPanel.AddEngagement.ID) + FEWizard.add_vf() + Click.id(Constants.Dashboard.Wizard.CloseButton.ID, wait_for_page=True) + Click.id(vf_left_nav_id) + Click.id(Constants.Dashboard.Overview.TeamMember.ID) + Wait.text_by_css(Constants.Dashboard.Wizard.Title.CSS, + Constants.Dashboard.Wizard.InviteTeamMembers.Title.TEXT) + Enter.text_by_name("email", user_content[1]['email']) + Wait.text_by_css(Constants.SubmitButton.CSS, + Constants.Dashboard.Wizard.InviteTeamMembers.Button.TEXT) + Click.css(Constants.SubmitButton.CSS) + Wait.id(Constants.Toast.ID) + Helper.internal_assert( + Get.by_id(Constants.Toast.ID), "Invite couldn't be created") + + @staticmethod + def invite_x_users_from_tm(list_of_invite_emails, countofUser, countOfem, num): + Enter.text_by_name( + "email", list_of_invite_emails[countofUser], wait_for_page=True) + for _ in range(num): + try: + session.run_negative( + lambda: Click.css("span.add-icon"), "css appears") + break + except: # button exists + pass + countofUser += 1 +# Click.css("span.add-icon") + Wait.xpath("//fieldset[" + str(countOfem) + "]/div/input") + Enter.text_by_xpath( + "//fieldset[" + str(countOfem) + "]/div/input", list_of_invite_emails[countofUser]) + countOfem += 1 + Click.css(Constants.SubmitButton.CSS, wait_for_page=True) + + @staticmethod + def create_x_vfs(user_content, engName, x): + vflist = [] + FEUser.login(user_content['email'], Constants.Default.Password.TEXT) + for _ in range(x): + vf_left_nav_id = "clickable-" + engName + Click.id(vf_left_nav_id) + Click.id(Constants.Dashboard.LeftPanel.AddEngagement.ID) + vfName = FEWizard.add_vf() + vflist.append(vfName) + Click.id( + Constants.Dashboard.Wizard.CloseButton.ID, wait_for_page=True) + return vflist + + @staticmethod + def validations_for_user2(user_content, inviteEmail, vflist): + # Fetch one AT&T user ID. + engagement_id = DBGeneral.select_where( + "engagement_id", "ice_vf", "name", vflist[0], 1) + engagement_manual_id = DBGeneral.select_where( + "engagement_manual_id", "ice_engagement", "uuid", engagement_id, 1) + engLeadEmail = DBUser.select_el_email(vflist[0]) + user_content['engagement_uuid'] = engagement_id + user_content['el_email'] = engLeadEmail + uuid = DBGeneral.select_where_email( + "uuid", "ice_user_profile", user_content['email']) + sponsor = ["AT&T", 'aaaaaa', inviteEmail, '3058000000'] + invitation_token = DBUser.select_invitation_token( + "invitation_token", "ice_invitation", "engagement_uuid", engagement_id, inviteEmail, 1) + signUpURLforContact = DBUser.get_contact_signup_url( + invitation_token, uuid, sponsor[2], sponsor[1], sponsor[3], sponsor[0]) + APIUser.signup_invited_user( + sponsor[0], inviteEmail, invitation_token, signUpURLforContact, user_content, True, wait_for_gitlab=False) + activationUrl2 = DBUser.get_activation_url(sponsor[2]) + FEGeneral.re_open(activationUrl2) # Login with 2nd user # + engName = engagement_manual_id + ": " + vflist[0] + title_id = "clickable-" + engName + FEUser.login(inviteEmail, Constants.Default.Password.TEXT, title_id) + for vfName in vflist: + # Fetch one AT&T user ID. + engagement_id = DBGeneral.select_where( + "engagement_id", "ice_vf", "name", vfName, 1) + engagement_manual_id = DBGeneral.select_where( + "engagement_manual_id", "ice_engagement", "uuid", engagement_id, 1) + engName = engagement_manual_id + ": " + vfName + vf_left_nav_id = "clickable-" + engName + Click.id(vf_left_nav_id, wait_for_page=True) + + @staticmethod + def invite_x_users_and_verify_VF_appers_for_invited(user_content, engName): + inviteEmail = Helper.rand_string('randomString') + "@intl." + ServiceProvider.email + vflist = FEInvite.create_x_vfs(user_content, engName, x=3) + for vfName in vflist: + # Fetch one AT&T user ID. + engagement_id = DBGeneral.select_where( + "engagement_id", "ice_vf", "name", vfName, 1) + engagement_manual_id = DBGeneral.select_where( + "engagement_manual_id", "ice_engagement", "uuid", engagement_id, 1) + engName = engagement_manual_id + ": " + vfName + vf_left_nav_id = "clickable-" + engName + Click.id(vf_left_nav_id) + FEWizard.invite_team_members_modal(inviteEmail) + FEGeneral.refresh() + # validations + FEInvite.validations_for_user2(user_content, inviteEmail, vflist) diff --git a/services/frontend/fe_next_step.py b/services/frontend/fe_next_step.py new file mode 100644 index 0000000..be59949 --- /dev/null +++ b/services/frontend/fe_next_step.py @@ -0,0 +1,56 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +''' +Created on 20 Jul 2017 +''' +from services.constants import Constants +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.wait import Wait + + +class FENextStep(object): + + @staticmethod + def check_select_deselect_all_files(): + Click.id(Constants.Dashboard.Overview.NextSteps.Add.AssociatedFiles.ID) + Click.link_text( + Constants.Dashboard.Overview.NextSteps.Add.AssociatedFiles.SELECT_ALL_FILES_NAME) + Wait.text_by_id( + Constants.Dashboard.Overview.NextSteps.Add.AssociatedFiles.ID, + Constants.Dashboard.Overview.NextSteps.Add.AssociatedFiles.ALL_FILES_SELECTED) diff --git a/services/frontend/fe_overview.py b/services/frontend/fe_overview.py new file mode 100644 index 0000000..8d05f0c --- /dev/null +++ b/services/frontend/fe_overview.py @@ -0,0 +1,427 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +import datetime + +from django.utils import timezone +from selenium.webdriver.support.select import Select + +from services.constants import Constants +from services.database.db_general import DBGeneral +from services.database.db_user import DBUser +from services.database.db_virtual_function import DBVirtualFunction +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.get import Get +from services.frontend.base_actions.wait import Wait +from services.frontend.fe_general import FEGeneral +from services.frontend.fe_user import FEUser +from services.frontend.fe_wizard import FEWizard +from services.helper import Helper +from services.logging_service import LoggingServiceFactory +from services.session import session + +logger = LoggingServiceFactory.get_logger() + +class FEOverview: + + @staticmethod + def click_on_vf(user_content): + vfFullName = user_content[ + 'engagement_manual_id'] + ": " + user_content['vfName'] + Enter.text_by_id(Constants.Dashboard.LeftPanel.SearchBox.ID, user_content[ + 'vfName']) + Click.id(Constants.Dashboard.LeftPanel.SearchBox.Results.ID % + user_content['vfName']) + Wait.text_by_id( + Constants.Dashboard.Overview.Title.ID, vfFullName) + + @staticmethod + def go_to_eng_overview_by_clicking_on_the_created_NS(user_content): + logger.debug( + "Go to engagement's overview by clicking on the created Next Step") + Click.name(user_content['engagement_manual_id'], wait_for_page=True) + Wait.text_by_id( + Constants.Dashboard.Overview.Title.ID, user_content['engagement_manual_id'] + ":", wait_for_page=True) + FEGeneral.re_open(Constants.Default.LoginURL.TEXT) + logger.debug("Login with EL user " + user_content['el_email']) + FEUser.login(user_content['el_email'], Constants.Default.Password.TEXT) + # Query to select all assigned next steps on TODO state # + el_native_id = str(DBGeneral.select_where( + "id", "ice_user_profile", "email", user_content['el_email'], 1)) + queryStr = "SELECT count(*) FROM ice_user_profile AS users, ice_next_step_assignees AS assignees, ice_next_step AS ns WHERE users.id=" + \ + el_native_id + \ + " AND users.id=assignees.iceuserprofile_id AND assignees.nextstep_id=ns.uuid AND ns.state='Incomplete';" + el_assigned_ns = str(DBGeneral.select_query(queryStr)) + logger.debug("el_assigned_ns=" + el_assigned_ns) + Wait.page_has_loaded() + if (int(el_assigned_ns) >= 5): + logger.debug( + "EL has 5 or more assigned next steps, checking that only 5 are shown") + ns_list = Get.by_id("next-steps-list") + if (ns_list.count("Engagement - ") > 5): + logger.error("More than 5 next steps are listed in dashboard.") + raise + + @staticmethod + def complete_defaults_nextsteps(engagement_id): + # NEXT STEP ID + next_steps = DBVirtualFunction.select_next_steps_uuids_by_stage( + engagement_id, Constants.EngagementStages.INTAKE) + for next_step in next_steps: + Wait.id(next_step) + Click.id(next_step, wait_for_page=True) + + @staticmethod + def check_stage_notifications(stage): + activityLogID = "activity-log-0" + activityLogMsg = "Engagement stage is now %s" % stage + uiActivityLog = Get.by_id(activityLogID) + if activityLogMsg not in uiActivityLog: + return False + return True + + @staticmethod + def check_stage_next_steps(stage, engagement_uuid): + ns_list = DBGeneral.select_where_and("description", "ice_next_step", + "engagement_id", engagement_uuid, + "engagement_stage", stage, 0) # List of next steps from DB. + logger.debug("Got list of Next Steps for current stage " + stage) + for i in range(len(ns_list)): + ns_description = ns_list[i] # Value number i from the list. + ns_uuid = DBGeneral.select_where_and("uuid", "ice_next_step", + "engagement_id", engagement_uuid, + "description", ns_description, 1) + logger.debug( + "Compare presented text of next step with the text from DB.") + portal_ns = Get.by_id("step-" + ns_uuid) + # Get from UI the text of relevant next step. + if ns_description not in portal_ns: + logger.error("Next step wasn't found in stage " + stage) + raise + + @staticmethod + def change_engagement_stage(next_stage, is_negative=False): + # Click on next stage. + Click.id(Constants.Dashboard.Overview.Stage.Set.ID + next_stage) + txtLine2ID = "modal-message-" + next_stage + if is_negative: + session.run_negative( + lambda: Wait.id(txtLine2ID), "Error: modal window opened.") + else: + Wait.text_by_id( + txtLine2ID, "Are you sure you want to set the Engagement's stage to " + next_stage + "?") + # Click on Approve (after validations inside window). + Click.xpath( + Constants.Dashboard.Overview.Stage.Approve.XPATH, wait_for_page=True) + + @staticmethod + def check_progress(expected_progress): + currentProgress = Get.by_id( + Constants.Dashboard.Overview.Progress.Percent.ID) + Helper.internal_assert(currentProgress, expected_progress) + + @staticmethod + def check_vnf_version(expected_progress): + current_vnf_value = Get.by_css( + "." + Constants.Dashboard.Overview.Progress.VnfVersion.CLASS) + Helper.internal_assert(current_vnf_value, expected_progress) + + @staticmethod + def set_progress(new_value): + Click.id(Constants.Dashboard.Overview.Progress.Change.ID) + Helper.internal_assert(Constants.Dashboard.Overview.Progress.Wizard.Title.TEXT, + Get.by_id(Constants.Dashboard.Modal.TITLE_ID)) + Enter.text_by_name( + Constants.Dashboard.Overview.Progress.Wizard.NAME, new_value) + Wait.text_by_css(Constants.SubmitButton.CSS, + Constants.Dashboard.Overview.Progress.Wizard.Button.TEXT) + Click.css(Constants.SubmitButton.CSS) + Wait.modal_to_dissappear() + + @staticmethod + def delete_next_step(next_step_uuid): + Click.id("step-" + next_step_uuid, wait_for_page=True) + Click.id("delete-" + next_step_uuid, wait_for_page=True) + Wait.text_by_id( + Constants.Dashboard.GeneralPrompt.Title.ID, "Delete Step") + Click.id( + Constants.Dashboard.GeneralPrompt.ApproveButton.ID, wait_for_page=True) + Wait.id_to_dissappear("test_" + next_step_uuid) + + @staticmethod + def click_on_admin_dropdown(): + Click.id( + Constants.Dashboard.Overview.AdminDropdown.ID, wait_for_page=True) + + @staticmethod + def click_on_archeive_engagement_from_dropdown(): + FEOverview.click_on_admin_dropdown() + Click.link_text( + Constants.Dashboard.Overview.AdminDropdown.ArchiveEngagement.LINK_TEXT, wait_for_page=True) + + @staticmethod + def archive_engagement_modal(engagement_manual_id, vf_name): + Wait.text_by_id(Constants.Dashboard.Overview.AdminDropdown.ArchiveEngagement.Wizard.Title.ID, + Constants.Dashboard.Overview.AdminDropdown.ArchiveEngagement.Wizard.Title.TEXT) + random_reason = Helper.rand_string() + Enter.text_by_name(Constants.Dashboard.Overview.AdminDropdown.ArchiveEngagement.Wizard.Reason.NAME, + random_reason) + Click.id(Constants.SubmitButton.ID) + Wait.text_by_id(Constants.Toast.ID, "Engagement '%s: %s' archived successfully." % + (engagement_manual_id, vf_name)) + query = "select archived_time,archive_reason from ice_engagement where engagement_manual_id='{engagement_manual_id}'".format( + engagement_manual_id=engagement_manual_id) + archived_time, db_reason = DBGeneral.select_query(query, "list") + Helper.assertTrue(archived_time != None) + Helper.internal_assert(random_reason, db_reason) + + @staticmethod + def click_on_change_reviewer_from_dropdown(): + FEOverview.click_on_admin_dropdown() + Click.link_text( + Constants.Dashboard.Overview.AdminDropdown.ChangeReviewer.LINK_TEXT) + + @staticmethod + def select_engagement_lead_from_list(el_name): + Wait.name( + Constants.Dashboard.Overview.AdminDropdown.ChangeReviewer.Wizard.Select.NAME, wait_for_page=True) + Select(session.ice_driver.find_element_by_name( + Constants.Dashboard.Overview.AdminDropdown.ChangeReviewer.Wizard.Select.NAME)).select_by_visible_text(el_name) + + @staticmethod + def change_engagement_lead_modal(el_name, is_reviewer=True): + Wait.text_by_id(Constants.Dashboard.Overview.AdminDropdown.ChangeReviewer.Wizard.Title.ID, + Constants.Dashboard.Overview.AdminDropdown.ChangeReviewer.Wizard.Title.TEXT) + FEOverview.select_engagement_lead_from_list(el_name) + if is_reviewer: + Wait.text_by_id( + Constants.Toast.ID, Constants.Dashboard.Overview.AdminDropdown.ChangeReviewer.Toast.TEXT) + else: + Wait.text_by_id( + Constants.Toast.ID, Constants.Dashboard.Overview.AdminDropdown.ChangePeerReviewer.Toast.TEXT) + + @staticmethod + def click_on_change_peer_reviewer_from_dropdown(): + FEOverview.click_on_admin_dropdown() + Click.link_text( + Constants.Dashboard.Overview.AdminDropdown.ChangePeerReviewer.LINK_TEXT) + Wait.text_by_id(Constants.Dashboard.Overview.AdminDropdown.ChangePeerReviewer.Wizard.Title.ID, + Constants.Dashboard.Overview.AdminDropdown.ChangePeerReviewer.Wizard.Title.TEXT) + + @staticmethod + def click_on_update_status_from_dropdown(): + FEOverview.click_on_admin_dropdown() + Click.link_text( + Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.LINK_TEXT) + Wait.text_by_id("update-engagement-status-title", "Update Status") + + @staticmethod + def fill_update_status_form_admin_dropdown(): + random_string = Helper.rand_string() + Enter.text_by_name( + Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.PROGRESS, str(50)) + Enter.date_picker(Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.PROGRESS_CSS, + Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.TARGET) + Enter.date_picker(Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.PROGRESS_CSS, + Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.HEAT) + Enter.date_picker(Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.PROGRESS_CSS, + Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.IMAGE_SACN) + Enter.date_picker(Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.PROGRESS_CSS, + Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.AIC) + Enter.date_picker(Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.PROGRESS_CSS, + Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.ASDC) + Enter.text_by_name( + Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.STATUS, random_string) + Click.css( + Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.SUBMIT, wait_for_page=True) + Wait.text_by_id( + Constants.Toast.ID, Constants.Dashboard.Overview.AdminDropdown.UpdateStatus.SUCCESS_MSG, wait_for_page=True) + Wait.text_by_id( + Constants.Dashboard.Overview.Status.Description.ID, random_string) + + @staticmethod + def get_next_step_description(idx): + return str(Get.by_id("step-description-%s" % idx, wait_for_page=True)) + + @staticmethod + def get_list_of_next_steps(): + i = 0 + ns_list = [] + steps_length = len( + session.ice_driver.find_elements_by_css_selector(".step-indication > li")) + while i < steps_length: + ns_list.append(FEOverview.get_next_step_description(i)) + i += 1 + return ns_list + + @staticmethod + def validate_next_steps_order(steps_uuids): + ui_steps = FEOverview.get_list_of_next_steps() + for idx, step_uuid in enumerate(steps_uuids): + db_step_text = DBVirtualFunction.select_next_step_description( + step_uuid) + Wait.text_by_id(Constants.Dashboard.Overview.NextSteps.Add.Description.STEP_DESC_ID + + str(idx), ui_steps[idx], wait_for_page=True) + if db_step_text != ui_steps[idx]: + raise AssertionError("Next step is not located in expected index. db_step_text = " + + db_step_text + " ui_steps[idx] = " + ui_steps[idx] + "|| uuid = " + step_uuid) + + @staticmethod + def next_steps_filter_by_files(): + Click.id( + Constants.Dashboard.Overview.NextSteps.FilterByFileDropDown.ID) + Click.link_text( + Constants.Dashboard.Overview.NextSteps.FilterByFileDropDown.ANY_FILE_LINK_TEXT) + Click.link_text( + Constants.Dashboard.Overview.NextSteps.FilterByFileDropDown.FILE0_LINK_TEXT) + Click.id( + Constants.Dashboard.Overview.NextSteps.FilterByFileDropDown.ID) + + @staticmethod + def complete_next_step(step_uuid): + Click.id(step_uuid) + + @staticmethod + def complete_next_step_and_wait_for_it_to_disappear(step_uuid): + Click.id(step_uuid) + Wait.id_to_dissappear(step_uuid) + + @staticmethod + def next_steps_filter_by_states(): + Click.id(Constants.Dashboard.Overview.NextSteps.StateDropDown.ID) + Click.link_text( + Constants.Dashboard.Overview.NextSteps.StateDropDown.INCOMPLETE_LINK_TEXT) + Click.link_text( + Constants.Dashboard.Overview.NextSteps.StateDropDown.COMPLETED_LINK_TEXT) + Click.id(Constants.Dashboard.Overview.NextSteps.StateDropDown.ID) + + @staticmethod + def add_next_step(): + Click.id(Constants.Dashboard.Overview.NextSteps.Add.ID) + Wait.text_by_css(Constants.Dashboard.Overview.NextSteps.Add.Title.CSS, + Constants.Dashboard.Overview.NextSteps.Add.Title.TEXT) + ns_description = "New next step - " + \ + Helper.rand_string("randomString") + Click.id(Constants.Dashboard.Overview.NextSteps.Add.Description.ID) + Enter.text_by_id( + Constants.Dashboard.Overview.NextSteps.Add.Description.ID, ns_description) + FEWizard.date_picker_add_ns(0) + Wait.text_by_css(Constants.SubmitButton.CSS, + Constants.Dashboard.Overview.NextSteps.Add.Button.TEXT) + Click.css(Constants.SubmitButton.CSS) + Wait.modal_to_dissappear() + + @staticmethod + def click_on_team_member(full_name): + Click.id(Constants.Dashboard.Overview.TeamMember.MEMBER_ID % full_name) + Wait.id(Constants.Dashboard.Overview.TeamMember.Title.ID) + + @staticmethod + def remove_user_from_eng_team(full_name, is_negative=False): + FEOverview.click_on_team_member(full_name) + if is_negative: + Wait.id_to_dissappear( + Constants.Dashboard.Overview.TeamMember.RemoveUser.ID) + else: + Click.id(Constants.Dashboard.Overview.TeamMember.RemoveUser.ID) + Wait.text_by_id(Constants.Dashboard.GeneralPrompt.UpperTitle.ID, + Constants.Dashboard.Overview.TeamMember.RemoveUser.Title.TEXT % full_name) + Wait.text_by_id(Constants.Dashboard.GeneralPrompt.Title.ID, + Constants.Dashboard.Overview.TeamMember.RemoveUser.Message.TEXT) + Click.id(Constants.Dashboard.GeneralPrompt.ApproveButton.ID) + FEGeneral.refresh() + Wait.id_to_dissappear( + Constants.Dashboard.Overview.TeamMember.MEMBER_ID % full_name) + + @staticmethod + def invite_and_reopen_link(user_content, other_el_email): + enguuid = DBGeneral.select_where( + "uuid", "ice_engagement", "engagement_manual_id", user_content['engagement_manual_id'], 1) + invitation_token = DBUser.select_invitation_token( + "invitation_token", "ice_invitation", "engagement_uuid", enguuid, other_el_email, 1) + inviterURL = Constants.Default.InviteURL.Login.TEXT + invitation_token + FEGeneral.re_open(inviterURL) + + @staticmethod + def create_and_verify_VF_with_VFversion(): + Click.id( + Constants.Dashboard.LeftPanel.AddEngagement.ID, wait_for_page=True) + vfName = FEWizard.add_vf() + version_name = DBVirtualFunction.select_vf_version_by_vf_name(vfName) + vfNameDb = DBVirtualFunction.select_vf_name_by_vf_version(version_name) + Helper.internal_assert(vfNameDb, vfName) + + @staticmethod + def validate_empty_associated_files(): + FEOverview.add_next_step() + Click.id(Constants.Dashboard.Overview.NextSteps.AssociatedFiles.ID) + Wait.text_by_id(Constants.Dashboard.Overview.NextSteps.AssociatedFiles.EmptyMsgID, + Constants.Dashboard.Overview.NextSteps.AssociatedFiles.EmptyMsg) + + @staticmethod + def validate_associated_files(file_name): + Click.id(Constants.Dashboard.Overview.NextSteps.AssociatedFiles.ID) + Wait.text_by_id( + Constants.Dashboard.Overview.NextSteps.AssociatedFiles.FileId, file_name) + + @staticmethod + def validate_bucket_url(eng_manual_id, vf_name): + expected_text = Constants.Dashboard.Overview.BucketURL.TEXT + \ + eng_manual_id + "_" + vf_name.lower() + Wait.text_by_id( + Constants.Dashboard.Overview.BucketURL.ID, expected_text, True) + + @staticmethod + def verify_validation_dates(): + validation_date = Get.by_id( + Constants.Dashboard.Overview.Progress.ValidationsDates.AIC_ID, True) + validation_date = datetime.datetime.strptime( + validation_date, "%m/%d/%y").date() + current_date = timezone.now().date() + Helper.internal_assert(validation_date, current_date) + + @staticmethod + def open_add_next_step_modal_from_overview(): + Click.id(Constants.Dashboard.Overview.NextSteps.Add.ID, + wait_for_page=True) + Wait.text_by_css(Constants.Dashboard.Checklist.AddNS.CSS, + Constants.Dashboard.Overview.NextSteps.Add.TITLE) + Helper.internal_assert( + Constants.Dashboard.Checklist.AddNS.TITLE, + Get.by_css(Constants.FEGeneral.CSS.H2)) diff --git a/services/frontend/fe_user.py b/services/frontend/fe_user.py new file mode 100644 index 0000000..91cf7eb --- /dev/null +++ b/services/frontend/fe_user.py @@ -0,0 +1,403 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from selenium.webdriver.support.select import Select + +from services.api.api_user import APIUser +from services.api.api_virtual_function import APIVirtualFunction +from services.constants import Constants +from services.database.db_general import DBGeneral +from services.database.db_user import DBUser +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.get import Get +from services.frontend.base_actions.wait import Wait +from services.frontend.fe_general import FEGeneral +from services.helper import Helper +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() + +class FEUser: + + @staticmethod + def login(email, password, expected_element=Constants.Dashboard.Statuses.Title.ID, element_type="id"): + try: + logger.debug("Verifying and Insert Login page elements:") + logger.debug("Insert Email " + email) + Wait.name(Constants.Login.Email.NAME, wait_for_page=True) + Enter.text_by_name(Constants.Login.Email.NAME, email) + logger.debug("Insert Password") + Enter.text_by_name(Constants.Login.Password.NAME, password) + logger.debug("Click Login Button") + Click.css(Constants.SubmitButton.CSS) + logger.debug("Login Button clicked") + if element_type == 'id': + Wait.id(expected_element, True) + elif element_type == 'css': + Wait.css(expected_element, True) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Login FAILED: email=%s password=%s" % (email, password) + logger.error(errorMsg) + raise Exception(errorMsg, e) + + @staticmethod + def relogin(email, password, expected_element=Constants.Dashboard.Statuses.Title.ID, element_type="id"): + FEGeneral.re_open(Constants.Default.LoginURL.TEXT) + FEUser.login(email, password, expected_element, element_type) + + @staticmethod + def logout(): + Click.id(Constants.Dashboard.Avatar.ID) + Click.link_text(Constants.Dashboard.Avatar.Logout.LINK_TEXT) + + @staticmethod + def activate_and_login(email, password, expected_element=Constants.Dashboard.Statuses.Title.ID, element_type="id"): + activationUrl = DBUser.get_activation_url(email) + FEGeneral.re_open(activationUrl) + FEUser.login(email, password, expected_element, element_type) + + @staticmethod + def open_account_form(): + Click.id(Constants.Dashboard.Avatar.ID, wait_for_page=True) + Click.link_text( + Constants.Dashboard.Avatar.Account.LINK_TEXT, wait_for_page=True) + + @staticmethod + # Update account API - only adds new SSH key! + def update_account_and_return_changes(): + try: + Select(session.ice_driver.find_element_by_name( + "company")).select_by_visible_text("Nokia") + randomName = Helper.rand_string("randomString") + Enter.text_by_name("fullname", randomName) + phone = "97258" + Helper.rand_string("randomNumber", 6) + Enter.text_by_name("phone", phone) + password = Constants.Default.Password.NewPass.TEXT + Enter.text_by_name("password", password) + Enter.text_by_name("confirm_password", password) + Wait.text_by_css("button.btn.btn-primary", "Update") + Click.css("button.btn.btn-primary") + Wait.text_by_id( + Constants.Toast.ID, "Account was updated successfully!") + Click.id(Constants.Dashboard.Statuses.ID) + + accountObj = [randomName, phone, password] + return accountObj + # If failed - count the failure and add the error to list of errors. + except: + errorMsg = "Failed in update accaunt ." + raise Exception(errorMsg) + raise + + @staticmethod + def go_to_account(): + try: + FEUser.click_on_avatar() + FEUser.click_on_account() + except Exception as e: + errorMsg = "Failed to go to Account page." + raise Exception(errorMsg, e) + + @staticmethod + def go_to_notifications(): + try: + FEUser.click_on_avatar() + FEUser.click_on_notifications() + Wait.page_has_loaded() + except Exception as e: + errorMsg = "Failed to go to Notifications page." + raise Exception(errorMsg, e) + + @staticmethod + def click_on_avatar(): + try: + Click.id(Constants.Dashboard.Avatar.ID, wait_for_page=True) + except Exception as e: + errorMsg = "Failed to click_on on Avatar." + raise Exception(errorMsg, e) + + @staticmethod + def click_on_admin(): + try: + Click.id( + Constants.Dashboard.Avatar.Admin.Title.ID, wait_for_page=True) + except Exception as e: + errorMsg = "Failed to click_on on Admin." + raise Exception(errorMsg, e) + + @staticmethod + def click_on_feedback(): + Click.id(Constants.Dashboard.Feedback.ID, wait_for_page=True) + Wait.id( + Constants.Dashboard.Feedback.FeedbackModal.SAVE_BTN_ID, wait_for_page=True) + + @staticmethod + def validate_feedback(description, user_email): + query = "SELECT user_id FROM ice_feedback where description = '{desc}'".format( + desc=description) + feedback_user_uuid = DBGeneral.select_query(query) + query = "SELECT id FROM ice_user_profile where email = '{email}'".format( + email=user_email) + user_uuid = DBGeneral.select_query(query) + Helper.internal_assert(user_uuid, feedback_user_uuid) + + @staticmethod + def add_feedback(): + Wait.css("textarea[name=\"description\"]", wait_for_page=True) + description = Helper.rand_string("randomString") + Enter.text_by_css("textarea[name=\"description\"]", description) + Click.id( + Constants.Dashboard.Feedback.FeedbackModal.SAVE_BTN_ID, wait_for_page=True) + Wait.text_by_id(Constants.Toast.ID, + "Feedback was sent successfully.", wait_for_page=True) + return description + + @staticmethod + def click_on_account(): + try: + Click.link_text(Constants.Dashboard.Avatar.Account.LINK_TEXT) + Wait.text_by_css(Constants.Dashboard.Avatar.Account.Title.CSS, + Constants.Dashboard.Avatar.Account.Title.TEXT) + except Exception as e: + errorMsg = "Failed to click_on on Admin." + raise Exception(errorMsg, e) + + @staticmethod + def click_on_notifications(): + try: + Click.link_text( + Constants.Dashboard.Avatar.Notifications.LINK_TEXT, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.Avatar.Notifications.Title.ID, + Constants.Dashboard.Avatar.Notifications.Title.TEXT, wait_for_page=True) + except Exception as e: + errorMsg = "Failed to click_on on Admin." + raise Exception(errorMsg, e) + + @staticmethod + def go_to_admin(): + try: + FEUser.click_on_avatar() + FEUser.click_on_admin() + except Exception as e: + errorMsg = "Failed to go to Admin page." + raise Exception(errorMsg, e) + + @staticmethod + def assigned_one_NS_to_user(user_content): + nextStepsNumber = int( + Get.by_id("next-steps-header").split('(')[1][:-1]) + if (nextStepsNumber != 0): + logger.error("assigned ns: " + str(nextStepsNumber)) + logger.error( + "APIUser should not have assigned next steps at first login.") + raise + if (Get.by_id("next-steps-list") != "No next steps are assigned to you."): + logger.error( + "No assigned next steps and text 'No next steps are assigned to you.' was not found.") + raise + token = "token " + APIUser.login_user(user_content['el_email']) + user_content['session_token'] = token + logger.debug( + "Adding new next step (via api) and assigning it to user " + user_content['full_name']) + APIVirtualFunction.add_next_step(user_content) + logger.debug( + "Refresh page and look for changes in assigned next steps section:") + FEGeneral.refresh() + logger.debug(" > Check if number has changed in 'Assigned To You'") + Wait.text_by_id( + "next-steps-header", "Assigned To You (1)", wait_for_page=True) + + @staticmethod + def set_ssh_key_from_account(key, is_negative=False): + FEUser.go_to_account() + Enter.text_by_name(Constants.Dashboard.Avatar.Account.SSHKey.NAME, key) + Click.css(Constants.SubmitButton.CSS) + if is_negative: + Wait.text_by_id( + Constants.Toast.ID, Constants.Dashboard.Avatar.Account.SSHKey.UpdateFailed.TEXT) + else: + Wait.text_by_id( + Constants.Toast.ID, Constants.Dashboard.Avatar.Account.Update.Success.TEXT) + + @staticmethod + def reset_password(): + Wait.text_by_css( + Constants.UpdatePassword.Title.CSS, Constants.UpdatePassword.Title.TEXT) + Wait.text_by_css( + Constants.UpdatePassword.SubTitle.CSS, Constants.UpdatePassword.SubTitle.TEXT) + Wait.text_by_css( + Constants.SubmitButton.CSS, Constants.UpdatePassword.Button.TEXT) + Enter.text_by_name( + Constants.UpdatePassword.Password.NAME, Constants.Default.Password.NewPass.TEXT) + Enter.text_by_name( + Constants.UpdatePassword.ConfirmPassword.NAME, Constants.Default.Password.NewPass.TEXT) + Click.css(Constants.SubmitButton.CSS) + Wait.text_by_id( + Constants.Toast.ID, Constants.UpdatePassword.Toast.TEXT) + + @staticmethod + def delete_notification(notificationID): + if isinstance(notificationID, tuple): + notificationID = notificationID[0] + delete_button = Constants.Dashboard.Avatar.Notifications.DeleteNotification.ID + \ + notificationID + # Click on delete button. + Click.id(delete_button, wait_for_page=True) + Wait.id_to_dissappear(delete_button) + + @staticmethod + def validate_notifications(notificationIDs, notification_list): + ui_list = [] + for notifID in notificationIDs: + if isinstance(notifID, tuple): + notifID = notifID[0] + ui_list.append(str(Get.by_id( + Constants.Dashboard.Avatar.Notifications.NotificationColumn.ID + notifID))) + for activity in notification_list: + if not any(activity in s for s in ui_list): + raise AssertionError( + "Activity: \"" + activity + "\" not appears in UI") + + @staticmethod + def click_on_export_excel(user_content): + Enter.text_by_id( + Constants.Dashboard.Statuses.SearchBox.ID, user_content['vfName']) + engName = user_content[ + 'engagement_manual_id'] + ": " + user_content['vfName'] + engSearchID = "eng-" + engName + Wait.id(engSearchID) + # Find the download link and click it + Click.id(Constants.Dashboard.Statuses.ExportExcel.ID) + + @staticmethod + def open_invite_team_member_form(vf_left_nav_id): + Click.id(vf_left_nav_id) + Click.id(Constants.Dashboard.Overview.TeamMember.ID) + Wait.text_by_name(Constants.Dashboard.Wizard.InviteTeamMembers.Title.NAME, + Constants.Dashboard.Wizard.InviteTeamMembers.Title.TEXT) + + @staticmethod + def invite_single_user_to_team(email): + Enter.text_by_name("email", email, wait_for_page=True) + Click.css(Constants.SubmitButton.CSS, wait_for_page=True) + + @staticmethod + def go_to_user_profile_settings(): + FEUser.go_to_account() + Click.id( + Constants.Dashboard.Avatar.Account.UserProfileSettings.ID, wait_for_page=True) + Wait.text_by_id(Constants.Dashboard.Avatar.Account.UserProfileSettings.TitleID, + Constants.Dashboard.Avatar.Account.UserProfileSettings.TitleText, wait_for_page=True) + + @staticmethod + def check_user_profile_settings_checkboxes(): + Click.id( + Constants.Dashboard.Avatar.Account.UserProfileSettings.ReceiveEmailsID, wait_for_page=True) + Click.id( + Constants.Dashboard.Avatar.Account.UserProfileSettings.ReceiveEmailEveryTimeID, wait_for_page=True) + Click.id( + Constants.Dashboard.Avatar.Account.UserProfileSettings.ReceiveDigestEmailID, wait_for_page=True) + Click.id( + Constants.Dashboard.Avatar.Account.UserProfileSettings.UpdateButtonID, wait_for_page=True) + + @staticmethod + def validate_user_profile_settings_checkboxes(checked): + Wait.page_has_loaded() + receive_emails = Get.is_selected_by_id( + Constants.Dashboard.Avatar.Account.UserProfileSettings.ReceiveEmailsID, wait_for_page=True) + Helper.internal_assert(receive_emails, checked) + receive_notifications = \ + Get.is_selected_by_id( + Constants.Dashboard.Avatar.Account.UserProfileSettings.ReceiveNotificationsID) + receive_email_every_time = \ + Get.is_selected_by_id( + Constants.Dashboard.Avatar.Account.UserProfileSettings.ReceiveEmailEveryTimeID) + Helper.internal_assert(receive_email_every_time, checked) + receive_digest_email = \ + Get.is_selected_by_id( + Constants.Dashboard.Avatar.Account.UserProfileSettings.ReceiveDigestEmailID, wait_for_page=True) + Helper.internal_assert(receive_digest_email, not checked) + + @staticmethod + def compare_notifications_count_for_user(expected_count): + Wait.text_by_id( + Constants.Dashboard.Avatar.Notifications.Count.ID, expected_count, wait_for_page=True) + + @staticmethod + def check_notification_number_is_not_presented(): + FEGeneral.refresh() + Wait.id_to_dissappear( + Constants.Dashboard.Avatar.Notifications.Count.ID, wait_for_page=True) + + @staticmethod + def validate_account_details(full_name, phone_number, ssh_key): + Helper.internal_assert(full_name, Get.value_by_name( + Constants.Dashboard.Avatar.Account.FullName.NAME)) + Helper.internal_assert(phone_number, Get.value_by_name( + Constants.Dashboard.Avatar.Account.Phone.NAME)) + Helper.internal_assert( + ssh_key, Get.value_by_name(Constants.Dashboard.Avatar.Account.SSHKey.NAME)) + + @staticmethod + def check_rgwa_access_key(my_key): + Wait.text_by_id( + Constants.Dashboard.Avatar.Account.RGWA.Key.KEY_ID, my_key) + + @staticmethod + def check_rgwa_access_secret(my_secret): + Click.id(Constants.Dashboard.Avatar.Account.RGWA.Secret.BUTTON_ID) + Wait.text_by_id( + Constants.Dashboard.Avatar.Account.RGWA.Secret.SECRET_ID, my_secret) + + @staticmethod + def get_rgwa_access_secret(): + Click.id(Constants.Dashboard.Avatar.Account.RGWA.Secret.BUTTON_ID, + wait_for_page=True) + secret = Get.by_id( + Constants.Dashboard.Avatar.Account.RGWA.Secret.SECRET_ID, wait_for_page=True) + return secret + + @staticmethod + def check_rgwa_access_secret_not_presented(): + Wait.text_by_id( + Constants.Dashboard.Avatar.Account.RGWA.Secret.SECRET_ID, + Constants.Dashboard.Avatar.Account.RGWA.Secret.SECRET_TEXT) diff --git a/services/frontend/fe_wizard.py b/services/frontend/fe_wizard.py new file mode 100644 index 0000000..777fe52 --- /dev/null +++ b/services/frontend/fe_wizard.py @@ -0,0 +1,216 @@ + +# ============LICENSE_START========================================== +# org.onap.vvp/test-engine +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from datetime import datetime + +from selenium.webdriver.support.ui import Select + +from services.constants import Constants, ServiceProvider +from services.frontend.base_actions.click import Click +from services.frontend.base_actions.enter import Enter +from services.frontend.base_actions.wait import Wait +from services.helper import Helper +from services.logging_service import LoggingServiceFactory +from services.session import session + + +logger = LoggingServiceFactory.get_logger() + +class FEWizard: + + E2Edate = None + + @staticmethod + def add_vf(): + try: + logger.debug("Tab Add Virtual Functions") + Wait.text_by_css( + Constants.Dashboard.Wizard.Title.CSS, Constants.Dashboard.Wizard.AddVF.Title.TEXT, wait_for_page=True) + vfName = "newVF" + Helper.rand_string("randomString") + vfVersion = "newVFVersion" + \ + Helper.rand_string( + "randomNumber") + Helper.rand_string("randomString") + Enter.text_by_name("virtualFunction", vfName) + Enter.text_by_name("VFversion", vfVersion, wait_for_page=True) + FEWizard.date_picker_wizard() + Select(session.ice_driver.find_element_by_id( + Constants.Dashboard.Wizard.AddVF.AIC_Version.TEXT)).select_by_visible_text("AIC 3.5") + Select(session.ice_driver.find_element_by_id( + Constants.Dashboard.Wizard.AddVF.ECOMP_Release.TEXT)).select_by_visible_text("Unknown") + session.E2Edate = FEWizard.get_lab_entry_date() + Click.css(Constants.SubmitButton.CSS, wait_for_page=True) + Wait.page_has_loaded() + Wait.name_to_dissappear("Add Virtual Function") + return vfName + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Failed to add a Virtual Function via modal window. Exception " + \ + str(e) + raise Exception(errorMsg) + + @staticmethod + def get_lab_entry_date(): + E2Edate = session.ice_driver.find_element_by_id( + "add-vf-hidden-target-lab-date").get_attribute("value") + return str(E2Edate) + + @staticmethod + def add_vendor_contact(): + logger.debug("Tab Add Vendor Contact") + Wait.text_by_css(Constants.Dashboard.Wizard.Title.CSS, + Constants.Dashboard.Wizard.AddVendorContact.Title.TEXT, wait_for_page=True) + Select(session.ice_driver.find_element_by_name( + "company")).select_by_visible_text("Ericsson") + fullname = Helper.rand_string( + "randomString") + Helper.rand_string("randomString") + Enter.text_by_name("fullname", fullname) + email = Helper.rand_string("randomString") + "@ericson.com" + Enter.text_by_name("email", email) + phone = "201" + Helper.rand_string("randomNumber", 6) + Enter.text_by_name("phone", phone) + Click.css(Constants.SubmitButton.CSS, wait_for_page=True) + Wait.name_to_dissappear("Add Vendor Contact", wait_for_page=True) + vendor = {"company": "Ericsson", "full_name": fullname, + "email": email, "phone": phone} + return vendor + + @staticmethod + def add_service_provider_internal(): + logger.debug( + "Tab Add " + ServiceProvider.MainServiceProvider + " Sponsor") + Wait.text_by_css( + Constants.Dashboard.Wizard.Title.CSS, "Add " + ServiceProvider.MainServiceProvider + " Sponsor") + fullname = Helper.rand_string( + "randomString") + Helper.rand_string("randomString") + Enter.text_by_name("fullname", fullname) + email = Helper.rand_string( + "randomString") + "@" + ServiceProvider.email + Enter.text_by_name("email", email) + phone = "201" + Helper.rand_string("randomNumber", 6) + logger.debug(phone) + Enter.text_by_name("phone", phone) + Click.css(Constants.SubmitButton.CSS) + Wait.name_to_dissappear("Add AT&T Sponsor") + sponsor = {"company": "AT&T", "full_name": fullname, + "email": email, "phone": phone} + return sponsor + + @staticmethod + def invite_team_members(email): + try: + logger.debug("Tab Invite Team Members") + Wait.text_by_name(Constants.Dashboard.Wizard.InviteTeamMembers.Title.NAME, + Constants.Dashboard.Wizard.InviteTeamMembers.Title.TEXT) + Enter.text_by_name("email", email) + Wait.text_by_css( + Constants.SubmitButton.CSS, Constants.Dashboard.Wizard.InviteTeamMembers.Button.TEXT) + Click.css(Constants.SubmitButton.CSS) + Wait.name_to_dissappear( + Constants.Dashboard.Wizard.InviteTeamMembers.Title.NAME) + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "FAILED in Tab Invite Team Members. Exception = %s" % e + raise Exception(errorMsg) + + @staticmethod + def add_ssh_key(is_negative=False): + logger.debug("About to add an SSH Key in modal window") + try: # Add SSH Key from modal window and return key value. + Wait.text_by_name(Constants.Dashboard.Wizard.AddSSHKey.Title.NAME, + Constants.Dashboard.Wizard.AddSSHKey.Title.TEXT) + # Generate an SSH Public Key. + sshKey = Helper.generate_sshpub_key() + if is_negative: + sshKey = sshKey[8:] + Enter.text_by_name("key", sshKey) + + # Check that the submit button exists. + Wait.text_by_css( + Constants.SubmitButton.CSS, Constants.Dashboard.Wizard.AddSSHKey.Title.TEXT) + + Click.css(Constants.SubmitButton.CSS) # Click on submit button. + if is_negative: + Wait.text_by_id( + Constants.Toast.ID, Constants.Dashboard.Avatar.Account.SSHKey.UpdateFailed.TEXT) + else: + Wait.name_to_dissappear( + Constants.Dashboard.Wizard.AddSSHKey.Title.NAME) + logger.debug("SSH Key added via modal window.") + return sshKey + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "Failed to add an SSH Key in the modal window. Exception=" + \ + str(e) + raise Exception(errorMsg) + + @staticmethod + def invite_team_members_modal(email): + try: + Click.id( + Constants.Dashboard.Overview.TeamMember.ID, wait_for_page=True) + Wait.text_by_css(Constants.Dashboard.Wizard.Title.CSS, + Constants.Dashboard.Wizard.InviteTeamMembers.Title.TEXT) + Enter.text_by_name("email", email) + Wait.text_by_css( + Constants.SubmitButton.CSS, Constants.Dashboard.Wizard.InviteTeamMembers.Button.TEXT) + Wait.css_to_dissappear( + '.inviteMembers-form button[disabled="disabled"].btn.btn-primary') + Wait.css(".inviteMembers-form button.btn.btn-primary") + Click.css(".inviteMembers-form button.btn.btn-primary") + Wait.modal_to_dissappear() + # If failed - count the failure and add the error to list of errors. + except Exception as e: + errorMsg = "FAILED in PopUp Invite Team Members. Exception=" + \ + str(e) + raise Exception(errorMsg) + + @staticmethod + def date_picker_add_ns(count): + try: + session.ice_driver.execute_script("var el = angular.element(document.querySelector('.addNextSteps')); el.scope().vm.nextSteps[" + str( + count) + "].duedate = new Date('" + str(datetime.today().isoformat()) + "')") + Click.css("div.modal-content", wait_for_page=True) + except Exception as e: + errorMsg = "Failed to select date with datePicker." + + raise Exception(errorMsg, str(e)) + + @staticmethod + def date_picker_wizard(): + Enter.date_picker('#e2e-lab-entry-date', 'choice.TargetLab') + Click.css('input[name="virtualFunction"]', wait_for_page=True) |