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