Skip to content

Commit

Permalink
Selenium - Targeting tests (#3883)
Browse files Browse the repository at this point in the history
* Init

* Test test_targeting_create_use_ids

* Add more tests

* Add more tests

* not fixed

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Test

* Added test_exclude_households_with_sanction_screen_flag

* Test

* Test2

* Added parametrization

* Black

* test_targeting_filters_and_labels

* Black

* Black

* test_targeting_parametrized_rules_filters

* test_targeting_parametrized_rules_filters_and_or test_targeting_parametrized_rules_filters

* test_targeting_parametrized_rules_filters_and_or test_targeting_parametrized_rules_filters

* test_targeting_parametrized_rules_filters_and_or

* Try to fix deadlock

* Add `order_by`

* Change `return` to `yield`

* Revert change

* Increase delay

* Remove outdated test

* Fixed

---------

Co-authored-by: Patryk Dabrowski <patryk.dabrowski@kellton.com>
Co-authored-by: Patryk Dabrowski <patryk.dabrowski@tivix.com>
Co-authored-by: Pavlo Mokiichuk <pv.pasha.pv@gmail.com>
  • Loading branch information
4 people authored Jul 10, 2024
1 parent 46d5ff1 commit 0b9f2db
Show file tree
Hide file tree
Showing 27 changed files with 862 additions and 320 deletions.
2 changes: 1 addition & 1 deletion backend/hct_mis_api/apps/core/base_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
1 change: 1 addition & 0 deletions backend/hct_mis_api/apps/core/fixtures/data-selenium.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [],
Expand Down
27 changes: 16 additions & 11 deletions backend/hct_mis_api/apps/household/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
12 changes: 6 additions & 6 deletions backend/hct_mis_api/apps/targeting/fixtures/data-cypress.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
},
Expand Down
12 changes: 10 additions & 2 deletions backend/hct_mis_api/apps/targeting/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
7 changes: 4 additions & 3 deletions backend/selenium_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down
10 changes: 5 additions & 5 deletions backend/selenium_tests/drawer/test_drawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion backend/selenium_tests/filters/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
6 changes: 3 additions & 3 deletions backend/selenium_tests/grievance/feedback/test_feedback.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@
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
def add_households(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/registration_data/fixtures/data-cypress.json")
call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/household/fixtures/data-cypress.json")
return
yield


@pytest.fixture
def create_programs(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/core/fixtures/data-selenium.json")
call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/program/fixtures/data-cypress.json")
return
yield


@pytest.mark.usefixtures("login")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@
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
def add_households(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/registration_data/fixtures/data-cypress.json")
call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/household/fixtures/data-cypress.json")
return
yield


@pytest.fixture
def create_programs(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/core/fixtures/data-selenium.json")
call_command("loaddata", f"{settings.PROJECT_ROOT}/apps/program/fixtures/data-cypress.json")
return
yield


@pytest.mark.usefixtures("login")
Expand Down
9 changes: 8 additions & 1 deletion backend/selenium_tests/helpers/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


class Common:
DEFAULT_TIMEOUT = 10
DEFAULT_TIMEOUT = 20

def __init__(self, driver: Chrome):
self.driver = driver
Expand Down Expand Up @@ -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)))
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
23 changes: 18 additions & 5 deletions backend/selenium_tests/page_object/filters.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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)

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 0b9f2db

Please sign in to comment.