Python Webdriver how to handle a browser pop up. It is not an alert generated by JavaScript
I have managed to solve this now. I used the following code:
self.driver.find_element_by_xpath("//*[text()='OK']").click()
The Ok button is clicked on in IE and the pop up closes.
How to Handle Alert Pop-up Notification in Selenium with Python for Chrome Driver
To click on CheckBox try this
elementchekbox = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.ID, "blockWhatsnewModal")))
elementchekbox.click()
To click submit button try this
btnSubmit = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Submit']")))
btnSubmit.click()
Selenium + Python: Microsoft Edge Alert - no such alert
I can now see why you initially offered a 50 point bounty on this question, because it is a very complex problem to solve via Selenium.
SOLVED -- 02/05/2021
This should have not been this difficult to solve!! I'm totally amazed at all of the posts across multiple forums on this issue. Solving this took lot of trails and errors.
Step 1:
Open Microsoft Edge and navigate to a site that invokes the dialog as shown below.
Step 2:
Check the box - Allows allow to open links of this type in the associated app. Click Open. Close the associated app and shutdown Microsoft Edge.
Step 3:
reopen Microsoft Edge and navigate to edge://settings/content/applicationLinks
The application(e.g., zoom) is now allowed to automatically open.
Step 4:
Close Microsoft Edge and launch Selenium with the following code:
from msedge.selenium_tools import Edge
from msedge.selenium_tools import EdgeOptions
edge_driver = '/usr/local/bin/msedgedriver'
edge_options = EdgeOptions()
edge_options.use_chromium = True
edge_options.add_argument("user-data-dir=/Users/user_name/Library/Application Support/Microsoft Edge/User Data")
edge_options.add_argument("profile-directory=Profile 1")
edge_options.add_experimental_option("useAutomationExtension", False)
edge_options.add_experimental_option("excludeSwitches", ['enable-automation'])
# I needed this to work on macOS
edge_capabilities = edge_options.capabilities
edge_capabilities["platform"] = "ANY"
edge_capabilities.update(edge_options.to_capabilities())
driver = Edge(executable_path=edge_driver, options=edge_options)
driver.get("https://zoom.us/j/000-000-000")
The zoom application will automatically open without the dialog.
It seems that either msedge or selenium is creating a new profile each time it was launched, which still happens, but now parameters from Profile 1 are being inherited.
UPDATE -- 02/04/2021
Based on lots of research it seems that this dialog CANNOT be handled when Selenium is controlling either Google Chrome, Microsoft Edge or Mozilla Firefox.
The dialog can be suppressed outside of Selenium using a variety of methods, including registry settings on Microsoft platforms running multiple versions of Windows, Property list(PLIST) on Apple platforms running macOS and even browser level switches.
BUT SO FAR NONE OF THESE METHODS HAVE WORK WITH SELENIUM
This dialog is being generated outside the browser (and Selenium) at the Operating System (OS) level. It seem that you have to deal with this dialog at the OS level when using Selenium.
These modules might be useful in dealing with this dialog at the OS level.
- win32gui - Microsoft
- win32com - Microsoft
- appscript - Apple
I found an issue similar to yours on Github under SeleniumHQ/selenium.
The issue AddUserProfilePreference: Protocol_handler was closed and never resolved.
ORIGINAL POST -- 01/31/2021
I have tired to bypass the dialog with:
driver.switch_to.alert.accept()
But this call throws this error:
selenium.common.exceptions.NoAlertPresentException: Message: no such alert (Session info: MicrosoftEdge=88.0.705.56)
I have tried to pass these options individually and in groups with EdgeOptions():
edge_options.add_argument("--disable-popup-blocking")
edge_options.add_argument('--disable-default-apps')
edge_options.add_argument('--allow-silent-push')
edge_options.add_argument('--disable-notifications')
edge_options.add_argument('--suppress-message-center-popups')
edge_options.add_argument('--inprivate')
But the dialog still shows up.
I have also tried this:
from msedge.selenium_tools import Edge
from msedge.selenium_tools import EdgeOptions
edge_driver = '/usr/local/bin/msedgedriver'
edge_options = EdgeOptions()
edge_options.use_chromium = True
prefs = {'profile.default_content_setting_values.notifications': 2}
edge_options.add_experimental_option('prefs', prefs)
edge_capabilities = edge_options.capabilities
# I needed this to work on macOS
edge_capabilities["platform"] = "ANY"
edge_capabilities.update(edge_options.to_capabilities())
driver = Edge(executable_path=edge_driver, capabilities=edge_capabilities)
driver.get("https://zoom.us/j/000-000-000")
But yet again the dialog pops-up.
I have also tried to edit the default Microsoft Edge profile. During this edit I allowed my test site (zoom.us) to do most things.
from msedge.selenium_tools import Edge
from msedge.selenium_tools import EdgeOptions
edge_driver = '/usr/local/bin/msedgedriver'
edge_options = EdgeOptions()
edge_options.use_chromium = True
edge_options.add_argument("user-data-dir=/Users/user_name/Library/Application Support/Microsoft Edge/User Data")
edge_capabilities = edge_options.capabilities
# I needed this to work on macOS
edge_capabilities["platform"] = "ANY"
edge_capabilities.update(edge_options.to_capabilities())
driver = Edge(executable_path=edge_driver, capabilities=edge_capabilities)
driver.get("https://zoom.us/j/000-000-000")
But the dialog still popped up, but the zoom application downloaded, which didn't happen before.
I have also tested dozens of these switches using edge_options.add_argument('switch_name'), but like before nothing worked.
So like I stated before this dialog isn't a normal Alert and it will likely require code or setting outside of Selenium. I'm trying to determine what additional measures are needed.
To me it seems that you need to find a python module or even an OS application that can determine either the PID or the focus on that popup. Once you can determine that via the OS you should be able to close the dialog.
I cannot test this Microsoft Windows example, which supposedly stops the dialog per site.
In this Microsoft Forum discussion users are discussing how to stop these alerts from happening in a Microsoft Edge browser. The users are suggesting enabling a PLIST for MacOS or a registry key for Microsoft OS.
I tested the PLIST, which worked in the Microsoft Edge browser, but only when it wasn't being controlled by selenium.
UPDATE -- 02-04-2021
I also tested these switches, which did not solve the dialog issue.
# references
#
# 1. https://chromium.googlesource.com/chromium/src/+/master/chrome/common/pref_names.cc
#
# 2. https://stackoverflow.com/questions/62926156/chrome-84-a-website-wants-to-open-this-application-handlers
#
# 3. https://support.google.com/chrome/a/thread/62872506?hl=en
#
# 4. https://bugs.chromium.org/p/chromium/issues/detail?id=982341
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
capabilities = DesiredCapabilities().CHROME
prefs = {"protocol_handler": {"allowed_origin_protocol_pairs": {"https://zoom.us/*": {"zoom.us": True}}}}
# prefs = {"protocol_handler": {"excluded_schemes": {"zoom": False}}}
# prefs = {"protocol_handler": {"policy.auto_launch_protocols_from_origins": {"https://zoom.us/*": {"zoom.us": True}}}}
# prefs = {"AutoLaunchProtocolsFromOrigins": [{"allowed_origins": ["*"], "protocol":"zoom.us"}]}
chrome_options.add_experimental_option('prefs', prefs)
capabilities.update(chrome_options.to_capabilities())
SIDE NOTE:
I was able to disable the banner "Microsoft Edge is being controlled by automated test software" using the switches below:
edge_options.add_experimental_option("useAutomationExtension", False)
edge_options.add_experimental_option("excludeSwitches", ['enable-automation'])
----------------------------------------
My system information
----------------------------------------
Platform: macOS
Python: 3.8.0
msedge-selenium-tools: 3.141.2
----------------------------------------
Python Selenium - Alert Like Authentication Pop Up
The reason you cannot "find" the element
The alert box is not an HTML element. It's not part of the webpage, thus you could not see it in the HTML code. The alert box is part of the browser.
Some context
What you are seeing is an example of the Basic access authentication. As the wiki stated, what usually would happen is that your app/browser automatically provides the username and password via a header field (the Authorization
header) in the request. In this case, your browser does not know the username and password yet so it asks for it via the browser's alert box.
My proposed solution
I believe the cleanest and easiest way to authenticate using selenium would be providing the credential during your get method like so:
chrome.get('http://username:password@domain')
In your specific case, it would be http://admin:admin@the-internet.herokuapp.com/basic_auth
.
However, as @Nic-Laforge mentioned, this solution is dependent on the fact that the browser supports it. (as of writing the latest Chrome supports it)
The solutions from the other StackOverflow post
Unlike my proposed solution, both of the solutions proposed in the similar StackOverflow post require additional libraries.
The first solution Mr. @Evander proposes is to use a pynput
library to simulate keyboard input. This solution requires the user to use a non-headless browser, to have the browser focused, and to not interact with the keyboard during the input.
The second solution is much nicer. As stated above, the Basic access authentication expects your credentials in the Authorization
header in the request. What Mr. @Evander did is use the selenium-wire
library to intercept selenium's request and add the header with the credentials.
Related Topics
How to Create an Object for a Django Model with a Many to Many Field
How to Isolate Everything Inside of a Contour, Scale It, and Test the Similarity to an Image
How to Replace Django's Primary Key with a Different Integer That Is Unique for That Table
Numpy: Fix Array with Rows of Different Lengths by Filling the Empty Elements with Zeros
Python: Sort Function Breaks in the Presence of Nan
Catch Exception and Continue Try Block in Python
Matplotlib Semi-Log Plot: Minor Tick Marks Are Gone When Range Is Large
How to Redirect Stderr in Python
Seeking from End of File Throwing Unsupported Exception
What's a Good Equivalent to Subprocess.Check_Call That Returns the Contents of Stdout
How to Rotate a Matplotlib Plot Through 90 Degrees
Python Method Name with Double-Underscore Is Overridden
Repeat Rows in Data Frame N Times
Python Split a String with at Least 2 Whitespaces