refactor: improved contact export tests
This commit is contained in:
parent
abdcce6042
commit
90e1d6e119
4
.gitignore
vendored
4
.gitignore
vendored
@ -3,4 +3,6 @@
|
|||||||
geckodriver.log
|
geckodriver.log
|
||||||
*.png
|
*.png
|
||||||
*.lock
|
*.lock
|
||||||
.vscode
|
.vscode
|
||||||
|
*.pyc
|
||||||
|
*__pycache__
|
@ -28,7 +28,7 @@ class BaseTester:
|
|||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level="INFO",
|
level="INFO",
|
||||||
format="%(message)s",
|
format="%(message)s",
|
||||||
datefmt="[%X]",
|
datefmt="[%X]", # TODO: Change date format
|
||||||
handlers=[RichHandler()]
|
handlers=[RichHandler()]
|
||||||
)
|
)
|
||||||
self.log = logging.getLogger("civiCRM-tester")
|
self.log = logging.getLogger("civiCRM-tester")
|
||||||
@ -145,6 +145,12 @@ class BaseTester:
|
|||||||
|
|
||||||
|
|
||||||
class SearchExportTester(BaseTester):
|
class SearchExportTester(BaseTester):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.search_url = self.base_url + "/civicrm/contact/search"
|
||||||
|
self.contact_selectall_id = "CIVICRM_QFID_ts_all_4"
|
||||||
|
self.contact_dropdown_id = "select2-chosen-4"
|
||||||
|
|
||||||
def _get_export_id(self) -> str:
|
def _get_export_id(self) -> str:
|
||||||
"""Parses url to get the param used to ID what search we are currently doing"""
|
"""Parses url to get the param used to ID what search we are currently doing"""
|
||||||
export_page_url = self.browser.current_url
|
export_page_url = self.browser.current_url
|
||||||
@ -153,7 +159,37 @@ class SearchExportTester(BaseTester):
|
|||||||
self.debug("got qf_key '%s' from url" % qf_key)
|
self.debug("got qf_key '%s' from url" % qf_key)
|
||||||
return qf_key
|
return qf_key
|
||||||
|
|
||||||
def download(self, data: dict) -> requests.Response:
|
def _get_contact_search_number(self) -> int:
|
||||||
|
"""Grabs the number of reported matches in a search on civicrm page"""
|
||||||
|
results = self.find_element_by_css_selector(
|
||||||
|
".form-layout-compressed > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2) > label:nth-child(2)"
|
||||||
|
)
|
||||||
|
matches = re.findall(r"(\d+)", results.text)
|
||||||
|
# Should just be one match in normal cases
|
||||||
|
result_no = int(matches[0])
|
||||||
|
return result_no
|
||||||
|
|
||||||
|
def _wait_for_search_to_load(self):
|
||||||
|
"""Wrapper to wait for a contact search to load
|
||||||
|
MUST BE CALLED AFTER YOU HAVE SEARCHED"""
|
||||||
|
# "alpha-filter" is element of the table
|
||||||
|
self.wait_until_visible((By.ID, "alpha-filter"))
|
||||||
|
self.debug("table of results has loaded")
|
||||||
|
|
||||||
|
def _select_option_from_magic_dropdown(self, option_id: str):
|
||||||
|
"""
|
||||||
|
Wrapper to click an option from the dropdown menu within the search on civicrm.
|
||||||
|
Magic dropdown because it literally is not how dropdowns should work at all
|
||||||
|
All options have an ID but this can change depending on the context of how you get to the search page
|
||||||
|
MUST BE CALLED WHEN ON THE SEARCH RESULTS PAGE
|
||||||
|
"""
|
||||||
|
self.debug("exporting results using the magic dropdown")
|
||||||
|
self.find_element_by_id(self.contact_selectall_id).click()
|
||||||
|
self.find_element_by_id(self.contact_dropdown_id).click()
|
||||||
|
self.find_element_by_id(option_id).click()
|
||||||
|
self.wait_until_visible((By.CSS_SELECTOR, ".crm-block"))
|
||||||
|
|
||||||
|
def download_export(self, data: dict) -> requests.Response:
|
||||||
"""
|
"""
|
||||||
Download exports from searches manually using requests
|
Download exports from searches manually using requests
|
||||||
This is because managing downloads within Selenium is a nightmare
|
This is because managing downloads within Selenium is a nightmare
|
||||||
@ -175,10 +211,8 @@ class SearchExportTester(BaseTester):
|
|||||||
# Most of this data is replicating the export settings so that the response is the csv data
|
# Most of this data is replicating the export settings so that the response is the csv data
|
||||||
data = {
|
data = {
|
||||||
"qfKey": self._get_export_id(),
|
"qfKey": self._get_export_id(),
|
||||||
"entryURL": self.base_url + "/civicrm/contact/search",
|
"entryURL": self.search_url,
|
||||||
**data # Add provided export data required for specific export requests
|
**data # Add provided export data required for specific export requests
|
||||||
}
|
}
|
||||||
res = session.request(
|
res = session.request("POST", self.search_url, data=data)
|
||||||
"POST", self.base_url + "/civicrm/contact/search", data=data
|
|
||||||
)
|
|
||||||
return res
|
return res
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import csv
|
import csv
|
||||||
import io
|
import io
|
||||||
import re
|
|
||||||
|
|
||||||
from selenium.webdriver.common.by import By
|
|
||||||
from selenium.webdriver.common.keys import Keys
|
from selenium.webdriver.common.keys import Keys
|
||||||
|
|
||||||
from .base import SearchExportTester
|
from .base import SearchExportTester
|
||||||
@ -16,14 +14,10 @@ class ContactExport(SearchExportTester):
|
|||||||
self.desc(
|
self.desc(
|
||||||
"Testing if exporting contacts from a search returns a CSV file with all expected contacts."
|
"Testing if exporting contacts from a search returns a CSV file with all expected contacts."
|
||||||
)
|
)
|
||||||
self.search_url = self.base_url + "/civicrm/contact/search"
|
|
||||||
|
|
||||||
self.contact_selectall_id = "CIVICRM_QFID_ts_all_4"
|
|
||||||
self.contact_dropdown_id = "select2-chosen-4"
|
|
||||||
self.contact_exportoption_id = "select2-result-label-15"
|
self.contact_exportoption_id = "select2-result-label-15"
|
||||||
|
|
||||||
def download_csv(self):
|
def download_csv(self):
|
||||||
# Data of the request that is specific for this export and not genertic like qr_key
|
# Data of the request that is specific for this export and not generic like qr_key
|
||||||
data = {
|
data = {
|
||||||
"_qf_Select_next": "Continue",
|
"_qf_Select_next": "Continue",
|
||||||
"exportOption": 1,
|
"exportOption": 1,
|
||||||
@ -31,7 +25,7 @@ class ContactExport(SearchExportTester):
|
|||||||
"postal_greeting": 1,
|
"postal_greeting": 1,
|
||||||
"addressee": 1,
|
"addressee": 1,
|
||||||
}
|
}
|
||||||
return self.download(data)
|
return self.download_export(data)
|
||||||
|
|
||||||
def calculate_exported_contacts_number(self) -> int:
|
def calculate_exported_contacts_number(self) -> int:
|
||||||
"""
|
"""
|
||||||
@ -41,7 +35,7 @@ class ContactExport(SearchExportTester):
|
|||||||
res = self.download_csv()
|
res = self.download_csv()
|
||||||
csv_file = io.StringIO(res.text)
|
csv_file = io.StringIO(res.text)
|
||||||
|
|
||||||
# Dict reader should remove headers
|
# DictReader removes header from count
|
||||||
exported_csv = csv.DictReader(csv_file)
|
exported_csv = csv.DictReader(csv_file)
|
||||||
exported_number_exports = sum(1 for row in exported_csv)
|
exported_number_exports = sum(1 for row in exported_csv)
|
||||||
self.debug(
|
self.debug(
|
||||||
@ -66,24 +60,9 @@ class ContactExport(SearchExportTester):
|
|||||||
search_box.send_keys(search_term)
|
search_box.send_keys(search_term)
|
||||||
search_box.send_keys(Keys.ENTER)
|
search_box.send_keys(Keys.ENTER)
|
||||||
self.debug("searching for contacts with term '%s'" % search_term)
|
self.debug("searching for contacts with term '%s'" % search_term)
|
||||||
self.wait_until_visible(
|
self._wait_for_search_to_load()
|
||||||
(By.ID, "alpha-filter")
|
result_no = self._get_contact_search_number()
|
||||||
) #wait for table to load
|
self._select_option_from_magic_dropdown(self.contact_exportoption_id)
|
||||||
self.debug("table of results has loaded")
|
|
||||||
|
|
||||||
results_text = self.find_element_by_css_selector(
|
|
||||||
".form-layout-compressed > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2) > label:nth-child(2)"
|
|
||||||
).text
|
|
||||||
matches = re.findall(
|
|
||||||
r"(\d+)", results_text
|
|
||||||
) # Should just be one match in normal cases
|
|
||||||
result_no = int(matches[0])
|
|
||||||
|
|
||||||
self.debug("exporting results using the magic dropdown")
|
|
||||||
self.find_element_by_id(self.contact_selectall_id).click()
|
|
||||||
self.find_element_by_id(self.contact_dropdown_id).click()
|
|
||||||
self.find_element_by_id(self.contact_exportoption_id).click()
|
|
||||||
self.wait_until_visible((By.CSS_SELECTOR, ".crm-block"))
|
|
||||||
|
|
||||||
exported_number_exports = self.calculate_exported_contacts_number()
|
exported_number_exports = self.calculate_exported_contacts_number()
|
||||||
if exported_number_exports == (result_no):
|
if exported_number_exports == (result_no):
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import io
|
import io
|
||||||
import re
|
|
||||||
|
|
||||||
from pdfminer.high_level import extract_text
|
from pdfminer.high_level import extract_text
|
||||||
from selenium.webdriver.common.by import By
|
|
||||||
from selenium.webdriver.common.keys import Keys
|
from selenium.webdriver.common.keys import Keys
|
||||||
|
|
||||||
from .base import SearchExportTester
|
from .base import SearchExportTester
|
||||||
@ -16,12 +14,9 @@ class SteeringCommitteePrintLabels(SearchExportTester):
|
|||||||
self.desc(
|
self.desc(
|
||||||
"Testing the pdf labels for the SteeringCommittee show all contacts names"
|
"Testing the pdf labels for the SteeringCommittee show all contacts names"
|
||||||
)
|
)
|
||||||
self.search_url = self.base_url + "/civicrm/contact/search"
|
|
||||||
self.group_dropdown = "s2id_autogen2"
|
self.group_dropdown = "s2id_autogen2"
|
||||||
self.search_button = "_qf_Basic_refresh"
|
self.search_button = "_qf_Basic_refresh"
|
||||||
self.mail_label_option = "select2-result-label-19"
|
self.mail_label_option = "select2-result-label-19"
|
||||||
self.contact_selectall_id = "CIVICRM_QFID_ts_all_4"
|
|
||||||
self.contact_dropdown_id = "select2-chosen-4"
|
|
||||||
# Using this to count amount of people in the exported pdf
|
# Using this to count amount of people in the exported pdf
|
||||||
# This will fail if someone is added that doesn't have a UK adddress
|
# This will fail if someone is added that doesn't have a UK adddress
|
||||||
self.pdf_search_string = "UNITED KINGDOM"
|
self.pdf_search_string = "UNITED KINGDOM"
|
||||||
@ -32,24 +27,10 @@ class SteeringCommitteePrintLabels(SearchExportTester):
|
|||||||
group_dropdown.click()
|
group_dropdown.click()
|
||||||
group_dropdown.send_keys("Steering Committee" + Keys.ENTER)
|
group_dropdown.send_keys("Steering Committee" + Keys.ENTER)
|
||||||
self.find_element_by_id(self.search_button).click()
|
self.find_element_by_id(self.search_button).click()
|
||||||
self.wait_until_visible(
|
self._wait_for_search_to_load()
|
||||||
(By.ID, "alpha-filter")
|
result_no = self._get_contact_search_number()
|
||||||
) #wait for table to load
|
|
||||||
self.debug("table of results has loaded")
|
|
||||||
# TODO: Refactor this in base class as a helper function because we do this in another test
|
|
||||||
results_text = self.find_element_by_css_selector(
|
|
||||||
".form-layout-compressed > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2) > label:nth-child(2)"
|
|
||||||
).text
|
|
||||||
matches = re.findall(
|
|
||||||
r"(\d+)", results_text
|
|
||||||
) # Should just be one match in normal cases
|
|
||||||
result_no = int(matches[0])
|
|
||||||
self.debug("exporting results using the magic dropdown")
|
self.debug("exporting results using the magic dropdown")
|
||||||
self.find_element_by_id(self.contact_selectall_id).click()
|
self._select_option_from_magic_dropdown(self.mail_label_option)
|
||||||
self.find_element_by_id(self.contact_dropdown_id).click()
|
|
||||||
self.find_element_by_id(self.mail_label_option).click()
|
|
||||||
|
|
||||||
self.wait_until_visible((By.CSS_SELECTOR, ".crm-block"))
|
|
||||||
# By omitting the field, we are effectively disabling the do not mail filter
|
# By omitting the field, we are effectively disabling the do not mail filter
|
||||||
data = {
|
data = {
|
||||||
"_qf_default": "Label:submit",
|
"_qf_default": "Label:submit",
|
||||||
@ -58,7 +39,7 @@ class SteeringCommitteePrintLabels(SearchExportTester):
|
|||||||
"location_type_id": "",
|
"location_type_id": "",
|
||||||
"_qf_Label_submit": "Make+Mailing+Labels"
|
"_qf_Label_submit": "Make+Mailing+Labels"
|
||||||
}
|
}
|
||||||
res = self.download(data)
|
res = self.download_export(data)
|
||||||
pdf_text = extract_text(io.BytesIO(res.content))
|
pdf_text = extract_text(io.BytesIO(res.content))
|
||||||
label_count = pdf_text.count(self.pdf_search_string)
|
label_count = pdf_text.count(self.pdf_search_string)
|
||||||
if result_no == label_count:
|
if result_no == label_count:
|
||||||
|
Loading…
Reference in New Issue
Block a user