refactor: improved contact export tests

This commit is contained in:
Roxie Gibson 2021-01-25 21:21:14 +00:00
parent abdcce6042
commit 90e1d6e119
Signed by untrusted user: roxxers
GPG Key ID: 5D0140EDEE123F4D
4 changed files with 53 additions and 57 deletions

4
.gitignore vendored
View File

@ -3,4 +3,6 @@
geckodriver.log
*.png
*.lock
.vscode
.vscode
*.pyc
*__pycache__

View File

@ -28,7 +28,7 @@ class BaseTester:
logging.basicConfig(
level="INFO",
format="%(message)s",
datefmt="[%X]",
datefmt="[%X]", # TODO: Change date format
handlers=[RichHandler()]
)
self.log = logging.getLogger("civiCRM-tester")
@ -145,6 +145,12 @@ class 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:
"""Parses url to get the param used to ID what search we are currently doing"""
export_page_url = self.browser.current_url
@ -153,7 +159,37 @@ class SearchExportTester(BaseTester):
self.debug("got qf_key '%s' from url" % 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
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
data = {
"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
}
res = session.request(
"POST", self.base_url + "/civicrm/contact/search", data=data
)
res = session.request("POST", self.search_url, data=data)
return res

View File

@ -1,8 +1,6 @@
import csv
import io
import re
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from .base import SearchExportTester
@ -16,14 +14,10 @@ class ContactExport(SearchExportTester):
self.desc(
"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"
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 = {
"_qf_Select_next": "Continue",
"exportOption": 1,
@ -31,7 +25,7 @@ class ContactExport(SearchExportTester):
"postal_greeting": 1,
"addressee": 1,
}
return self.download(data)
return self.download_export(data)
def calculate_exported_contacts_number(self) -> int:
"""
@ -41,7 +35,7 @@ class ContactExport(SearchExportTester):
res = self.download_csv()
csv_file = io.StringIO(res.text)
# Dict reader should remove headers
# DictReader removes header from count
exported_csv = csv.DictReader(csv_file)
exported_number_exports = sum(1 for row in exported_csv)
self.debug(
@ -66,24 +60,9 @@ class ContactExport(SearchExportTester):
search_box.send_keys(search_term)
search_box.send_keys(Keys.ENTER)
self.debug("searching for contacts with term '%s'" % search_term)
self.wait_until_visible(
(By.ID, "alpha-filter")
) #wait for table to load
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"))
self._wait_for_search_to_load()
result_no = self._get_contact_search_number()
self._select_option_from_magic_dropdown(self.contact_exportoption_id)
exported_number_exports = self.calculate_exported_contacts_number()
if exported_number_exports == (result_no):

View File

@ -1,8 +1,6 @@
import io
import re
from pdfminer.high_level import extract_text
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from .base import SearchExportTester
@ -16,12 +14,9 @@ class SteeringCommitteePrintLabels(SearchExportTester):
self.desc(
"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.search_button = "_qf_Basic_refresh"
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
# This will fail if someone is added that doesn't have a UK adddress
self.pdf_search_string = "UNITED KINGDOM"
@ -32,24 +27,10 @@ class SteeringCommitteePrintLabels(SearchExportTester):
group_dropdown.click()
group_dropdown.send_keys("Steering Committee" + Keys.ENTER)
self.find_element_by_id(self.search_button).click()
self.wait_until_visible(
(By.ID, "alpha-filter")
) #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._wait_for_search_to_load()
result_no = self._get_contact_search_number()
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.mail_label_option).click()
self.wait_until_visible((By.CSS_SELECTOR, ".crm-block"))
self._select_option_from_magic_dropdown(self.mail_label_option)
# By omitting the field, we are effectively disabling the do not mail filter
data = {
"_qf_default": "Label:submit",
@ -58,7 +39,7 @@ class SteeringCommitteePrintLabels(SearchExportTester):
"location_type_id": "",
"_qf_Label_submit": "Make+Mailing+Labels"
}
res = self.download(data)
res = self.download_export(data)
pdf_text = extract_text(io.BytesIO(res.content))
label_count = pdf_text.count(self.pdf_search_string)
if result_no == label_count: