I try to understand where is the problem in code:
class WebTest(unittest.TestCase):
#classmethod
def setUpClass(cls):
binary = FirefoxBinary('/home/andrew/Downloads/firefox 45/firefox')
cls.browser = webdriver.Firefox(firefox_binary=binary)
cls.wait = WebDriverWait(cls.browser, 10)
cls.browser.maximize_window()
cls.browser.get('http://www.test.com/')
def test_login_menu_elements(self):
self.wait.until(EC.element_to_be_clickable((By.XPATH, "//a[#id='menu_min']"))).click()
check_icons(self)
self.wait.until(EC.element_to_be_clickable((By.XPATH, "//a[#id='menu_min']"))).click()
check_fields(self)
def test_add_news(self):
self.wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(.,'News')]"))).click()
self.wait.until(EC.element_to_be_clickable((By.XPATH, "//a[#href='/manager/news']"))).click()
#classmethod
def tearDownClass(cls):
cls.browser.quit()
if __name__=='__main__':
unittest.main()
Every time I receive TimeoutException, and I really don't understand why, and where is the problem in the code
A TimeoutException can be received without having any logical or syntantic errors with your code.
TimeoutExceptions will be raised when the wait.until expected conditions aren't found.
Some things I have found to help:
Isolate the xpath by using chrome/firefox dev tools and right clicking on the element, and show xpath
Using the xpath from the step above, make sure that the condition chose is correct
ime having front end experience, using css selectors is usually more intuative and more understandable than relative xpaths.
check the selector you are using by opening up dev tools console and using $x({{ XPATH_HERE }}) to make sure it is valid
for dynamic HTML use python debugger and make sure that html is in the expected state between each expected condition
Related
When I use below code, the website doesn't go on to the next page.
import unittest
from selenium import webdriver
import time
class ProductPurchase(unittest.TestCase):
"""
Purchase the product on the website http://automationpractice.com/index.php
"""
# Preconditions
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.get("http://automationpractice.com/index.php")
self.driver.maximize_window()
def teardown(self):
self.driver.quit()
# Buying a product on the website
def test_wrong_agreement(self):
driver = self.webdriver
time.sleep(2)
#Click on "Quick view"
quickview_btn = driver.find_element_by_xpath("/html/body/div/div[2]/div/div[2]/div/div[1]/ul[1]/li[1]/div/div[1]/div/a[2]").click()
if __name__ == '__main__':
unittest.main(verbosity=2)
It should go on to the next page but xPath doesn't work.
Hello and good luck on learning test automation.
The first thing I do when an xpath does not work is to check it, usually using an extension like this one to make sure it is correct. Additionally, it is better to use a shorter xpath so there is less room for mistake i.e. "//img[#title='Printed Dress']"
Try the following xpath and use javaScript executor to click on Quick View
This code will click 1st element on the page.If you wish to click all Quick Viw button sequentially you need to write logic further.
driver.get("http://automationpractice.com/index.php")
driver.maximize_window()
ele_Quikview=driver.find_element_by_xpath('(//a[#class="quick-view"])[1]')
driver.execute_script("arguments[0].click();",ele_Quikview)
I'm newbie in Selenium. I start to learn Selenium via book. And I struggle with unclear behavior of Selenium. For educational purposes I use this site:
http://magento-demo.lexiconn.com/ - I'm trying to find search button by its class name, (which is: class='button search button') or by it xpath
search_button = self.driver.find_element_by_xpath('/html/body/div/div[2]/header/div/div[4]/form/div[1]/button')
or
search_button = self.driver.find_element_by_class_name('button')
but each time selenium unable to find it. Please help me to understand reason of such behavior. Thank you
I used Selenium IDE and it shows me XPATH: //button[#type='submit']
when I tried to find element by xpath,I have got the same error and it is strange. Please advise.
My code is:
import unittest
from selenium import webdriver
class HomePageTest(unittest.TestCase):
#classmethod
def setUpClass(cls):
#create new Firefox session
cls.driver = webdriver.Firefox()
cls.driver.implicitly_wait(30)
cls.driver.maximize_window()
#navvigate to application home page
cls.driver.get('http://magento-demo.lexiconn.com/')
def test_search__text_field_max_length(self):
#get the search text box
search_field=self.driver.find_element_by_id("search")
#check maxlenght attribute st to 128
self.assertEqual("128",search_field.get_attribute("maxlength"))
def test_search_button_enabled(self):
# get Search button
search_button = self.driver.find_element_by_class_name('button')
# check Search button is enabled
self.assertTrue(search_button.is_enabled())
#classmethod
def tearDown(self):
#close the browser window
self.driver.quit()
if __name__=='__main__':
unittest.main(verbosity=2)
Try this :
search_button = self.driver.find_element_by_xpath('//button[#class="button search-button"]')
Try downloading the selenium IDE plugin, install and start recording. Click on the button you want and view how its target is recorded in the IDE. Programmatically, selenium will accept the same xpaths and other selectors as the IDE. After it's been recorded in the IDE, there is a pull down on the target field that lets you see all the different ways you can select that element, ie xpath vs. by class etc.
http://www.seleniumhq.org/projects/ide/
you might try:
css=button.button.search-button
//button[#type='submit']
//form[#id='search_mini_form']/div/button
I think the issue is that your locator isn't specific enough. There is more than one button on the page and more than one element with class=button on the page. This CSS selector is working for me.
self.driver.find_element_by_css_selector("button[title='Search']")
Try this way using xpath locator
Explanation: Use title attribute of <button> tag.
self.driver.find_element_by_xpath("//button[#title='Search']")
OR
Explanation: Use title and type attribute of <button> tag.
self.driver.find_element_by_xpath("//button[#title='Search'][#type='submit']")
How do I print a webpage using selenium please.
import time
from selenium import webdriver
# Initialise the webdriver
chromeOps=webdriver.ChromeOptions()
chromeOps._binary_location = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
chromeOps._arguments = ["--enable-internal-flash"]
browser = webdriver.Chrome("C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe", port=4445, chrome_options=chromeOps)
time.sleep(3)
# Login to Webpage
browser.get('www.webpage.com')
Note: I am using the, at present, current version of Google Chrome: Version 32.0.1700.107 m
While it's not directly printing the webpage, it is easy to take a screenshot of the entire current page:
browser.save_screenshot("screenshot.png")
Then the image can be printed using any image printing library. I haven't personally used any such library so I can't necessarily vouch for it, but a quick search turned up win32print which looks promising.
The key "trick" is that we can execute JavaScript in the selenium browser window using the "execute_script" method of the selenium webdriver, and if you execute the JavaScript command "window.print();" it will activate the browsers print function.
Now, getting it to work elegantly requires setting a few preferences to print silently, remove print progress reporting, etc. Here is a small but functional example that loads up and prints whatever website you put in the last line (where 'http://www.cnn.com/' is now):
import time
from selenium import webdriver
import os
class printing_browser(object):
def __init__(self):
self.profile = webdriver.FirefoxProfile()
self.profile.set_preference("services.sync.prefs.sync.browser.download.manager.showWhenStarting", False)
self.profile.set_preference("pdfjs.disabled", True)
self.profile.set_preference("print.always_print_silent", True)
self.profile.set_preference("print.show_print_progress", False)
self.profile.set_preference("browser.download.show_plugins_in_list",False)
self.driver = webdriver.Firefox(self.profile)
time.sleep(5)
def get_page_and_print(self, page):
self.driver.get(page)
time.sleep(5)
self.driver.execute_script("window.print();")
if __name__ == "__main__":
browser_that_prints = printing_browser()
browser_that_prints.get_page_and_print('http://www.cnn.com/')
The key command you were probably missing was "self.driver.execute_script("window.print();")" but one needs some of that setup in init to make it run smooth so I thought I'd give a fuller example. I think the trick alone is in a comment above so some credit should go there too.
for i in driver.find_elements_by_class_name("endorse-count"):
try:
i.click()
except:
continue
elem = WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.CLASS_NAME, "dialog-window")))
src = elem.get_attribute("innerHTML")
add_skill(name, src)
WebDriverWait(driver, timeout=10)
I'm getting the following error while running the above code -
selenium.common.exceptions.StaleElementReferenceException: Message: u'Element is no longer attached to the DOM' ; Stacktrace:
at fxdriver.cache.getElementAt (resource://fxdriver/modules/web_element_cache.js:7646)
for line -
src = elem.get_attribute("innerHTML")
I'm running this code on LinkedIn user profile page, after logging in.
I tried putting the following line of code after "i.click()" -
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
But then I see that function "add_skill(name, src)" is not called and none of the code after driver.manage() is called, though for loop and further i.click() work fine.
Selenium is trying to complete actions (such as clicking a button or link) before verifying that the target element has rendered on the page. Selenium can be more patient, but you have to explicitly ask him to be.
For example, if you are testing something that makes an AJAX request, you can try something like this (in Ruby):
# timeout is in seconds
def wait_for_ajax(timeout=x)
time_limit, interval = (Time.now + timeout), 0.5
loop do
break if #driver.execute_script "return jQuery.active == 0"
sleep interval
raise "Wait for AJAX timed out after waiting for #{timeout} seconds" if Time.now > time_limit
end
end
To ensure your tests are fully comprehensive, always make Selenium waits for elements to load before running a task.
I had faced a similar issue and tried refreshing the page before finding that element, and it worked...
driver.navigate().refresh();
Though I couldnt reason out how this worked.
If this works for you as well, please let me know. I just want to learn more about this exception.
you can refer this page to learn about a similar issue
I had a similar problem when trying to execute some javascript (IJavaScripExecutor). I created an IWebElement and passed that to the JSE and that failed for me. When I moved the driver.FindElement(BySelector) into my JSE call, then it worked. (C# code ahead.)
Instead of:
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
IWebElement tableEl = driver.FindElement(selector);
js.ExecuteScript(script, tableEl);
I had to do:
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript(script, driver.FindElement(selector));
You may have to do something similar: move your selector or element creation onto the same line as what you are trying to do. Or, maybe, in your case:
src = driver.find_element_by_class_name("dialog-window").get_attribute("innerHTML")
Upon closer inspection, that's what looks to be your problem, there's a stale web element object when you try to use the get_attribute method.
Below is my script which check is element present. When I give this selector:
css=input[name='flightSearchParam[3].originAirport']
in Selenium Ide it find me this element, but when I run this in selenium rc it can't find it. I think that it is a problem with brackets.
What I must to change to find this element by selenium rc?
I run it at Windows XP and Polish Culture
Script is ready to run.
# -*- coding: utf-8 -*-
from selenium import selenium
import unittest, time, re
class Untitled(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
self.selenium = selenium("localhost", 5555, "*chrome", "http://www.aa.com/")
self.selenium.start()
def test_untitled(self):
sel = self.selenium
sel.open("/international/internationalSplashAccess.do?countryCodeForIP=PL")
sel.click("localeSubmit")
sel.wait_for_page_to_load("30000")
for i in range(60):
try:
if sel.is_element_present("aa-hp-multi-city-link2"): break
except: pass
time.sleep(1)
else: self.fail("time out")
sel.click("aa-hp-multi-city-link2")
sel.click("flightSearchForm.button.reSubmit")
sel.wait_for_page_to_load("30000")
for i in range(60):
try:
if sel.is_element_present(u"css=input[name='flightSearchParam[3].originAirport']"): break
except: pass
time.sleep(1)
else: self.fail("time out")
def tearDown(self):
self.selenium.stop()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
Body for :
conn.request("POST", "/selenium-server/driver/", body, headers)
u'cmd=isElementPresent&1=css%3Dinput%5Bname%3DflightSearchParam%5B2%5D.originAirport%5D&sessionId=02b3341a3fee46f5a1e6d9c13d6e8916'
EDIT
I change it to sel.is_element_present("dom=document.getElementsByName('flightSearchParam[3].originAirport')[0]"):
and it find this element. But, I still don't know why css doesn't work here :/
if the HTML code is
<input name="flightSearchParam[3].originAirport">
Then the CSS Selector for it will be
css=input[name='flightSearchParam\[3\].originAirport']
You have to escape the bracket which has a specific meaning for CSS selectors.
I had a similar issue that may gain you some insight towards a solution for your problem:
Firefox Selenium IDE returned this target during a recording:
css=input[name="keywords"]
the correct CSS selector argument to obtain this element turned out to be (selenium 2.41):
solution = driver.find_element_by_css_selector('input[name="keywords"]')
So, in your case, this might work:
css= 'input[name="flightSearchParam[3].originAirport"]'
solution = driver.find_element_by_css_selector(css)
Note: in the Python Selenium, I've never needed to escape brackets which indicate indices...
Try escaping the brackets with backslashes.
It appears RC doesn't translate the escape sequence. I would recommend using XPath Attributes. In your case it would be -
sel.is_element_present("//input[#name='flightSearchParam[3].originAirport']")