[IMP] script selenium lib: support specific directory for selenium grid

- fix algorithm scrollto_element, center it, not scroll if already in
view if not too low
This commit is contained in:
Mathieu Benoit 2025-12-01 09:43:01 -05:00
parent 2740064e1c
commit 07a149bde4

View file

@ -4,18 +4,15 @@
import datetime import datetime
import getpass import getpass
import json
import logging import logging
import os import os
import random import random
import re import re
import shutil
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
import time import time
import tkinter as tk import tkinter as tk
from subprocess import getoutput
from tkinter import filedialog from tkinter import filedialog
from pykeepass import PyKeePass from pykeepass import PyKeePass
@ -79,7 +76,10 @@ class SeleniumLib(object):
self.config_file = config_file.ConfigFile() self.config_file = config_file.ConfigFile()
self.kdbx = None self.kdbx = None
self.video_recorder = None self.video_recorder = None
self.default_download_dir_path = tempfile.mkdtemp() if config.use_download_path_default:
self.default_download_dir_path = "/home/seluser/Downloads"
else:
self.default_download_dir_path = tempfile.mkdtemp()
if self.config.video_suffix: if self.config.video_suffix:
self.filename_recording = ( self.filename_recording = (
f"video_{self.config.video_suffix}_" f"video_{self.config.video_suffix}_"
@ -136,9 +136,10 @@ class SeleniumLib(object):
firefox_options.set_preference( firefox_options.set_preference(
"browser.download.manager.showWhenStarting", False "browser.download.manager.showWhenStarting", False
) )
firefox_options.set_preference( if self.default_download_dir_path:
"browser.download.dir", self.default_download_dir_path firefox_options.set_preference(
) "browser.download.dir", self.default_download_dir_path
)
firefox_options.set_preference( firefox_options.set_preference(
"browser.helperApps.neverAsk.saveToDisk", "browser.helperApps.neverAsk.saveToDisk",
"application/octet-stream,application/pdf,application/x-pdf", "application/octet-stream,application/pdf,application/x-pdf",
@ -248,9 +249,10 @@ class SeleniumLib(object):
firefox_options.set_preference( firefox_options.set_preference(
"browser.download.manager.showWhenStarting", False "browser.download.manager.showWhenStarting", False
) )
firefox_options.set_preference( if self.default_download_dir_path:
"browser.download.dir", self.default_download_dir_path firefox_options.set_preference(
) "browser.download.dir", self.default_download_dir_path
)
firefox_options.set_preference( firefox_options.set_preference(
"browser.helperApps.neverAsk.saveToDisk", "browser.helperApps.neverAsk.saveToDisk",
"application/octet-stream,application/pdf,application/x-pdf", "application/octet-stream,application/pdf,application/x-pdf",
@ -813,35 +815,59 @@ class SeleniumLib(object):
def scrollto_element( def scrollto_element(
self, self,
element, element,
offset_middle=True,
smooth_scroll=True, smooth_scroll=True,
smooth_speed=50, smooth_speed=50,
smooth_fps=1 / 25, smooth_fps=1 / 25,
viewport_ele=None, viewport_ele=None,
): ):
window_y = self.driver.execute_script(
"return window.scrollY || window.pageYOffset;"
)
window_height = self.driver.get_window_size().get("height")
element_height = element.rect["height"]
viewport_height = self.driver.execute_script(
"return window.innerHeight || document.documentElement.clientHeight;"
)
if viewport_ele: if viewport_ele:
scroll_origin = ScrollOrigin.from_element(viewport_ele, 10, 10) scroll_origin = ScrollOrigin.from_element(viewport_ele, 10, 10)
else: else:
scroll_origin = ScrollOrigin.from_viewport(10, 10) scroll_origin = ScrollOrigin.from_viewport(10, 10)
delta_y = element.rect["y"] delta_y = element.rect["y"]
if offset_middle: target_distance = (
# TODO check size windows and divide by 2 delta_y - (viewport_height - element_height) / 2 - window_y
delta_y -= 400 )
if window_y < delta_y < window_y + viewport_height - 50:
# No need to scroll
return
print(f"scroll to xpath at y:{delta_y} position") print(f"scroll to xpath at y:{delta_y} position")
if smooth_scroll: if smooth_scroll:
actual_pos = 0 actual_pos = 0
while delta_y > actual_pos: # Detect go top or bot
actual_pos += smooth_speed if delta_y > window_y:
print(actual_pos) step = abs(int(smooth_speed)) # to the top
condition = lambda a, d: a < d
go_down = True
else:
step = -abs(int(smooth_speed)) # to the bot
condition = lambda a, d: a > d
go_down = False
while condition(actual_pos, target_distance):
# TODO detect when cannot scroll, stop scrolling
actual_pos += step
if go_down and actual_pos > target_distance:
step = actual_pos - target_distance
elif not go_down and actual_pos < target_distance:
step = actual_pos - target_distance
ActionChains(self.driver).scroll_from_origin( ActionChains(self.driver).scroll_from_origin(
scroll_origin, 0, int(smooth_speed) scroll_origin, 0, int(step)
).perform() ).perform()
print(f"Wait {smooth_fps} seconds") print(f"Wait {smooth_fps} seconds")
time.sleep(smooth_fps) time.sleep(smooth_fps)
print("end") print("end")
else: else:
ActionChains(self.driver).scroll_from_origin( ActionChains(self.driver).scroll_from_origin(
scroll_origin, 0, int(delta_y) scroll_origin, 0, int(target_distance)
).perform() ).perform()
# action = ActionChains(self.driver) # action = ActionChains(self.driver)
@ -1708,6 +1734,14 @@ def fill_parser(parser):
"--use_network", "--use_network",
help="Specify the adress, example: http://localhost:4444", help="Specify the adress, example: http://localhost:4444",
) )
group_browser.add_argument(
"--use_download_path_default",
action="store_true",
help="Actually, the download path is a temporary directory. "
"This will enable default path to /home/seluser/Downloads, "
"need this with Selenium Grid by network. "
"Will delete all file into /home/seluser/Downloads at startup.",
)
group_browser.add_argument( group_browser.add_argument(
"--window_size", "--window_size",
help="Example 1920,1080", help="Example 1920,1080",