Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added open test for windows 10 #33

Merged
merged 12 commits into from
Dec 17, 2024
2 changes: 1 addition & 1 deletion frameworks/desktop/desktop_config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"linux_run_command": "onlyoffice-desktopeditors",
"mac_run_command": "/Applications/ONLYOFFICE.app/Contents/MacOS/ONLYOFFICE",
"windows_run_command": ""
"windows_run_command": "powershell.exe \"& 'C:\\Program Files\\ONLYOFFICE\\DesktopEditors\\DesktopEditors.exe'\""
}
14 changes: 8 additions & 6 deletions frameworks/desktop/desktop_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self, data: Data):
self.log_file = join(self.tmp_dir, "desktop.log")
self.create_log_file()
self.debug_command = '--ascdesktop-support-debug-info'
self.log_out_cmd = f'--ascdesktop-log-file={"stdout" if HostInfo().os != "windows" else self.log_file}'
self.log_out_cmd = f'--ascdesktop-log-file="stdout"'

def open(self, file_path: str = None, debug_mode: bool = False, log_out_mode: bool = False) -> Popen:
command = (
Expand Down Expand Up @@ -54,10 +54,7 @@ def wait_until_open(
)

def get_version(self) -> "str | None":
version = re.findall(
r"\d+\.\d+\.\d+\.\d+",
FileUtils.output_cmd(f'{self._generate_running_command()} --version')
)
version = re.findall(r"\d+\.\d+\.\d+\.\d+", FileUtils.output_cmd(self._generate_get_version_cmd()))
return version[0] if version else None

def _read_log(self, wait_msg: str, stdout_process: Popen) -> str:
Expand All @@ -70,7 +67,6 @@ def _read_log(self, wait_msg: str, stdout_process: Popen) -> str:
self.create_log_file()
return line.strip()


def create_log_file(self):
FileUtils.create_dir(dirname(self.log_file), stdout=False)
FileUtils.file_writer(self.log_file, '', mode='w')
Expand All @@ -88,6 +84,12 @@ def _generate_running_command(self):
return run_cmd
raise ValueError(f"[red]|ERROR| Can't get running command, key: {HostInfo().os}_run_command")

def _generate_get_version_cmd(self) -> str:
if self.os.lower() == 'windows':
path = re.search(r"'(.*?)'", self._generate_running_command())
return f"powershell.exe (Get-Item '{path.group(1) if path else None}').VersionInfo.FileVersion"
return f'{self._generate_running_command()} --version'

@staticmethod
def _get_config(path):
config_path = path if path and isfile(path) else join(dirname(realpath(__file__)), 'desktop_config.json')
Expand Down
3 changes: 3 additions & 0 deletions frameworks/desktop/package/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ def _get_install_command(
apt_get_installer: bool = False,
custom_installer: str = None
) -> str:
if self.path.lower().endswith('.exe'):
return f'powershell.exe Start-Process {self.path} -ArgumentList "/silent", "/norestart" -Wait'

if custom_installer:
return f"sudo {custom_installer} {self.path}"

Expand Down
6 changes: 5 additions & 1 deletion frameworks/desktop/package/url_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"os_family": {
"debian": ["debian", "ubuntu", "linuxmint", "pop"],
"rhel": ["centos", "redos", "altlinux", "fedora"],
"suse": ["opensuse"]
"suse": ["opensuse"],
"inno": ["windows"]
},
"package_name": {
"debian": {
Expand All @@ -19,6 +20,9 @@
"suse": {
"package_cef107": "onlyoffice-desktopeditors-[version]~cef107.suse12.x86_64.rpm",
"package": "onlyoffice-desktopeditors-[version].suse12.x86_64.rpm"
},
"inno": {
"package": "ONLYOFFICE-DesktopEditors-[version]-x64.exe"
}
}
}
2 changes: 1 addition & 1 deletion frameworks/desktop/package/url_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def _os_family(self) -> str:

@property
def _version_for_url(self):
if self._os == 'windows':
if HostInfo().os == 'windows':
return self.version.version
return f"{self.version.major}.{self.version.minor}-{self.version.build}"

Expand Down
17 changes: 16 additions & 1 deletion frameworks/host_control/FileUtils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
import json
from os import makedirs, walk
from os.path import isfile, isdir, join, basename, getsize
from os.path import isfile, isdir, join, basename, getsize, exists
from shutil import copyfile
from subprocess import getoutput, Popen, PIPE
from codecs import open as codecs_open

Expand Down Expand Up @@ -53,6 +54,20 @@ def get_headers(url: str, stderr: bool = False):
return None


@staticmethod
def copy(
path_from: str,
path_to: str,
stderr: bool = True,
) -> None:
if not exists(path_from):
return print(f"[red]|WARNING| Path not exist: {path_from}") if stderr else None

if isfile(path_from):
copyfile(path_from, path_to)
else:
return print(f"[red] Cant copy dir: {path_from}")

@staticmethod
def download(
url: str,
Expand Down
1 change: 1 addition & 0 deletions frameworks/host_control/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from .FileUtils import FileUtils
from .host_info import HostInfo
from .windows import Window
7 changes: 7 additions & 0 deletions frameworks/host_control/windows/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from frameworks.host_control import HostInfo

if HostInfo().os == 'windows':
from .windows_window import WindowsWindow as Window
else:
from .linux_window import LinuxWindow as Window
19 changes: 19 additions & 0 deletions frameworks/host_control/windows/linux_window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from typing import Optional

from .window import Window


class LinuxWindow(Window):

@staticmethod
def get_hwnd(class_name: str, text: str) -> Optional[int]:
pass

@staticmethod
def get_child_window_hwnd(window_hwnd: int, child_window_title: str, child_window_text: str) -> Optional[int]:
pass

@staticmethod
def click_on_button(button_hwnd: int):
pass
18 changes: 18 additions & 0 deletions frameworks/host_control/windows/window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from abc import ABC, abstractmethod
from typing import Optional


class Window(ABC):

@staticmethod
@abstractmethod
def get_hwnd(class_name: str, text: str) -> Optional[int]: ...

@staticmethod
@abstractmethod
def get_child_window_hwnd(window_hwnd: int, child_window_title: str, child_window_text: str) -> Optional[int]: ...

@staticmethod
@abstractmethod
def click_on_button(button_hwnd: int): ...
50 changes: 50 additions & 0 deletions frameworks/host_control/windows/windows_window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
from typing import Optional

from .window import Window

try:
import win32gui
import win32con
except ImportError:
pass


class WindowsWindow(Window):

@staticmethod
def get_hwnd(class_name: str, text: str) -> Optional[int]:
data = []

def enum_windows_callback(hwnd: int, data: list):
if win32gui.IsWindowVisible(hwnd):
if (
class_name.strip() == win32gui.GetClassName(hwnd).strip()
and text.strip() == win32gui.GetWindowText(hwnd).strip()
):
data.append(hwnd)

win32gui.EnumWindows(enum_windows_callback, data)
return data[0] if data else None

@staticmethod
def get_child_window_hwnd(window_hwnd: int, child_window_title: str, child_window_text: str) -> Optional[int]:
data = []

def find_button(hwnd, data: list):
cls_name, text = win32gui.GetClassName(hwnd), win32gui.GetWindowText(hwnd)
if cls_name in child_window_title and child_window_text in text:
data.append(hwnd)

win32gui.EnumChildWindows(window_hwnd, find_button, data)
return data[0] if data else None

@staticmethod
def click_on_button(button_hwnd: int):
try:
win32gui.SendMessage(button_hwnd, win32con.BM_CLICK, 0, 0)
except Exception as ex:
print(ex)



8 changes: 6 additions & 2 deletions frameworks/image_handler/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ def find_template_on_window(
return None

@staticmethod
def is_present(template_path: str, window_coordinates: tuple = None, threshold: "int | float" = 0.8) -> bool:
def is_present(
template: "str | cv2.imread",
window_coordinates: tuple = None,
threshold: "int | float" = 0.8
) -> bool:
window = cv2.cvtColor(Image.grab_coordinate(window_coordinates), cv2.COLOR_BGR2GRAY)
template = cv2.cvtColor(cv2.imread(template_path), cv2.COLOR_BGR2GRAY)
template = cv2.cvtColor(cv2.imread(template) if isinstance(template, str) else template, cv2.COLOR_BGR2GRAY)
_, max_val, _, _ = cv2.minMaxLoc(cv2.matchTemplate(window, template, cv2.TM_CCOEFF_NORMED))
return True if max_val >= threshold else False

Expand Down
10 changes: 6 additions & 4 deletions frameworks/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ class TestData:
project_dir: str = getcwd()
tmp_dir: str = join(project_dir, 'tmp')
reports_dir: str = join(project_dir, 'reports')
img_template: str = join(project_dir, 'tests', 'assets', 'image_template')
bad_files_dir: str = join(project_dir, 'tests', 'assets', 'bad_files')
good_files_dir: str = join(project_dir, 'tests', 'assets', 'good_files')
lic_file_path: str = join(project_dir, 'tests', 'assets', 'test_lic.lickey')
test_assets: str = join(project_dir, 'tests', 'assets')
img_template: str = join(test_assets, 'image_template')
bad_files_dir: str = join(test_assets, 'bad_files')
good_files_dir: str = join(test_assets, 'good_files')
lic_file_path: str = join(test_assets, 'test_lic.lickey')
config: json = FileUtils.read_json(join(project_dir, 'config.json'))
cache_dir: str = config.get("cache_dir", None)
warning_window_info: str = join(test_assets, "warning_window_info.json")
85 changes: 49 additions & 36 deletions install_requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,64 @@
import re
import subprocess as sb

requirements_file = 'requirements.txt'
poetry_requirements = 'pyproject.toml'
exceptions = ['python']
try:
import tomlkit
except ImportError:
sb.call("pip install tomlkit==0.11.6", shell=True)
import tomlkit

Python36 = {
OS = platform.system().lower()
REQUIREMENTS_FILE = "requirements.txt"
POETRY_FILE = "pyproject.toml"
EXCEPTIONS = {"python"}
PYTHON36_VERSIONS = {
"opencv-python": "4.3.0.38",
"rich": "12.6.0"
}
def write(text, mode='w'):
with open(requirements_file, mode) as f:
f.write(text)

def old_system_package_version(package):
for pkg, version in Python36.items():
if package.lower() == pkg.lower():
return version
return ''

def create_requirements():
with open(poetry_requirements) as t:
for package, version in tomlkit.parse(t.read())['tool']['poetry']['dependencies'].items():
if package.lower() not in exceptions:
if isinstance(version, dict):
if 'git' in version:
write(f"git+{version.get('git')}@{version.get('branch')}", 'a')
continue
elif int(platform.python_version().rsplit(".", 1)[0].replace('.', '')) < 39:
version = old_system_package_version(package)
else:
version = re.sub(r'[*^]', '', version)
write(f"{package}{('==' + version) if version else ''}\n", 'a')

def write_to_file(content, mode="w"):
with open(REQUIREMENTS_FILE, mode) as f:
f.write(content)

def get_version_for_old_python(package):
return PYTHON36_VERSIONS.get(package.lower(), "")

def get_dependency_version(package, version_info, is_old_python):
if isinstance(version_info, dict):
if "git" in version_info:
return f"git+{version_info['git']}@{version_info.get('branch', 'main')}"
if package.lower() == "pywin32":
return re.sub(r"[*^]", "", version_info.get("version", ""))
elif is_old_python:
return get_version_for_old_python(package)
else:
return re.sub(r"[*^]", "", version_info)
return ""

def generate_requirements():
is_old_python = int(platform.python_version_tuple()[1]) < 9 # Python < 3.9

with open(POETRY_FILE, "r") as f:
poetry_data = tomlkit.parse(f.read())

dependencies = poetry_data.get("tool", {}).get("poetry", {}).get("dependencies", {})
for package, version_info in dependencies.items():
if package.lower() in EXCEPTIONS:
continue

version = get_dependency_version(package, version_info, is_old_python)
if package.lower() == "pywin32" and OS != "windows":
continue
write_to_file(f"{package}=={version}\n" if version else f"{package}\n", "a")

def upgrade_pip():
sb.call('python -m pip install --upgrade pip', shell=True)
sb.call("python -m pip install --upgrade pip", shell=True)

def install_requirements():
sb.call(f'pip install -r {requirements_file}', shell=True)

def install_tomlkit():
sb.call('pip install tomlkit==0.11.6', shell=True)
sb.call(f"pip install -r {REQUIREMENTS_FILE}", shell=True)

if __name__ == "__main__":
install_tomlkit()
import tomlkit
upgrade_pip()
write('# -*- coding: utf-8 -*-\n', 'w')
create_requirements()
write_to_file("# -*- coding: utf-8 -*-\n", "w") # Очистка файла
generate_requirements()
install_requirements()
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pyvirtualdisplay = "*"
opencv-python = "*"
urllib3 = '*'
pillow = '*'
pywin32 = { version = "*", markers = "sys_platform == 'win32'" }


[build-system]
Expand Down
Binary file added tests/assets/image_template/errors/error_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions tests/assets/warning_window_info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Default_app_window": {
"class_name": "#32770",
"window_text": "ONLYOFFICE Desktop Editors",
"button_class_name": "Button",
"button_text": "No"
}
}
Loading
Loading