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
update atspi_test
for improving CIs
#1330
base: atspi
Are you sure you want to change the base?
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## atspi #1330 +/- ##
==========================================
- Coverage 94.15% 94.14% -0.01%
==========================================
Files 60 60
Lines 23036 23034 -2
==========================================
- Hits 21689 21686 -3
- Misses 1347 1348 +1 |
Changing the Not only this PR, by not running the tests on Linux, the coverage is reduced and If possible, the GHA would be triggered automatically by a PR. |
Hmm... All the tasks are in "queued" status. Only CodeQL checks passed. I'm not sure why they are all queued. |
Regarding approvals I've sent an invitation to the org with triage access to the repository. Hope CI can run for your PRs automatically after accepting the invitation. |
Thank you! First, I'd like to investigate those problems by checking the GHA configuration and manually re-running CI for other PRs. |
I found that Ubuntu 18.04 is already marked as unsupported in GHA. This might be the reason it's stuck in the 'queued' state. I will update the |
I've found some problems with CIs, tests, and dependency packages. Python 2.7 is not supported with
|
with the latest actions.
Looking at the production codebase, the Linux I think that is the reason tests using
|
def start(self, cmd_line, timeout=None, retry_interval=None, | |
create_new_console=False, wait_for_idle=True, work_dir=None): | |
"""Start the application as specified by cmd_line""" | |
command_line = shlex.split(cmd_line) | |
try: | |
process = subprocess.Popen(command_line, shell=create_new_console) | |
except Exception as exc: | |
# if it failed for some reason | |
message = ('Could not create the process "%s"\n' | |
'Error returned by CreateProcess: %s') % (cmd_line, str(exc)) | |
raise AppStartError(message) | |
self._proc_descriptor = process | |
self.process = process.pid | |
return self |
pywinauto/pywinauto/windows/application.py
Lines 394 to 460 in bf7f789
def start(self, cmd_line, timeout=None, retry_interval=None, | |
create_new_console=False, wait_for_idle=True, work_dir=None): | |
"""Start the application as specified by cmd_line""" | |
# try to parse executable name and check it has correct bitness | |
if '.exe' in cmd_line and self.backend.name == 'win32': | |
exe_name = cmd_line.split('.exe')[0] + '.exe' | |
_warn_incorrect_binary_bitness(exe_name) | |
if timeout is None: | |
timeout = Timings.app_start_timeout | |
if retry_interval is None: | |
retry_interval = Timings.app_start_retry | |
start_info = win32process.STARTUPINFO() | |
# we need to wrap the command line as it can be modified | |
# by the function | |
command_line = cmd_line | |
# Actually create the process | |
dw_creation_flags = 0 | |
if create_new_console: | |
dw_creation_flags = win32con.CREATE_NEW_CONSOLE | |
try: | |
(h_process, _, dw_process_id, _) = win32process.CreateProcess( | |
None, # module name | |
command_line, # command line | |
None, # Process handle not inheritable. | |
None, # Thread handle not inheritable. | |
0, # Set handle inheritance to FALSE. | |
dw_creation_flags, # Creation flags. | |
None, # Use parent's environment block. | |
work_dir, # If None - use parent's starting directory. | |
start_info) # STARTUPINFO structure. | |
except Exception as exc: | |
# if it failed for some reason | |
message = ('Could not create the process "%s"\n' | |
'Error returned by CreateProcess: %s') % (cmd_line, str(exc)) | |
raise AppStartError(message) | |
self.process = dw_process_id | |
if self.backend.name == 'win32': | |
self.__warn_incorrect_bitness() | |
def app_idle(): | |
"""Return true when the application is ready to start""" | |
result = win32event.WaitForInputIdle( | |
h_process, int(timeout * 1000)) | |
# wait completed successfully | |
if result == 0: | |
return True | |
# the wait returned because it timed out | |
if result == win32con.WAIT_TIMEOUT: | |
return False | |
return bool(self.windows()) | |
# Wait until the application is ready after starting it | |
if wait_for_idle and not app_idle(): | |
warnings.warn('Application is not loaded correctly (WaitForInputIdle failed)', RuntimeWarning) | |
self.actions.log("Started " + cmd_line + " application.") | |
return self |
connect
pywinauto/pywinauto/linux/application.py
Lines 82 to 117 in bf7f789
def connect(self, **kwargs): | |
"""Connect to an already running process | |
The action is performed according to only one of parameters | |
:param pid: a process ID of the target | |
:param path: a path used to launch the target | |
.. seealso:: | |
:func:`pywinauto.findwindows.find_elements` - the keyword arguments that | |
are also can be used instead of **pid** or **path** | |
""" | |
connected = False | |
if 'pid' in kwargs: | |
self.process = kwargs['pid'] | |
assert_valid_process(self.process) | |
connected = True | |
elif 'path' in kwargs: | |
for proc_id in os.listdir('/proc'): | |
if proc_id == 'curproc': | |
continue | |
try: | |
with open('/proc/{}/cmdline'.format(proc_id), mode='rb') as fd: | |
content = fd.read().decode().split('\x00') | |
except IOError: | |
continue | |
if kwargs['path'] in " ".join(content): | |
self.process = int(proc_id) | |
connected = True | |
break | |
if not connected: | |
raise RuntimeError( | |
"You must specify process or handle") |
pywinauto/pywinauto/windows/application.py
Lines 299 to 392 in bf7f789
def connect(self, **kwargs): | |
"""Connect to an already running process | |
The action is performed according to only one of parameters | |
:param pid: a process ID of the target | |
:param handle: a window handle of the target | |
:param path: a path used to launch the target | |
:param timeout: a timeout for process start (relevant if path is specified) | |
.. seealso:: | |
:func:`pywinauto.findwindows.find_elements` - the keyword arguments that | |
are also can be used instead of **pid**, **handle** or **path** | |
""" | |
timeout = Timings.app_connect_timeout | |
retry_interval = Timings.app_connect_retry | |
if 'timeout' in kwargs and kwargs['timeout'] is not None: | |
timeout = kwargs['timeout'] | |
if 'retry_interval' in kwargs and kwargs['retry_interval'] is not None: | |
retry_interval = kwargs['retry_interval'] | |
connected = False | |
if 'pid' in kwargs: | |
self.process = kwargs['pid'] | |
try: | |
wait_until(timeout, retry_interval, self.is_process_running, value=True) | |
except TimeoutError: | |
raise ProcessNotFoundError('Process with PID={} not found!'.format(self.process)) | |
connected = True | |
elif 'process' in kwargs: | |
warnings.warn("'process' keyword is deprecated, use 'pid' instead", DeprecationWarning) | |
kwargs['pid'] = self.process = kwargs['process'] | |
del kwargs['process'] | |
try: | |
wait_until(timeout, retry_interval, self.is_process_running, value=True) | |
except TimeoutError: | |
raise ProcessNotFoundError('Process with PID={} not found!'.format(self.process)) | |
connected = True | |
elif 'handle' in kwargs: | |
if not handleprops.iswindow(kwargs['handle']): | |
message = "Invalid handle 0x%x passed to connect()" % ( | |
kwargs['handle']) | |
raise RuntimeError(message) | |
self.process = handleprops.processid(kwargs['handle']) | |
connected = True | |
elif 'path' in kwargs: | |
try: | |
self.process = wait_until_passes( | |
timeout, retry_interval, process_from_module, | |
ProcessNotFoundError, kwargs['path'], | |
) | |
except TimeoutError: | |
raise ProcessNotFoundError('Process "{}" not found!'.format(kwargs['path'])) | |
connected = True | |
elif kwargs: | |
kwargs['backend'] = self.backend.name | |
# XXX: vryabov | |
# if 'found_index' not in kwargs: | |
# kwargs['found_index'] = 0 | |
#if 'visible_only' not in kwargs: | |
# kwargs['visible_only'] = False | |
if 'timeout' in kwargs: | |
del kwargs['timeout'] | |
self.process = wait_until_passes( | |
timeout, retry_interval, findwindows.find_element, | |
exceptions=(findwindows.ElementNotFoundError, findbestmatch.MatchError, | |
controls.InvalidWindowHandle, controls.InvalidElement), | |
*(), **kwargs | |
).process_id | |
else: | |
self.process = findwindows.find_element(**kwargs).process_id | |
connected = True | |
if not connected: | |
raise RuntimeError( | |
"You must specify some of process, handle, path or window search criteria.") | |
if self.backend.name == 'win32': | |
self.__warn_incorrect_bitness() | |
if not handleprops.has_enough_privileges(self.process): | |
warning_text = "Python process has no rights to make changes " \ | |
"in the target GUI (run the script as Administrator)" | |
warnings.warn(warning_text, UserWarning) | |
return self |
To stabilize the CI, we need changes not only in the tests but also in the production codebase.
I'm not well-versed in Linux, so I hope someone else with Linux expertise can come up with a good implementation.
In the scope of this PR, I plan to make changes only to atspi_test.yml
.
I specified Install dependencies failure log
https://github.com/pywinauto/pywinauto/actions/runs/6123447605/job/16621351664 The cost of continuing to support Python 2.7 has increased compared to a few years ago. Any opinions would be appreciated. |
- add `Install sudo` - Remove redundant `with/without sudo` branches
I have been considering a way to support Python 2.7 in an Ubuntu environment using Here is a part of the message when using the
I've realized that |
I feel that there isn't much benefit in supporting
Therefore, nowadays, I think there are very few developers eagerly anticipating support for |
I confirmed that submitting a new PR or temporarily closing and reopening a previous PR causes the GHA to run. However, with my current permissions, I cannot execute "Cancel workflow", "Re-run failed jobs", or "Re-run all jobs". As mentioned earlier, tests for Without "Cancel workflow", I cannot cancel unterminated tests, resulting in a significant amount of time spent running tests for all conditions in the matrix. |
So I removed Python 2.7 from matrix(bf7f789...fc675c1). |
please see #1329