diff --git a/backend/hct_mis_api/apps/core/base_test_case.py b/backend/hct_mis_api/apps/core/base_test_case.py
index 88bffa2d20..d48a4a6073 100644
--- a/backend/hct_mis_api/apps/core/base_test_case.py
+++ b/backend/hct_mis_api/apps/core/base_test_case.py
@@ -199,7 +199,7 @@ def rebuild_search_index(cls) -> None:
@pytest.fixture(autouse=True)
def _setup_elasticsearch(self, django_elasticsearch_setup: None) -> None:
# Setup elasticsearch to work in parallel
- pass
+ yield
class UploadDocumentsBase(APITestCase):
diff --git a/backend/hct_mis_api/apps/core/fixtures/data-selenium.json b/backend/hct_mis_api/apps/core/fixtures/data-selenium.json
index a1eac6294c..66209e304a 100644
--- a/backend/hct_mis_api/apps/core/fixtures/data-selenium.json
+++ b/backend/hct_mis_api/apps/core/fixtures/data-selenium.json
@@ -8,6 +8,7 @@
"code": "full_test",
"description": "Full individual collected",
"active": true,
+ "type": "STANDARD",
"individual_filters_available": true,
"household_filters_available": true,
"compatible_types": [],
diff --git a/backend/hct_mis_api/apps/household/fixtures.py b/backend/hct_mis_api/apps/household/fixtures.py
index f0de6f51fa..ceeaf16fb1 100644
--- a/backend/hct_mis_api/apps/household/fixtures.py
+++ b/backend/hct_mis_api/apps/household/fixtures.py
@@ -424,33 +424,38 @@ def create_household_and_individuals(
if household_data.get("size") is None:
household_data["size"] = len(individuals_data)
if "program" not in household_data:
- program = ProgramFactory()
- else:
- program = household_data["program"]
- if "registration_data_import" not in household_data:
- rdi = RegistrationDataImportFactory(program=program)
- household_data["registration_data_import"] = rdi
+ household_data["program"] = ProgramFactory()
+
household: Household = HouseholdFactory.build(**household_data)
household.program.save()
household.household_collection.save()
- household.registration_data_import.imported_by.save()
+ household.registration_data_import.program = household.program
household.registration_data_import.program.save()
+ household.registration_data_import.imported_by.save()
household.registration_data_import.save()
- household.program.save()
for individual_data in individuals_data:
if "program" not in individual_data:
- individual_data["program"] = program
+ individual_data["program"] = household.program
if "registration_data_import" not in individual_data:
- individual_data["registration_data_import"] = household_data["registration_data_import"]
+ individual_data["registration_data_import"] = household.registration_data_import
individuals: List[Individual] = [
IndividualFactory(
- household=household,
+ household=None,
**individual_data,
)
for individual_data in individuals_data
]
household.head_of_household = individuals[0]
household.save()
+
+ individuals_to_update = []
+ for index, individual in enumerate(individuals):
+ if index == 0:
+ individual.relationship = "HEAD"
+ individual.household = household
+ individuals_to_update.append(individual)
+ Individual.objects.bulk_update(individuals_to_update, ("relationship", "household"))
+
return household, individuals
diff --git a/backend/hct_mis_api/apps/targeting/fixtures/data-cypress.json b/backend/hct_mis_api/apps/targeting/fixtures/data-cypress.json
index a588c4447e..301a665a14 100644
--- a/backend/hct_mis_api/apps/targeting/fixtures/data-cypress.json
+++ b/backend/hct_mis_api/apps/targeting/fixtures/data-cypress.json
@@ -66,12 +66,12 @@
"vulnerability_score_max": null,
"excluded_ids": "",
"exclusion_reason": "",
- "total_households_count": 2,
- "total_individuals_count": 8,
- "child_male_count": 0,
- "child_female_count": 0,
- "adult_male_count": 0,
- "adult_female_count": 0,
+ "total_households_count": 3,
+ "total_individuals_count": 7,
+ "child_male_count": 1,
+ "child_female_count": 6,
+ "adult_male_count": 1,
+ "adult_female_count": 2,
"storage_file": null
}
},
diff --git a/backend/hct_mis_api/apps/targeting/mutations.py b/backend/hct_mis_api/apps/targeting/mutations.py
index dd1a08d259..93f8fb288a 100644
--- a/backend/hct_mis_api/apps/targeting/mutations.py
+++ b/backend/hct_mis_api/apps/targeting/mutations.py
@@ -98,10 +98,18 @@ def get_unicef_ids(ids_string: str, type_id: str, program: Program) -> str:
ids_list = [i.strip() for i in ids_list]
if type_id == "household":
hh_ids = [hh_id for hh_id in ids_list if hh_id.startswith("HH")]
- list_ids = Household.objects.filter(unicef_id__in=hh_ids, program=program).values_list("unicef_id", flat=True)
+ list_ids = (
+ Household.objects.filter(unicef_id__in=hh_ids, program=program)
+ .order_by("unicef_id")
+ .values_list("unicef_id", flat=True)
+ )
if type_id == "individual":
ind_ids = [ind_id for ind_id in ids_list if ind_id.startswith("IND")]
- list_ids = Individual.objects.filter(unicef_id__in=ind_ids, program=program).values_list("unicef_id", flat=True)
+ list_ids = (
+ Individual.objects.filter(unicef_id__in=ind_ids, program=program)
+ .order_by("unicef_id")
+ .values_list("unicef_id", flat=True)
+ )
return ", ".join(list_ids)
diff --git a/backend/selenium_tests/conftest.py b/backend/selenium_tests/conftest.py
index 06a91c2c28..5da5d78d73 100644
--- a/backend/selenium_tests/conftest.py
+++ b/backend/selenium_tests/conftest.py
@@ -176,7 +176,7 @@ def driver() -> Chrome:
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--enable-logging")
chrome_options.add_argument("--window-size=1920,1080")
- return webdriver.Chrome(options=chrome_options)
+ yield webdriver.Chrome(options=chrome_options)
@pytest.fixture(autouse=True)
@@ -201,7 +201,7 @@ def login(browser: Chrome) -> Chrome:
browser.add_cookie({"name": "csrftoken", "value": pytest.CSRF})
browser.add_cookie({"name": "sessionid", "value": pytest.SESSION_ID})
browser.get(f"{browser.live_server.url}")
- return browser
+ yield browser
@pytest.fixture
@@ -397,6 +397,7 @@ def business_area() -> BusinessArea:
"region_code": "64",
"region_name": "SAR",
"slug": "afghanistan",
+ "screen_beneficiary": True,
"has_data_sharing_agreement": True,
"is_payment_plan_applicable": True,
"is_accountability_applicable": True,
@@ -406,7 +407,7 @@ def business_area() -> BusinessArea:
FlagState.objects.get_or_create(
**{"name": "ALLOW_ACCOUNTABILITY_MODULE", "condition": "boolean", "value": "True", "required": False}
)
- return business_area
+ yield business_area
@pytest.fixture
diff --git a/backend/selenium_tests/drawer/test_drawer.py b/backend/selenium_tests/drawer/test_drawer.py
index 8598b4e688..46ccdbb9cc 100644
--- a/backend/selenium_tests/drawer/test_drawer.py
+++ b/backend/selenium_tests/drawer/test_drawer.py
@@ -16,27 +16,27 @@
@pytest.fixture
def social_worker_program() -> Program:
- return get_program_with_dct_type_and_name("Worker Program", "WORK", DataCollectingType.Type.SOCIAL)
+ yield get_program_with_dct_type_and_name("Worker Program", "WORK", DataCollectingType.Type.SOCIAL)
@pytest.fixture
def normal_program() -> Program:
- return get_program_with_dct_type_and_name("Normal Program", "NORM", DataCollectingType.Type.STANDARD)
+ yield get_program_with_dct_type_and_name("Normal Program", "NORM", DataCollectingType.Type.STANDARD)
@pytest.fixture
def active_program() -> Program:
- return get_program_with_dct_type_and_name("Active Program", "ACTI", status=Program.ACTIVE)
+ yield get_program_with_dct_type_and_name("Active Program", "ACTI", status=Program.ACTIVE)
@pytest.fixture
def draft_program() -> Program:
- return get_program_with_dct_type_and_name("Draft Program", "DRAF", status=Program.DRAFT)
+ yield get_program_with_dct_type_and_name("Draft Program", "DRAF", status=Program.DRAFT)
@pytest.fixture
def finished_program() -> Program:
- return get_program_with_dct_type_and_name("Finished Program", "FINI", status=Program.FINISHED)
+ yield get_program_with_dct_type_and_name("Finished Program", "FINI", status=Program.FINISHED)
def get_program_with_dct_type_and_name(
diff --git a/backend/selenium_tests/filters/test_filters.py b/backend/selenium_tests/filters/test_filters.py
index b4f9c26509..80c2bdaa23 100644
--- a/backend/selenium_tests/filters/test_filters.py
+++ b/backend/selenium_tests/filters/test_filters.py
@@ -277,7 +277,7 @@ def create_rdi() -> None:
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
+ yield
@pytest.mark.usefixtures("login")
diff --git a/backend/selenium_tests/grievance/feedback/test_feedback.py b/backend/selenium_tests/grievance/feedback/test_feedback.py
index aec38b6c53..2cb3856cf5 100644
--- a/backend/selenium_tests/grievance/feedback/test_feedback.py
+++ b/backend/selenium_tests/grievance/feedback/test_feedback.py
@@ -18,7 +18,7 @@
def add_feedbacks(django_db_setup: Generator[None, None, None], django_db_blocker: DjangoDbBlocker) -> None:
with django_db_blocker.unblock():
call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/accountability/fixtures/data-cypress.json")
- return
+ yield
@pytest.fixture
@@ -26,7 +26,7 @@ def add_households(django_db_setup: Generator[None, None, None], django_db_block
with django_db_blocker.unblock():
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")
- return
+ yield
@pytest.fixture
@@ -34,7 +34,7 @@ def create_programs(django_db_setup: Generator[None, None, None], django_db_bloc
with django_db_blocker.unblock():
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
+ yield
@pytest.mark.usefixtures("login")
diff --git a/backend/selenium_tests/grievance/grievance_tickets/test_grievance_tickets.py b/backend/selenium_tests/grievance/grievance_tickets/test_grievance_tickets.py
index 5635646e12..0374aee44b 100644
--- a/backend/selenium_tests/grievance/grievance_tickets/test_grievance_tickets.py
+++ b/backend/selenium_tests/grievance/grievance_tickets/test_grievance_tickets.py
@@ -16,7 +16,7 @@
def add_grievance(django_db_setup: Generator[None, None, None], django_db_blocker: DjangoDbBlocker) -> None:
with django_db_blocker.unblock():
call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/grievance/fixtures/data-cypress.json")
- return
+ yield
@pytest.fixture
@@ -24,7 +24,7 @@ def add_households(django_db_setup: Generator[None, None, None], django_db_block
with django_db_blocker.unblock():
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")
- return
+ yield
@pytest.fixture
@@ -32,7 +32,7 @@ def create_programs(django_db_setup: Generator[None, None, None], django_db_bloc
with django_db_blocker.unblock():
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
+ yield
@pytest.mark.usefixtures("login")
diff --git a/backend/selenium_tests/helpers/helper.py b/backend/selenium_tests/helpers/helper.py
index a990e40a03..076df7ee16 100644
--- a/backend/selenium_tests/helpers/helper.py
+++ b/backend/selenium_tests/helpers/helper.py
@@ -11,7 +11,7 @@
class Common:
- DEFAULT_TIMEOUT = 10
+ DEFAULT_TIMEOUT = 20
def __init__(self, driver: Chrome):
self.driver = driver
@@ -137,3 +137,10 @@ def get_value_of_attributes(self, attribute: str = "data-cy") -> None:
print(f"{ii.text}: {ii.get_attribute(attribute)}") # type: ignore
except BaseException:
print(f"No text: {ii.get_attribute(attribute)}") # type: ignore
+
+ def mouse_on_element(self, element: WebElement) -> None:
+ hover = ActionChains(self.driver).move_to_element(element) # type: ignore
+ hover.perform()
+
+ def wait_for_element_clickable(self, locator: str) -> bool:
+ return self._wait().until(EC.element_to_be_clickable((By.XPATH, locator)))
diff --git a/backend/selenium_tests/managerial_console/test_managerial_console.py b/backend/selenium_tests/managerial_console/test_managerial_console.py
index 406db855a3..2704960224 100644
--- a/backend/selenium_tests/managerial_console/test_managerial_console.py
+++ b/backend/selenium_tests/managerial_console/test_managerial_console.py
@@ -16,7 +16,7 @@
@pytest.fixture
def create_active_test_program() -> Program:
- return create_program("Test Programm")
+ yield create_program("Test Programm")
def create_program(
diff --git a/backend/selenium_tests/page_object/filters.py b/backend/selenium_tests/page_object/filters.py
index a3ea15a863..e8a1efbc75 100644
--- a/backend/selenium_tests/page_object/filters.py
+++ b/backend/selenium_tests/page_object/filters.py
@@ -1,3 +1,5 @@
+from time import sleep
+
from page_object.base_components import BaseComponents
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
@@ -87,7 +89,7 @@ class Filters(BaseComponents):
importedByInput = 'div[data-cy="Imported By-input"]'
def getFiltersSearch(self) -> WebElement:
- return self.wait_for(self.filtersSearch)
+ return self.wait_for(self.filtersSearch).find_element(By.XPATH, "./div/input")
def getFiltersDocumentType(self) -> WebElement:
return self.wait_for(self.filtersDocumentType)
@@ -101,6 +103,17 @@ def getFiltersProgram(self) -> WebElement:
def getFiltersStatus(self) -> WebElement:
return self.wait_for(self.filtersStatus)
+ def selectFiltersSatus(self, status: str) -> None:
+ self.getFiltersStatus().click()
+ self.wait_for(f'li[data-value="{status.upper()}"]').click()
+ for _ in range(10):
+ sleep(1)
+ if status.capitalize() in self.getFiltersStatus().text:
+ self.getButtonFiltersApply().click()
+ break
+ else:
+ raise Exception(f"Status: {status.capitalize()} does not occur.")
+
def getFiltersFsp(self) -> WebElement:
return self.wait_for(self.filtersFsp)
@@ -138,10 +151,10 @@ def getFiltersSector(self) -> WebElement:
return self.wait_for(self.filtersSector)
def getFiltersNumberOfHouseholdsMin(self) -> WebElement:
- return self.wait_for(self.filtersNumberOfHouseholdsMin)
+ return self.wait_for(self.filtersNumberOfHouseholdsMin).find_element(By.XPATH, "./div/input")
def getFiltersNumberOfHouseholdsMax(self) -> WebElement:
- return self.wait_for(self.filtersNumberOfHouseholdsMax)
+ return self.wait_for(self.filtersNumberOfHouseholdsMax).find_element(By.XPATH, "./div/input")
def getFiltersBudgetMin(self) -> WebElement:
return self.wait_for(self.filtersBudgetMin)
@@ -186,10 +199,10 @@ def getMenuItemFiltersText(self) -> WebElement:
return self.wait_for(self.menuItemFiltersText)
def getFiltersTotalHouseholdsCountMin(self) -> WebElement:
- return self.wait_for(self.filtersTotalHouseholdsCountMin)
+ return self.wait_for(self.filtersTotalHouseholdsCountMin).find_element(By.XPATH, "./div/input")
def getFiltersTotalHouseholdsCountMax(self) -> WebElement:
- return self.wait_for(self.filtersTotalHouseholdsCountMax)
+ return self.wait_for(self.filtersTotalHouseholdsCountMax).find_element(By.XPATH, "./div/input")
def getGlobalProgramFilterContainer(self) -> WebElement:
return self.wait_for(self.globalProgramFilterContainer)
diff --git a/backend/selenium_tests/page_object/targeting/create_new.py b/backend/selenium_tests/page_object/targeting/create_new.py
deleted file mode 100644
index ead99a221b..0000000000
--- a/backend/selenium_tests/page_object/targeting/create_new.py
+++ /dev/null
@@ -1,87 +0,0 @@
-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
deleted file mode 100644
index edf2795c02..0000000000
--- a/backend/selenium_tests/page_object/targeting/t_details_page.py
+++ /dev/null
@@ -1,130 +0,0 @@
-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 6191b89369..00fdc03a60 100644
--- a/backend/selenium_tests/page_object/targeting/targeting.py
+++ b/backend/selenium_tests/page_object/targeting/targeting.py
@@ -1,6 +1,7 @@
from time import sleep
from page_object.base_components import BaseComponents
+from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from hct_mis_api.apps.core.utils import encode_id_base64
@@ -22,9 +23,23 @@ class Targeting(BaseComponents):
rows = 'tr[role="checkbox"]'
createUserFilters = 'div[data-cy="menu-item-filters-text"]'
createUseIDs = 'div[data-cy="menu-item-ids-text"]'
+ buttonInactiveCreateNew = 'a[data-cy="button-target-population-create-new"]'
+ tooltip = 'div[role="tooltip"]'
+ statusContainer = 'div[data-cy="status-container"]'
+ loadingRows = 'tr[data-cy="table-row"]'
+ buttonTargetPopulation = 'button[data-cy="button-target-population-info"]'
+ buttonApply = 'button[data-cy="button-filters-apply"]'
+ buttonClear = 'button[data-cy="button-filters-clear"]'
+ tabFieldList = 'button[data-cy="tab-field-list"]'
+ tabTargetingDiagram = 'button[data-cy="tab-targeting-diagram"]'
+ name = 'th[data-cy="name"]'
+ status = 'th[data-cy="status"]'
+ numOfHouseholds = 'th[data-cy="num-of-households"]'
+ dateCreated = 'th[data-cy="date-created"]'
+ lastEdited = 'th[data-cy="last-edited"]'
+ createdBy = 'th[data-cy="created-by"]'
# Texts
-
textTitlePage = "Targeting"
textCreateNew = "Create new"
textTabTitle = "Target Populations"
@@ -35,8 +50,6 @@ class Targeting(BaseComponents):
textTabDateCreated = "Date Created"
textTabLastEdited = "Last Edited"
textTabCreatedBy = "Created by"
- buttonApply = 'button[data-cy="button-filters-apply"]'
- buttonClear = 'button[data-cy="button-filters-clear"]'
def navigate_to_page(self, business_area_slug: str, program_id: str) -> None:
self.driver.get(self.get_page_url(business_area_slug, program_id))
@@ -50,6 +63,9 @@ def get_page_url(self, business_area_slug: str, program_id: str) -> str:
def getTitlePage(self) -> WebElement:
return self.wait_for(self.titlePage)
+ def waitForTextTitlePage(self, text: str) -> bool:
+ return self.wait_for_text(text, self.titlePage)
+
def getSearchFilter(self) -> WebElement:
return self.wait_for(self.searchFilter)
@@ -97,8 +113,61 @@ def chooseTargetPopulations(self, number: int) -> WebElement:
sleep(1)
return self.get_elements(self.rows)[number]
+ def countTargetPopulations(self, number: int) -> None:
+ for _ in range(5):
+ if len(self.getTargetPopulationsRows()) == number:
+ break
+ else:
+ raise TimeoutError(f"{len(self.getTargetPopulationsRows())} target populations instead of {number}")
+
def getCreateUseFilters(self) -> WebElement:
return self.wait_for(self.createUserFilters)
def getCreateUseIDs(self) -> WebElement:
return self.wait_for(self.createUseIDs)
+
+ def getButtonInactiveCreateNew(self) -> WebElement:
+ return self.wait_for(self.buttonInactiveCreateNew)
+
+ def geTooltip(self) -> WebElement:
+ return self.wait_for(self.tooltip)
+
+ def getStatusContainer(self) -> WebElement:
+ return self.wait_for(self.statusContainer)
+
+ def getTabFieldList(self) -> WebElement:
+ return self.wait_for(self.tabFieldList)
+
+ def getTabTargetingDiagram(self) -> WebElement:
+ return self.wait_for(self.tabTargetingDiagram)
+
+ def getButtonTargetPopulation(self) -> WebElement:
+ return self.wait_for(self.buttonTargetPopulation)
+
+ def getLoadingRows(self) -> WebElement:
+ return self.wait_for(self.loadingRows)
+
+ def getColumnName(self) -> WebElement:
+ return self.wait_for(self.name).find_element(By.CSS_SELECTOR, self.tabColumnLabel)
+
+ def getColumnStatus(self) -> WebElement:
+ return self.wait_for(self.status).find_element(By.CSS_SELECTOR, self.tabColumnLabel)
+
+ def getColumnNumOfHouseholds(self) -> WebElement:
+ return self.wait_for(self.numOfHouseholds).find_element(By.CSS_SELECTOR, self.tabColumnLabel)
+
+ def getColumnDateCreated(self) -> WebElement:
+ return self.wait_for(self.dateCreated).find_element(By.CSS_SELECTOR, self.tabColumnLabel)
+
+ def getColumnLastEdited(self) -> WebElement:
+ return self.wait_for(self.lastEdited).find_element(By.CSS_SELECTOR, self.tabColumnLabel)
+
+ def getColumnCreatedBy(self) -> WebElement:
+ return self.wait_for(self.createdBy).find_element(By.CSS_SELECTOR, self.tabColumnLabel)
+
+ def disappearLoadingRows(self) -> WebElement:
+ try:
+ self.getLoadingRows()
+ except BaseException:
+ self.getStatusContainer()
+ return self.wait_for_disappear(self.loadingRows)
diff --git a/backend/selenium_tests/page_object/targeting/targeting_create.py b/backend/selenium_tests/page_object/targeting/targeting_create.py
index e77c2408f1..712cb10763 100644
--- a/backend/selenium_tests/page_object/targeting/targeting_create.py
+++ b/backend/selenium_tests/page_object/targeting/targeting_create.py
@@ -1,3 +1,5 @@
+from time import sleep
+
from page_object.base_components import BaseComponents
from selenium.webdriver.remote.webelement import WebElement
@@ -14,6 +16,7 @@ class TargetingCreate(BaseComponents):
targetingCriteriaAutoComplete = 'input[data-cy="autocomplete-target-criteria-option-{}"]'
targetingCriteriaValue = '[data-cy="select-filters[{}].value"]'
targetingCriteriaAddDialogSaveButton = 'button[data-cy="button-target-population-add-criteria"]'
+ targetingCriteriaAddDialogSaveButtonEdit = '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"]'
@@ -24,7 +27,10 @@ class TargetingCreate(BaseComponents):
inputHouseholdids = 'input[data-cy="input-householdIds"]'
inputIncludedIndividualIds = 'div[data-cy="input-included-individual-ids"]'
inputIndividualids = 'input[data-cy="input-individualIds"]'
+ inputFlagexcludeifonsanctionlist = 'span[data-cy="input-flagExcludeIfOnSanctionList"]'
inputFlagexcludeifactiveadjudicationticket = 'span[data-cy="input-flagExcludeIfActiveAdjudicationTicket"]'
+ iconSelected = '[data-testid="CheckBoxIcon"]'
+ iconNotSelected = '[data-testid="CheckBoxOutlineBlankIcon"]'
inputName = 'input[data-cy="input-name"]'
divTargetPopulationAddCriteria = 'div[data-cy="button-target-population-add-criteria"]'
titleExcludedEntries = 'h6[data-cy="title-excluded-entries"]'
@@ -39,15 +45,35 @@ class TargetingCreate(BaseComponents):
buttonHouseholdRule = 'button[data-cy="button-household-rule"]'
buttonIndividualRule = 'button[data-cy="button-individual-rule"]'
buttonTargetPopulationAddCriteria = 'button[data-cy="button-target-population-add-criteria"]'
+ buttonSave = 'button[data-cy="button-save"]'
+ inputFiltersValueFrom = 'input[data-cy="input-filters[{}].value.from"]'
+ inputFiltersValueTo = 'input[data-cy="input-filters[{}].value.to"]'
+ inputFiltersValue = 'input[data-cy="input-filters[{}].value"]'
+ autocompleteTargetCriteriaValues = 'div[data-cy="autocomplete-target-criteria-values"]'
+ selectMany = 'div[data-cy="select-many"]'
+ buttonEdit = 'button[data-cy="button-edit"]'
+
# Texts
textTargetingCriteria = "Targeting Criteria"
def getPageHeaderTitle(self) -> WebElement:
return self.wait_for(self.pageHeaderTitle)
- def getButtonTargetPopulationCreate(self) -> WebElement:
+ def getButtonTargetPopulationCreate(self) -> bool:
return self.wait_for(self.buttonTargetPopulationCreate)
+ def clickButtonTargetPopulationCreate(self) -> bool:
+ for _ in range(10):
+ self.wait_for(self.buttonTargetPopulationCreate).click()
+ try:
+ self.wait_for_disappear(self.buttonTargetPopulationCreate)
+ break
+ except BaseException:
+ print("Error: Try again to click Save button during Target Population creation")
+ else:
+ raise Exception(f"Element {self.buttonTargetPopulationCreate} not found")
+ return True
+
def getInputName(self) -> WebElement:
return self.wait_for(self.inputName)
@@ -66,6 +92,15 @@ def getInputIndividualids(self) -> WebElement:
def getInputFlagexcludeifactiveadjudicationticket(self) -> WebElement:
return self.wait_for(self.inputFlagexcludeifactiveadjudicationticket)
+ def getInputFlagexcludeifonsanctionlist(self) -> WebElement:
+ return self.wait_for(self.inputFlagexcludeifonsanctionlist)
+
+ def getIconNotSelected(self) -> WebElement:
+ return self.wait_for(self.iconNotSelected)
+
+ def getIconSelected(self) -> WebElement:
+ return self.wait_for(self.iconSelected)
+
def getButtonTargetPopulationAddCriteria(self) -> WebElement:
return self.wait_for(self.buttonTargetPopulationAddCriteria)
@@ -117,6 +152,13 @@ def getAddPeopleRuleButton(self) -> WebElement:
def getTargetingCriteriaAutoComplete(self, index: int = 0) -> WebElement:
return self.wait_for(self.targetingCriteriaAutoComplete.format(index))
+ def getTargetingCriteriaAutoCompleteIndividual(self, index: int = 0) -> WebElement:
+ for _ in range(5):
+ if len(self.get_elements(self.targetingCriteriaAutoComplete.format(index))) >= 2:
+ break
+ sleep(1)
+ return self.get_elements(self.targetingCriteriaAutoComplete.format(index))[1]
+
def getTargetingCriteriaValue(self, index: int = 0) -> WebElement:
return self.wait_for(self.targetingCriteriaValue.format(index))
@@ -131,3 +173,24 @@ def getFieldName(self) -> WebElement:
def getTargetPopulationSaveButton(self) -> WebElement:
return self.wait_for(self.targetPopulationSaveButton)
+
+ def getButtonSave(self) -> WebElement:
+ return self.wait_for(self.buttonSave)
+
+ def getInputFiltersValueFrom(self, fiter_number: int = 0) -> WebElement:
+ return self.wait_for(self.inputFiltersValueFrom.format(fiter_number))
+
+ def getInputFiltersValueTo(self, fiter_number: int = 0) -> WebElement:
+ return self.wait_for(self.inputFiltersValueTo.format(fiter_number))
+
+ def getInputFiltersValue(self, fiter_number: str) -> WebElement:
+ return self.wait_for(self.inputFiltersValue.format(fiter_number))
+
+ def getAutocompleteTargetCriteriaValues(self) -> WebElement:
+ return self.wait_for(self.autocompleteTargetCriteriaValues)
+
+ def getSelectMany(self) -> WebElement:
+ return self.wait_for(self.selectMany)
+
+ def getButtonEdit(self) -> WebElement:
+ return self.wait_for(self.buttonEdit)
diff --git a/backend/selenium_tests/page_object/targeting/targeting_details.py b/backend/selenium_tests/page_object/targeting/targeting_details.py
index 56625451cc..63ca3186a7 100644
--- a/backend/selenium_tests/page_object/targeting/targeting_details.py
+++ b/backend/selenium_tests/page_object/targeting/targeting_details.py
@@ -1,3 +1,5 @@
+from time import sleep
+
from page_object.base_components import BaseComponents
from selenium.webdriver.remote.webelement import WebElement
@@ -8,20 +10,24 @@ class TargetingDetails(BaseComponents):
status = 'div[data-cy="target-population-status"]'
criteria_container = 'div[data-cy="criteria-container"]'
lock_button = 'button[data-cy="button-target-population-lock"]'
+ lockPopupButton = 'button[data-cy="button-target-population-modal-lock"]'
household_table_cell = "table tr:nth-of-type({}) td:nth-of-type({})"
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"]'
+ inputName = 'input[data-cy="input-name"]'
buttonDelete = 'button[data-cy="button-delete"]'
buttonEdit = 'a[data-cy="button-edit"]'
+ buttonIconEdit = 'button[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"]'
+ buttonMarkReady = 'button[data-cy="button-target-population-send-to-hope"]'
+ buttonPopupMarkReady = 'button[data-cy="button-target-population-modal-send-to-hope"]'
targetPopulationStatus = 'div[data-cy="target-population-status"]'
labelizedFieldContainerCreatedBy = 'div[data-cy="labelized-field-container-created-by"]'
labelCreatedBy = 'div[data-cy="label-created by"]'
@@ -35,6 +41,11 @@ class TargetingDetails(BaseComponents):
labelSendDate = 'div[data-cy="label-Send date"]'
criteriaContainer = 'div[data-cy="criteria-container"]'
checkboxExcludeIfActiveAdjudicationTicket = 'span[data-cy="checkbox-exclude-if-active-adjudication-ticket"]'
+ checkboxExcludePeopleIfActiveAdjudicationTicket = (
+ 'span[data-cy="checkbox-exclude-people-if-active-adjudication-ticket"]'
+ )
+ checkboxExcludeIfOnSanctionList = 'span[data-cy="checkbox-exclude-if-on-sanction-list"]'
+ iconSelected = '[data-testid="CheckBoxIcon"]'
labelFemaleChildren = 'div[data-cy="label-Female Children"]'
labelFemaleAdults = 'div[data-cy="label-Female Adults"]'
labelMaleChildren = 'div[data-cy="label-Male Children"]'
@@ -44,6 +55,10 @@ class TargetingDetails(BaseComponents):
tableTitle = 'h6[data-cy="table-title"]'
tableLabel = 'span[data-cy="table-label"]'
tablePagination = 'div[data-cy="table-pagination"]'
+ statusContainer = 'div[data-cy="status-container"]'
+ householdSizeFrom = 'input[data-cy="input-filters[0].value.from"]'
+ householdSizeTo = 'input[data-cy="input-filters[0].value.to"]'
+ dialogBox = 'div[role="dialog"]'
# Texts
# Elements
@@ -51,15 +66,27 @@ class TargetingDetails(BaseComponents):
def getPageHeaderTitle(self) -> WebElement:
return self.wait_for(self.pageHeaderTitle)
+ def waitForTextTitlePage(self, text: str) -> bool:
+ return self.wait_for_text(text, self.titlePage)
+
def getButtonTargetPopulationDuplicate(self) -> WebElement:
return self.wait_for(self.buttonTargetPopulationDuplicate)
+ def getInputName(self) -> WebElement:
+ return self.wait_for(self.inputName)
+
+ def disappearInputName(self) -> WebElement:
+ return self.wait_for_disappear(self.inputName)
+
def getButtonDelete(self) -> WebElement:
return self.wait_for(self.buttonDelete)
def getButtonEdit(self) -> WebElement:
return self.wait_for(self.buttonEdit)
+ def getButtonIconEdit(self) -> WebElement:
+ return self.wait_for(self.buttonIconEdit)
+
def getButtonRebuild(self) -> WebElement:
return self.wait_for(self.buttonRebuild)
@@ -75,9 +102,23 @@ def getDetailsGrid(self) -> WebElement:
def getLabelStatus(self) -> WebElement:
return self.wait_for(self.labelStatus)
+ def waitForLabelStatus(self, status: str) -> WebElement:
+ for _ in range(10):
+ sleep(1)
+ if status.upper() in self.getLabelStatus().text:
+ return self.wait_for(self.labelStatus)
+ else:
+ raise Exception(f"Status: {status.capitalize()} does not occur.")
+
def getTargetPopulationStatus(self) -> WebElement:
return self.wait_for(self.targetPopulationStatus)
+ def getButtonMarkReady(self) -> WebElement:
+ return self.wait_for(self.buttonMarkReady)
+
+ def getButtonPopupMarkReady(self) -> WebElement:
+ return self.wait_for(self.buttonPopupMarkReady)
+
def getLabelizedFieldContainerCreatedBy(self) -> WebElement:
return self.wait_for(self.labelizedFieldContainerCreatedBy)
@@ -112,7 +153,16 @@ def getCriteriaContainer(self) -> WebElement:
return self.wait_for(self.criteriaContainer)
def getCheckboxExcludeIfActiveAdjudicationTicket(self) -> WebElement:
- return self.wait_for(self.checkboxExcludeIfActiveAdjudicationTicket)
+ return self.get(self.checkboxExcludeIfActiveAdjudicationTicket)
+
+ def getCheckboxExcludePeopleIfActiveAdjudicationTicket(self) -> WebElement:
+ return self.get(self.checkboxExcludePeopleIfActiveAdjudicationTicket)
+
+ def getCheckboxExcludeIfOnSanctionList(self) -> WebElement:
+ return self.wait_for(self.checkboxExcludeIfOnSanctionList)
+
+ def getIconSelected(self) -> WebElement:
+ return self.wait_for(self.iconSelected)
def getLabelFemaleChildren(self) -> WebElement:
return self.wait_for(self.labelFemaleChildren)
@@ -150,6 +200,9 @@ def getStatus(self) -> WebElement:
def getLockButton(self) -> WebElement:
return self.wait_for(self.lock_button)
+ def getLockPopupButton(self) -> WebElement:
+ return self.wait_for(self.lockPopupButton)
+
def getHouseholdTableCell(self, row: int, column: int) -> WebElement:
return self.wait_for(self.household_table_cell.format(row, column))
@@ -158,3 +211,18 @@ def getPeopleTableRows(self) -> list[WebElement]:
def getHouseholdTableRows(self) -> list[WebElement]:
return self.get_elements(self.household_table_rows)
+
+ def getStatusContainer(self) -> WebElement:
+ return self.wait_for(self.statusContainer)
+
+ def disappearStatusContainer(self) -> bool:
+ return self.wait_for_disappear(self.statusContainer)
+
+ def getHouseholdSizeFrom(self) -> WebElement:
+ return self.wait_for(self.householdSizeFrom)
+
+ def getHouseholdSizeTo(self) -> WebElement:
+ return self.wait_for(self.householdSizeTo)
+
+ def getDialogBox(self) -> WebElement:
+ return self.wait_for(self.dialogBox)
diff --git a/backend/selenium_tests/payment_module/test_payment_module.py b/backend/selenium_tests/payment_module/test_payment_module.py
index 386248362a..83c857f016 100644
--- a/backend/selenium_tests/payment_module/test_payment_module.py
+++ b/backend/selenium_tests/payment_module/test_payment_module.py
@@ -25,7 +25,7 @@
def create_test_program() -> Program:
BusinessArea.objects.filter(slug="afghanistan").update(is_payment_plan_applicable=True)
dct = DataCollectingTypeFactory(type=DataCollectingType.Type.STANDARD)
- return ProgramFactory(
+ yield ProgramFactory(
name="Test Program",
programme_code="1234",
start_date=datetime.now() - relativedelta(months=1),
@@ -61,7 +61,7 @@ def create_payment_plan(create_test_program: Program) -> PaymentPlan:
is_follow_up=False,
program_id=tp.program.id,
)
- return payment_plan[0]
+ yield payment_plan[0]
@pytest.mark.usefixtures("login")
diff --git a/backend/selenium_tests/program_details/test_program_details.py b/backend/selenium_tests/program_details/test_program_details.py
index dcaf0c3793..c506d6f95c 100644
--- a/backend/selenium_tests/program_details/test_program_details.py
+++ b/backend/selenium_tests/program_details/test_program_details.py
@@ -20,7 +20,7 @@
@pytest.fixture
def standard_program() -> Program:
- return get_program_with_dct_type_and_name("Test For Edit", "TEST")
+ yield get_program_with_dct_type_and_name("Test For Edit", "TEST")
def get_program_with_dct_type_and_name(
@@ -43,7 +43,7 @@ def get_program_with_dct_type_and_name(
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
+ yield
@pytest.mark.usefixtures("login")
@@ -54,12 +54,10 @@ def test_program_details(self, standard_program: Program, pageProgrammeDetails:
pageProgrammeDetails.selectGlobalProgramFilter("Test For Edit").click()
# Check Details page
assert "Test For Edit" in pageProgrammeDetails.getHeaderTitle().text
- pageProgrammeDetails.screenshot("0")
assert "DRAFT" in pageProgrammeDetails.getProgramStatus().text
assert "Test For Edit" in pageProgrammeDetails.getHeaderTitle().text
assert "REMOVE" in pageProgrammeDetails.getButtonRemoveProgram().text
assert "EDIT PROGRAMME" in pageProgrammeDetails.getButtonEditProgram().text
- pageProgrammeDetails.screenshot("1")
assert "ACTIVATE" in pageProgrammeDetails.getButtonActivateProgram().text
assert "" in pageProgrammeDetails.getCopyProgram().text
assert "DRAFT" in pageProgrammeDetails.getProgramStatus().text
diff --git a/backend/selenium_tests/programme_management/test_programme_management.py b/backend/selenium_tests/programme_management/test_programme_management.py
index 06221ad6a1..32fda41520 100644
--- a/backend/selenium_tests/programme_management/test_programme_management.py
+++ b/backend/selenium_tests/programme_management/test_programme_management.py
@@ -18,7 +18,7 @@
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
+ yield
@pytest.mark.usefixtures("login")
diff --git a/backend/selenium_tests/programme_population/test_households.py b/backend/selenium_tests/programme_population/test_households.py
index 7d79b8dd1f..5f2b37ddf4 100644
--- a/backend/selenium_tests/programme_population/test_households.py
+++ b/backend/selenium_tests/programme_population/test_households.py
@@ -12,14 +12,14 @@
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
+ yield
@pytest.fixture
def add_households() -> None:
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")
- return
+ yield
@pytest.mark.usefixtures("login")
diff --git a/backend/selenium_tests/programme_population/test_individuals.py b/backend/selenium_tests/programme_population/test_individuals.py
index c552891623..f66a42b427 100644
--- a/backend/selenium_tests/programme_population/test_individuals.py
+++ b/backend/selenium_tests/programme_population/test_individuals.py
@@ -12,14 +12,14 @@
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
+ yield
@pytest.fixture
def add_households() -> None:
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")
- return
+ yield
@pytest.mark.usefixtures("login")
diff --git a/backend/selenium_tests/registration_data_import/test_registration_data_import.py b/backend/selenium_tests/registration_data_import/test_registration_data_import.py
index a196e8ab20..2bcf2d636c 100644
--- a/backend/selenium_tests/registration_data_import/test_registration_data_import.py
+++ b/backend/selenium_tests/registration_data_import/test_registration_data_import.py
@@ -28,13 +28,13 @@ def registration_datahub(db) -> None: # type: ignore
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
+ yield
@pytest.fixture
def add_rdi() -> None:
call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/registration_data/fixtures/data-cypress.json")
- return
+ yield
@pytest.fixture
diff --git a/backend/selenium_tests/targeting/test_targeting.py b/backend/selenium_tests/targeting/test_targeting.py
index 25fd27fbc1..0a0b4272a2 100644
--- a/backend/selenium_tests/targeting/test_targeting.py
+++ b/backend/selenium_tests/targeting/test_targeting.py
@@ -1,77 +1,83 @@
from datetime import datetime
+from uuid import UUID
from django.conf import settings
from django.core.management import call_command
-from django.db import transaction
import pytest
from dateutil.relativedelta import relativedelta
from page_object.targeting.targeting import Targeting
from page_object.targeting.targeting_create import TargetingCreate
from page_object.targeting.targeting_details import TargetingDetails
+from selenium.common import NoSuchElementException
from selenium.webdriver import ActionChains, Keys
+from selenium.webdriver.common.by import By
+from hct_mis_api.apps.account.models import User
from hct_mis_api.apps.core.fixtures import DataCollectingTypeFactory
from hct_mis_api.apps.core.models import BusinessArea, DataCollectingType
-from hct_mis_api.apps.household.fixtures import create_household_and_individuals
+from hct_mis_api.apps.household.fixtures import (
+ create_household,
+ create_household_and_individuals,
+)
from hct_mis_api.apps.household.models import HEARING, HOST, REFUGEE, SEEING, Household
from hct_mis_api.apps.program.fixtures import ProgramFactory
from hct_mis_api.apps.program.models import Program
+from hct_mis_api.apps.targeting.fixtures import TargetingCriteriaFactory
+from hct_mis_api.apps.targeting.models import TargetPopulation
+from selenium_tests.page_object.filters import Filters
pytestmark = pytest.mark.django_db(transaction=True, databases=["registration_datahub", "default"])
@pytest.fixture
def sw_program() -> Program:
- return get_program_with_dct_type_and_name(
- "SW Program", dct_type=DataCollectingType.Type.SOCIAL, status=Program.ACTIVE
+ yield get_program_with_dct_type_and_name(
+ "Test Programm", dct_type=DataCollectingType.Type.SOCIAL, status=Program.ACTIVE
)
@pytest.fixture
def non_sw_program() -> Program:
- return get_program_with_dct_type_and_name(
- "Non SW Program", dct_type=DataCollectingType.Type.STANDARD, status=Program.ACTIVE
+ yield get_program_with_dct_type_and_name(
+ "Test Programm", dct_type=DataCollectingType.Type.STANDARD, status=Program.ACTIVE
)
+def create_custom_household(observed_disability: list[str], residence_status: str = HOST) -> Household:
+ program = Program.objects.get(name="Test Programm")
+ household, _ = create_household_and_individuals(
+ household_data={
+ "unicef_id": "HH-00-0000.0442",
+ "rdi_merge_status": "MERGED",
+ "business_area": program.business_area,
+ "program": program,
+ "residence_status": residence_status,
+ },
+ individuals_data=[
+ {
+ "rdi_merge_status": "MERGED",
+ "business_area": program.business_area,
+ "observed_disability": observed_disability,
+ },
+ ],
+ )
+ return household
+
+
@pytest.fixture
def household_with_disability() -> Household:
- program = Program.objects.first()
- with transaction.atomic():
- household, individuals = create_household_and_individuals(
- household_data={"business_area": program.business_area, "program": program, "residence_status": HOST},
- individuals_data=[
- {"business_area": program.business_area, "observed_disability": [SEEING, HEARING]},
- ],
- )
- return household
+ yield create_custom_household(observed_disability=[SEEING, HEARING])
@pytest.fixture
def household_without_disabilities() -> Household:
- program = Program.objects.first()
- with transaction.atomic():
- household, individuals = create_household_and_individuals(
- household_data={"business_area": program.business_area, "program": program, "residence_status": HOST},
- individuals_data=[
- {"business_area": program.business_area, "observed_disability": []},
- ],
- )
- return household
+ yield create_custom_household(observed_disability=[])
@pytest.fixture
def household_refugee() -> Household:
- program = Program.objects.first()
- with transaction.atomic():
- household, individuals = create_household_and_individuals(
- household_data={"business_area": program.business_area, "program": program, "residence_status": REFUGEE},
- individuals_data=[
- {"business_area": program.business_area, "observed_disability": []},
- ],
- )
- return household
+ yield create_custom_household(observed_disability=[], residence_status=REFUGEE)
def get_program_with_dct_type_and_name(
@@ -89,11 +95,36 @@ def get_program_with_dct_type_and_name(
return program
+@pytest.fixture
+def create_targeting(household_without_disabilities: Household) -> TargetPopulation:
+ program = Program.objects.first()
+ target_population = TargetPopulation.objects.update_or_create(
+ pk=UUID("00000000-0000-0000-0000-faceb00c0123"),
+ name="Test Target Population",
+ targeting_criteria=TargetingCriteriaFactory(),
+ status=TargetPopulation.STATUS_OPEN,
+ business_area=BusinessArea.objects.get(slug="afghanistan"),
+ program=Program.objects.get(name="Test Programm"),
+ created_by=User.objects.first(),
+ )[0]
+ target_population.save()
+ household, _ = create_household(
+ household_args={
+ "unicef_id": "HH-00-0000.0442",
+ "business_area": program.business_area,
+ "program": program,
+ "residence_status": HOST,
+ },
+ )
+ target_population.households.set([household])
+ yield target_population
+
+
@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
+ yield
@pytest.fixture
@@ -101,6 +132,7 @@ def add_targeting() -> None:
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")
+ yield
@pytest.mark.usefixtures("login")
@@ -175,11 +207,12 @@ def test_smoke_targeting_details_page(
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 "6" in pageTargetingDetails.getLabelFemaleChildren().text
+ assert "1" in pageTargetingDetails.getLabelMaleChildren().text
+ assert "2" in pageTargetingDetails.getLabelFemaleAdults().text
+ assert "1" in pageTargetingDetails.getLabelMaleAdults().text
+ assert "3" in pageTargetingDetails.getLabelTotalNumberOfHouseholds().text
+ assert "7" in pageTargetingDetails.getLabelTargetedIndividuals().text
assert "Households" in pageTargetingDetails.getTableTitle().text
expected_menu_items = [
"ID",
@@ -269,3 +302,492 @@ def test_create_targeting_for_normal_program(
actions = ActionChains(pageTargetingDetails.driver)
actions.move_to_element(pageTargetingDetails.getHouseholdTableCell(1, 1)).perform() # type: ignore
assert len(pageTargetingDetails.getHouseholdTableRows()) == 1
+
+
+@pytest.mark.usefixtures("login")
+class TestTargeting:
+ def test_targeting_create_use_ids_hh(
+ self,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ 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.getInputHouseholdids().send_keys(household_with_disability.unicef_id)
+ pageTargetingCreate.getInputName().send_keys(f"Target Population for {household_with_disability.unicef_id}")
+ pageTargetingCreate.clickButtonTargetPopulationCreate()
+ target_population = TargetPopulation.objects.get(
+ name=f"Target Population for {household_with_disability.unicef_id}"
+ )
+ assert (
+ "1"
+ == str(target_population.total_individuals_count)
+ == pageTargetingDetails.getLabelTargetedIndividuals().text
+ )
+ assert (
+ str(target_population.total_households_count) == pageTargetingDetails.getLabelTotalNumberOfHouseholds().text
+ )
+ assert str(target_population.status) in pageTargetingDetails.getLabelStatus().text
+
+ def test_targeting_create_use_ids_individual(
+ self,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ 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.getInputIndividualids().send_keys("IND-88-0000.0002")
+ pageTargetingCreate.getInputName().send_keys("Target Population for IND-88-0000.0002")
+ pageTargetingCreate.clickButtonTargetPopulationCreate()
+ target_population = TargetPopulation.objects.get(name="Target Population for IND-88-0000.0002")
+ assert (
+ "4"
+ == str(target_population.total_individuals_count)
+ == pageTargetingDetails.getLabelTargetedIndividuals().text
+ )
+ assert (
+ str(target_population.total_households_count) == pageTargetingDetails.getLabelTotalNumberOfHouseholds().text
+ )
+ assert str(target_population.status) in pageTargetingDetails.getLabelStatus().text
+ pageTargetingDetails.getButtonRebuild().click()
+
+ def test_targeting_rebuild(
+ self,
+ create_programs: None,
+ create_targeting: TargetPopulation,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ pageTargetingCreate: TargetingCreate,
+ ) -> None:
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.chooseTargetPopulations(0).click()
+ pageTargetingDetails.getLabelStatus()
+ pageTargetingDetails.getButtonRebuild().click()
+ pageTargetingDetails.getStatusContainer()
+ pageTargetingDetails.disappearStatusContainer()
+
+ def test_targeting_mark_ready(
+ self,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ filters: Filters,
+ pageTargetingDetails: TargetingDetails,
+ pageTargetingCreate: TargetingCreate,
+ ) -> None:
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ filters.selectFiltersSatus("OPEN")
+ pageTargeting.chooseTargetPopulations(0).click()
+ pageTargetingDetails.getLabelStatus()
+ pageTargetingDetails.getLockButton().click()
+ pageTargetingDetails.getLockPopupButton().click()
+ pageTargetingDetails.waitForLabelStatus("LOCKED")
+ pageTargetingDetails.getButtonMarkReady().click()
+ pageTargetingDetails.getButtonPopupMarkReady().click()
+ pageTargetingDetails.waitForLabelStatus("READY")
+
+ def test_copy_targeting(
+ self,
+ create_programs: None,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ pageTargetingCreate: TargetingCreate,
+ ) -> None:
+ program = Program.objects.get(name="Test Programm")
+ pageTargeting.selectGlobalProgramFilter(program.name).click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.chooseTargetPopulations(0).click()
+ pageTargetingDetails.getButtonTargetPopulationDuplicate().click()
+ pageTargetingDetails.getInputName().send_keys("a1!")
+ pageTargetingDetails.get_elements(pageTargetingDetails.buttonTargetPopulationDuplicate)[1].click()
+ pageTargetingDetails.disappearInputName()
+ assert "a1!" in pageTargetingDetails.getTitlePage().text
+ assert "OPEN" in pageTargetingDetails.getTargetPopulationStatus().text
+ assert "PROGRAMME" in pageTargetingDetails.getLabelizedFieldContainerProgramName().text
+ assert "Test Programm" in pageTargetingDetails.getLabelProgramme().text
+ assert "2" in pageTargetingDetails.getLabelTotalNumberOfHouseholds().text
+ assert "8" in pageTargetingDetails.getLabelTargetedIndividuals().text
+
+ def test_edit_targeting(
+ self,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ pageTargetingCreate: TargetingCreate,
+ ) -> None:
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.chooseTargetPopulations(0).click()
+ pageTargetingDetails.getButtonEdit().click()
+ pageTargetingDetails.getInputName().send_keys(Keys.CONTROL + "a")
+ pageTargetingDetails.getInputName().send_keys("New Test Data")
+ pageTargetingDetails.getButtonIconEdit().click()
+ pageTargetingDetails.getHouseholdSizeFrom().send_keys(Keys.CONTROL + "a")
+ pageTargetingDetails.getHouseholdSizeFrom().send_keys("0")
+ pageTargetingDetails.getHouseholdSizeTo().send_keys(Keys.CONTROL + "a")
+ pageTargetingDetails.getHouseholdSizeTo().send_keys("9")
+ pageTargetingCreate.get_elements(pageTargetingCreate.targetingCriteriaAddDialogSaveButton)[1].click()
+ pageTargetingCreate.getButtonSave().click()
+ pageTargetingDetails.getButtonEdit()
+ assert pageTargetingDetails.waitForTextTitlePage("New Test Data")
+ assert "9" in pageTargetingDetails.getCriteriaContainer().text
+
+ def test_delete_targeting(
+ self,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ ) -> None:
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.disappearLoadingRows()
+ old_list = pageTargeting.getTargetPopulationsRows()
+ assert 2 == len(old_list)
+ assert "Copy TP" in old_list[0].text
+
+ pageTargeting.chooseTargetPopulations(0).click()
+ pageTargetingDetails.getButtonDelete().click()
+ pageTargetingDetails.getDialogBox()
+ pageTargetingDetails.get_elements(pageTargetingDetails.buttonDelete)[1].click()
+ pageTargeting.disappearLoadingRows()
+ new_list = pageTargeting.getTargetPopulationsRows()
+ assert 1 == len(new_list)
+ assert "Test NEW TP" in new_list[0].text
+
+ def test_targeting_different_program_statuses(
+ self,
+ create_programs: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ pageTargetingCreate: TargetingCreate,
+ ) -> None:
+ program = Program.objects.get(name="Test Programm")
+ program.status = Program.DRAFT
+ program.save()
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.mouse_on_element(pageTargeting.getButtonInactiveCreateNew())
+ assert "Program has to be active to create a new Target Population" in pageTargeting.geTooltip().text
+ program.status = Program.ACTIVE
+ program.save()
+ pageTargeting.driver.refresh()
+ pageTargeting.getButtonCreateNew()
+ program.status = Program.FINISHED
+ program.save()
+ pageTargeting.driver.refresh()
+ pageTargeting.mouse_on_element(pageTargeting.getButtonInactiveCreateNew())
+ assert "Program has to be active to create a new Target Population" in pageTargeting.geTooltip().text
+
+ @pytest.mark.parametrize(
+ "test_data",
+ [
+ pytest.param(
+ {
+ "type": "SOCIAL",
+ "text": "Exclude People with Active Adjudication Ticket",
+ },
+ id="People",
+ ),
+ pytest.param(
+ {
+ "type": "STANDARD",
+ "text": "Exclude Households with Active Adjudication Ticket",
+ },
+ id="Program population",
+ ),
+ ],
+ )
+ def test_exclude_households_with_active_adjudication_ticket(
+ self,
+ test_data: dict,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ pageTargetingCreate: TargetingCreate,
+ ) -> None:
+ program = Program.objects.get(name="Test Programm")
+ program.data_collecting_type.type = test_data["type"]
+ program.data_collecting_type.save()
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.getButtonCreateNew().click()
+ pageTargeting.getCreateUseIDs().click()
+ pageTargetingCreate.getInputHouseholdids().send_keys(household_with_disability.unicef_id)
+ pageTargetingCreate.getInputName().send_keys(f"Test {household_with_disability.unicef_id}")
+ pageTargetingCreate.getInputFlagexcludeifactiveadjudicationticket().click()
+ pageTargetingCreate.clickButtonTargetPopulationCreate()
+ with pytest.raises(NoSuchElementException):
+ pageTargetingDetails.getCheckboxExcludeIfOnSanctionList().find_element(
+ By.CSS_SELECTOR, pageTargetingDetails.iconSelected
+ )
+ if test_data["type"] == "SOCIAL":
+ pageTargetingDetails.getCheckboxExcludePeopleIfActiveAdjudicationTicket()
+ pageTargetingDetails.getCheckboxExcludePeopleIfActiveAdjudicationTicket().find_element(
+ By.CSS_SELECTOR, pageTargetingDetails.iconSelected
+ )
+ assert (
+ test_data["text"]
+ in pageTargetingDetails.getCheckboxExcludePeopleIfActiveAdjudicationTicket()
+ .find_element(By.XPATH, "./..")
+ .text
+ )
+ elif test_data["type"] == "STANDARD":
+ pageTargetingDetails.getCheckboxExcludeIfActiveAdjudicationTicket()
+ pageTargetingDetails.getCheckboxExcludeIfActiveAdjudicationTicket().find_element(
+ By.CSS_SELECTOR, pageTargetingDetails.iconSelected
+ )
+ assert (
+ test_data["text"]
+ in pageTargetingDetails.getCheckboxExcludeIfActiveAdjudicationTicket()
+ .find_element(By.XPATH, "./..")
+ .text
+ )
+
+ @pytest.mark.parametrize(
+ "test_data",
+ [
+ pytest.param(
+ {
+ "type": "SOCIAL",
+ "text": "Exclude People with an active sanction screen flag",
+ },
+ id="People",
+ ),
+ pytest.param(
+ {
+ "type": "STANDARD",
+ "text": "Exclude Households with an active sanction screen flag",
+ },
+ id="Program population",
+ ),
+ ],
+ )
+ def test_exclude_households_with_sanction_screen_flag(
+ self,
+ test_data: dict,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ pageTargetingCreate: TargetingCreate,
+ ) -> None:
+ program = Program.objects.get(name="Test Programm")
+ program.data_collecting_type.type = test_data["type"]
+ program.data_collecting_type.save()
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.getButtonCreateNew().click()
+ pageTargeting.getCreateUseIDs().click()
+ pageTargetingCreate.getInputHouseholdids().send_keys(household_with_disability.unicef_id)
+ pageTargetingCreate.getInputName().send_keys(f"Test {household_with_disability.unicef_id}")
+ pageTargetingCreate.getInputFlagexcludeifonsanctionlist().click()
+ pageTargetingCreate.clickButtonTargetPopulationCreate()
+ pageTargetingDetails.getCheckboxExcludeIfOnSanctionList()
+ # ToDo: Add after merge to develop
+ # assert (
+ # test_data["text"]
+ # in pageTargetingDetails.getCheckboxExcludeIfOnSanctionList().find_element(By.XPATH, "./..").text
+ # )
+ pageTargetingDetails.getCheckboxExcludeIfOnSanctionList().find_element(
+ By.CSS_SELECTOR, pageTargetingDetails.iconSelected
+ )
+ with pytest.raises(NoSuchElementException):
+ pageTargetingDetails.getCheckboxExcludePeopleIfActiveAdjudicationTicket().find_element(
+ By.CSS_SELECTOR, pageTargetingDetails.iconSelected
+ )
+
+ def test_targeting_info_button(
+ self,
+ create_programs: None,
+ pageTargeting: Targeting,
+ ) -> None:
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.getButtonTargetPopulation().click()
+ pageTargeting.getTabFieldList()
+ pageTargeting.getTabTargetingDiagram().click()
+
+ def test_targeting_filters(
+ self,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ filters: Filters,
+ ) -> None:
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ filters.getFiltersSearch().send_keys("Copy")
+ filters.getButtonFiltersApply().click()
+ pageTargeting.countTargetPopulations(1)
+ assert "OPEN" in pageTargeting.getStatusContainer().text
+ filters.getButtonFiltersClear().click()
+ filters.getFiltersStatus().click()
+ filters.select_listbox_element("Open").click()
+ filters.getButtonFiltersApply().click()
+ pageTargeting.countTargetPopulations(1)
+ assert "OPEN" in pageTargeting.getStatusContainer().text
+ filters.getButtonFiltersClear().click()
+ filters.getFiltersTotalHouseholdsCountMin().send_keys("10")
+ filters.getFiltersTotalHouseholdsCountMax().send_keys("10")
+ filters.getButtonFiltersApply().click()
+ pageTargeting.countTargetPopulations(0)
+ filters.getButtonFiltersClear().click()
+ filters.getFiltersTotalHouseholdsCountMin().send_keys("1")
+ filters.getFiltersTotalHouseholdsCountMax().send_keys("3")
+ pageTargeting.countTargetPopulations(2)
+ filters.getButtonFiltersClear().click()
+
+ def test_targeting_and_labels(
+ self,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ ) -> None:
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.getColumnName().click()
+ pageTargeting.disappearLoadingRows()
+ assert "Copy TP" in pageTargeting.chooseTargetPopulations(0).text
+ pageTargeting.getColumnName().click()
+ pageTargeting.disappearLoadingRows()
+ assert "Test NEW TP" in pageTargeting.chooseTargetPopulations(0).text
+ pageTargeting.getColumnStatus().click()
+ pageTargeting.disappearLoadingRows()
+ assert "Test NEW TP" in pageTargeting.chooseTargetPopulations(0).text
+ pageTargeting.getColumnStatus().click()
+ pageTargeting.disappearLoadingRows()
+ assert "Copy TP" in pageTargeting.chooseTargetPopulations(0).text
+ pageTargeting.getColumnNumOfHouseholds().click()
+ pageTargeting.disappearLoadingRows()
+ assert "Test NEW TP" in pageTargeting.chooseTargetPopulations(0).text
+ pageTargeting.getColumnDateCreated().click()
+ pageTargeting.disappearLoadingRows()
+ assert "Test NEW TP" in pageTargeting.chooseTargetPopulations(0).text
+ pageTargeting.getColumnDateCreated().click()
+ pageTargeting.disappearLoadingRows()
+ assert "Copy TP" in pageTargeting.chooseTargetPopulations(0).text
+ pageTargeting.getColumnLastEdited().click()
+ pageTargeting.disappearLoadingRows()
+ assert "Test NEW TP" in pageTargeting.chooseTargetPopulations(0).text
+ pageTargeting.getColumnLastEdited().click()
+ pageTargeting.disappearLoadingRows()
+ assert "Copy TP" in pageTargeting.chooseTargetPopulations(0).text
+ pageTargeting.getColumnCreatedBy().click()
+ pageTargeting.disappearLoadingRows()
+ assert "est NEW TP" in pageTargeting.chooseTargetPopulations(0).text
+
+ def test_targeting_parametrized_rules_filters(
+ self,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ pageTargetingCreate: TargetingCreate,
+ ) -> None:
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.getButtonCreateNew().click()
+ pageTargeting.getButtonCreateNewByFilters().click()
+ assert "New Target Population" in pageTargetingCreate.getTitlePage().text
+ pageTargetingCreate.getAddCriteriaButton().click()
+ pageTargetingCreate.getAddPeopleRuleButton().click()
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().click()
+ pageTargetingCreate.select_listbox_element("Females Age 0 - 5").click()
+ pageTargetingCreate.getInputFiltersValueFrom(0).send_keys("0")
+ pageTargetingCreate.getInputFiltersValueTo(0).send_keys("1")
+ pageTargetingCreate.getInputFiltersValueTo(0).send_keys("1")
+ pageTargetingCreate.getButtonTargetPopulationAddCriteria().click()
+ pageTargetingCreate.getInputName().send_keys("Target Population for Females Age 0 - 5")
+ pageTargetingCreate.getInputFlagexcludeifactiveadjudicationticket().click()
+ pageTargetingCreate.clickButtonTargetPopulationCreate()
+ assert "Females Age 0 - 5: 11" in pageTargetingCreate.getCriteriaContainer().text
+
+ def test_targeting_parametrized_rules_filters_and_or(
+ self,
+ create_programs: None,
+ household_with_disability: Household,
+ add_targeting: None,
+ pageTargeting: Targeting,
+ pageTargetingDetails: TargetingDetails,
+ pageTargetingCreate: TargetingCreate,
+ ) -> None:
+ pageTargeting.selectGlobalProgramFilter("Test Programm").click()
+ pageTargeting.getNavTargeting().click()
+ pageTargeting.getButtonCreateNew().click()
+ pageTargeting.getButtonCreateNewByFilters().click()
+ assert "New Target Population" in pageTargetingCreate.getTitlePage().text
+ pageTargetingCreate.getAddCriteriaButton().click()
+ pageTargetingCreate.getAddPeopleRuleButton().click()
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().click()
+ pageTargetingCreate.select_listbox_element("Females Age 0 - 5").click()
+ pageTargetingCreate.getInputFiltersValueFrom(0).send_keys("0")
+ pageTargetingCreate.getInputFiltersValueTo(0).send_keys("1")
+ pageTargetingCreate.getButtonHouseholdRule().click()
+ pageTargetingCreate.getTargetingCriteriaAutoComplete(1).click()
+ pageTargetingCreate.select_listbox_element("Village").click()
+ pageTargetingCreate.getInputFiltersValue(1).send_keys("Testtown")
+ pageTargetingCreate.getButtonIndividualRule().click()
+ pageTargetingCreate.getTargetingCriteriaAutoCompleteIndividual().click()
+ pageTargetingCreate.select_listbox_element("Does the Individual have disability?").click()
+ pageTargetingCreate.getSelectMany().click()
+ pageTargetingCreate.select_multiple_option_by_name(HEARING, SEEING)
+ pageTargetingCreate.getTargetingCriteriaAddDialogSaveButton().click()
+ assert "Females Age 0 - 5: 1" in pageTargetingCreate.getCriteriaContainer().text
+ assert "Village: Testtown" in pageTargetingCreate.getCriteriaContainer().text
+ assert (
+ "Does the Individual have disability?: Difficulty hearing (even if using a hearing aid), Difficulty seeing (even if wearing glasses)"
+ in pageTargetingCreate.getCriteriaContainer().text
+ )
+ pageTargetingCreate.getButtonEdit().click()
+ pageTargetingCreate.getTargetingCriteriaAutoCompleteIndividual()
+ pageTargetingCreate.get_elements(pageTargetingCreate.targetingCriteriaAddDialogSaveButton)[1].click()
+ pageTargetingCreate.getInputName().send_keys("Target Population")
+ assert "ADD 'OR'FILTER" in pageTargetingCreate.getTargetingCriteriaAddDialogSaveButton().text
+ pageTargetingCreate.getTargetingCriteriaAddDialogSaveButton().click()
+ pageTargetingCreate.getAddHouseholdRuleButton().click()
+ pageTargetingCreate.getTargetingCriteriaAutoComplete().click()
+ pageTargetingCreate.select_listbox_element("Males age 0 - 5 with disability").click()
+ pageTargetingCreate.getInputFiltersValueFrom(0).send_keys("1")
+ pageTargetingCreate.getInputFiltersValueTo(0).send_keys("10")
+ pageTargetingCreate.get_elements(pageTargetingCreate.targetingCriteriaAddDialogSaveButton)[1].click()
+ pageTargetingCreate.getTargetPopulationSaveButton().click()
+ assert "Females Age 0 - 5: 1" in pageTargetingCreate.getCriteriaContainer().text
+ assert "Village: Testtown" in pageTargetingCreate.getCriteriaContainer().text
+ assert (
+ "Does the Individual have disability?: Difficulty hearing (even if using a hearing aid), Difficulty seeing (even if wearing glasses)"
+ in pageTargetingCreate.getCriteriaContainer().text
+ )
+ assert (
+ "Males age 0 - 5 with disability: 1 -10"
+ in pageTargetingCreate.get_elements(pageTargetingCreate.criteriaContainer)[1].text
+ )
diff --git a/deployment/docker-compose.selenium.yml b/deployment/docker-compose.selenium.yml
index 7fa7859afb..7d17e14278 100644
--- a/deployment/docker-compose.selenium.yml
+++ b/deployment/docker-compose.selenium.yml
@@ -33,7 +33,7 @@ services:
command: |
bash -c "
waitforit -host=db -port=5432 -timeout=30
- pytest -svvv selenium_tests --reruns 3 --reruns-delay 1 --cov-report xml:./coverage.xml --html-report=./report/report.html --randomly-seed=42
+ pytest -svvv selenium_tests --cov-report xml:./coverage.xml --html-report=./report/report.html --randomly-seed=42
"
depends_on:
db:
diff --git a/frontend/src/components/targeting/TargetPopulationCore.tsx b/frontend/src/components/targeting/TargetPopulationCore.tsx
index 44097e944e..36802db922 100644
--- a/frontend/src/components/targeting/TargetPopulationCore.tsx
+++ b/frontend/src/components/targeting/TargetPopulationCore.tsx
@@ -101,11 +101,15 @@ export const TargetPopulationCore = ({
{householdIds.length > 0 && (
- {householdIds}
+
+ {householdIds}
+
)}
{individualIds.length > 0 && (
- {individualIds}
+
+ {individualIds}
+
)}