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 BASE_URL = "https://crm-dev.caat.org.uk/" USERNAME = "roxie" PASSWORD = "" fireFoxOptions = webdriver.FirefoxOptions() fireFoxOptions.headless = True browser = webdriver.Firefox(options=fireFoxOptions) def login(): """ Login to civicrm so we can continue with the proper cookies """ browser.get(BASE_URL) username = browser.find_element_by_id("edit-name") password = browser.find_element_by_id("edit-pass") submit = browser.find_element_by_id("edit-submit") username.send_keys(USERNAME) password.send_keys(PASSWORD) submit.click() wait = WebDriverWait(browser, 20) # Wait for the js elements load so we know the cookies are good. wait.until( EC.visibility_of_element_located( ( By.CSS_SELECTOR, "#widget-6 > div:nth-child(1) > div:nth-child(1) > h3:nth-child(4)" ) ) ) def test_contactexport(search_term: str): search_url = "https://crm-dev.caat.org.uk/civicrm/contact/search" browser.get(search_url) search_box = browser.find_element_by_id("sort_name") search_box.send_keys(search_term) search_box.send_keys(Keys.ENTER) wait = WebDriverWait(browser, 60) wait.until( EC.visibility_of_element_located( ( By.ID, "alpha-filter" #wait for table to load ) ) ) results_text = browser.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]) browser.find_element_by_id("CIVICRM_QFID_ts_all_4").click() browser.find_element_by_id("select2-chosen-4").click() browser.find_element_by_id("select2-result-label-15").click() wait.until( EC.visibility_of_element_located((By.CSS_SELECTOR, ".crm-block")) ) browser.save_screenshot("screenshot.png") export_page_url = browser.current_url parsed = urlparse.urlparse(export_page_url) qf_key = parse_qs(parsed.query)['qfKey'] session_cookie = {} for cookie in 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?") return session = requests.Session() session.cookies.update({session_cookie["name"]: session_cookie["value"]}) 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 ) with open("tmp.csv", "w") as csv_file: csv_file.write(req.text) with open("tmp.csv", "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) 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) ) # search > contact > add something in the name thing > select all button > change magic dropdown to export > continue and it will do the download def logout(): wait = WebDriverWait(browser, 20) browser.get(BASE_URL + "/user/logout") # Wait for the next page to load to finish logging out wait.until(EC.visibility_of_element_located((By.ID, "tabs-wrapper"))) try: login() test_contactexport("john") test_contactexport("j") test_contactexport("e") #wait_for_download() logout() finally: try: browser.close() except: pass