I have a Jenkins pipeline that executes a program in a remote server that uses pywin to manipulate an application for functional tests.
My application works great while I have the remote desktop oppened but when I close the remote desktop and run it from Jenkins, the app gets lost.
What I do is to open the app and send an enter key.
This is my app:
os.startfile("C:\\Program Files (x86)\\SAP\\FrontEnd\\SAPgui\\saplogon.exe")
time.sleep(5)
handle = win32gui.FindWindow(0, "SAP Logon 740")
keyboard = Controller()
keyboard.press(Key.enter)
So I tried to add focus to the app to force the focus without success:
os.startfile("C:\\Program Files (x86)\\SAP\\FrontEnd\\SAPgui\\saplogon.exe")
time.sleep(5)
handle = win32gui.FindWindow(0, "SAP Logon 740")
win32gui.ShowWindow(handle, 5)
win32gui.SetForegroundWindow(handle)
keyboard = Controller()
keyboard.press(Key.enter)
I changed the key presses to this with the same result:
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys('{ENTER}')
I tried changing to pywinauto trying to do a click on a button instead of sending the enter but I found more problems, as pywinauto is not recognizing my app titles:
app = Application().start("C:\\Program Files (x86)\\SAP\\FrontEnd\\SAPgui\\saplogon.exe")
app["SAP Logon 740"] # this doesn't work
app.top_window_() # this doesn't work either
handle = win32gui.FindWindow(0, "SAP Logon 740")
sapApp = app.window_(handle = handle) #Finally this works but...
sapApp["Log &On"].click() # This doesn't work
sapApp.log_on.Click() # This doesn't work
I get this exception:
ctypes.ArgumentError: argument 2: <class 'TypeError'>: expected LP_c_ulong instance instead of pointer to c_long
I know that's the name because I tried:
print(sapApp.descendants(control_type="MenuBar"))
And got this results:
[<win32_controls.ButtonWrapper - 'Log &On', Button, 14221798>, ...]
So I know that's the name of the button but haven't been able to click on it.
I also tried setting focus to the app, with the same result:
sapApp.SetFocus()
With the remote desktop oppened everything works fine but it its closed my app doesn't get the enter
So has anyone had this problem before? I'm running out of ideas what else can I try?
Thanks
EDIT:
This is the full trace for the ctypes error:
File "e:\Jenkins\workspace\my-project\scripts\test_pywin.py", line 23, in <module> sapApp.log_on.Click()
File "E:\Python_V365\lib\site-packages\pywinauto\controls\hwndwrapper.py", line 725, in click self.verify_actionable()
File "E:\Python_V365\lib\site-packages\pywinauto\base_wrapper.py", line 591, in verify_actionable self.wait_for_idle()
File "E:\Python_V365\lib\site-packages\pywinauto\controls\hwndwrapper.py", line 710, in wait_for_idle win32functions.WaitGuiThreadIdle(self)
File "E:\Python_V365\lib\site-packages\pywinauto\win32functions.py", line 283, in WaitGuiThreadIdle GetWindowThreadProcessId(handle, ctypes.byref(process_id))
ctypes.ArgumentError: argument 2: <class 'TypeError'>: expected LP_c_ulong instance instead of pointer to c_long
Also tried (backend="uia") to start the app with the same results:
app = Application(backend="uia").start("C:\\Program Files (x86)\\SAP\\FrontEnd\\SAPgui\\saplogon.exe")
And trying the connect after starting the program gives me this error:
app = Application().connect(title="SAP Logon 740", timeout=10)
File "e:\Jenkins\workspace\tacion_BehaveImplementation-637TPHZXXSFG4MVWWWJCBSJOWSAVPZMPOYFKFKNYKRT5XRBIZFBQ\scripts\test_pywin.py", line 12, in <module> app = Application().connect(title="SAP Logon 740", timeout=10)
File "E:\Python_V365\lib\site-packages\pywinauto\application.py", line 944, in connect self.process = findwindows.find_element(**kwargs).process_id
File "E:\Python_V365\lib\site-packages\pywinauto\findwindows.py", line 84, in find_element elements = find_elements(**kwargs)
TypeError: find_elements() got an unexpected keyword argument 'timeout'
This finally works:
app = Application().connect(title="SAP Logon 740", backend="uia")
sapApp = app["SAP Logon 740"]
But found out the problem is actually that I need to wait for the app to fully load so this works too:
app = Application().start("C:\\Program Files (x86)\\SAP\\FrontEnd\\SAPgui\\saplogon.exe")
time.sleep(5)
app["SAP Logon 740"]
But still the same problem with the button