seleniumbase / SeleniumBase

📊 Python's all-in-one framework for web crawling, scraping, testing, and reporting. Supports pytest. UC Mode provides stealth. Includes many tools.
https://seleniumbase.io
MIT License
5.16k stars 958 forks source link

Maximize window function `maximize_window` raising `WebDriverException` #2661

Closed chahak13 closed 6 months ago

chahak13 commented 6 months ago

Hello!

Thanks again for your help on this project! I ran into another issue while running chrome in headed mode with a virtual display attached to it. Here's a simple script to reproduce:

import os
import platform
import pyautogui
import Xlib

from seleniumbase import SB
from sbvirtualdisplay import Display

display = None
if platform.system() == "Linux":
    display = Display(visible=False, size=(1920, 1080))
    display.start()

    pyautogui._pyautogui_x11._display = Xlib.display.Display(os.environ["DISPLAY"])

with SB(
    uc=True,
    xvfb=False,
    browser="chrome",
    # maximize=True,
    headed=True,
) as sb:
    print(sb.driver.get_window_size())
    sb.driver.maximize_window()
    print(sb.driver.get_window_size())
    sb.driver.get("https://duckduckgo.com")
    sb.save_screenshot("maximized_ddg.png")

This on running gives the following stacktrace:

root@1d18535d46ac:/opt/test# DISPLAY=:99 python sb_maximize_test.py
{'width': 1280, 'height': 840}
{'width': 1919, 'height': 1079}
Traceback (most recent call last):
  File "/opt/test/sb_maximize_test.py", line 28, in <module>
    sb.driver.get("https://duckduckgo.com")
  File "/usr/local/lib/python3.10/site-packages/seleniumbase/core/browser_launcher.py", line 3737, in <lambda>
    driver.get = lambda url: uc_special_open_if_cf(
  File "/usr/local/lib/python3.10/site-packages/seleniumbase/core/browser_launcher.py", line 397, in uc_special_open_if_cf
    driver.default_get(url)  # The original one
  File "/usr/local/lib/python3.10/site-packages/seleniumbase/undetected/__init__.py", line 381, in get
    return super().get(url)
  File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 356, in get
    self.execute(Command.GET, {"url": url})
  File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 347, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py", line 229, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: disconnected: not connected to DevTools
  (failed to check if window was closed: disconnected: not connected to DevTools)
  (Session info: chrome=123.0.6312.86)
Stacktrace:
#0 0x555555cce8a3 <unknown>
#1 0x5555559c48c6 <unknown>
#2 0x5555559ab090 <unknown>
#3 0x5555559aaf73 <unknown>
#4 0x5555559c6c42 <unknown>
#5 0x555555a4f5cc <unknown>
#6 0x555555a31343 <unknown>
#7 0x555555a02593 <unknown>
#8 0x555555a02f5e <unknown>
#9 0x555555c9288b <unknown>
#10 0x555555c967e5 <unknown>
#11 0x555555c805b1 <unknown>
#12 0x555555c97372 <unknown>
#13 0x555555c658bf <unknown>
#14 0x555555cbd768 <unknown>
#15 0x555555cbd93b <unknown>
#16 0x555555ccd9f4 <unknown>
#17 0x7fffff7a8ea7 start_thread

If I comment out the sb.driver.maximize_window() call, then it works fine :/ Any ideas what I'm doing wrong? Thank you!

chahak13 commented 6 months ago

Actually, I managed to simplify it further and remove the Xlib and pyautogui code.

import pyautogui

from seleniumbase import SB
from seleniumbase.config import settings as sb_settings

sb_settings.HEADLESS_START_WIDTH = 1920
sb_settings.HEADLESS_START_HEIGHT = 1080

with SB(
    uc=True,
    xvfb=True,
    browser="chrome",
    # maximize=True,
) as sb:
    print(sb.driver.get_window_size())
    sb.driver.maximize_window()
    print(sb.driver.get_window_size())
    sb.driver.get("https://duckduckgo.com")
    pyautogui.screenshot("maximized_ddg.png")

This does not start the browser with a maximized size but instead prints out

{'width': 1280, 'height': 840}

and if I try maximize_window() then it gives the error.

{'width': 1280, 'height': 840}
Traceback (most recent call last):
  File "/opt/test/sb_maximize_test.py", line 22, in <module>
    print(sb.driver.get_window_size())
  File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 870, in get_window_size
    size = self.get_window_rect()
  File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 920, in get_window_rect
    return self.execute(Command.GET_WINDOW_RECT)["value"]
  File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 347, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py", line 229, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: disconnected: not connected to DevTools
  (failed to check if window was closed: disconnected: not connected to DevTools)
  (Session info: chrome=123.0.6312.86)
Stacktrace:
#0 0x555555cce8a3 <unknown>
#1 0x5555559c48c6 <unknown>
#2 0x5555559aa24f <unknown>
#3 0x5555559aab9f <unknown>
#4 0x5555559aaaf4 <unknown>
#5 0x55555599bfa9 <unknown>
#6 0x55555599c231 <unknown>
#7 0x555555a640cf <unknown>
#8 0x555555a315a2 <unknown>
#9 0x555555a4fc19 <unknown>
#10 0x555555a31343 <unknown>
#11 0x555555a02593 <unknown>
#12 0x555555a02f5e <unknown>
#13 0x555555c9288b <unknown>
#14 0x555555c967e5 <unknown>
#15 0x555555c805b1 <unknown>
#16 0x555555c97372 <unknown>
#17 0x555555c658bf <unknown>
#18 0x555555cbd768 <unknown>
#19 0x555555cbd93b <unknown>
#20 0x555555ccd9f4 <unknown>
#21 0x7fffff7a8ea7 start_thread
mdmintz commented 6 months ago

Since there's no real screen on a headless virtual display (such as on headless Linux), the maximize function doesn't make as much sense because the maximize function tells the browser window to match those screen dimensions.

That's probably one of the reasons why the original undetected-chromedriver had so many issues with maximization while in UC Mode: https://github.com/search?q=repo%3Aultrafunkamsterdam%2Fundetected-chromedriver+maximize&type=issues

I looked into it, and the best solution was setting the window to specific dimensions if using headless Linux, (eg. with driver.set_window_size(width, height)).

If you find a better solution, let me know. I personally don't think maximization is necessary since that means screen sizes won't be consistent for all users if they have different screen sizes. Also, driver.maximize_window() comes from raw Selenium (and not SeleniumBase), so I can't even make changes to it directly if I found the exact issue.