From 1c00a3e4a74c6da068bb5e5eaf2e938d8a81bc50 Mon Sep 17 00:00:00 2001 From: szymon-kellton <130459593+szymon-kellton@users.noreply.github.com> Date: Tue, 14 May 2024 13:04:06 +0200 Subject: [PATCH] Selenium: Targeting smoke tests (#3822) * Init * Added test_smoke_targeting_details_page * Added creation page smoke tests * Edited ci.yml * Black * Fixes after conflicts * Update ci.yml * Upgrade helper.py * mypy fix --- .github/workflows/ci.yml | 2 +- backend/selenium_tests/helpers/helper.py | 8 +- .../page_object/targeting/create_new.py | 87 ++++++++++++ .../page_object/targeting/t_details_page.py | 130 ++++++++++++++++++ .../page_object/targeting/targeting.py | 66 +++------ .../page_object/targeting/targeting_create.py | 77 ++++++++++- .../targeting/targeting_details.py | 129 ++++++++++++++++- ..._create_targeting.py => test_targeting.py} | 105 ++++++++++++++ .../selenium_tests/tools/tag_name_finder.py | 29 ++-- 9 files changed, 569 insertions(+), 64 deletions(-) create mode 100644 backend/selenium_tests/page_object/targeting/create_new.py create mode 100644 backend/selenium_tests/page_object/targeting/t_details_page.py rename backend/selenium_tests/targeting/{test_create_targeting.py => test_targeting.py} (57%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 564061536c..c3308685c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -316,4 +316,4 @@ jobs: echo "Failed to trigger deploy for pipeline $pipeline" exit 1 fi - done \ No newline at end of file + done diff --git a/backend/selenium_tests/helpers/helper.py b/backend/selenium_tests/helpers/helper.py index 1e368da1d9..35f75fa1fb 100644 --- a/backend/selenium_tests/helpers/helper.py +++ b/backend/selenium_tests/helpers/helper.py @@ -20,6 +20,11 @@ def __init__(self, driver: Chrome): def _wait(self, timeout: int = DEFAULT_TIMEOUT) -> WebDriverWait: return WebDriverWait(self.driver, timeout) + @staticmethod + def _wait_using_element(element: WebElement, timeout: int = DEFAULT_TIMEOUT) -> WebDriverWait: + # find and wait only in other element area (instead of whole driver) + return WebDriverWait(element, timeout) + def get(self, locator: str, element_type: str = By.CSS_SELECTOR) -> WebElement: return self.driver.find_element(element_type, locator) @@ -56,8 +61,9 @@ def select_listbox_element( items = select_element.find_elements("tag name", tag_name) for item in items: if name in item.text: + self._wait().until(EC.element_to_be_clickable((By.XPATH, f"//*[contains(text(), '{name}')]"))) return item - return select_element + raise AssertionError(f"Element: {name} is not in the list.") def check_page_after_click(self, button: WebElement, url_fragment: str) -> None: programme_creation_url = self.driver.current_url diff --git a/backend/selenium_tests/page_object/targeting/create_new.py b/backend/selenium_tests/page_object/targeting/create_new.py new file mode 100644 index 0000000000..ead99a221b --- /dev/null +++ b/backend/selenium_tests/page_object/targeting/create_new.py @@ -0,0 +1,87 @@ +from page_object.base_components import BaseComponents +from selenium.webdriver.remote.webelement import WebElement + + +class CreateNew(BaseComponents): + pageHeaderContainer = 'div[data-cy="page-header-container"]' + pageHeaderTitle = 'h5[data-cy="page-header-title"]' + buttonTargetPopulationCreate = 'button[data-cy="button-target-population-create"]' + inputDivName = 'div[data-cy="input-name"]' + inputIncludedHouseholdIds = 'div[data-cy="input-included-household-ids"]' + inputHouseholdids = 'input[data-cy="input-householdIds"]' + inputIncludedIndividualIds = 'div[data-cy="input-included-individual-ids"]' + inputIndividualids = 'input[data-cy="input-individualIds"]' + inputFlagexcludeifactiveadjudicationticket = 'span[data-cy="input-flagExcludeIfActiveAdjudicationTicket"]' + inputName = 'input[data-cy="input-name"]' + + pageHeaderContainer = 'div[data-cy="page-header-container"]' + pageHeaderTitle = 'h5[data-cy="page-header-title"]' + buttonTargetPopulationCreate = 'button[data-cy="button-target-population-create"]' + divTargetPopulationAddCriteria = 'div[data-cy="button-target-population-add-criteria"]' + inputFlagexcludeifactiveadjudicationticket = 'span[data-cy="input-flagExcludeIfActiveAdjudicationTicket"]' + titleExcludedEntries = 'h6[data-cy="title-excluded-entries"]' + buttonShowHideExclusions = 'button[data-cy="button-show-hide-exclusions"]' + inputExcludedIds = 'div[data-cy="input-excluded-ids"]' + inputExcludedids = 'input[data-cy="input-excludedIds"]' + inputExclusionReason = 'div[data-cy="input-exclusion-reason"]' + titleAddFilter = 'h6[data-cy="title-add-filter"]' + autocompleteTargetCriteria = 'div[data-cy="autocomplete-target-criteria"]' + fieldChooserFilters = 'div[data-cy="field-chooser-filters[0]"]' + autocompleteTargetCriteriaOption = 'input[data-cy="autocomplete-target-criteria-option-0"]' + buttonHouseholdRule = 'button[data-cy="button-household-rule"]' + buttonIndividualRule = 'button[data-cy="button-individual-rule"]' + buttonTargetPopulationAddCriteria = 'button[data-cy="button-target-population-add-criteria"]' + + def getPageHeaderTitle(self) -> WebElement: + return self.wait_for(self.pageHeaderTitle) + + def getButtonTargetPopulationCreate(self) -> WebElement: + return self.wait_for(self.buttonTargetPopulationCreate) + + def getInputName(self) -> WebElement: + return self.wait_for(self.inputName) + + def getInputIncludedHouseholdIds(self) -> WebElement: + return self.wait_for(self.inputIncludedHouseholdIds) + + def getInputHouseholdids(self) -> WebElement: + return self.wait_for(self.inputHouseholdids) + + def getInputIncludedIndividualIds(self) -> WebElement: + return self.wait_for(self.inputIncludedIndividualIds) + + def getInputIndividualids(self) -> WebElement: + return self.wait_for(self.inputIndividualids) + + def getInputFlagexcludeifactiveadjudicationticket(self) -> WebElement: + return self.wait_for(self.inputFlagexcludeifactiveadjudicationticket) + + def getButtonTargetPopulationAddCriteria(self) -> WebElement: + return self.wait_for(self.buttonTargetPopulationAddCriteria) + + def getDivTargetPopulationAddCriteria(self) -> WebElement: + return self.wait_for(self.divTargetPopulationAddCriteria) + + def getTitleExcludedEntries(self) -> WebElement: + return self.wait_for(self.titleExcludedEntries) + + def getButtonShowHideExclusions(self) -> WebElement: + return self.wait_for(self.buttonShowHideExclusions) + + def getInputExcludedIds(self) -> WebElement: + return self.wait_for(self.inputExcludedIds) + + def getInputExcludedids(self) -> WebElement: + return self.wait_for(self.inputExcludedids) + + def getInputExclusionReason(self) -> WebElement: + return self.wait_for(self.inputExclusionReason) + + def getButtonHouseholdRule(self) -> WebElement: + return self.wait_for(self.buttonHouseholdRule) + + def getButtonIndividualRule(self) -> WebElement: + return self.wait_for(self.buttonIndividualRule) + + def getAutocompleteTargetCriteriaOption(self) -> WebElement: + return self.wait_for(self.autocompleteTargetCriteriaOption) diff --git a/backend/selenium_tests/page_object/targeting/t_details_page.py b/backend/selenium_tests/page_object/targeting/t_details_page.py new file mode 100644 index 0000000000..edf2795c02 --- /dev/null +++ b/backend/selenium_tests/page_object/targeting/t_details_page.py @@ -0,0 +1,130 @@ +from page_object.base_components import BaseComponents +from selenium.webdriver.remote.webelement import WebElement + + +class DetailsTargeting(BaseComponents): + pageHeaderContainer = 'div[data-cy="page-header-container"]' + pageHeaderTitle = 'h5[data-cy="page-header-title"]' + buttonTargetPopulationDuplicate = 'button[data-cy="button-target-population-duplicate"]' + buttonDelete = 'button[data-cy="button-delete"]' + buttonEdit = 'a[data-cy="button-edit"]' + buttonRebuild = 'button[data-cy="button-rebuild"]' + buttonTargetPopulationLock = 'button[data-cy="button-target-population-lock"]' + detailsTitle = 'div[data-cy="details-title"]' + detailsGrid = 'div[data-cy="details-grid"]' + labelStatus = 'div[data-cy="label-Status"]' + targetPopulationStatus = 'div[data-cy="target-population-status"]' + labelizedFieldContainerCreatedBy = 'div[data-cy="labelized-field-container-created-by"]' + labelCreatedBy = 'div[data-cy="label-created by"]' + labelizedFieldContainerCloseDate = 'div[data-cy="labelized-field-container-close-date"]' + labelProgrammePopulationCloseDate = 'div[data-cy="label-Programme population close date"]' + labelizedFieldContainerProgramName = 'div[data-cy="labelized-field-container-program-name"]' + labelProgramme = 'div[data-cy="label-Programme"]' + labelizedFieldContainerSendBy = 'div[data-cy="labelized-field-container-send-by"]' + labelSendBy = 'div[data-cy="label-Send by"]' + labelizedFieldContainerSendDate = 'div[data-cy="labelized-field-container-send-date"]' + labelSendDate = 'div[data-cy="label-Send date"]' + criteriaContainer = 'div[data-cy="criteria-container"]' + checkboxExcludeIfActiveAdjudicationTicket = 'span[data-cy="checkbox-exclude-if-active-adjudication-ticket"]' + labelFemaleChildren = 'div[data-cy="label-Female Children"]' + labelFemaleAdults = 'div[data-cy="label-Female Adults"]' + labelMaleChildren = 'div[data-cy="label-Male Children"]' + labelMaleAdults = 'div[data-cy="label-Male Adults"]' + labelTotalNumberOfHouseholds = 'div[data-cy="label-Total Number of Households"]' + labelTargetedIndividuals = 'div[data-cy="label-Targeted Individuals"]' + tableTitle = 'h6[data-cy="table-title"]' + tableLabel = 'span[data-cy="table-label"]' + tablePagination = 'div[data-cy="table-pagination"]' + + def getPageHeaderTitle(self) -> WebElement: + return self.wait_for(self.pageHeaderTitle) + + def getButtonTargetPopulationDuplicate(self) -> WebElement: + return self.wait_for(self.buttonTargetPopulationDuplicate) + + def getButtonDelete(self) -> WebElement: + return self.wait_for(self.buttonDelete) + + def getButtonEdit(self) -> WebElement: + return self.wait_for(self.buttonEdit) + + def getButtonRebuild(self) -> WebElement: + return self.wait_for(self.buttonRebuild) + + def getButtonTargetPopulationLock(self) -> WebElement: + return self.wait_for(self.buttonTargetPopulationLock) + + def getDetailsTitle(self) -> WebElement: + return self.wait_for(self.detailsTitle) + + def getDetailsGrid(self) -> WebElement: + return self.wait_for(self.detailsGrid) + + def getLabelStatus(self) -> WebElement: + return self.wait_for(self.labelStatus) + + def getTargetPopulationStatus(self) -> WebElement: + return self.wait_for(self.targetPopulationStatus) + + def getLabelizedFieldContainerCreatedBy(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerCreatedBy) + + def getLabelCreatedBy(self) -> WebElement: + return self.wait_for(self.labelCreatedBy) + + def getLabelizedFieldContainerCloseDate(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerCloseDate) + + def getLabelProgrammePopulationCloseDate(self) -> WebElement: + return self.wait_for(self.labelProgrammePopulationCloseDate) + + def getLabelizedFieldContainerProgramName(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerProgramName) + + def getLabelProgramme(self) -> WebElement: + return self.wait_for(self.labelProgramme) + + def getLabelizedFieldContainerSendBy(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerSendBy) + + def getLabelSendBy(self) -> WebElement: + return self.wait_for(self.labelSendBy) + + def getLabelizedFieldContainerSendDate(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerSendDate) + + def getLabelSendDate(self) -> WebElement: + return self.wait_for(self.labelSendDate) + + def getCriteriaContainer(self) -> WebElement: + return self.wait_for(self.criteriaContainer) + + def getCheckboxExcludeIfActiveAdjudicationTicket(self) -> WebElement: + return self.wait_for(self.checkboxExcludeIfActiveAdjudicationTicket) + + def getLabelFemaleChildren(self) -> WebElement: + return self.wait_for(self.labelFemaleChildren) + + def getLabelFemaleAdults(self) -> WebElement: + return self.wait_for(self.labelFemaleAdults) + + def getLabelMaleChildren(self) -> WebElement: + return self.wait_for(self.labelMaleChildren) + + def getLabelMaleAdults(self) -> WebElement: + return self.wait_for(self.labelMaleAdults) + + def getLabelTotalNumberOfHouseholds(self) -> WebElement: + return self.wait_for(self.labelTotalNumberOfHouseholds) + + def getLabelTargetedIndividuals(self) -> WebElement: + return self.wait_for(self.labelTargetedIndividuals) + + def getTableTitle(self) -> WebElement: + return self.wait_for(self.tableTitle) + + def getTableLabel(self) -> WebElement: + return self.get_elements(self.tableLabel) + + def getTablePagination(self) -> WebElement: + return self.wait_for(self.tablePagination) diff --git a/backend/selenium_tests/page_object/targeting/targeting.py b/backend/selenium_tests/page_object/targeting/targeting.py index e60742905d..6191b89369 100644 --- a/backend/selenium_tests/page_object/targeting/targeting.py +++ b/backend/selenium_tests/page_object/targeting/targeting.py @@ -1,3 +1,5 @@ +from time import sleep + from page_object.base_components import BaseComponents from selenium.webdriver.remote.webelement import WebElement @@ -18,6 +20,8 @@ class Targeting(BaseComponents): tabColumnLabel = 'span[data-cy="table-label"]' statusOptions = 'li[role="option"]' rows = 'tr[role="checkbox"]' + createUserFilters = 'div[data-cy="menu-item-filters-text"]' + createUseIDs = 'div[data-cy="menu-item-ids-text"]' # Texts @@ -70,23 +74,8 @@ def getButtonCreateNewByFilters(self) -> WebElement: def getTabTitle(self) -> WebElement: return self.wait_for(self.tabTitle) - def getTabColumnName(self) -> WebElement: - return self.wait_for(self.tabColumnLabel).eq(0) - - def getTabColumnStatus(self) -> WebElement: - return self.wait_for(self.tabColumnLabel).eq(1) - - def getTabColumnNOHouseholds(self) -> WebElement: - return self.wait_for(self.tabColumnLabel).eq(2) - - def getTabColumnDateCreated(self) -> WebElement: - return self.wait_for(self.tabColumnLabel).eq(3) - - def getTabColumnLastEdited(self) -> WebElement: - return self.wait_for(self.tabColumnLabel).eq(4) - - def getTabColumnCreatedBy(self) -> WebElement: - return self.wait_for(self.tabColumnLabel).eq(5) + def getTabColumnLabel(self) -> list[WebElement]: + return self.get_elements(self.tabColumnLabel) def getStatusOption(self) -> WebElement: return self.wait_for(self.statusOptions) @@ -97,30 +86,19 @@ def getApply(self) -> WebElement: def getClear(self) -> WebElement: return self.wait_for(self.buttonClear) - def getTargetPopulationsRows(self) -> WebElement: - return self.wait_for(self.rows) - - def checkElementsOnPage(self) -> None: - self.getTitlePage().should("be.visible").contains(self.textTitlePage) - # self.getButtonFiltersExpand().click() - self.getSearchFilter().should("be.visible") - self.getStatusFilter().should("be.visible") - self.getMinNumberOfHouseholdsFilter().should("be.visible") - self.getMaxNumberOfHouseholdsFilter().should("be.visible") - self.getButtonCreateNew().should("be.visible").contains(self.textCreateNew) - self.getTabTitle().should("be.visible").contains(self.textTabTitle) - self.getTabColumnName().should("be.visible").contains(self.textTabName) - self.getTabColumnStatus().should("be.visible").contains(self.textTabStatus) - self.getTabColumnNOHouseholds() - self.getTabColumnDateCreated() - self.getTabColumnLastEdited() - self.getTabColumnCreatedBy() - - def selectStatus(self, status: str) -> None: - self.getStatusFilter().click() - self.getStatusOption().contains(status).click() - self.pressEscapeFromElement(self.getStatusOption().contains(status)) - self.getApply().click() - - def chooseTargetPopulationRow(self, row: int) -> WebElement: - return self.getTargetPopulationsRows().eq(row) + def getTargetPopulationsRows(self) -> list[WebElement]: + return self.get_elements(self.rows) + + def chooseTargetPopulations(self, number: int) -> WebElement: + try: + self.wait_for(self.rows) + return self.get_elements(self.rows)[number] + except IndexError: + sleep(1) + return self.get_elements(self.rows)[number] + + def getCreateUseFilters(self) -> WebElement: + return self.wait_for(self.createUserFilters) + + def getCreateUseIDs(self) -> WebElement: + return self.wait_for(self.createUseIDs) diff --git a/backend/selenium_tests/page_object/targeting/targeting_create.py b/backend/selenium_tests/page_object/targeting/targeting_create.py index b530446a26..e77c2408f1 100644 --- a/backend/selenium_tests/page_object/targeting/targeting_create.py +++ b/backend/selenium_tests/page_object/targeting/targeting_create.py @@ -16,10 +16,85 @@ class TargetingCreate(BaseComponents): targetingCriteriaAddDialogSaveButton = 'button[data-cy="button-target-population-add-criteria"]' criteriaContainer = 'div[data-cy="criteria-container"]' targetPopulationSaveButton = 'button[data-cy="button-target-population-create"]' + pageHeaderContainer = 'div[data-cy="page-header-container"]' + pageHeaderTitle = 'h5[data-cy="page-header-title"]' + buttonTargetPopulationCreate = 'button[data-cy="button-target-population-create"]' + inputDivName = 'div[data-cy="input-name"]' + inputIncludedHouseholdIds = 'div[data-cy="input-included-household-ids"]' + inputHouseholdids = 'input[data-cy="input-householdIds"]' + inputIncludedIndividualIds = 'div[data-cy="input-included-individual-ids"]' + inputIndividualids = 'input[data-cy="input-individualIds"]' + inputFlagexcludeifactiveadjudicationticket = 'span[data-cy="input-flagExcludeIfActiveAdjudicationTicket"]' + inputName = 'input[data-cy="input-name"]' + divTargetPopulationAddCriteria = 'div[data-cy="button-target-population-add-criteria"]' + titleExcludedEntries = 'h6[data-cy="title-excluded-entries"]' + buttonShowHideExclusions = 'button[data-cy="button-show-hide-exclusions"]' + inputExcludedIds = 'div[data-cy="input-excluded-ids"]' + inputExcludedids = 'input[data-cy="input-excludedIds"]' + inputExclusionReason = 'div[data-cy="input-exclusion-reason"]' + titleAddFilter = 'h6[data-cy="title-add-filter"]' + autocompleteTargetCriteria = 'div[data-cy="autocomplete-target-criteria"]' + fieldChooserFilters = 'div[data-cy="field-chooser-filters[0]"]' + autocompleteTargetCriteriaOption = 'input[data-cy="autocomplete-target-criteria-option-0"]' + buttonHouseholdRule = 'button[data-cy="button-household-rule"]' + buttonIndividualRule = 'button[data-cy="button-individual-rule"]' + buttonTargetPopulationAddCriteria = 'button[data-cy="button-target-population-add-criteria"]' # Texts textTargetingCriteria = "Targeting Criteria" - # Elements + def getPageHeaderTitle(self) -> WebElement: + return self.wait_for(self.pageHeaderTitle) + + def getButtonTargetPopulationCreate(self) -> WebElement: + return self.wait_for(self.buttonTargetPopulationCreate) + + def getInputName(self) -> WebElement: + return self.wait_for(self.inputName) + + def getInputIncludedHouseholdIds(self) -> WebElement: + return self.wait_for(self.inputIncludedHouseholdIds) + + def getInputHouseholdids(self) -> WebElement: + return self.wait_for(self.inputHouseholdids) + + def getInputIncludedIndividualIds(self) -> WebElement: + return self.wait_for(self.inputIncludedIndividualIds) + + def getInputIndividualids(self) -> WebElement: + return self.wait_for(self.inputIndividualids) + + def getInputFlagexcludeifactiveadjudicationticket(self) -> WebElement: + return self.wait_for(self.inputFlagexcludeifactiveadjudicationticket) + + def getButtonTargetPopulationAddCriteria(self) -> WebElement: + return self.wait_for(self.buttonTargetPopulationAddCriteria) + + def getDivTargetPopulationAddCriteria(self) -> WebElement: + return self.wait_for(self.divTargetPopulationAddCriteria) + + def getTitleExcludedEntries(self) -> WebElement: + return self.wait_for(self.titleExcludedEntries) + + def getButtonShowHideExclusions(self) -> WebElement: + return self.wait_for(self.buttonShowHideExclusions) + + def getInputExcludedIds(self) -> WebElement: + return self.wait_for(self.inputExcludedIds) + + def getInputExcludedids(self) -> WebElement: + return self.wait_for(self.inputExcludedids) + + def getInputExclusionReason(self) -> WebElement: + return self.wait_for(self.inputExclusionReason) + + def getButtonHouseholdRule(self) -> WebElement: + return self.wait_for(self.buttonHouseholdRule) + + def getButtonIndividualRule(self) -> WebElement: + return self.wait_for(self.buttonIndividualRule) + + def getAutocompleteTargetCriteriaOption(self) -> WebElement: + return self.wait_for(self.autocompleteTargetCriteriaOption) def getTargetingCriteria(self) -> WebElement: return self.wait_for(self.targetingCriteria) diff --git a/backend/selenium_tests/page_object/targeting/targeting_details.py b/backend/selenium_tests/page_object/targeting/targeting_details.py index 41f3b80100..56625451cc 100644 --- a/backend/selenium_tests/page_object/targeting/targeting_details.py +++ b/backend/selenium_tests/page_object/targeting/targeting_details.py @@ -12,18 +12,141 @@ class TargetingDetails(BaseComponents): people_table_rows = '[data-cy="target-population-people-row"]' household_table_rows = '[data-cy="target-population-household-row"]' + pageHeaderContainer = 'div[data-cy="page-header-container"]' + pageHeaderTitle = 'h5[data-cy="page-header-title"]' + buttonTargetPopulationDuplicate = 'button[data-cy="button-target-population-duplicate"]' + buttonDelete = 'button[data-cy="button-delete"]' + buttonEdit = 'a[data-cy="button-edit"]' + buttonRebuild = 'button[data-cy="button-rebuild"]' + buttonTargetPopulationLock = 'button[data-cy="button-target-population-lock"]' + detailsTitle = 'div[data-cy="details-title"]' + detailsGrid = 'div[data-cy="details-grid"]' + labelStatus = 'div[data-cy="label-Status"]' + targetPopulationStatus = 'div[data-cy="target-population-status"]' + labelizedFieldContainerCreatedBy = 'div[data-cy="labelized-field-container-created-by"]' + labelCreatedBy = 'div[data-cy="label-created by"]' + labelizedFieldContainerCloseDate = 'div[data-cy="labelized-field-container-close-date"]' + labelProgrammePopulationCloseDate = 'div[data-cy="label-Programme population close date"]' + labelizedFieldContainerProgramName = 'div[data-cy="labelized-field-container-program-name"]' + labelProgramme = 'div[data-cy="label-Programme"]' + labelizedFieldContainerSendBy = 'div[data-cy="labelized-field-container-send-by"]' + labelSendBy = 'div[data-cy="label-Send by"]' + labelizedFieldContainerSendDate = 'div[data-cy="labelized-field-container-send-date"]' + labelSendDate = 'div[data-cy="label-Send date"]' + criteriaContainer = 'div[data-cy="criteria-container"]' + checkboxExcludeIfActiveAdjudicationTicket = 'span[data-cy="checkbox-exclude-if-active-adjudication-ticket"]' + labelFemaleChildren = 'div[data-cy="label-Female Children"]' + labelFemaleAdults = 'div[data-cy="label-Female Adults"]' + labelMaleChildren = 'div[data-cy="label-Male Children"]' + labelMaleAdults = 'div[data-cy="label-Male Adults"]' + labelTotalNumberOfHouseholds = 'div[data-cy="label-Total Number of Households"]' + labelTargetedIndividuals = 'div[data-cy="label-Targeted Individuals"]' + tableTitle = 'h6[data-cy="table-title"]' + tableLabel = 'span[data-cy="table-label"]' + tablePagination = 'div[data-cy="table-pagination"]' + # Texts # Elements + def getPageHeaderTitle(self) -> WebElement: + return self.wait_for(self.pageHeaderTitle) + + def getButtonTargetPopulationDuplicate(self) -> WebElement: + return self.wait_for(self.buttonTargetPopulationDuplicate) + + def getButtonDelete(self) -> WebElement: + return self.wait_for(self.buttonDelete) + + def getButtonEdit(self) -> WebElement: + return self.wait_for(self.buttonEdit) + + def getButtonRebuild(self) -> WebElement: + return self.wait_for(self.buttonRebuild) + + def getButtonTargetPopulationLock(self) -> WebElement: + return self.wait_for(self.buttonTargetPopulationLock) + + def getDetailsTitle(self) -> WebElement: + return self.wait_for(self.detailsTitle) + + def getDetailsGrid(self) -> WebElement: + return self.wait_for(self.detailsGrid) + + def getLabelStatus(self) -> WebElement: + return self.wait_for(self.labelStatus) + + def getTargetPopulationStatus(self) -> WebElement: + return self.wait_for(self.targetPopulationStatus) + + def getLabelizedFieldContainerCreatedBy(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerCreatedBy) + + def getLabelCreatedBy(self) -> WebElement: + return self.wait_for(self.labelCreatedBy) + + def getLabelizedFieldContainerCloseDate(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerCloseDate) + + def getLabelProgrammePopulationCloseDate(self) -> WebElement: + return self.wait_for(self.labelProgrammePopulationCloseDate) + + def getLabelizedFieldContainerProgramName(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerProgramName) + + def getLabelProgramme(self) -> WebElement: + return self.wait_for(self.labelProgramme) + + def getLabelizedFieldContainerSendBy(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerSendBy) + + def getLabelSendBy(self) -> WebElement: + return self.wait_for(self.labelSendBy) + + def getLabelizedFieldContainerSendDate(self) -> WebElement: + return self.wait_for(self.labelizedFieldContainerSendDate) + + def getLabelSendDate(self) -> WebElement: + return self.wait_for(self.labelSendDate) + + def getCriteriaContainer(self) -> WebElement: + return self.wait_for(self.criteriaContainer) + + def getCheckboxExcludeIfActiveAdjudicationTicket(self) -> WebElement: + return self.wait_for(self.checkboxExcludeIfActiveAdjudicationTicket) + + def getLabelFemaleChildren(self) -> WebElement: + return self.wait_for(self.labelFemaleChildren) + + def getLabelFemaleAdults(self) -> WebElement: + return self.wait_for(self.labelFemaleAdults) + + def getLabelMaleChildren(self) -> WebElement: + return self.wait_for(self.labelMaleChildren) + + def getLabelMaleAdults(self) -> WebElement: + return self.wait_for(self.labelMaleAdults) + + def getLabelTotalNumberOfHouseholds(self) -> WebElement: + return self.wait_for(self.labelTotalNumberOfHouseholds) + + def getLabelTargetedIndividuals(self) -> WebElement: + return self.wait_for(self.labelTargetedIndividuals) + + def getTableTitle(self) -> WebElement: + return self.wait_for(self.tableTitle) + + def getTableLabel(self) -> WebElement: + return self.get_elements(self.tableLabel) + + def getTablePagination(self) -> WebElement: + return self.wait_for(self.tablePagination) + def getTitlePage(self) -> WebElement: return self.wait_for(self.titlePage) def getStatus(self) -> WebElement: return self.wait_for(self.status) - def getCriteriaContainer(self) -> WebElement: - return self.wait_for(self.criteria_container) - def getLockButton(self) -> WebElement: return self.wait_for(self.lock_button) diff --git a/backend/selenium_tests/targeting/test_create_targeting.py b/backend/selenium_tests/targeting/test_targeting.py similarity index 57% rename from backend/selenium_tests/targeting/test_create_targeting.py rename to backend/selenium_tests/targeting/test_targeting.py index 0fe1396f29..467d213380 100644 --- a/backend/selenium_tests/targeting/test_create_targeting.py +++ b/backend/selenium_tests/targeting/test_targeting.py @@ -1,5 +1,7 @@ from datetime import datetime +from django.conf import settings +from django.core.management import call_command from django.db import transaction import pytest @@ -87,6 +89,109 @@ def get_program_with_dct_type_and_name( return program +@pytest.fixture +def create_programs() -> None: + call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/core/fixtures/data-selenium.json") + call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/program/fixtures/data-cypress.json") + return + + +@pytest.fixture +def add_targeting() -> None: + call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/household/fixtures/documenttype.json") + call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/registration_data/fixtures/data-cypress.json") + call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/household/fixtures/data-cypress.json") + call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/targeting/fixtures/data-cypress.json") + + +@pytest.mark.usefixtures("login") +class TestSmokeTargeting: + def test_smoke_targeting_page(self, create_programs: None, add_targeting: None, pageTargeting: Targeting) -> None: + pageTargeting.selectGlobalProgramFilter("Test Programm").click() + pageTargeting.getNavTargeting().click() + assert "Targeting" in pageTargeting.getTitlePage().text + assert "CREATE NEW" in pageTargeting.getButtonCreateNew().text + expected_column_names = ["Name", "Status", "Num. of Households", "Date Created", "Last Edited", "Created by"] + assert expected_column_names == [name.text for name in pageTargeting.getTabColumnLabel()] + assert 2 == len(pageTargeting.getTargetPopulationsRows()) + pageTargeting.getButtonCreateNew().click() + assert "Use Filters" in pageTargeting.getCreateUseFilters().text + assert "Use IDs" in pageTargeting.getCreateUseIDs().text + + def test_smoke_targeting_create_use_filters( + self, create_programs: None, add_targeting: None, pageTargeting: Targeting, pageTargetingCreate: TargetingCreate + ) -> None: + pageTargeting.selectGlobalProgramFilter("Test Programm").click() + pageTargeting.getNavTargeting().click() + pageTargeting.getButtonCreateNew().click() + pageTargeting.getCreateUseFilters().click() + assert "New Target Population" in pageTargetingCreate.getPageHeaderTitle().text + assert "SAVE" in pageTargetingCreate.getButtonTargetPopulationCreate().text + pageTargetingCreate.getInputName() + pageTargetingCreate.getDivTargetPopulationAddCriteria().click() + pageTargetingCreate.getButtonHouseholdRule().click() + pageTargetingCreate.getButtonIndividualRule().click() + pageTargetingCreate.getAutocompleteTargetCriteriaOption().click() + + def test_smoke_targeting_create_use_ids( + self, create_programs: None, add_targeting: None, pageTargeting: Targeting, pageTargetingCreate: TargetingCreate + ) -> None: + pageTargeting.selectGlobalProgramFilter("Test Programm").click() + pageTargeting.getNavTargeting().click() + pageTargeting.getButtonCreateNew().click() + pageTargeting.getCreateUseIDs().click() + assert "New Target Population" in pageTargetingCreate.getPageHeaderTitle().text + assert "SAVE" in pageTargetingCreate.getButtonTargetPopulationCreate().text + pageTargetingCreate.getInputName() + pageTargetingCreate.getInputIncludedHouseholdIds() + pageTargetingCreate.getInputHouseholdids() + pageTargetingCreate.getInputIncludedIndividualIds() + pageTargetingCreate.getInputIndividualids() + + def test_smoke_targeting_details_page( + self, + create_programs: None, + add_targeting: None, + pageTargeting: Targeting, + pageTargetingDetails: TargetingDetails, + ) -> None: + pageTargeting.selectGlobalProgramFilter("Test Programm").click() + pageTargeting.getNavTargeting().click() + pageTargeting.chooseTargetPopulations(0).click() + assert "Copy TP" in pageTargetingDetails.getPageHeaderTitle().text + pageTargetingDetails.getButtonTargetPopulationDuplicate() + pageTargetingDetails.getButtonDelete() + assert "EDIT" in pageTargetingDetails.getButtonEdit().text + assert "REBUILD" in pageTargetingDetails.getButtonRebuild().text + assert "LOCK" in pageTargetingDetails.getButtonTargetPopulationLock().text + assert "Details" in pageTargetingDetails.getDetailsTitle().text + assert "OPEN" in pageTargetingDetails.getLabelStatus().text + assert "OPEN" in pageTargetingDetails.getTargetPopulationStatus().text + assert "CREATED BY" in pageTargetingDetails.getLabelizedFieldContainerCreatedBy().text + pageTargetingDetails.getLabelCreatedBy() + assert "PROGRAMME POPULATION CLOSE DATE" in pageTargetingDetails.getLabelizedFieldContainerCloseDate().text + assert "PROGRAMME" in pageTargetingDetails.getLabelizedFieldContainerProgramName().text + assert "Test Programm" in pageTargetingDetails.getLabelProgramme().text + assert "SEND BY" in pageTargetingDetails.getLabelizedFieldContainerSendBy().text + assert "-" in pageTargetingDetails.getLabelSendBy().text + assert "-" in pageTargetingDetails.getLabelSendDate().text + assert "-" in pageTargetingDetails.getCriteriaContainer().text + assert "0" in pageTargetingDetails.getLabelFemaleChildren().text + assert "0" in pageTargetingDetails.getLabelMaleChildren().text + assert "0" in pageTargetingDetails.getLabelMaleAdults().text + assert "2" in pageTargetingDetails.getLabelTotalNumberOfHouseholds().text + assert "8" in pageTargetingDetails.getLabelTargetedIndividuals().text + assert "Households" in pageTargetingDetails.getTableTitle().text + expected_menu_items = [ + "ID", + "Head of Household", + "Household Size", + "Administrative Level 2", + "Score", + ] + assert expected_menu_items == [i.text for i in pageTargetingDetails.getTableLabel()] + + @pytest.mark.usefixtures("login") class TestCreateTargeting: def test_create_targeting_for_people( diff --git a/backend/selenium_tests/tools/tag_name_finder.py b/backend/selenium_tests/tools/tag_name_finder.py index 3c94ca72f3..81c9752b95 100644 --- a/backend/selenium_tests/tools/tag_name_finder.py +++ b/backend/selenium_tests/tools/tag_name_finder.py @@ -1,18 +1,6 @@ from selenium.webdriver import Chrome from selenium.webdriver.common.by import By -default_url = "http://localhost:8080" -url = input(f"Url of page (default is {default_url}):") -if not url: - url = default_url - -driver = Chrome() - -driver.get(url) -label = input("Choose the label (default it data-cy):") -if not label: - label = "data-cy" - def printing(what: str) -> None: for ii in ids: @@ -27,8 +15,21 @@ def printing(what: str) -> None: print(f"def {method_name}(self) -> WebElement: \n\treturn self.wait_for(self.{var_name})\n") -while 1: - input("Open the page and press Enter") +default_url = "http://localhost:8080" +url = input(f"Url of page (default is {default_url}):") +if not url: + url = default_url + +driver = Chrome() + +driver.get(url) +label = input("Choose the label (default it data-cy):") +if not label: + label = "data-cy" + +exit_loop = "" +while exit_loop != "exit": + exit_loop = input("Open the page and press Enter or write exit") ids = driver.find_elements(By.XPATH, f"//*[@{label}]") printing("Labels") print("\n")