I'm using webdriver to click on a submit button on a form in an iframe. Basically:
self.driver.find_element_by_css_selector("[name~='field_1']").clear()
self.driver.find_element_by_css_selector("[name~='field_1']").send_keys("123")
self.driver.find_element_by_css_selector("[name~='field_1']").send_keys(Keys.RETURN)
self.driver.switch_to_window(self.driver.window_handles[-1])
self.assertEqual(self.driver.current_url, "http://fake_address.com")
I've also tried:
self.driver.find_element_by_css_selector("[name~='field_1']").clear()
self.driver.find_element_by_css_selector("[name~='field_1']").send_keys("123")
self.driver.find_element_by_css_selector("#submit-endslide").click()
self.driver.switch_to_window(self.driver.window_handles[-1])
self.assertEqual(self.driver.current_url, "http://fake_address.com")
and:
self.driver.find_element_by_css_selector("[name~='field_1']").clear()
self.driver.find_element_by_css_selector("[name~='field_1']").send_keys("123")
self.driver.find_element_by_css_selector("#submit-endslide").submit()
self.driver.switch_to_window(self.driver.window_handles[-1])
self.assertEqual(self.driver.current_url, "http://fake_address.com")
I've been getting:
Traceback (most recent call last):
File "test_ytplayer_smoke_form.py", line 198, in testSmallFormSubmission
self.driver.find_element_by_css_selector("[name~='field_1']").send_keys(Keys.RETURN)
File "/home/giant/our_player/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 293, in send_keys
self._execute(Command.SEND_KEYS_TO_ELEMENT, {'value': typing})
File "/home/giant/our_player/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 370, in _execute
return self._parent.execute(command, params)
File "/home/giant/our_player/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 166, in execute
self.error_handler.check_response(response)
File "/home/giant/our_player/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 164, in check_response
raise exception_class(message, screen, stacktrace)
TimeoutException: Message: u'Selenium took too long to run your command.
Then
WebDriverException: Message: u'Due to a previous error, this job has already finished.
Regardless of which method I choose, I will always get a timeout when clicking the submit button;
(I've already tried increasing the timeout to 300)
Note:When I watch the test run, the submit button is being clicked and a new tab will open, but the test will never pass due to the exceptions.
There seemed to be a browser specific issue Chrome V28 that was causing this issue; I updated to the latest browser version Chrome V35 and this seemed to be resolved
As my comment says, we need more info, but comments are ugly to edit, so I add more info here:
Instead of wait based on time, try WebDriverWait see here for start.
Store element in variable when found, like:
field_1 = self.driver.find_element_by_css_selector("[name~='field_1']")
field_1.clear()
field_1.send_keys("123")
submit = self.driver.find_element_by_css_selector("#submit-endslide")
submit.click()
But try to use WebElementDrive and ExpectedConditions instead of driver methods directly.
Related
This is my current code, but whenever I run it I get an error on the last line
stale element reference: element is not attached to the page document
from selenium import webdriver
url = "https://otctransparency.finra.org/otctransparency/OtcDownload"
driver.get(url)
driver.maximize_window()
driver.implicitly_wait(5)
agree = driver.find_elements_by_xpath("//button[#class='btn btn-warning']")[0]
agree.click()
nonats = driver.find_element_by_link_text('OTC (Non-ATS) Download')
nonats.click()
driver.find_element_by_xpath("//img[#src='./assets/icon_download.png']").click()
driver.switch_to.window(driver.window_handles[0])
driver.find_element_by_xpath("(//div[#class='checkbox-inline'])[2]").click()
driver.find_element_by_xpath("(//div[#class='checkbox-inline'])[1]").click()
driver.implicitly_wait(5)
button = driver.find_element_by_xpath("//img[#src='./assets/icon_download.png']")
print(button.is_displayed())
button.click()
When I run my code in debugging mode line by line, everything works fine without any errors. Any help would be great.
Edit: This is my stack trace
Traceback (most recent call last):
File "C:\Users\derpe\Desktop\python projects personal\testing finra\untitled1.py", line 31, in <module>
button.click()
File "C:\Users\derpe\anaconda3\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
self._execute(Command.CLICK_ELEMENT)
File "C:\Users\derpe\anaconda3\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
return self._parent.execute(command, params)
File "C:\Users\derpe\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\derpe\anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
StaleElementReferenceException: stale element reference: element is not attached to the page document
(Session info: chrome=86.0.4240.75)
The checkbox clicks are triggering a page refresh while you're searching for the download link.
Call sleep to allow the refresh to finish.
driver.implicitly_wait(5)
import time # add this
time.sleep(1) # add this
button = driver.find_element_by_xpath("//img[#src='./assets/icon_download.png']")
print(button.is_displayed())
button.click()
I tried other selenium waits, but they did not work for me. Probably because the element search succeeds before the refresh starts but still clicks to late.
This question is very similar to Selenium webdriver can't find elements at chrome://downloads
I'm trying to use Selenium with Python (3) to get at the cancel button on the chrome://downloads page. My use case is that I have an obfuscated link for which a random token is generated every time a user clicks on it. If you don't click on it, you can't start the download (it seems to fire a piece of js that generates the token, but I haven't been successful in digging through the code to figure out how that happens).
For my test to pass, all I need is to verify that:
The download starts (and doesn't give a 404), and
The file it's trying to download is the right size.
The way that I'm trying to accomplish this is by triggering the download by clicking on the button element, then having Selenium open chrome://downloads, cancel the download, and capture the file size of the file that it attempted to download.
In theory this seems like it should work, the stumbling block is trying to access any elements in the #shadow-root tags on the chrome://downloads page. The solution to the other question which I linked above unfortunately no longer works:
driver = webdriver.Chrome("chromedriver.exe")
driver.get("chrome://downloads/")
manager = driver.find_element_by_css_selector('body/deep/downloads-manager')
item = manager.find_element_by_css_selector('body/deep/downloads-item')
shadow = driver.execute_script('return arguments[0].shadowRoot;', item)
link = shadow.find_element_by_css_selector('div#title-area>a')
file_url = link.get_attribute("href")
... as it fails on the item declaration line:
>>> item = manager.find_element_by_css_selector('body/deep/downloads-item')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 430, in find_element_by_css_selector
return self.find_element(by=By.CSS_SELECTOR, value=css_selector)
File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 659, in find_element
{"using": by, "value": value})['value']
File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
return self._parent.execute(command, params)
File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/usr/local/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"body/deep/downloads-item"}
(Session info: chrome=80.0.3987.149)
This is out of my area of expertise, and any help in figuring out how to get at the cancel button would be greatly appreciated.
Please try the below.
driver.execute_script("document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector("cr-button[focus-type='cancel']").click()")
If you need more information how to work on the shadow-root elements, please refer here. And if you want to work on the downloads then you can refer to this and update the js as per your requirement.
I'm having a lot of troubles to find a clean and reliable way to wait in my Python Selenium tests. I've been using Implicit wait for a long time and for some reason it started being unstable so I switched to explicit wait. For some reason, I can't figure out a way for my tests to work 100% of the time. Right now, even though the code being tested and the test itself does not change, problems are happening again and again. (I'd say it works 50% of the time). When problems are happening, it's usually and the same lines. Here are some of them :
for th in td_list:
if(th.text == "18"):
th.click()
break
time.sleep(3)
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.ID, "closeModalDisplayBill"))
)
Here the "closeModalDisplayBill" is a button that has to be pushed. The problem it raises is the following :
Traceback (most recent call last):
File "./scripts/test-sl/SeleniumTest.py", line 54, in test_selenium_launcher
frontAdminErr = SlFrontAdminErr(driver, self.add)
File "/Users/JNEB/WebstormProjects/backend/backend/scripts/test-sl/SlFrontAdminErr.py", line 45, in __init__
driver.find_element_by_id("closeModalAddComp").click()
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webelement.py", line 78, in click
self._execute(Command.CLICK_ELEMENT)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webelement.py", line 499, in _execute
return self._parent.execute(command, params)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 297, in execute
self.error_handler.check_response(response)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
raise exception_class(message, screen, stacktrace)
ElementNotInteractableException: Message:
Another place where problems are recurrent is when Selenium try to open a modal to edit some stuff (clicking or clearing inputs is pretty unstable). Here is the code :
time.sleep(5)
driver.implicitly_wait(15)
driver.find_element_by_id("btnLogin").click()
time.sleep(1)
driver.find_element_by_id("login-email").clear()
And here is the log when the bug happen (trying to clear the login-email input field) :
Traceback (most recent call last):
File "./scripts/test-sl/SeleniumTest.py", line 39, in test_selenium_launcher
frontUserTest = SlFrontUser(self, driver, self.add)
File "/Users/JNEB/WebstormProjects/backend/backend/scripts/test-sl/SlFrontUser.py", line 21, in __init__
driver.find_element_by_id("login-email").clear()
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webelement.py", line 93, in clear
self._execute(Command.CLEAR_ELEMENT)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webelement.py", line 499, in _execute
return self._parent.execute(command, params)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 297, in execute
self.error_handler.check_response(response)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
raise exception_class(message, screen, stacktrace)
InvalidElementStateException: Message: Element is not currently interactable and may not be manipulated
The same test can be successful four or five times in a row and then bug the same amount of time. (Everything here is tested from my own computer). When those tests are done through Jenkins it gets worse. Some of the time the full suite of test can be done in 10 or 8 minutes, but some of the time thoses tests will be done/failing after 30 minutes. I figure that the slow factor on Jenkins can be one of the reason my tests are unstable, but that doesn't explain why those bug appear regularly on my own computer.
All those tests are launched from another Python Script that initiate the firefox driver instance and then launch all the tests like such :
class SeleniumTestLauncher(unittest.TestCase):
environmnent = "envName"
add = ""
quickbooks_url = "https://developer.intuit.com/"
port = ""
driver = webdriver.Firefox()
base_url = ""
def setUpAdd(self):
self.driver.implicitly_wait(30)
self.verificationErrors = []
self.accept_next_alert = True
def test_selenium_launcher(self):
driver = self.driver
### -- Here just call every selenium test -- ###
## -- Test Front User -- ##
frontUserTest = SlFrontUser(self, driver, self.add)
SECOND EDIT :
As suggested I removed all the implicitly_wait() for explicit_wait. Seems a bit more stable but I still encounters bugs. For instance :
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.ID, "closeModalDisplayBill"))
)
driver.find_element_by_id("closeModalDisplayBill").click()
Even though the driver should wait for 'closeModalDisplayBill' to be clickable to actually attempt to click, I get this error :
Traceback (most recent call last):
File "./scripts/test-sl/SeleniumTest.py", line 53, in test_selenium_launcher
frontUserTest = SlFrontUser(self, driver, self.add)
File "/Users/JNEB/WebstormProjects/backend/backend/scripts/test-sl/SlFrontUser.py", line 37, in __init__
driver.find_element_by_id("closeModalDisplayBill").click()
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webelement.py", line 78, in click
self._execute(Command.CLICK_ELEMENT)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webelement.py", line 499, in _execute
return self._parent.execute(command, params)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 297, in execute
self.error_handler.check_response(response)
File "/Library/Python/2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
raise exception_class(message, screen, stacktrace)
ElementNotInteractableException: Message:
EDIT 3 :
Using only explicit wait is as unstable as before. Most of the errors I run into are those : "InvalidElementStateException: Message: Element is not currently interactable and may not be manipulated". I don't understand why Selenium tries to click on the "input field" even though I use an explicit_wait. For instance :
time.sleep(3)
element = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.ID, "login-email"))
)
driver.find_element_by_id("login-email").clear()
Here I ask selenium to wait for 'login-email' to be present, and if it is, to click on it. The wait returns before the 20 seconds timeout but the .clear() function throw a "InvalidElementStateException: Message: Element is not currently interactable and may not be manipulated".
closeModalDialog suggests that your application is based on some Ajax framework.
Automating Ajax applications using Selenium can sometimes be a big challenge. An element seems to be visible and clickable at time X when Webriver is trying to locate the element, but there are still some pending javascript code which modifies the DOM and will change this element at time X+10 miliseconds when the test is trying to click on the element, and Webdriver in this case usually throws one of: ElementNotVisibleException, InvalidElementStateException, StaleElementReferenceException, ElementNotInteractableException.
The test is working fine on a local (fast) machine, but fails on much slower virtual machines, or when the application is under heavy load and it's response times increase.
First of all discuss this issue with your developers.
Our appliaction is based on JSF + Primefaces framework and we had many issues like above while trying to automate our product. We have discussed the issues with our developers, and they put simple Status component in the header on each page, which indicates whether there are ongoing (active) ajax request or not. Secondly, since Primefaces is using jQuery (many ajax framoworks are using jQuery), we are also checking if jQuery status is ready (for details see this answer
We have created a simple waitForPrimefacesAndJQuery function that waits unitil Primefaces status and jQuery status are ready, and have been using this function everywhere alongsize with standard WebDriverWait.
This has solved 99,9% of issues.
There are still some components which don't want to cooperate though.
For them we usually use a brute-force method - simply cath the exception and try again a few times, for example in this way:
for(int i=0; i <= 5; i++ ){
try{
findElement( element ).click();
break;
} catch( ElementNotVisibleException | InvalidElementStateException
| StaleElementReferenceException | ElementNotInteractableException )
{
// swallow the exception, wait some time and try again
sleep( 500 );
}
}
I am trying to track down an error in Python Selenium. The error message is..
Traceback (most recent call last):
File "C:\myscipt\main.py", line 110, in <module>
source_mysource(func1, func2, func3, func4, func5, func6, func7, func8, func9)
File "C:\myscipt\sources\functions.py", line 132, in source_mysource
current_url = driver.current_url
File "C:\Users\tom\AppData\Local\Programs\Python\Python35\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 454, in current_url
return self.execute(Command.GET_CURRENT_URL)['value']
File "C:\Users\tom\AppData\Local\Programs\Python\Python35\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 201, in execute
self.error_handler.check_response(response)
File "C:\Users\tom\AppData\Local\Programs\Python\Python35\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 193, in check_response
raise exception_class(message, screen, stacktrace, value['alert'].get('text'))
selenium.common.exceptions.UnexpectedAlertPresentException: Alert Text: To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier.
<super: <class 'WebDriverException'>, <UnexpectedAlertPresentException object>>
Is the error saying that the line current_url = driver.current_url is the one that is triggering the error or is it the next line?
When you use .current_url property of a WebDriver instance, a GET_CURRENT_URL webdriver command is sent, which is triggering an error in your case. What happens is, the currently opened web-page is not the current top-level browsing context because of the alert being present, and, according to the specification, it should and fails with an error.
In other words, current URL cannot be retrieved when there is an opened active alert.
I have a form to be completed and a button to be pressed on a page which would take me to another URL(post form completion) and that page has another button upon clicking which the results filled in the form will be downloaded in a well arranged pdf format. I am currently having difficulty in navigating to the second URL upon clicking the first URL's button, that is, when I try to select any second window's component, I get the following error.
Traceback (most recent call last):
self.driver.find_element_by_css_selector('.buttons.button-save').click()
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 376, in find_element_by_css_selector
return self.find_element(by=By.CSS_SELECTOR, value=css_selector)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 664, in find_element
{'using': by, 'value': value})['value']
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 175, in execute
self.error_handler.check_response(response)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 166, in check_response
raise exception_class(message, screen, stacktrace)
NoSuchElementException: Message: Unable to locate element: {"method":"css selector","selector":".buttons.button-save"}
I also tried using explicit wait before I try to click on the second page's button, but it didn't work.
Any help would be appreciated, thanks !
Edit :
When I took a screenshot after clicking the button on the first page and saved the image, I could only see a screenshot of the first URL. Also, I added an explicit wait to locate the presence of an element in the second URL and I got the following traceback
Traceback (most recent call last):
EC.presence_of_element_located((By.ID, "button-save")))
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/support/wait.py", line 75, in until
raise TimeoutException(message, screen, stacktrace)
Relevant Code,
#Clicking the save button
self.driver.find_element_by_css_selector('.submit.submit.submit').click()
#Waiting to click on the button in second URL
element = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.ID, "button-save")))
#Saving the screenshot to check in which window it is
self.driver.save_screenshot('file2.png')
#Click the button on the second page
self.driver.find_element_by_css_selector('.buttons.button-save').click()