Skip to content

Commit

Permalink
Install the latest minor chromedriver version for a milestone
Browse files Browse the repository at this point in the history
Fixes #180

Directly matching the browser version appeared problematic when the
latest browser version did not have a matching driver version. Now, the
latest version is installed, while still ensuring there is the same
major version (e.g. browser v117.* and driver v117.*).

To not download the chromedriver in Docker images (the driver download
is very finicky with Alpine Linux), an environment variable in the
Docker image is set and read in the script to keep the downloaded
chromedriver, as we want that to be set up in the image, not the script.
  • Loading branch information
jdholtz committed Nov 9, 2023
1 parent 775f9ed commit d1a169f
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 3 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
When upgrading to a new version, make sure to follow the directions under the "Upgrading" header of the corresponding version.
If there is no "Upgrading" header for that version, no post-upgrade actions need to be performed.

## Upcoming
### Bug Fixes
- Fix situations where the Chromedriver version isn't available for the current browser version
([#180](https://github.com/jdholtz/auto-southwest-check-in/issues/180))

### Upgrading
- Upgrade the dependencies to the latest versions by running `pip install -r requirements.txt`


## 7.0 (2023-11-05)
### New Features
Expand Down
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ FROM python:3.12-alpine

WORKDIR /app

# Define so the script knows not to download a new driver version, as
# this Docker image already downloads a compatible chromedriver
ENV AUTO_SOUTHWEST_CHECK_IN_DOCKER 1

RUN apk add --update --no-cache chromium chromium-chromedriver

COPY requirements.txt requirements.txt
Expand Down
10 changes: 9 additions & 1 deletion lib/webdriver.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import json
import os
import re
import time
from typing import TYPE_CHECKING, Any, Dict, List
Expand Down Expand Up @@ -101,9 +102,16 @@ def get_reservations(self, account_monitor: AccountMonitor) -> List[JSON]:
def _get_driver(self) -> Driver:
logger.debug("Starting webdriver for current session")
browser_path = self.checkin_scheduler.reservation_monitor.config.browser_path

driver_version = "mlatest"
if os.environ.get("AUTO_SOUTHWEST_CHECK_IN_DOCKER") == "1":
# This environment variable is set in the Docker image. Makes sure a new driver
# is not downloaded as the Docker image already has the correct driver
driver_version = "keep"

driver = Driver(
binary_location=browser_path,
driver_version="browser", # Always ensure the browser and driver versions match
driver_version=driver_version,
headless=True,
uc_cdp_events=True,
undetectable=True,
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ apprise==1.6.0
certifi==2023.07.22
pytz==2023.3.post1 # Remove when this script only supports Python 3.9+
requests==2.31.0
seleniumbase==4.20.9
seleniumbase==4.21.0
14 changes: 13 additions & 1 deletion tests/unit/test_webdriver.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
from typing import Any, Dict
from unittest import mock

Expand Down Expand Up @@ -67,12 +68,23 @@ def test_get_reservations_fetches_reservations(
mock_chrome.add_cdp_listener.assert_called_once()
mock_chrome.quit.assert_called_once()

def test_get_driver_returns_a_webdriver_with_one_request(self) -> None:
def test_get_driver_returns_a_webdriver_with_one_request(self, mock_chrome: mock.Mock) -> None:
driver = self.driver._get_driver()
driver.add_cdp_listener.assert_called_once()
driver.get.assert_called_once()

assert mock_chrome.call_args.kwargs.get("driver_version") == "mlatest"

def test_get_driver_keeps_driver_version_in_docker(self, mock_chrome: mock.Mock) -> None:
# This env variable will be set in the Docker image
os.environ["AUTO_SOUTHWEST_CHECK_IN_DOCKER"] = "1"

driver = self.driver._get_driver()
driver.add_cdp_listener.assert_called_once()
driver.get.assert_called_once()

assert mock_chrome.call_args.kwargs.get("driver_version") == "keep"

def test_headers_listener_sets_headers_when_correct_url(self, mocker: MockerFixture) -> None:
mocker.patch.object(self.driver, "_get_needed_headers", return_value={"test": "headers"})
data = {"params": {"request": {"url": CHECKIN_HEADERS_URL, "headers": {}}}}
Expand Down

0 comments on commit d1a169f

Please sign in to comment.