My issue: Being able to detect an alert box has been opened, verify the text inside the alert, confirm the text and then close the alert. Then, go back and correct the invalid email.
My test is one for registering a user. I need to validate when someone might input incorrect data or mismatched data. In this case, I am entering an email and verifying the email first entered. Should they have a mismatch, a popup will appear alerting the user to check the email addresses they have entered and that they match. So far all I can get is an error.
Error:
E UnexpectedAlertPresentException: Message: u'Modal dialog
present' ; Stacktrace: Method nsCommandProcessor.prototype.execute
threw an error in file:///var/folders/1j/x3cxkrqn3sscdyq0t36169hr0000gn/T/tmpTCqMgm/extensions/fxdriver#googlecode.com/components/command_processor.js
I thought my code would handle this, but nope. If someone could point out my, obvious to you, mistake I would be grateful.
My entire test code:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re
class ChallengeTests(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(5)
self.base_url = "https://www.testpage.com"
self.verificationErrors = []
self.accept_next_alert = True
# SIGN UP NEW USER
def test_00_sign_up(self):
driver = self.driver
driver.get(self.base_url + "/")
driver.find_element_by_id("remail").send_keys("foobar#me.com")
driver.find_element_by_id("remail_confirm").send_keys("bar#me.com")
driver.find_element_by_id("next").click()
alert = self.driver.switch_to_alert()
alert = self.assertTrue(self.is_text_present("The email addresses you entered"))
driver.find_element_by_id("remail_confirm").send_keys("foobar#me.com")
driver.find_element_by_id("registration_button").click()
# NON TESTS
def is_element_present(self, how, what):
try:
self.driver.find_element(by=how, value=what) # to find page elements
except NoSuchElementException, e: return False
return True
def is_text_present(self, text):
try:
body = self.driver.find_element_by_tag_name("body") # find body tag element
except NoSuchElementException, e: return False
return text in body.text # check if the text is in body's text
def is_alert_present(self):
try:
self.driver.switch_to_alert()
except NoAlertPresentException, e:
return False
def close_alert_and_get_its_text(self):
try:
alert = self.driver.switch_to_alert()
alert_text = alert.text
if self.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: self.accept_next_alert = True
return True
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
On newer version of Python(3.4)
def is_alert_present(self):
try:
self.driver.switch_to_alert()
except NoAlertPresentException:
return False
Try waiting for the alert to appear, before directly switching to it.
If that does not work, I have a feeling that the popup actually is a weblement and not a JS alert. if that is the case try looking for a selector using the browser developer tools and directly interact with it.
Related
I've never really done any serious coding before so please bear with me if I say something incorrect, and just correct me so I know better.
I've create a very simple Selenium IDE test case where it searches a term through google and then waits for a certain link to come up:
Base Url: https://www.google.com/
open | /
sendKeys | id=lst-ib | This is Sparta${KEY_ENTER}
waitForElementPresent | xpath=(//a[contains(text(),'300 (film) - Wikipedia')])[2]
clickAndWait | xpath=(//a[contains(text(),'300 (film) - Wikipedia')])[2]
And when I export that as a Python2/unittest/WebDriver it gives me this .py file:
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
class ThisIsSpartaTestCase(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "https://www.google.com/"
self.verificationErrors = []
self.accept_next_alert = True
def test_this_is_sparta_test_case(self):
driver = self.driver
driver.get(self.base_url + "/")
driver.find_element_by_id("lst-ib").send_keys("This is Sparta", Keys.ENTER)
for i in range(60):
try:
if self.is_element_present(By.XPATH, "(//a[contains(text(),'300 (film) - Wikipedia')])[2]"): break
except: pass
time.sleep(1)
else: self.fail("time out")
driver.find_element_by_xpath("(//a[contains(text(),'300 (film) - Wikipedia')])[2]").click()
def is_element_present(self, how, what):
try: self.driver.find_element(by=how, value=what)
except NoSuchElementException as e: return False
return True
def is_alert_present(self):
try: self.driver.switch_to_alert()
except NoAlertPresentException as e: return False
return True
def close_alert_and_get_its_text(self):
try:
alert = self.driver.switch_to_alert()
alert_text = alert.text
if self.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: self.accept_next_alert = True
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
Which works, and it's all great and dandy.
My issue is that I would like to output a message onto the Python IDLE Shell that says something like "The link element is present" when the python code is able to find the wiki link on the Google page. I tried to do a "print "Wiki Link is Found on Google Page" after the return True in def is_element_present, and even though it runs, it doesn't output that message onto the Shell.
Do any of y'all know how to make it output a message onto the Shell?
Please let me know, thank you!
I recorded a script by selenium IDE in Firefox, and exported to python webdriver. but when I run the code, it will open the skype support page at the same time. Don't know why.
My firefox is the latest(50.1.0), python 2.7.12, selenium 3.0.2
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
class Test2(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "http://www.cic.gc.ca/english/visit/"
self.verificationErrors = []
self.accept_next_alert = True
def test_2(self):
driver = self.driver
driver.get(self.base_url)
driver.find_element_by_id("kw").click()
driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys("tt")
driver.find_element_by_id("su").click()
def is_element_present(self, how, what):
try: self.driver.find_element(by=how, value=what)
except NoSuchElementException as e: return False
return True
def is_alert_present(self):
try: self.driver.switch_to_alert()
except NoAlertPresentException as e: return False
return True
def close_alert_and_get_its_text(self):
try:
alert = self.driver.switch_to_alert()
alert_text = alert.text
if self.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: self.accept_next_alert = True
# def tearDown(self):
# self.driver.quit()
# self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
I am not a python/selenium expert, but I think I have experienced the same problem. I have just recently installed selenium in my Enthought Canopy application.The following simple code produces a Skype web-browser window:
#file: selenium2.py .
from selenium import webdriver
#browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser.get('http://seleniumhq.org/') # always gets skype ???
"""
This url window is the response:
https://support.skype.com/en/faq/FA34612/what-is-the-skype-extension
"""
I have a python script generated from selenium, it works fine on my localhost.
Now I want to run it from my web hosting, I already checked that my web hosting support python.
If not possible, is there an alternative solution for selenium?
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
class HellowWorld(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "https://www.google.com/"
self.verificationErrors = []
self.accept_next_alert = True
def test_hellow_world(self):
driver = self.driver
driver.get(self.base_url + "/")
driver.find_element_by_id("lst-ib").clear()
driver.find_element_by_id("lst-ib").send_keys("hello world")
def is_element_present(self, how, what):
try: self.driver.find_element(by=how, value=what)
except NoSuchElementException as e: return False
return True
def is_alert_present(self):
try: self.driver.switch_to_alert()
except NoAlertPresentException as e: return False
return True
def close_alert_and_get_its_text(self):
try:
alert = self.driver.switch_to_alert()
alert_text = alert.text
if self.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: self.accept_next_alert = True
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
I found a good alternative based on google's puppeteer library.
All information that do you need is in this web page pypeteer
You can install it using: pip install pyppeteer
Here an example of code to take a screenshoot:
import asyncio
from pyppeteer import launch
async def main():
browser = await launch()
page = await browser.newPage()
await page.goto('https://example.com')
await page.screenshot({'path': 'example.png'})
await browser.close()
asyncio.get_event_loop().run_until_complete(main())
I think that the best option is to connect to a remote webdriver setting a remote host with selenium port.
Example: http://remotehost:4444
const {Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');
let options = new firefox.Options()
.setProfile('/profile/path/on/remote/host')
.setBinary('/install/dir/on/remote/host/firefox-bin');
let driver = new Builder()
.forBrowser('firefox')
.usingServer('http://{remote-host}:4444/wd/hub')
.setFirefoxOptions(options)
.build();
I have a python script that runs different selenium WebDrivers which have been exported into python. The script and webdrivers do what I want them to do. When the script executes a webdriver, the webdriver will do what it needs to then go back and continue the script but then it will pause and firefox will pop up again and execute the same webdriver task again. This doesn't affect the results I get from the webdrivers or the script but it increases my run-time significantly.
After the first exectution of a webdriver the shell will return:
Ran 1 test in 192.680s
OK
However, when it repeats the webdriver unexpectedly it only returns a period "."
Here is the code for the webdriver,
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re
class WebdriverViewas(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = #website I'm interested in visiting
self.verificationErrors = []
self.accept_next_alert = True
def test_webdriver_viewas(self):
#Here I just tell the webdriver what to do, I doubt this is causing the problem
def is_element_present(self, how, what):
try: self.driver.find_element(by=how, value=what)
except NoSuchElementException, e: return False
return True
def is_alert_present(self):
try: self.driver.switch_to_alert()
except NoAlertPresentException, e: return False
return True
def close_alert_and_get_its_text(self):
try:
alert = self.driver.switch_to_alert()
alert_text = alert.text
if self.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: self.accept_next_alert = True
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__=='__main__':
try:
unittest.main()
except SystemExit as inst:
if inst.args[0] is True: # raised by sys.exit(True) when tests failed
raise
I suspected the problem could be solved with the unittest module but I've found nothing in the research I've done nor have I been able to find anyone with a similar problem.
I am using selenium package with Python (https://pypi.python.org/pypi/selenium) with Windows 7.
When I try to login to my facebook account I use the send_keys command, e.g.
elem = browser.find_element_by_name("email")
elem.send_keys(email);
elem = browser.find_element_by_name("pass")
elem.send_keys(password);
Login fails apparently because the second send_keys drops the first character of the password (I found this by directly sending the password characters to the email field.
What's going on? Why can't selenium do something so simple as sending keys to an input field?
Is this some kind of a protection measure coded by Facebook to reject automatic scripting?
Tried to send the whole alphabet and got this:
abcdefghijklmnopqrstuvwxyzBCDFGIKLNOQSTWX
Notice how many characters are missing...
Update
Apparently the problem has nothing to do with facebook but to the chrome driver.
If I send the following simple code
browser = webdriver.Chrome()
browser.get("https://www.google.com") # Load page
elem = browser.find_element_by_name("q") # Find the query box
query= "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
elem.send_keys(query)
With chrome driver I get
BCDFGIKLNOQSTWX
Notice how A, E, H ... Y, Z are missing
With firefox driver (replacing browser = webdriver.Chrome() with browser = webdriver.Firefox() I get:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
I ran into a similar problem as OP and was satisfied with none of the answers written here nor anywhere else on this site that I could find.
Since I read during my research that the issue was at some point in time fixed, I have to assume that it re-appeared nowadays.
As P.T. mentioned, if you run into similar problems, chances are the chromedrivers/firefoxdrivers are buggy again.
Since none of the solutions I found helped alleviate the issue, I instead opted for just circumventing selenium and its drivers altogether. So I used javascript to first find the element (through its absolute Xpath), then write to it / set it.
from selenium import webdriver
def write_to_element(driver, element_xpath, input_string),
js_command = f'document.evaluate(\'{xpath}\', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.value = \'{input_string}\';'
driver.execute_script(js_command)
driver = webdriver.Chrome()
driver.get('WebPage/With/Element/You/Want/To/Write/To')
xpath = 'Xpath/Of/Element/You/Want/To/Write/To'
write_to_element(driver, xpath, 'SomeRandomInput')
document.evaluate(\'{xpath}\', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null) evaluates the xpath to an element, so essentially finds your element on the webpage.
.singleNodeValue.value = \'{input_string}\';' sets the value of that element to input_string
Looks like there are (were) some bugs in the Chrome webdriver: https://code.google.com/p/chromedriver/issues/detail?id=435
The core of the problem looks to be when either the keyboard is configured for a non-English language, or if the webdriver process and the chrome display are running in different language/environments (e.g., when going through a remote display from one host to another, etc.)
I've solved using a custom method for send_keys, which works a little bit lower but fast enough.
from selenium.webdriver.remote.webelement import WebElement
def send_keys(el: WebElement, keys: str):
for i in range(len(keys)):
el.send_keys(keys[i])
send_keys(el, keys)
Use selenium Ide and export test case in python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re
class Test1(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "https://www.facebook.com/"
self.verificationErrors = []
self.accept_next_alert = True
def test_1(self):
driver = self.driver
driver.get(self.base_url + "/")
driver.find_element_by_id("email").clear()
driver.find_element_by_id("email").send_keys("username")
driver.find_element_by_id("pass").clear()
driver.find_element_by_id("pass").send_keys("password")
driver.find_element_by_id("u_0_b").click()
driver.find_element_by_xpath("//div[#id='u_ps_0_1_5']/div/div").click()
driver.find_element_by_link_text("1 Requests").click()
driver.find_element_by_id("globalContainer").click()
def is_element_present(self, how, what):
try: self.driver.find_element(by=how, value=what)
except NoSuchElementException, e: return False
return True
def is_alert_present(self):
try: self.driver.switch_to_alert()
except NoAlertPresentException, e: return False
return True
def close_alert_and_get_its_text(self):
try:
alert = self.driver.switch_to_alert()
alert_text = alert.text
if self.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: self.accept_next_alert = True
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()