From eb79032e29523882dc3921d8ec1f246c16d252eb Mon Sep 17 00:00:00 2001 From: manosnoam Date: Mon, 26 Feb 2024 08:34:59 +0000 Subject: [PATCH] Stabilize Dashboard Test Suite (415) Fix known Automation bugs and general stability of Dashboard Suite 415. It also includes fixes to Keywords in Storages, Workbenches and Projects resources, that are being used by this suite: - `Create PersistentVolume Storage` option to update existing PVC - Fix supported mount name with to lower case and dashes only - `Workbench Should Be Listed` with timeout option - Fix `Select Existing Data Connection` in Workbench - `Wait Until Project Is Open` first waits for spinner ball to disappear - `Open Workbench` waits for workbench link, before clicking it - `Verify Cluster Settings Is Available` by `data-testid` - Increase timeout waiting to switch to/from JupyterLab console - New Storage KW: `Delete All PVC In Project From CLI` - New Common KW: `Get All Text Under Element` - New Common KW: `Get All Strings That Contain` - Removed All Tags of Product/Automation Bugs (All Suite Tests Passed) - Append to Suite 415: `Test Tags Dashboard` Signed-off-by: manosnoam --- ods_ci/tests/Resources/Common.robot | 22 +++++ .../Page/ODH/ODHDashboard/ODHDashboard.robot | 30 +++--- .../ODHDataScienceProject/Projects.resource | 20 ++-- .../ODHDataScienceProject/Storages.resource | 95 +++++++++++++------ .../Workbenches.resource | 44 +++++---- .../415__ods_dashboard_projects.robot | 63 ++++++------ 6 files changed, 164 insertions(+), 110 deletions(-) diff --git a/ods_ci/tests/Resources/Common.robot b/ods_ci/tests/Resources/Common.robot index a5395d0d0..6a4007f2d 100644 --- a/ods_ci/tests/Resources/Common.robot +++ b/ods_ci/tests/Resources/Common.robot @@ -105,6 +105,28 @@ CSS Property Value Should Be Run Keyword And Continue On Failure Should Be Equal ${actual_value} ${exp_value} END +Get All Text Under Element + [Documentation] Returns a list of all text content under an element tree, including trailing spaces + # This is usefull since Get Text ignores trailing spaces and sibling elements. + # The returned list can be evaluated with keyword: Should Contain ${text_list} Text Data + [Arguments] ${parent_element} + ${elements}= Get WebElements ${parent_element} + ${text_list}= Create List + FOR ${element} IN @{elements} + ${text}= Get Element Attribute ${element} textContent + Append To List ${text_list} ${text} + END + RETURN ${text_list} + +Get All Strings That Contain + [Documentation] Returns new list of strings, for each item in ${list_of_strings} that contains ${substring_to_search} + [Arguments] ${list_of_strings} ${substring_to_search} + ${matched_list}= Create List + FOR ${str} IN @{list_of_strings} + IF "${substring_to_search}" in "${str}" Append To List ${matched_list} ${str} + END + RETURN ${matched_list} + Page Should Contain A String In List [Documentation] Verifies that page contains at least one of the strings in text_list [Arguments] ${text_list} diff --git a/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDashboard.robot b/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDashboard.robot index 0a44452ae..6301c3b10 100644 --- a/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDashboard.robot +++ b/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDashboard.robot @@ -32,6 +32,7 @@ ${IMAGE_XP_OLD}= ${HEADER_XP}/img[contains(@class, 'odh-card__header-brand')] ${APPS_DICT_PATH_LATEST}= ods_ci/tests/Resources/Files/AppsInfoDictionary_latest.json ${SIDEBAR_TEXT_CONTAINER_XP}= //div[contains(@class,'odh-markdown-view')] ${SUCCESS_MSG_XP}= //div[@class='pf-v5-c-alert pf-m-success'] +${PAGE_TITLE_XP}= //*[@data-testid="app-page-title" and text()="Cluster settings"] ${USAGE_DATA_COLLECTION_XP}= //*[@id="usage-data-checkbox"] ${CUSTOM_IMAGE_SOFTWARE_TABLE}= //caption[contains(., "the advertised software")]/../tbody ${CUSTOM_IMAGE_PACKAGE_TABLE}= //caption[contains(., "the advertised packages")]/../tbody @@ -256,7 +257,7 @@ Load Expected Data Of RHODS Explore Section Wait Until Cards Are Loaded [Documentation] Waits until the Application cards are displayed in the page - Run Keyword And Continue On Failure Wait Until Page Contains Element + Run Keyword And Ignore Error Wait Until Page Contains Element ... xpath:${CARDS_XP} timeout=15s error="This might be caused by bug RHOAIENG-404" Get App ID From Card @@ -508,7 +509,7 @@ Verify Cluster Settings Is Available Page Should Contain Settings Menu.Navigate To Page Settings Cluster settings Capture Page Screenshot - Wait Until Page Contains Update global settings for all users timeout=30 + Wait Until Page Contains Element ${PAGE_TITLE_XP} timeout=30 Wait Until Page Contains Element ${USAGE_DATA_COLLECTION_XP} timeout=30 Verify Cluster Settings Is Not Available @@ -755,9 +756,9 @@ Get Dashboard Pods Names Get Dashboard Pod Logs [Documentation] Fetches the logs from one dashboard pod [Arguments] ${pod_name} - ${pod_logs}= Oc Get Pod Logs name=${pod_name} namespace=${APPLICATIONS_NAMESPACE} container=rhods-dashboard - ${pod_logs_lines}= Split String string=${pod_logs} separator=\n - ${n_lines}= Get Length ${pod_logs_lines} + ${pod_logs}= Oc Get Pod Logs name=${pod_name} namespace=${APPLICATIONS_NAMESPACE} container=rhods-dashboard + ${pod_logs_lines}= Split String string=${pod_logs} separator=\n + ${n_lines}= Get Length ${pod_logs_lines} Log ${pod_logs_lines}[${n_lines-3}:] IF "${pod_logs_lines}[${n_lines-1}]" == "${EMPTY}" Remove From List ${pod_logs_lines} ${n_lines-1} @@ -768,8 +769,10 @@ Get Dashboard Pod Logs Get ConfigMaps For RHODS Groups Configuration [Documentation] Returns a dictionary containing "rhods-group-config" and "groups-config" ... ConfigMaps - ${rgc_status} ${rgc_yaml}= Run Keyword And Ignore Error OpenShiftLibrary.Oc Get kind=ConfigMap name=${RHODS_GROUPS_CONFIG_CM} namespace=${APPLICATIONS_NAMESPACE} - ${gc_status} ${gc_yaml}= Run Keyword And Ignore Error OpenShiftLibrary.Oc Get kind=ConfigMap name=${GROUPS_CONFIG_CM} namespace=${APPLICATIONS_NAMESPACE} + ${rgc_status} ${rgc_yaml}= Run Keyword And Ignore Error OpenShiftLibrary.Oc Get + ... kind=ConfigMap name=${RHODS_GROUPS_CONFIG_CM} namespace=${APPLICATIONS_NAMESPACE} + ${gc_status} ${gc_yaml}= Run Keyword And Ignore Error OpenShiftLibrary.Oc Get + ... kind=ConfigMap name=${GROUPS_CONFIG_CM} namespace=${APPLICATIONS_NAMESPACE} IF $rgc_status == 'FAIL' ${rgc_yaml}= Create List ${EMPTY} END @@ -783,7 +786,7 @@ Get ConfigMaps For RHODS Groups Configuration Get Links From Switcher [Documentation] Returns the OpenShift Console and OpenShift Cluster Manager Link ${list_of_links} = Create List - ${link_elements}= Get WebElements //a[@class="pf-m-external pf-v5-c-app-launcher__menu-item" and not(starts-with(@href, '#'))] + ${link_elements} = Get WebElements //a[@class="pf-m-external pf-v5-c-app-launcher__menu-item" and not(starts-with(@href, '#'))] FOR ${ext_link} IN @{link_elements} ${href}= Get Element Attribute ${ext_link} href Append To List ${list_of_links} ${href} @@ -798,16 +801,15 @@ Maybe Wait For Dashboard Loading Spinner Page [Documentation] Detecs the loading symbol (spinner) and wait for it to disappear. ... If the spinner does not appear, the keyword ignores the error. [Arguments] ${timeout-pre}=3s ${timeout}=5s - ${do not wait for spinner}= Get Variable Value ${ODH_DASHBOARD_DO_NOT_WAIT_FOR_SPINNER_PAGE} # defaults to None if undefined IF ${do not wait for spinner} == ${true} RETURN END - + ${spinner_ball} = Set Variable xpath=//span[@class="pf-v5-c-spinner__tail-ball"] Run Keyword And Ignore Error Run Keywords - ... Wait Until Page Contains Element xpath=//span[@class="pf-v5-c-spinner__tail-ball"] timeout=${timeout-pre} + ... Wait Until Page Contains Element ${spinner_ball} timeout=${timeout-pre} ... AND - ... Wait Until Page Does Not Contain Element xpath=//span[@class="pf-v5-c-spinner__tail-ball"] timeout=${timeout} + ... Wait Until Page Does Not Contain Element ${spinner_ball} timeout=${timeout} Reload RHODS Dashboard Page [Documentation] Reload the web page and wait for RHODS Dashboard @@ -822,7 +824,7 @@ Handle Deletion Confirmation Modal [Arguments] ${item_title} ${item_type} ${press_cancel}=${FALSE} ${additional_msg}=${NONE} # Once fixed https://issues.redhat.com/browse/RHODS-9730 change the button xpath to # xpath=//button[text()="Delete ${item_type}"] - ${delete_btn_xp} Set Variable xpath=//button[contains(text(), 'Delete')] + ${delete_btn_xp} = Set Variable xpath=//button[contains(text(), 'Delete')] Wait Until Generic Modal Appears Run Keyword And Warn On Failure Page Should Contain Delete ${item_type}? Run Keyword And Warn On Failure Page Should Contain This action cannot be undone. @@ -845,7 +847,7 @@ Click Action From Actions Menu [Arguments] ${item_title} ${action} ${item_type}=${NONE} Click Element xpath=//tr[td[@data-label="Name"]//*[text()="${item_title}"]]/td[contains(@class,"-table__action")]//button[@aria-label="Kebab toggle"] # robocop: disable IF "${item_type}" != "${NONE}" - ${action}= Catenate ${action} ${item_type} + ${action} = Catenate ${action} ${item_type} END Wait Until Page Contains Element xpath=//tr[td[@data-label="Name"]//*[text()="${item_title}"]]//td//li//*[text()="${action}"] # robocop: disable Click Element xpath=//tr[td[@data-label="Name"]//*[text()="${item_title}"]]//td//li//*[text()="${action}"] diff --git a/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Projects.resource b/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Projects.resource index a44cf548d..7371463f8 100644 --- a/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Projects.resource +++ b/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Projects.resource @@ -30,7 +30,7 @@ Is Data Science Projects Page Open [Documentation] Checks if Data Science Projects home page is open. Returns TRUE or FALSE Close Generic Modal If Present ${page_open}= Run Keyword And Return Status Page Should Contain Element ${DS_PROJECT_XP} - [Return] ${page_open} + RETURN ${page_open} Open Data Science Project Details Page [Documentation] Verifies submenu Settings > "Data Science Projects" is visible @@ -78,14 +78,14 @@ Is Data Science Project Details Page Open [Arguments] ${project_title} ${page_open}= Run Keyword And Return Status ... SeleniumLibrary.Page Should Contain Element xpath=//h1[contains(text(),"${project_title}")] - [Return] ${page_open} + RETURN ${page_open} Wait Until Project Is Open [Documentation] Waits until a DS Project Details page is laoded [Arguments] ${project_title} ${timeout-pre-spinner}=3s ${timeout-spinner}=5s - Wait Until Page Contains Element xpath=//h1[contains(text(),"${project_title}")] timeout=30 Maybe Wait For Dashboard Loading Spinner Page ... timeout-pre=${timeout-pre-spinner} timeout=${timeout-spinner} + Wait Until Page Contains Element xpath=//h1[contains(text(),"${project_title}")] timeout=30s Project Should Be Listed [Documentation] Checks a Project is available in DS Project home page @@ -161,7 +161,7 @@ Get Openshift Namespace From Data Science Project [Arguments] ${project_title} ${rc} ${k8s_name}= Run And Return Rc And Output oc get projects -o json | jq '.items[] | select((.metadata.annotations."openshift.io/display-name" != null) and (.metadata.labels."opendatahub.io/dashboard"=="true") and (.metadata.annotations."openshift.io/display-name"=="${project_title}")) | .metadata.name' # robocop: disable ${k8s_name}= Replace String ${k8s_name} " ${EMPTY} - [Return] ${k8s_name} + RETURN ${k8s_name} Delete Data Science Projects From CLI [Documentation] Deletes the Openshift Projects using OpenshiftLibrary. @@ -290,14 +290,8 @@ Workbench Launch Link Should Be Disabled Get All Displayed Projects [Documentation] Gets all the DS projects visible in the DS Projects home page - ${projects_names}= Create List - ${elements}= Get WebElements xpath=//td[@data-label="Name"]//a - FOR ${element} IN @{elements} - # Get exact project display name (including trailing spaces) - ${name}= Get Element Attribute ${element} textContent - Append To List ${projects_names} ${name} - END - [Return] ${projects_names} + ${projects_names}= Get All Text Under Element xpath=//td[@data-label="Name"]//a + RETURN ${projects_names} Number Of Displayed Projects Should Be [Documentation] Checks the number the DS projects visible in the DS Projects home page is expected @@ -424,4 +418,4 @@ Clean Project From Workbench Resources ... ${pvc_title}=${workbench_title} Delete Workbench From CLI workbench_title=${workbench_title} ... project_title=${project_title} - Delete PVC From CLI pvc_title=${pvc_title} project_title=${project_title} + Delete PVC In Project From CLI pvc_title=${pvc_title} project_title=${project_title} diff --git a/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Storages.resource b/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Storages.resource index ca6a5f78e..dd9a97d09 100644 --- a/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Storages.resource +++ b/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Storages.resource @@ -12,9 +12,9 @@ ${STORAGE_DESCR_INPUT_XP}= xpath=//textarea[@name="create-new-storage-de ${STORAGE_SIZE_INPUT_XP}= xpath=//input[@aria-label="Input"] ${STORAGE_SIZE_PLUS_BTN_XP}= xpath=//div/button[@aria-label="Plus"] ${STORAGE_MOUNT_DIR_INPUT_XP}= xpath=//input[@aria-label="mount-path-folder-value"] -${STORAGE_WORKBENCH_SELECTOR_XP}= xpath=//div[contains(@class,"modal")]//div[contains(@class,"pf-c-select")]/ul/li +${STORAGE_WORKBENCH_SELECTOR_XP}= xpath=//div[contains(@class,"modal")]//ul/li ${STORAGE_ADD_BTN_1_XP}= ${STORAGE_SECTION_XP}//button[.="Add cluster storage"] -${STORAGE_ADD_BTN_2_XP}= xpath=//footer//button[.="Add storage"] +${STORAGE_SUBMIT_BTN_XP}= xpath=//footer//button[@data-testid="modal-submit-button"] *** Keywords *** @@ -54,10 +54,11 @@ Storage Size Should Be IF "${pvc_status_phase}" == "Pending" # PVC hasn't been bound yet - only simple text with max storage should be shown ${storage_size_el}= Set Variable - ... ${STORAGE_SECTION_XP}//tr[@class="pf-c-table__expandable-row pf-m-expanded"]/td/div[strong[text()="Size"]]/div # robocop: disable + ... ${STORAGE_SECTION_XP}//td[contains(@data-label,"Size")]//div[strong[text()="Size"]]/div # robocop: disable Wait Until Page Contains Element ${storage_size_el} timeout=20s - ${displayed_size}= Get Text ${storage_size_el} - Run Keyword And Continue On Failure Should Be Equal As Strings ${displayed_size} Max ${size}Gi + ${displayed_sizes}= Get All Text Under Element ${storage_size_el} + ${matched_sizes}= Get All Strings That Contain ${displayed_sizes} ${size}Gi + Run Keyword And Continue On Failure Should Not Be Empty ${matched_sizes} ELSE IF "${pvc_status_phase}" == "Bound" # PVC is now or had been bound already sometime in past - there is: # - a number stating current usage @@ -66,15 +67,16 @@ Storage Size Should Be # Note: it may take some time before UI updates the storage # info WRT cluster usage, look like it does so every 60s ${bound_storage_size_el}= Set Variable - ... ${STORAGE_SECTION_XP}//tr[contains(@class, "-table__expandable-row pf-m-expanded")]/td/div[strong[text()="Size"]]/div/div[3]/div # robocop: disable - Wait Until Page Contains Element ${bound_storage_size_el} timeout=80s - ${displayed_size}= Get Text ${bound_storage_size_el} - Run Keyword And Continue On Failure Should Be Equal As Strings ${displayed_size} ${size}Gi + ... ${STORAGE_SECTION_XP}//td[contains(@data-label,"Size")]//div[strong[text()="Size"]]/div/div[3]/div # robocop: disable + Wait Until Page Contains Element ${bound_storage_size_el} timeout=2m + ${displayed_sizes}= Get All Text Under Element ${bound_storage_size_el} + ${matched_sizes}= Get All Strings That Contain ${displayed_sizes} ${size}Gi + Run Keyword And Continue On Failure Should Not Be Empty ${matched_sizes} ${rc} ${oc_object_size}= Run And Return Rc And Output ... oc get pvc -n ${namespace} -o jsonpath='{.items[?(@.metadata.annotations.openshift\\.io/display-name=="${name}")].status.capacity.storage}' # robocop: disable Should Be Equal As Integers ${rc} 0 ... An error occurred during the check of PVC ${name} '.status.capacity.storage' value! - Run Keyword And Continue On Failure Should Be Equal As Strings ${oc_object_size} ${size}Gi + Run Keyword And Continue On Failure Should Contain ${oc_object_size} ${size}Gi ELSE ${error_msg}= Catenate The PVC is in a '${pvc_status_phase}' state which we don't expect for this ... scenario. We expect either 'Pending' or 'Bound' states here. Please, either complete the @@ -82,23 +84,34 @@ Storage Size Should Be Fail ${error_msg} RETURN 1 END - # This check is common for both "Pending" and "Bound" states of PVC. + # This check is common for both "Pending" and "Bound" states of PVC, and it verifies storage size directly via OC CLI ${rc} ${oc_object_size}= Run And Return Rc And Output - ... oc get pvc -n ${namespace} -o jsonpath='{.items[?(@.metadata.annotations.openshift\\.io/display-name=="${name}")].spec.resources.requests.storage}' # robocop: disable + ... oc get pvc -n ${namespace} -o jsonpath="{.items[?(@.metadata.annotations['openshift\\.io/display-name']=='${name}')].spec.resources.requests.storage}" # robocop: disable Should Be Equal As Integers ${rc} 0 ... An error occurred during the check of PVC ${name} '.spec.resources.requests.storage' value! Run Keyword And Continue On Failure Should Be Equal As Strings ${oc_object_size} ${size}Gi Create PersistentVolume Storage [Documentation] Create a PersistenVolume storage in DS Project details page - [Arguments] ${project_title} ${name} ${description} ${size} ${connected_workbench}=${NONE} ${press_cancel}=${FALSE} - Click Button ${STORAGE_ADD_BTN_1_XP} + [Arguments] ${project_title} ${name} ${description} ${size} ${connected_workbench}=${NONE} + ... ${press_cancel}=${FALSE} ${existing_storage}=${FALSE} + IF ${existing_storage} + ${storage_row_xpath}= Set Variable xpath://tr[starts-with(., '${name} ') and contains(., 'Persistent storage')] + ${existing_storage}= Run Keyword And Return Status + ... Wait Until Page Contains Element ${storage_row_xpath} + END + IF "${existing_storage}" == "${TRUE}" + Log Storage '${name}' already exists, editing storage console=True + ODHDashboard.Click Action From Actions Menu item_title=${name} action=Edit + ELSE + Click Button ${STORAGE_ADD_BTN_1_XP} + END Fill In New PV Data ${name} ${description} ${size} ${connected_workbench} IF ${press_cancel} == ${TRUE} Click Button ${GENERIC_CANCEL_BTN_XP} ELSE - Wait Until Element Is Enabled ${STORAGE_ADD_BTN_2_XP} - Click Button ${STORAGE_ADD_BTN_2_XP} + Wait Until Element Is Enabled ${STORAGE_SUBMIT_BTN_XP} + Click Button ${STORAGE_SUBMIT_BTN_XP} END Wait Until Generic Modal Disappears Wait Until Project Is Open project_title=${project_title} @@ -106,13 +119,13 @@ Create PersistentVolume Storage Fill In New PV Data [Documentation] Compiles the modal for creating a new PersistenVolume storage in DS Project details page [Arguments] ${name} ${description} ${size} ${connected_workbench}=${NONE} - ${is_storage_modal}= Run Keyword And Return Status Page Should Contain Element ${STORAGE_ADD_BTN_2_XP} + ${is_storage_modal}= Run Keyword And Return Status Page Should Contain Element ${STORAGE_SUBMIT_BTN_XP} Wait Until Page Contains Element ${STORAGE_NAME_INPUT_XP} - IF ${is_storage_modal} == ${TRUE} Run Keyword And Continue On Failure Element Should Be Disabled ${STORAGE_ADD_BTN_2_XP} + IF ${is_storage_modal} Run Keyword And Continue On Failure Element Should Be Disabled ${STORAGE_SUBMIT_BTN_XP} Clear Element Text ${STORAGE_NAME_INPUT_XP} Input Text ${STORAGE_NAME_INPUT_XP} ${name} Wait Until Page Contains Element ${STORAGE_DESCR_INPUT_XP} - IF ${is_storage_modal} == ${TRUE} Run Keyword And Continue On Failure Element Should Be Enabled ${STORAGE_ADD_BTN_2_XP} + IF ${is_storage_modal} Run Keyword And Continue On Failure Element Should Be Enabled ${STORAGE_SUBMIT_BTN_XP} Input Text ${STORAGE_DESCR_INPUT_XP} ${description} Clear Element Text ${STORAGE_SIZE_INPUT_XP} IF ${size} > 1 @@ -121,13 +134,15 @@ Fill In New PV Data END END IF "${connected_workbench}" == "${NONE}" - Log msg=you are not connecting any workbenchs to ${name} PV + Log msg=Creating PV Storage '${name}' without a Workbench console=True ELSE - Run Keyword And Continue On Failure Element Should Be Enabled xpath=//div[contains(@class,"modal")]//div[contains(@class,"pf-c-select")] + Log msg=Creating PV Storage '${name}' for Workbenches: @{connected_workbench} console=True + Run Keyword And Continue On Failure Element Should Be Enabled + ... xpath=//div[contains(@class,"modal")]//input[contains(@placeholder,"Select a workbench to connect")] FOR ${workbench_title} IN @{connected_workbench} - ${mount_dir}= Set Variable ${connected_workbench}[${workbench_title}] + ${mount_dir}= Genereta Mount Name ${workbench_title} Set Connection Between PV And Workbench ${workbench_title} ${mount_dir} - Run Keyword And Continue On Failure Element Should Be Enabled ${STORAGE_ADD_BTN_2_XP} + Run Keyword And Continue On Failure Element Should Be Enabled ${STORAGE_SUBMIT_BTN_XP} END END @@ -139,7 +154,7 @@ Set Connection Between PV And Workbench Wait Until Page Contains Element ${STORAGE_WORKBENCH_SELECTOR_XP}/button[text()="${workbench_title}"] Click Element ${STORAGE_WORKBENCH_SELECTOR_XP}/button[text()="${workbench_title}"] Wait Until Page Contains Element ${STORAGE_MOUNT_DIR_INPUT_XP} - Run Keyword And Continue On Failure Element Should Be Disabled ${STORAGE_ADD_BTN_2_XP} + Run Keyword And Continue On Failure Element Should Be Disabled ${STORAGE_SUBMIT_BTN_XP} Input Text ${STORAGE_MOUNT_DIR_INPUT_XP} ${mount_dir} Delete Storage @@ -151,13 +166,35 @@ Delete Storage Get Openshift PVC From Storage [Documentation] Retrieves the PVC resource name from Openshift given the Displayed Name in DS Project details page [Arguments] ${name} ${namespace} - ${rc} ${pvc_name}= Run And Return Rc And Output oc get pvc -n ${namespace} -o jsonpath='{.items[?(@.metadata.annotations.openshift\\.io/display-name=="${name}")].metadata.name}' - RETURN ${rc} ${pvc_name} + ${result}= Run Process + ... oc get pvc -n ${namespace} -o jsonpath\='{.items[?(@.metadata.annotations.openshift\\.io/display-name\=\="${name}")].metadata.name}' + ... shell=yes + RETURN ${result.rc} ${result.stdout} -Delete PVC From CLI - [Documentation] Deletes a given PVC from CLI +Delete PVC In Project From CLI + [Documentation] Deletes a single PVC in a project from CLI [Arguments] ${pvc_title} ${project_title} ${ns_name}= Get Openshift Namespace From Data Science Project project_title=${project_title} ${_} ${cr_name}= Get Openshift PVC From Storage ... name=${pvc_title} namespace=${ns_name} - Oc Delete kind=PersistentVolumeClaim name=${cr_name} namespace=${ns_name} + IF "${cr_name}" == "${EMPTY}" + Log msg=There is probably no PVC with Display Name equal to ${cr_name} + ... level=WARN + ELSE + Oc Delete kind=PersistentVolumeClaim name=${cr_name} namespace=${ns_name} + END + +Delete All PVC In Project From CLI + [Documentation] Deletes All PVCs in a project from CLI + [Arguments] ${project_title} + ${ns_name}= Get Openshift Namespace From Data Science Project project_title=${project_title} + ${result}= Run Process + ... oc delete pvc -n ${ns_name} --all shell=yes + Should Be True ${result.rc} == 0 msg=${result.stderr} + +Genereta Mount Name + [Documentation] Generate a supported mount directory name (lower case and dashes only) from string '${str}' + [Arguments] ${str} + ${str}= Replace String Using Regexp string=${str} pattern=[^a-zA-Z] replace_with=- + ${str}= Convert To Lower Case ${str.strip('-')} + RETURN ${str} diff --git a/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Workbenches.resource b/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Workbenches.resource index b05bab58b..a863c9767 100644 --- a/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Workbenches.resource +++ b/ods_ci/tests/Resources/Page/ODH/ODHDashboard/ODHDataScienceProject/Workbenches.resource @@ -155,12 +155,12 @@ Add Existing Data Connection In Workbench # Use the `Jump to section` again to move the expanded form into view Click Element //a[@href="#data-connections"] Click Element ${WORKBENCH_EXISTING_CONNECTION_RAD_XP} - Select Existing Data Connection data_connection=${data_connection} + Select Existing Data Connection In Workbench data_connection=${data_connection} -Select Existing Data Connection +Select Existing Data Connection In Workbench [Documentation] Selects the existing data connection in the workbench creation page from a dropdown list [Arguments] ${data_connection} - Click Element ${ENV_DATA_CONNECTION_SECTION_XP}//div[contains(@class,"pf-c-select")]/button + Click Element ${ENV_DATA_CONNECTION_SECTION_XP}//input[contains(@placeholder,"Select a data connection")] Wait Until Page Contains Element xpath=//ul[@role="listbox"]/li/button[text()="${data_connection}"] Click Element xpath=//ul[@role="listbox"]/li/button[text()="${data_connection}"] @@ -252,10 +252,10 @@ Select Workbench Container Size Workbench Should Be Listed [Documentation] Checks a workbench is listed in the DS Project details page - [Arguments] ${workbench_title} + [Arguments] ${workbench_title} ${timeout}=5s Run keyword And Continue On Failure ... Wait Until Page Contains Element - ... ${WORKBENCH_SECTION_XP}//td[@data-label="Name"]/*[div[text()="${workbench_title}"]] + ... ${WORKBENCH_SECTION_XP}//td[@data-label="Name"]/*[div[text()="${workbench_title}"]] timeout=${timeout} Workbench With Description Should Be Listed [Documentation] Checks a workbench with particular name and description is listed in the DS Project details page @@ -281,8 +281,6 @@ Workbench Status Should Be Status Error Icon Should Appear [Documentation] Checks if the error icon appears on the given workbench [Arguments] ${workbench_title} - Reload Page - Wait Until Project Is Open project_title=${PRJ_TITLE} Page Should Contain Element ... ${WORKBENCH_SECTION_XP}//tr[td[@data-label="Name"]/*[div[text()="${workbench_title}"]]]/td[@data-label="Status"]//p//${ERROR_ICON_XP} # robocop: disable Mouse Over ${WORKBENCH_SECTION_XP}//tr[td[@data-label="Name"]/*[div[text()="${workbench_title}"]]]/td[@data-label="Status"]//p//${ERROR_ICON_XP} # robocop: disable @@ -356,8 +354,11 @@ Launch And Access Workbench Open Workbench [Documentation] Clicks on "open" link for a given workbench [Arguments] ${workbench_title} - Click Link ${WORKBENCH_SECTION_XP}//tr[td[@data-label="Name"]/*[div[text()="${workbench_title}"]]]/td//a[text()="Open"] - Switch Window NEW + ${open_workbench_link}= Set Variable + ... ${WORKBENCH_SECTION_XP}//tr[td[@data-label="Name"]/*[div[text()="${workbench_title}"]]]/td//a[text()="Open"] + Wait Until Page Contains Element ${open_workbench_link} timeout=30s + Click Link ${open_workbench_link} + Switch Window NEW Stop Workbench [Documentation] Stops a workbench from DS Project details page @@ -422,19 +423,21 @@ Check Launched Workbench Is The Correct One Get Openshift Notebook CR From Workbench [Documentation] Retrieves name of Notebook CR corresponding to a workbench [Arguments] ${workbench_title} ${namespace} - ${rc} ${cr_name}= Run And Return Rc And Output oc get notebook -n ${namespace} -o jsonpath='{.items[?(@.metadata.annotations.openshift\\.io/display-name=="${workbench_title}")].metadata.name}' - RETURN ${rc} ${cr_name} + ${result}= Run Process + ... oc get notebook -n ${namespace} -o jsonpath\='{.items[?(@.metadata.annotations.openshift\\.io/display-name\=\="${workbench_title}")].metadata.name}' + ... shell=yes + RETURN ${result.rc} ${result.stdout} Start Workbench Should Fail [Documentation] Checks the workbench fails to start - [Arguments] ${workbench_title} + [Arguments] ${prj_title} ${workbench_title} + Wait Until Project Is Open project_title=${prj_title} ${failed}= Run Keyword And Return Status ... Wait Until Workbench Is Started workbench_title=${workbench_title} IF ${failed} != ${FALSE} Fail msg=Workbench is expected to fail starting... Run Keyword And Continue On Failure Wait Until Keyword Succeeds 30 times 2s ... Status Error Icon Should Appear workbench_title=${workbench_title} - Reload Page - Workbench Should Be Listed ${workbench_title} + Workbench Should Be Listed ${workbench_title} timeout=30s Wait Until Keyword Succeeds 20 times 2s ... Status Error Icon Should Appear workbench_title=${workbench_title} @@ -548,19 +551,18 @@ Delete Workbench From CLI ${_} ${cr_name}= Get Openshift Notebook CR From Workbench ... workbench_title=${workbench_title} namespace=${ns_name} IF "${cr_name}" == "${EMPTY}" - Log msg=There is probably no Workbench with Diplay Name equal to ${workbench_title} + Log msg=There is probably no Workbench with Display Name equal to ${workbench_title} ... level=WARN ELSE - Oc Delete kind=Notebook name=${cr_name} namespace=${ns_name} - WHILE ${TRUE} - ${_} ${cr_name}= Get Openshift Notebook CR From Workbench - ... workbench_title=${workbench_title} namespace=${ns_name} - IF "${cr_name}" == "${EMPTY}" BREAK + Oc Delete kind=Notebook name=${cr_name} namespace=${ns_name} + WHILE ${TRUE} + ${_} ${cr_name}= Get Openshift Notebook CR From Workbench + ... workbench_title=${workbench_title} namespace=${ns_name} + IF "${cr_name}" == "${EMPTY}" BREAK Sleep 5s reason=let's not overload the API END END - Get Workbench Pod [Documentation] Retrieves info of a workbench pod: namespace, CR resource name and pod definition [Arguments] ${workbench_title} ${project_title} diff --git a/ods_ci/tests/Tests/400__ods_dashboard/415__ods_dashboard_projects/415__ods_dashboard_projects.robot b/ods_ci/tests/Tests/400__ods_dashboard/415__ods_dashboard_projects/415__ods_dashboard_projects.robot index 6ec24d3e5..ecb32c5bb 100644 --- a/ods_ci/tests/Tests/400__ods_dashboard/415__ods_dashboard_projects/415__ods_dashboard_projects.robot +++ b/ods_ci/tests/Tests/400__ods_dashboard/415__ods_dashboard_projects/415__ods_dashboard_projects.robot @@ -10,7 +10,7 @@ Resource ../../../Resources/Page/ODH/ODHDashboard/ODHDataScienceProjec Suite Setup Project Suite Setup Suite Teardown Project Suite Teardown Test Setup Launch Data Science Project Main Page - +Test Tags Dashboard *** Variables *** ${PRJ_TITLE}= ODS-CI Common Prj @@ -108,9 +108,6 @@ Verify User Can Create A Data Science Project [Tags] Smoke Sanity ODS-1775 Tier1 [Documentation] Verifies users can create a DS project Open Data Science Projects Home Page - # Create Data Science Project title=${PRJ_TITLE} description=${PRJ_DESCRIPTION} - # ... resource_name=${PRJ_RESOURCE_NAME} - # Open Data Science Projects Home Page Log message=DS Project creation covered by the Suite Setup Project Should Be Listed project_title=${PRJ_TITLE} Project's Owner Should Be expected_username=${TEST_USER_3.USERNAME} project_title=${PRJ_TITLE} @@ -121,8 +118,8 @@ Verify User Can Create And Start A Workbench With Existent PV Storage [Documentation] Verifies users can create a workbench and connect an existent PersistenVolume ${pv_name}= Set Variable ${PV_BASENAME}-existent Open Data Science Project Details Page project_title=${PRJ_TITLE} - Create PersistentVolume Storage name=${pv_name} description=${PV_DESCRIPTION} - ... size=${PV_SIZE} connected_workbench=${NONE} project_title=${PRJ_TITLE} + Create PersistentVolume Storage name=${pv_name} description=${PV_DESCRIPTION} project_title=${PRJ_TITLE} + ... size=${PV_SIZE} connected_workbench=${NONE} existing_storage=${TRUE} Create Workbench workbench_title=${WORKBENCH_2_TITLE} workbench_description=${WORKBENCH_2_DESCRIPTION} ... prj_title=${PRJ_TITLE} image_name=${NB_IMAGE} deployment_size=Small ... storage=Persistent pv_existent=${TRUE} pv_name=${pv_name} pv_description=${NONE} pv_size=${NONE} @@ -136,23 +133,30 @@ Verify User Can Create And Start A Workbench With Existent PV Storage Verify User Can Create A PV Storage [Tags] Sanity Tier1 ODS-1819 - ... AutomationBug [Documentation] Verifies users can Create PersistentVolume Storage ... THIS MUST BE UPDATED TO CHECK WORKBENCH GETS RESTARTED LIKE FOR ODS-1825. ... MAIN GOAL OF THE TEST CASE IS COVERED BY ODS-1814 ${pv_name}= Set Variable ${PV_BASENAME}-A ${ns_name}= Get Openshift Namespace From Data Science Project project_title=${PRJ_TITLE} Open Data Science Project Details Page project_title=${PRJ_TITLE} - ${workbenches}= Create Dictionary ${WORKBENCH_TITLE}=mount-data - Create PersistentVolume Storage name=${pv_name} description=${PV_DESCRIPTION} - ... size=${PV_SIZE} connected_workbench=${NONE} press_cancel=${TRUE} - ... project_title=${PRJ_TITLE} - Create PersistentVolume Storage name=${pv_name} description=${PV_DESCRIPTION} - ... size=${PV_SIZE} connected_workbench=${workbenches} project_title=${PRJ_TITLE} + Create Workbench workbench_title=${WORKBENCH_TITLE} workbench_description=${WORKBENCH_DESCRIPTION} + ... prj_title=${PRJ_TITLE} image_name=${NB_IMAGE} deployment_size=Small + ... storage=Persistent pv_existent=${NONE} + ... pv_name=${NONE} pv_description=${NONE} pv_size=${NONE} + ${workbenches}= Create List ${WORKBENCH_TITLE} + Create PersistentVolume Storage name=${pv_name} description=${PV_DESCRIPTION} project_title=${PRJ_TITLE} + ... size=${PV_SIZE} connected_workbench=${NONE} press_cancel=${TRUE} + Create PersistentVolume Storage name=${pv_name} description=${PV_DESCRIPTION} project_title=${PRJ_TITLE} + ... size=${PV_SIZE} connected_workbench=${workbenches} existing_storage=${TRUE} Storage Should Be Listed name=${pv_name} description=${PV_DESCRIPTION} ... type=Persistent storage connected_workbench=${workbenches} Check Corresponding PersistentVolumeClaim Exists storage_name=${pv_name} namespace=${ns_name} Storage Size Should Be name=${pv_name} namespace=${ns_name} size=${PV_SIZE} + [Teardown] Run Keywords + ... Clean Project From Workbench Resources workbench_title=${WORKBENCH_TITLE} + ... project_title=${PRJ_TITLE} pvc_title=${pv_name} + ... AND + ... Delete All PVC In Project From CLI project_title=${PRJ_TITLE} Verify User Can Create And Start A Workbench Adding A New PV Storage [Tags] Smoke Sanity ODS-1816 Tier1 ExcludeOnDisconnected @@ -219,7 +223,7 @@ Verify User Can Create A S3 Data Connection And Connect It To Workbenches ... aws_s3_endpoint=${DC_S3_ENDPOINT} aws_region=${DC_S3_REGION} ... connected_workbench=${workbenches} Data Connection Should Be Listed name=${DC_2_S3_NAME} type=${DC_S3_TYPE} connected_workbench=${workbenches} - Run Keyword And Continue On Failure Workbench Status Should Be workbench_title=${WORKBENCH_TITLE} + Run Keyword And Ignore Error Wait Until Workbench Is Started workbench_title=${WORKBENCH_TITLE} ... status=${WORKBENCH_STATUS_STARTING} Run Keyword And Continue On Failure Wait Until Workbench Is Started workbench_title=${WORKBENCH_TITLE} Workbench Status Should Be workbench_title=${WORKBENCH_2_TITLE} status=${WORKBENCH_STATUS_STOPPED} @@ -258,9 +262,7 @@ Verify User Can Delete A Data Connection Verify user can create a workbench with an existing data connection [Tags] Tier1 ODS-2176 [Documentation] Verifies users can create a workbench with an existing data connection - ${data_connection_name}= Set Variable aDataConnection - Open Data Science Project Details Page project_title=${PRJ_TITLE} Create S3 Data Connection project_title=${PRJ_TITLE} ... dc_name=${data_connection_name} @@ -276,7 +278,7 @@ Verify user can create a workbench with an existing data connection # The Workbench and the Data connection appear on the project details page. Workbench Should Be Listed workbench_title=${WORKBENCH_TITLE} # The data connection has the workbench name in the "Connected workbenches" column - ${workbenches}= Create Dictionary ${WORKBENCH_TITLE}=mount-data + ${workbenches}= Create List ${WORKBENCH_TITLE} Data Connection Should Be Listed name=${data_connection_name} type=${DC_S3_TYPE} ... connected_workbench=${workbenches} @@ -310,7 +312,6 @@ Verify User Can Create Environment Variables By Uploading YAML Secret/ConfigMap ... ODS-1883 [Documentation] Verify user can set environment varibles in their workbenches by ... uploading a yaml Secret or Config Map file. - ... ProductBug: RHODS-8249 ${envs_var_secret}= Create Dictionary filepath=${ENV_SECRET_FILEPATH} ... k8s_type=Secret input_type=${UPLOAD_TYPE} ${envs_var_cm}= Create Dictionary filepath=${ENV_CM_FILEPATH} @@ -340,43 +341,40 @@ Verify User Can Create Environment Variables By Uploading YAML Secret/ConfigMap ... pvc_title=${WORKBENCH_4_TITLE}-PV Verify User Can Log Out And Return To Project From Jupyter Notebook # robocop: disable - [Tags] Sanity Tier1 ODS-1971 AutomationBug + [Tags] Sanity Tier1 ODS-1971 [Documentation] Verifies user can log out and return to the project from Jupyter notebook. ... Users have 2 options: ... 1. click "File" > "Log Out" to actually close the login session ... 2. click "File" > "Hub Control Panel" to return to project details page - ... AutomationBug: JupyterLibrary's log out keyword seems to be broken - [Setup] Run Keywords - ... Open Data Science Project Details Page project_title=${PRJ_TITLE} - ... AND - ... Create Workbench workbench_title=${WORKBENCH_TITLE} workbench_description=${WORKBENCH_DESCRIPTION} + Open Data Science Project Details Page project_title=${PRJ_TITLE} + Create Workbench workbench_title=${WORKBENCH_TITLE} workbench_description=${WORKBENCH_DESCRIPTION} ... prj_title=${PRJ_TITLE} image_name=${NB_IMAGE} deployment_size=Small ... storage=Persistent pv_name=${NONE} pv_existent=${NONE} ... pv_description=${NONE} pv_size=${NONE} ... press_cancel=${FALSE} envs=${NONE} - ... AND - ... Wait Until Workbench Is Started workbench_title=${WORKBENCH_TITLE} + Wait Until Workbench Is Started workbench_title=${WORKBENCH_TITLE} Open Workbench workbench_title=${WORKBENCH_TITLE} Run Keyword And Continue On Failure ... Log In Should Be Requested Access To Workbench username=${TEST_USER_3.USERNAME} password=${TEST_USER_3.PASSWORD} ... auth_type=${TEST_USER_3.AUTH_TYPE} Open JupyterLab Control Panel - Wait Until Project Is Open project_title=${PRJ_TITLE} + Wait Until Project Is Open project_title=${PRJ_TITLE} timeout-pre-spinner=1m timeout-spinner=2m Workbench Status Should Be workbench_title=${WORKBENCH_TITLE} ... status=${WORKBENCH_STATUS_RUNNING} Open Workbench workbench_title=${WORKBENCH_TITLE} Run Keyword And Continue On Failure ... Log In Should Not Be Requested - Wait Until JupyterLab Is Loaded + Wait Until JupyterLab Is Loaded timeout=2m Logout JupyterLab - Wait Until Project Is Open project_title=${PRJ_TITLE} + Wait Until Project Is Open project_title=${PRJ_TITLE} timeout-pre-spinner=1m timeout-spinner=2m Workbench Status Should Be workbench_title=${WORKBENCH_TITLE} ... status=${WORKBENCH_STATUS_RUNNING} Open Workbench workbench_title=${WORKBENCH_TITLE} Run Keyword And Continue On Failure ... Log In Should Be Requested - [Teardown] Stop Workbench workbench_title=${WORKBENCH_TITLE} + [Teardown] Clean Project From Workbench Resources workbench_title=${WORKBENCH_TITLE} + ... project_title=${PRJ_TITLE} Verify Event Log Is Accessible While Starting A Workbench [Tags] Tier1 Sanity @@ -431,7 +429,6 @@ Verify User Can Cancel Workbench Start From Event Log Verify Error Is Reported When Workbench Fails To Start # robocop: disable [Tags] Tier1 Sanity ... ODS-1973 - ... AutomationBug [Documentation] Verify UI informs users about workbenches failed to start. ... At the moment the test is considering only the scenario where ... the workbench fails for Insufficient resources. @@ -444,7 +441,7 @@ Verify Error Is Reported When Workbench Fails To Start # robocop: disable ... press_cancel=${FALSE} envs=${NONE} Workbench Status Should Be workbench_title=${WORKBENCH_5_TITLE} ... status=${WORKBENCH_STATUS_STARTING} - Start Workbench Should Fail workbench_title=${WORKBENCH_5_TITLE} + Start Workbench Should Fail prj_title=${PRJ_TITLE} workbench_title=${WORKBENCH_5_TITLE} Open Notebook Event Log workbench_title=${WORKBENCH_5_TITLE} ... exp_preview_text=Insufficient Event Log Should Report The Failure exp_progress_text=Insufficient resources to start @@ -592,6 +589,7 @@ Project Suite Setup ${to_delete}= Create List ${PRJ_TITLE} Set Suite Variable ${PROJECTS_TO_DELETE} ${to_delete} RHOSi Setup + Delete Data Science Projects From CLI ocp_projects=${PROJECTS_TO_DELETE} Launch Data Science Project Main Page Create Data Science Project title=${PRJ_TITLE} description=${PRJ_DESCRIPTION} ... resource_name=${PRJ_RESOURCE_NAME} @@ -600,7 +598,6 @@ Project Suite Teardown [Documentation] Suite teardown steps after testing DS Projects. It Deletes ... all the DS projects created by the tests and run RHOSi teardown SeleniumLibrary.Close All Browsers - # Delete All Data Science Projects From CLI Delete Data Science Projects From CLI ocp_projects=${PROJECTS_TO_DELETE} RHOSi Teardown