Skip to content

Commit b65d802

Browse files
committed
html2print: minor cleanups on windows
1 parent 84481a9 commit b65d802

5 files changed

Lines changed: 43 additions & 17 deletions

File tree

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Mark the file as binary, so that Git won't not convert the line endings
2+
# Otherwise, the file becomes unreadable for bash inside Docker (on Windows platforms)
3+
entrypoint.sh -text

.github/workflows/ci-windows.yml

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,7 @@ jobs:
2828
shell: powershell
2929

3030
- name: Check Chrome Version
31-
run: '& "C:\Program Files\Google\Chrome\Application\chrome.exe" --version'
32-
shell: powershell
33-
34-
- name: Add Chrome to PATH
35-
run: |
36-
$chromePath = "C:\Program Files\Google\Chrome\Application"
37-
echo "Adding $chromePath to PATH"
38-
echo "$chromePath" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH
39-
shell: powershell
40-
41-
- name: Verify Chrome Installation
42-
run: chrome --version
31+
run: '(Get-Item "C:\Program Files\Google\Chrome\Application\chrome.exe").VersionInfo'
4332
shell: powershell
4433

4534
- name: Upgrade pip

html2print/html2print.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,18 @@ def _download_chromedriver(
109109
path_to_cached_chrome_driver: str,
110110
) -> str:
111111
url = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json"
112-
response = ChromeDriverManager.send_http_get_request(url).json()
112+
response = ChromeDriverManager.send_http_get_request(url)
113+
if response is None:
114+
raise RuntimeError(
115+
"Could not download known-good-versions-with-downloads.json"
116+
)
117+
118+
response = response.json()
119+
if response is None:
120+
raise RuntimeError(
121+
"Could not parse known-good-versions-with-downloads.json"
122+
)
123+
assert isinstance(response, dict)
113124

114125
matching_versions = [
115126
item
@@ -118,7 +129,7 @@ def _download_chromedriver(
118129
]
119130

120131
if not matching_versions:
121-
raise Exception(
132+
raise RuntimeError(
122133
f"No compatible ChromeDriver found for Chrome version {chrome_major_version}"
123134
)
124135

@@ -142,6 +153,11 @@ def _download_chromedriver(
142153
)
143154
response = ChromeDriverManager.send_http_get_request(driver_url)
144155

156+
if response is None:
157+
raise Exception(
158+
f"Could not download ChromeDriver from {driver_url}"
159+
)
160+
145161
Path(path_to_driver_cache_dir).mkdir(parents=True, exist_ok=True)
146162
zip_path = os.path.join(path_to_driver_cache_dir, "chromedriver.zip")
147163
print( # noqa: T201
@@ -179,6 +195,9 @@ def send_http_get_request(url: str) -> Response:
179195
f"html2print: "
180196
f"failed to get response for URL: {url} with error: {last_error}"
181197
)
198+
raise RuntimeError(
199+
f"GET request failed after 3 attempts: {url}"
200+
) from last_error
182201

183202
@staticmethod
184203
def get_chrome_version() -> Optional[str]:
@@ -328,14 +347,23 @@ def create_webdriver(
328347
service = Service(path_to_chrome)
329348

330349
webdriver_options = Options()
350+
# Workaround for Windows: chrome is not typically found in the PATH, so need to supply the exact binary location manually
351+
if platform.system() == "Windows":
352+
import browsers
353+
354+
webdriver_options.binary_location = browsers.get("chrome")["path"]
331355
webdriver_options.add_argument("start-maximized")
332356
webdriver_options.add_argument("disable-infobars")
333357
# Doesn't seem to be needed.
334358
# webdriver_options.add_argument('--disable-gpu') # noqa: ERA001
335359
webdriver_options.add_argument("--disable-extensions")
336-
webdriver_options.add_argument("--headless=chrome")
337-
# FIXME: This is not nice but otherwise it does not work in Ubuntu 24-based Docker image.
338-
# https://github.com/SeleniumHQ/selenium/issues/15327#issuecomment-2689287561
360+
# Use --headless=new, as it seems to be more stable on Windows (available since Chrome 109).
361+
# see https://www.selenium.dev/blog/2023/headless-is-going-away/
362+
webdriver_options.add_argument("--headless=new")
363+
# Docker disables some syscalls that are required for Chrome's sandbox to work.
364+
# https://stackoverflow.com/questions/68855734/how-to-setup-chrome-sandbox-on-docker-container.
365+
# See also https://github.com/SeleniumHQ/selenium/issues/15327#issuecomment-2689287561.
366+
# We prefer isolation of the container over isolation of tabs within Chrome, and thus disable the sandbox.
339367
webdriver_options.add_argument("--no-sandbox")
340368

341369
# The Chrome option --disable-dev-shm-usage disables the use of /dev/shm

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ dependencies = [
5454

5555
# requests is used by HTML2PDF_HTTPClient.
5656
"requests",
57+
58+
# To detect the browers path (needed on Windows)
59+
'pybrowsers; platform_system == "Windows"',
5760
]
5861

5962
[project.optional-dependencies]

tests/integration/lit.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ config.suffixes = ['.itest', '.c']
2323
config.is_windows = lit_config.isWindows
2424
if not lit_config.isWindows:
2525
config.available_features.add('PLATFORM_IS_NOT_WINDOWS')
26+
27+
# $HOME is required for Chrome under Linux as it wants to store things in ~/.local
28+
config.environment['HOME'] = os.environ.get('HOME', '/tmp')

0 commit comments

Comments
 (0)