I ran into the exact same problem. In javascript, confirm() is a blocking function. Other code waits for it to return. However, Selenium is somehow circumventing this, meaning the popup returns None right away.
driver.execute_script("return confirm('Do you like apples?');")
This is true for all three popup windows. (The values listed are what they are supposed to return).
alert() returns None
confirm() returns bool
prompt() returns str
The way that you make them return properly is to assign their values to a preexisting variable.
driver.execute_script("let response;")
driver.execute_script("response = confirm('Do you like apples?');")
user_likes_apples = driver.execute_script("return response;")
This only works if you define response in an entirely seperate call. The following does not work.
driver.execute_script("let response; response = confirm('Do you like apples?');")
driver.execute_script("return response;")
Below I've developed a full example. Hope it's useful.
from typing import Optional
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException, NoSuchWindowException, NoAlertPresentException
class PopupDriver(webdriver.Chrome):
# Show a popup in the browser
def _show_popup(self, popup: str, message: str) -> Optional[object]:
self.execute_script("let result;") # must be seperate
self.execute_script("result = %s('%s');" % (popup, message))
self.wait.until(EC.alert_is_present())
# Function to determine whether user has closed alert
def popup_is_closed(driver: webdriver.Chrome) -> bool:
try: response = dir(self.switch_to.alert)
except NoAlertPresentException: return True
return False
# Wait until alert is closed by user
self.wait.until(popup_is_closed)
# Return alert text value
return self.execute_script("return result;")
# Show an alert popup in the browser
def show_alert(self, message: str) -> None:
self._show_popup("alert", message)
# Show a confirmation popup in the browser
def show_confirmation(self, message: str) -> bool:
return self._show_popup("confirm", message)
# Show a prompt popup in the browser
def show_prompt(self, message: str) -> str:
return self._show_popup("prompt", message)
# Oh so difficult
def ask_the_hard_questions(self) -> None:
self.show_alert("Hello world!")
user_is_sane = self.show_confirmation("Continue if you think the world is a sphere.")
print("You think that the Earth is ", "not " * user_is_sane, "flat.", sep="")
print("Your name is", self.show_prompt(r"What\'s your name?")) # escape single quote
# Handle exceptions
def run(self) -> None:
try: self.ask_the_hard_questions()
except TimeoutException: # user did not respond within timeout
try: self.show_alert("You timed out. Stumped, huh?")
except TimeoutException: pass
except NoSuchWindowException: pass # user closed the window
finally: self.quit()
if __name__ == "__main__":
p = PopupDriver()
p.run()