-
Notifications
You must be signed in to change notification settings - Fork 0
/
tennis.py
111 lines (94 loc) · 5.55 KB
/
tennis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import os
import datetime
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from utils import handle_screenshot
from dotenv import load_dotenv
# load environmental variables
load_dotenv()
class TennisCourtBooking:
def __init__(self, driver, wait):
self.driver = driver
self.wait = wait
self.today = datetime.datetime.now().strftime("%A")
self.url = os.getenv("TENNISHACK_URL")
self.booking_url = os.getenv('TENNISHACK_BOOKING_URL')
self.username = os.getenv('TENNISHACK_USERNAME')
self.password = os.getenv('TENNISHACK_PASSWORD')
def login(self):
try:
self.driver.get(self.url)
print('Page loaded')
username_el = self.driver.find_element(By.CSS_SELECTOR,'#p_lt_ContentWidgets_pageplaceholder_p_lt_zoneContent_CHO_Widget_LoginFormWithFullscreenBackground_XLarge_loginCtrl_BaseLogin_UserName')
password_el = self.driver.find_element(By.CSS_SELECTOR,'#p_lt_ContentWidgets_pageplaceholder_p_lt_zoneContent_CHO_Widget_LoginFormWithFullscreenBackground_XLarge_loginCtrl_BaseLogin_Password')
login_button_el = self.driver.find_element(By.CSS_SELECTOR,'#p_lt_ContentWidgets_pageplaceholder_p_lt_zoneContent_CHO_Widget_LoginFormWithFullscreenBackground_XLarge_loginCtrl_BaseLogin_LoginButton')
username_el.send_keys(self.username)
password_el.send_keys(self.password)
login_button_el.click()
print('Logged in')
except Exception as e:
print(f'Error logging into page: {e}')
handle_screenshot(self.driver)
def navigate_to_booking_page(self):
try:
self.driver.get(self.booking_url)
print('Successfully navigated to booking page')
self.wait.until(EC.frame_to_be_available_and_switch_to_it(self.driver.find_element(By.XPATH, '//*[@id="module"]')))
self.wait.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="form1"]/div[3]/div[1]/div/div/div/div[3]/div/div[5]/div[1]/div/div/div')))
two_days_advance_div = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="form1"]/div[3]/div[1]/div/div/div/div[3]/div/div[2]/div/div/div/div[4]')))
self.driver.execute_script("arguments[0].click();", two_days_advance_div)
print('Navigated to correct date')
except Exception as e:
print(f'Error moving to booking URL: {e}')
handle_screenshot(self.driver)
def book_tennis_court(self):
court_name, time = self.determine_booking_details()
try:
self.wait.until(EC.visibility_of_element_located((By.XPATH, '/html/body/form/div[3]/div[1]/div/div/div/div[3]/div/div[5]/div[1]/div')))
xpath_expression = f"//div[@class='court-col ng-scope'][.//div[@class='court-name ng-binding' and contains(text(), '{court_name}')]]//*[text()='{time}']"
court_list = self.driver.find_elements(By.XPATH, xpath_expression)
print(f'Found {len(court_list)} slots at {time} for {court_name}')
if len(court_list) == 0:
print(f"No available slots at {time} for {court_name}. Trying to book any available court at 7 PM.")
self.book_any_available_court()
else:
self.select_and_book_court(court_list, court_name, time)
except Exception as e:
print(f'Error in booking process: {e}')
handle_screenshot(self.driver)
def determine_booking_details(self):
if self.today in ['Thursday', 'Friday']:
return "Court 4", "10:00 AM"
else:
return "Court 1", "7:00 PM"
def book_any_available_court(self):
any_court_xpath = "//div[@class='court-col ng-scope']//*[text()='7 PM']"
any_court_list = self.driver.find_elements(By.XPATH, any_court_xpath)
if len(any_court_list) == 0:
print("No available courts at 7 PM.")
else:
any_court_slot = any_court_list[0]
print(f'Booking an available court at 7 PM.')
self.driver.execute_script("arguments[0].click();", any_court_slot)
print('Moved to booking.')
def select_and_book_court(self, court_list, court_name, time):
court_slot = court_list[0]
print(f'Today is {self.today}. Booking {court_name} at {time}.')
self.driver.execute_script("arguments[0].click();", court_slot)
print('Moved to booking date.')
def complete_booking(self):
print('navigating to booking page')
self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#form1 > div.inner-wrap > div.container.c-module > div > div > div > div.main-content.ng-scope > div > div.content.row > div.col-xs-12.col-sm-7.section-2 > div > div.row > div > div > a")))
print('page loaded')
book_button_el = self.driver.find_element(By.CSS_SELECTOR, "#form1 > div.inner-wrap > div.container.c-module > div > div > div > div.main-content.ng-scope > div > div.content.row > div.col-xs-12.col-sm-7.section-2 > div > div.row > div > div > a")
print('found book button')
self.driver.execute_script("arguments[0].click();", book_button_el)
# confirm booking
confirmation = self.wait.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="form1"]/div[3]/div[1]/div/div/div/div[3]/div/div[1]/h1')))
if confirmation:
print('booked!')
self.driver.quit()
def run(self):
self.navigate_to_booking_page()
self.book_tennis_court()
self.complete_booking()