Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Как указать путь для скачивания в Safari

downloadfile
safari
webdriver
Теги: #<Tag:0x00007f7b64c53d20> #<Tag:0x00007f7b64c53be0> #<Tag:0x00007f7b64c53a78>

(Марат) #1

Как при старте SafariDriver указать путь для скачивания файлов?

Я пытался сделать так (Python):

capabilities = DesiredCapabilities.SAFARI.copy()
# вариант 1
capabilities["safari.options"] = {"dataDir": downloadDir}
# вариант 2
capabilities["safari.options.dataDir"] = downloadDir
driver = WebDriver(desired_capabilities=capabilities)

Все равно скачивает в ~/Downloads


(Сергей Кузьмин) #2
defaults write com.apple.Safari DownloadsPath ~/My\ Downloads

Capture_Safari|429x30


(Марат) #3

Спасибо!


(Марат) #4

Может кому будет полезно в будущем. Я использую такую обертку для работы с Safari.

import subprocess
from selenium.webdriver import DesiredCapabilities
from selenium.webdriver.safari.webdriver import WebDriver
from typing import Optional


class SafariDriver(WebDriver):
    def __init__(self, download_dir: str) -> None:
        self._params = (
            Param("DownloadsPath", download_dir),
            IntParam("AlwaysPromptForDownloadFolder", "0"),
            IntParam("AutoOpenSafeDownloads", "0"),
        )
        super().__init__(desired_capabilities=capabilities)

    def quit(self) -> None:
        super().quit()
        for param in self._params:
            param.recover()


class Param:
    def __init__(self, name: str, value: str, type_: str = "-string") -> None:
        self.domain = "com.apple.Safari"
        self.name = name
        self.type_ = type_
        self.saved_value = self.read()
        self.write(value)

    def recover(self):
        if self.saved_value is None:
            self.delete()
        else:
            self.write(self.saved_value)

    def read(self) -> Optional[str]:
        try:
            return subprocess.check_output(["defaults", "read", self.domain, self.name],
                                           stderr=subprocess.STDOUT).strip()
        except subprocess.CalledProcessError as ex:
            if "not exist" in str(ex.output):
                # в этом случае такого параметра нет
                return None
            else:
                raise

    def write(self, value: str) -> None:
        subprocess.check_call(["defaults", "write", self.domain, self.name, self.type_, value])

    def delete(self) -> None:
        subprocess.check_call(["defaults", "delete", self.domain, self.name])


class IntParam(Param):
    def __init__(self, name: str, value: str) -> None:
        super().__init__(name, value, "-int")