Upload file using selenium, VirtualDisplay and dwm

Roman Krasniak
2 min readMay 18, 2021

--

I use this approach when I can not simply change the value of the file input tag.

We will run it console, so we should use PyVirtualDisplay with window manager (I am using gdm, you can try fluxbox it is easy to install but need more RAM then gdm) and Xephyr for debug. To run window manager we will use EasyProcess

So we will call File Upload Dialog, by clicking on element or button, then we simulate send keys with pynput and all these running in our console.

import time
from easyprocess import EasyProcess
from pynput.keyboard import Key, Controller
from pyvirtualdisplay import Display
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


class ImageUploadAutomation:
def __init__(self, data_directory, screen_width, screen_height):
self.chrome_path = "path/to/chrome"
self.data_directory = data_directory
self.screen_width = screen_width
self.screen_height = screen_height
self.chrome_options = self._set_options()
self.driver = None

def _set_options(self):
chrome_options = Options()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-notifications")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument(
f"--window-size={self.screen_width},{self.screen_height}"
)
chrome_options.add_argument("--start-maximized")
chrome_options.add_argument(f"user-data-dir={self.data_directory}")
chrome_options.add_experimental_option(
"excludeSwitches", ["disable-popup-blocking"]
)
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
return chrome_options

def upload(self, photo):
# Change visible to 1 if you want to use Xephyr debug
with Display(
visible=0, size=(self.screen_width, self.screen_height)
) as display:
with EasyProcess(["dwm"]) as process:
self.driver = webdriver.Chrome(
executable_path=self.chrome_path,
chrome_options=self.chrome_options
)
keyboard = Controller()
url = "https://www.exmaple.com"

self.driver.get(url)
test = self.driver.find_element_by_xpath(
"//div[@aria-label='Add Photos']"
)
time.sleep(1)
test.click()
time.sleep(1)
for key in photo.path:
keyboard.press(key)
keyboard.release(key)
# keyboard.press(Key.enter)
with keyboard.pressed(Key.enter):
pass

--

--