Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
43edcc1
Seems to resolve the make_request retry error in Docker when fetching…
dmytrokoren Feb 20, 2025
1ef78aa
This fixes the issue with 403
dmytrokoren Mar 3, 2025
863bc8e
Fixed missing return type
dmytrokoren Mar 3, 2025
b47f54f
Fixed unit test AssertionError
dmytrokoren Mar 3, 2025
0878922
Missed this one, fixed AssertionError
dmytrokoren Mar 3, 2025
6fda805
feat: Delete temp files after browser quit to prevent 429 errors
dmytrokoren Mar 4, 2025
fb60baa
Updated method
dmytrokoren Mar 4, 2025
ce5f9f2
Added tests for _reset_temp_dir
dmytrokoren Mar 4, 2025
ac70ea5
Updated WebDriver to use constant temp_dir
dmytrokoren Mar 5, 2025
f8ce48e
Updated unit tests
dmytrokoren Mar 5, 2025
410b8e7
Removed tests, need JD's help.
dmytrokoren Mar 5, 2025
968bd59
Assigned user-agent to driver
dmytrokoren Mar 5, 2025
60bbf5e
Added unit tests
dmytrokoren Mar 5, 2025
17f9a3a
Reverted back to previous changes where temp_dir is reset
dmytrokoren Mar 6, 2025
887c0dc
Fixed return type
dmytrokoren Mar 6, 2025
0afb60f
Check in using multiple threads, each starting one second after the
jdholtz Mar 7, 2025
d84cddf
Merge branch 'develop' into webdriver-enhacement
dmytrokoren Mar 7, 2025
2c698f2
Merge remote-tracking branch 'auto-southwest-check-in/multiple-checki…
dmytrokoren Mar 7, 2025
128a8c5
Revert "Merge remote-tracking branch 'auto-southwest-check-in/multipl…
dmytrokoren Mar 9, 2025
354ee8d
Added few seconds before making POST request for check-in flight
dmytrokoren Mar 9, 2025
0b0ffdb
Added a short delay before making the Fare Check request to prevent r…
dmytrokoren Mar 9, 2025
d14833c
Merge branch 'develop' into webdriver-enhacement
dmytrokoren Mar 10, 2025
710b89c
Update to remove temp dir when login fails and retries
dmytrokoren Mar 14, 2025
3d73b5d
Move reset_temp_dir to a class method and other minor changes
jdholtz Jul 22, 2025
02cb1c5
Remove blank line in checkin handler
jdholtz Jul 22, 2025
1aa9a2a
switched from css to xpath on click elements and added click to login…
dmytrokoren Jul 26, 2025
b3b2a78
Merge remote-tracking branch 'upstream/develop' into webdriver-enhace…
dmytrokoren Jul 26, 2025
33e3547
Fix E501 by breaking long line in webdriver login flow
dmytrokoren Jul 26, 2025
fd02b06
Chnages to test and login click
dmytrokoren Jul 26, 2025
fcc6f3d
Modified tests and webdriver
dmytrokoren Aug 3, 2025
dccc9e7
Bumped Python version in Dockerfile; requirements.txt updated accordi…
dmytrokoren Aug 28, 2025
d3b9bf0
Fix Docker issue with second WebDriver instance - Encountered a CDP b…
dmytrokoren Sep 7, 2025
daea99e
Updated python version
dmytrokoren Sep 7, 2025
3954787
Merge branch 'develop' into webdriver-enhacement
dmytrokoren Sep 7, 2025
a4be021
Updated webdriver to see if Ubuntu run will be resolved
dmytrokoren Sep 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.12-rc-alpine
FROM python:3.9-alpine3.17

WORKDIR /app

Expand Down
24 changes: 13 additions & 11 deletions lib/webdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,10 @@ def locator(self, length: int = 6) -> str:
from .reservation_monitor import AccountMonitor

BASE_URL = "https://mobile.southwest.com"
CHECKIN_URL = BASE_URL + "/air/check-in/"
CHECKIN_URL = BASE_URL + "/air/check-in"
LOGIN_URL = BASE_URL + "/api/security/v4/security/token"
TRIPS_URL = BASE_URL + "/api/mobile-misc/v1/mobile-misc/page/upcoming-trips"
HEADERS_URL = (
f"{BASE_URL}/api/mobile-air-operations/v1/mobile-air-operations/page/check-in/{MOCK_LOCATOR}"
)
HEADERS_URL = BASE_URL + "/api/mobile-air-operations/v1/mobile-air-operations/page/check-in"

# Southwest's code when logging in with the incorrect information
INVALID_CREDENTIALS_CODE = 400518024
Expand Down Expand Up @@ -151,10 +149,12 @@ def get_reservations(self, account_monitor: AccountMonitor) -> list[JSON]:
# See https://github.com/jdholtz/auto-southwest-check-in/issues/226
driver.click_if_visible(".button-popup.confirm-button")

driver.click(".login-button--box")
driver.click('//span[contains(text(), "Log in")]')
time.sleep(random_sleep_duration(2, 3))
driver.type('input[name="userNameOrAccountNumber"]', account_monitor.username)
driver.type('input[name="password"]', f"{account_monitor.password}\n")
driver.type('input[name="password"]', f"{account_monitor.password}")
time.sleep(random_sleep_duration(1.5, 2.5))
driver.click("//button[@id='login-btn']")

# Wait for the necessary information to be set
self._wait_for_attribute(driver, "headers_set")
Expand Down Expand Up @@ -184,7 +184,7 @@ def _get_driver(self) -> Driver:
driver_version=driver_version,
user_data_dir=self.get_temp_dir(),
headed=IS_DOCKER,
headless1=not IS_DOCKER,
headless1=True,
uc_cdp_events=True,
undetectable=True,
incognito=True,
Expand All @@ -203,7 +203,7 @@ def _get_driver(self) -> Driver:
driver.type('input[name="recordLocator"]', f"{MOCK_LOCATOR}")
driver.type('input[name="firstName"]', f"{MOCK_FIRST_NAME}")
driver.type('input[name="lastName"]', f"{MOCK_LAST_NAME}")
driver.click("button[type='submit']")
driver.click('//button[normalize-space(text())="Retrieve reservation"]')
driver.click_if_visible(".button-popup.confirm-button")
self._take_debug_screenshot(driver, "after_form_submission.png")

Expand All @@ -215,7 +215,7 @@ def _headers_listener(self, data: JSON) -> None:
in the checkin_scheduler.
"""
request = data["params"]["request"]
if request["url"] == HEADERS_URL:
if request["url"].startswith(HEADERS_URL):
self.checkin_scheduler.headers = self._get_needed_headers(request["headers"])
self.headers_set = True

Expand Down Expand Up @@ -279,9 +279,11 @@ def _click_login_button(self, driver: Driver) -> None:
# yet there was an error
return

login_button = "button#login-btn"
login_button = "//button[@id='login-btn']"
try:
seleniumbase_actions.wait_for_element_not_visible(driver, login_button, timeout=5)
seleniumbase_actions.wait_for_element_absent(
driver, login_button, by="xpath", timeout=5
)
except Exception:
logger.debug("Login form failed to submit. Clicking login button again")
driver.click(login_button)
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_monitoring_and_scheduling.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,4 +238,4 @@ def mock_get_driver(self: WebDriver) -> mock.Mock:
assert len(scheduler.flights) == 2

# Ensures the 429 error was handled correctly
assert mock_check_flight_price.call_count == 2 * len(scheduler.flights)
assert mock_check_flight_price.call_count == len(scheduler.flights)
2 changes: 1 addition & 1 deletion tests/unit/test_webdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def test_click_login_button_does_not_click_when_form_submits(
self, mocker: MockerFixture, mock_chrome: mock.Mock
) -> None:
mocker.patch("seleniumbase.fixtures.page_actions.wait_for_element_not_visible")
mocker.patch.object(mock_chrome, "is_element_visible", return_value=False)
mocker.patch.object(mock_chrome, "is_element_visible", return_value=True)
self.driver._click_login_button(mock_chrome)
mock_chrome.click.assert_not_called()

Expand Down
Loading