I am trying to automate some basic web browser manipulation. As part of this sequence there is a popup window that must be dealt with. Once the python code the causes the popup window to appear happens, no other code past that point will run until I manually close that window. Then all remaining code runs fine.
I've try this below to try to deal with handling the popup but to no avail:
for handle in browser.window_handles:
print "Handle = ",handle
browswer.switch_to_window(handle);
elem=browser.find_element_by_tag_name("title")
print elem.get_attrbitue("value")
I cannot even get a basic 'print' command to execute until I close the popup window. Is there a need to set some type of event handler BEFORE the code is called that brings the popup menu?
Thanks for any suggestions.
Related
I'm using Python and Selenium to write an automation script in Internet Explorer.
When the web page throws up some kind of modal dialog box, the Python code stops running and just waits for some action to be taken on the popup. After you press the "yes" or "no" button, then the Python code continues.
I believe the underlying Javascript function that is getting called (saveClicked()) is generating the popup box using this line of code:
var result=window.showModalDialog('whatever....')
Does anyone know how to handle this in Selenium? I want my code to click "ok" in this window or to just accept it. I tried right-clicking on the window to look at source code, etc. but those options are not given to me...the only options are "move/close".
I've looked to see if there is some kind of default IE capability in Selenium that will just automatically accept all modal dialog boxes but haven't found any. I also thought of maybe wrapping the call to the Javascript function with something that would somehow send a keystroke to the alert. I'm open to anything!
Here is the code: It never moves past the .execute_script line...it just sits there waiting.
print('Saving')
# I have to do this because I can't get the handle to the save button
# using any of the known Selenium methods but calling the JS works
driver.execute_script('saveClicked();')
print('Test')
driver.switch_to().alert().send_keys(Keys.ENTER)
The code just STOPS after the Javascript is executed and never moves to the print('test') line or any other code I put there.
Any python selenium code suggestions to solve this would be greatly appreciated.
one way: you can try to use Alert to manage popups
Alert(driver).accept()
otherwise you can see the active window or tab with:
#get current window handle
p = driver.current_window_handle
#get windows
chwd = driver.window_handles
driver.switch_to.window(chwd[1])
reference:
https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.alert
Try:
message = "saveClicked()" # or any other of your messages
driver.execute_script(f"alert(\"{message}\");")
driver.switch_to.alert.accept()
I'm trying to get PyWinAuto to click a button as soon as it's enabled. Here's what I currently have:
while running:
try:
app = pywinauto.Application().connect(title='Microsoft Outlook', class_name="#32770")['Microsoft Outlook']
app.Allow.Wait('ready', retry_interval=0.1)
app.Allow.Click()
print('Clicked')
except (pywinauto.findbestmatch.MatchError, pywinauto.findwindows.ElementNotFoundError):
time.sleep(0.1)
pass
This works just fine if I start it running after the button is active, clicking and printing 'Clicked' as expected. If I run it before the button is active, it waits for it as expected and then seems to try and click it - Printing 'clicked' repeatedly until I click either mouse button or press enter. If I take the click() out and get it to just return app.Allow then the result is as expected regardless of when I load the script, so it does seem to be click() that's the hangup.
The behaviour is the same regardless of where I click or which window I have active - It'll work if I click anywhere or anything, but it won't do anything at all until I do... Which defeats the object of the automation, really!
Any ideas?
Thanks!
First you have to run the script as Administrator if you use .connect(...). I've already added warning about that and error in the .click() method when target process has higher privileges. See pull request #499. It will be included into coming pywinauto==0.6.5.
There is one more method: .click_input() moves mouse cursor and performs real click. While .click() just sends WM_CLICK window message (might be useful for minimized or non-active window).
P.S. By the way, for Outlook I'd recommend using Application(backend="uia") and you'll have no Win32 API specific problems. See Getting Started Guide about backends difference.
In the app I'm trying to automate there is an error window that could pop-up in literally any moment of application work. Then I need to perform some actions like logging this event and stop next automation steps. So I need to catch this moment. How can I do it?
This window always has the same properties (auto_id) so I can describe it before it exist. I can think of using something like a timer which will always check for existence of this window (with the help of .exists(), I guess). But maybe there is a better way of doing it?
PyQt4/5 on OSX El Capitan
I have a QMessageBox/QDialog which I want to be modal and want to block input from other GUI items while a process is running. The QDialog should provide the user the option to cancel the said process, but not allow him or her to do anything else with the GUI in the meantime.
Once the process is finished, it should close the QDialog and enable input to the main application again. Because things should happen in the background while the dialog is shown, I am not using exec_() to display the dialog.
Here is a simple example of my code:
self.openingDialog = QtWidgets.QMessageBox(self.main_window)
self.openingDialog.setText(_(u"Opening experiment. Please wait"))
self.openingDialog.setStandardButtons(QtWidgets.QMessageBox.Cancel)
self.openingDialog.reject.connect(<some_function>)
self.openingDialog.show()
self.openingDialog.raise_()
... [Perform process] ...
self.openingDialog.done(0)
self.openingDialog.close()
self.openingDialog.deleteLater()
Everything works nicely in the sense that the dialog box is shown, and that no interaction is possible with other GUI elements while it is displayed. However, when has process is finished, the dialog box is automatically closed but it is still not possible to interact with other GUI elements afterwards. The GUI does not respond to mouse clicks, menu items are not accessible, and you can't even click the close button, so the application needs to be Force Quit.
What am I doing wrong in automatically closing the QDialog?
Ok, I have found sort of a workaround, although I don't think it is an elegant solution.
If I set the window modality to 'window modal' instead of 'application modal' by using:
self.openingDialog.setWindowModality(QtCore.Qt.WindowModal)
then the application regains focus and accessibility after the dialog has been closed by the program.
Still this doesn't solve the problem when the dialog is an application modal, but for now this serves my needs.
I use GtkAboutDialog and everything works fine except the close button of this widget. All other buttons works fine, I don't know how but all buttons have default callbacks and they create and destroy the windows.
But the "Close" button of GtkAboutDialog widget does not work. I can not even see it's widget. So, can I access it?
[CLARIFICATION] What you're looking at is gtk.AboutDialog — popup window displaying information about an application (new in PyGTK 2.6). This window contains the 'close' button widget which is contained in a GtkHButtonBox widget. The GtkHButtonBox widget is the highest level widget I am able to access for some. Any ideas on how to get to the "close" button and connect a handler for a callback signal?
You don't conenct signals in the same way for a dialog as you do for a window. I made the same mistake when learning PyGTK.
The most basic form of a dialog is you display and run the dialog with:
aboutdialog.run()
Often you will then immediately call:
aboutdialog.destroy()
The .run() line is a loop, which runs until something happens within the dialog.
There is a working example here.
The gtk.AboutDialog is just a gtk.Dialog, and you handle responses from it in the same way. Instead of connecting to the clicked signal of the buttons, the dialog code handles that for you and returns a reponse from your run() call. You can check the value of the response returned to figure out what button was clicked.
If you're trying to override some behaviour instead, you can connect to the response signal of gtk.Dialog.
This is an old question, but since it's one of the first hits from google, I thought I'd throw in the solution that I found. You need an event handler to show the about dialog and one to close it. The first will likely be connected to your help->about menuitem's activate signal. The latter should be connected to the response signal of the about dialog. The two handlers will look something like this:
def on_menuitemHelpAbout_activate(self, *args):
self.builder.get_object('aboutdialog').show()
def on_aboutdialog_response(self, *args):
self.builder.get_object('aboutdialog').hide()
In the example above, I'm using the GtkBuilder to find my about dialog because I've constructed the interface with glade. Note that I'm using .show() over .run() because I don't see the sense in pausing program execution until the dialog is closed. Finally, the response handler can be made to take whatever action depending upon the response, but I'm ignoring it here.