This is just to make sure we don't try and look for an element that doesn't exist for every user.
158 lines
5.8 KiB
Python
158 lines
5.8 KiB
Python
import os
|
|
import re
|
|
import csv
|
|
import urllib.parse as urlparse
|
|
from urllib.parse import parse_qs
|
|
|
|
import requests
|
|
from selenium import webdriver
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.common.keys import Keys
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
|
|
|
|
class BaseTester:
|
|
BASE_URL = "https://crm-dev.caat.org.uk/"
|
|
USERNAME = "roxie"
|
|
PASSWORD = ""
|
|
|
|
def __init__(self):
|
|
fireFoxOptions = webdriver.FirefoxOptions()
|
|
fireFoxOptions.headless = True
|
|
self.browser = webdriver.Firefox(options=fireFoxOptions)
|
|
self.wait = WebDriverWait(self.browser, 20)
|
|
|
|
def login(self):
|
|
""" Login to civicrm so we can continue with the proper cookies """
|
|
self.browser.get(self.BASE_URL)
|
|
username = self.browser.find_element_by_id("edit-name")
|
|
password = self.browser.find_element_by_id("edit-pass")
|
|
submit = self.browser.find_element_by_id("edit-submit")
|
|
username.send_keys(self.USERNAME)
|
|
password.send_keys(self.PASSWORD)
|
|
submit.click()
|
|
|
|
# Wait for the js elements load so we know the cookies are good.
|
|
# Waits for "Recent Items" part of sidebar which is unique when logged in
|
|
self.wait.until(
|
|
EC.visibility_of_element_located((By.ID, "block-civicrm-2"))
|
|
)
|
|
|
|
def logout(self):
|
|
self.browser.get(self.BASE_URL + "/user/logout")
|
|
# Wait for the next page to load to finish logging out
|
|
self.wait.until(
|
|
EC.visibility_of_element_located((By.ID, "tabs-wrapper"))
|
|
)
|
|
|
|
def find_element_by_id(self, *args, **kwargs):
|
|
return self.browser.find_element_by_id(*args, **kwargs)
|
|
|
|
def find_element_by_css_selector(self, *args, **kwargs):
|
|
return self.browser.find_element_by_css_selector(*args, **kwargs)
|
|
|
|
def wait_until_visible(self, locator):
|
|
return self.wait.until(EC.visibility_of_element_located(locator))
|
|
|
|
|
|
class ContactExport(BaseTester):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.search_url = "https://crm-dev.caat.org.uk/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):
|
|
session_cookie = {}
|
|
for cookie in self.browser.get_cookies():
|
|
if re.findall(r"^SSESS.*", cookie.get("name")):
|
|
session_cookie = cookie
|
|
if not session_cookie:
|
|
print("NO SESSION COOKIE FOUND. Are you logged in?")
|
|
raise RuntimeError("No session cookie found.")
|
|
|
|
session = requests.Session()
|
|
session.cookies.update(
|
|
{session_cookie["name"]: session_cookie["value"]}
|
|
)
|
|
qf_key = self.get_export_id()
|
|
data = {
|
|
"qfKey": qf_key,
|
|
"entryURL": "https://crm-dev.caat.org.uk/civicrm/contact/search",
|
|
"_qf_Select_next": "Continue",
|
|
"exportOption": 1,
|
|
"mergeOption": 0,
|
|
"postal_greeting": 1,
|
|
"addressee": 1,
|
|
}
|
|
req = session.request(
|
|
"POST",
|
|
"https://crm-dev.caat.org.uk/civicrm/contact/search",
|
|
data=data
|
|
)
|
|
return req
|
|
|
|
def calculate_exported_contacts_number(self):
|
|
req = self.download_csv()
|
|
file_name = "/tmp/exportedRecords.csv"
|
|
with open(file_name, "w") as csv_file:
|
|
csv_file.write(req.text)
|
|
with open(file_name, "r") as csv_file:
|
|
# Dict reader should remove headers
|
|
exported_csv = csv.DictReader(csv_file)
|
|
exported_number_exports = sum(1 for row in exported_csv)
|
|
os.remove(file_name)
|
|
return exported_number_exports
|
|
|
|
def get_export_id(self) -> str:
|
|
export_page_url = self.browser.current_url
|
|
parsed = urlparse.urlparse(export_page_url)
|
|
return parse_qs(parsed.query)['qfKey']
|
|
|
|
def test(self, search_term: str):
|
|
try:
|
|
self.login()
|
|
self.browser.get(self.search_url)
|
|
search_box = self.find_element_by_id("sort_name")
|
|
search_box.send_keys(search_term)
|
|
search_box.send_keys(Keys.ENTER)
|
|
self.wait_until_visible(
|
|
(By.ID, "alpha-filter")
|
|
) #wait for table to load
|
|
|
|
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.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"))
|
|
|
|
req = self.download_csv()
|
|
exported_number_exports = self.calculate_exported_contacts_number()
|
|
if exported_number_exports == (result_no):
|
|
print(
|
|
"TEST PASSED: Number of expected contact exports for '{}' matches actual number of exports - Expected: {}, Actual: {}"
|
|
.format(search_term, result_no, exported_number_exports)
|
|
)
|
|
else:
|
|
print(
|
|
"TEST FAILED: Number of expected contact exports for '{}' WAS NOT EQUAL to actual number of exports - Expected: {}, Actual: {}"
|
|
.format(search_term, result_no, exported_number_exports)
|
|
)
|
|
finally:
|
|
self.logout()
|
|
self.browser.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
ContactExport().test("John")
|