Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ ln -s $(pipx environment --value PIPX_LOCAL_VENVS)/standardebooks/lib/python3.*/
brew install standardebooks
```

When building a project with images, a browser instance is used to render SVGs to PNGs. If you don’t have Chrome or Firefox installed then you need to manually enable Safari to be used to do this:

```shell
safaridriver --enable
```

### Alternative: pipx

If you want a more granular install you can install the dependencies manually and the toolset with `pipx`:
Expand Down
30 changes: 27 additions & 3 deletions se/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium.webdriver.safari.options import Options as SafariOptions
from selenium.webdriver.remote.webdriver import WebDriver

import se
Expand All @@ -32,6 +33,7 @@ class BrowserType(Enum):

FIREFOX = 1
CHROME = 2
SAFARI = 3

@staticmethod
def from_string(value: str|None) -> "BrowserType | None":
Expand All @@ -50,6 +52,9 @@ def from_string(value: str|None) -> "BrowserType | None":
if "chrome" in value or "chromium" in value:
return BrowserType.CHROME

if "safari" in value:
return BrowserType.SAFARI

return None

@staticmethod
Expand Down Expand Up @@ -87,8 +92,15 @@ def __init__(self):
self.executable_path: Path
self._driver: WebDriver | None = None

browsers = list(installed_browsers.browsers())

# Safari is a backup choice so make sure it’s last
safari_entry = next((browser for browser in browsers if browser['name'] == 'safari'), None)
if safari_entry:
browsers.append(browsers.pop(browsers.index(safari_entry)))

try:
for installed_browser in installed_browsers.browsers():
for installed_browser in browsers:
browser_type = BrowserType.from_string(installed_browser["name"])
if browser_type:
installed_browser_location = str(installed_browser["location"])
Expand Down Expand Up @@ -120,7 +132,7 @@ def __init__(self):
except Exception as ex:
raise se.MissingDependencyException(f"Couldn’t find web browser. Message: {ex}")

raise se.MissingDependencyException("Couldn’t find [command]chrome[/], [command]chromium[/], or [command]firefox[/].")
raise se.MissingDependencyException("Couldn’t find [command]chrome[/], [command]chromium[/], [command]firefox[/], or [command]safari[/].")

@property
def driver(self) -> WebDriver:
Expand All @@ -136,8 +148,11 @@ def driver(self) -> WebDriver:
elif self.type == BrowserType.FIREFOX:
self._driver = self._initialize_selenium_firefox_webdriver()

elif self.type == BrowserType.SAFARI:
self._driver = self._initialize_selenium_safari_webdriver()

else:
raise se.MissingDependencyException("Couldn’t find [command]chrome[/], [command]chromium[/], or [command]firefox[/].")
raise se.MissingDependencyException("Couldn’t find [command]chrome[/], [command]chromium[/], [command]firefox[/], or [command]safari[/].")

except Exception as ex:
raise se.MissingDependencyException(f"Couldn’t start web browser. Message: {ex}")
Expand Down Expand Up @@ -242,3 +257,12 @@ def _initialize_selenium_firefox_webdriver(self) -> WebDriver:
return webdriver.Firefox(options=options, service=service) # type: ignore This is an error in Selenium's type stub.

return webdriver.Firefox(options=options) # type: ignore This is an error in Selenium's type stub.

def _initialize_selenium_safari_webdriver(self) -> WebDriver:
"""
Initialize a Selenium Safari-compatible driver and return it for use in other applications.
"""

options = SafariOptions()

return webdriver.Safari(options=options) # type: ignore This is an error in Selenium's type stub.