问题
Im trying to automate a task we do almost daily. I read that python in combination with selenium would be perfect to approach this task. Any advice is welcome :)
See my code below.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
usernameStr = 'USERNAME'
passwordStr = 'PASSWORD'
browser = webdriver.Chrome()
browser.get('https://www.partner.co.il/he-il/login/login/?TYPE=100663297&REALMOID=06-f94d9340-8677-4c32-9f36-efd036fe99f0&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=vmwebcms9&TARGET=-SM-HTTPS%3a%2f%2fwww%2epartner%2eco%2eil%2fcopa%2fpages%2fprotected%2fprotectedredirect%2easpx%3foriginal%3dhttps%3a%2f%2fwww%2epartner%2eco%2eil%2faccount_actions')
# fill in username
username = browser.find_element_by_xpath('//*[@id="USER"]')
username.send_keys(usernameStr)
# fil the password
password = browser.find_element_by_xpath('//*[@id="PASSWORD"]')
password.click()
password.send_keys(passwordStr)
# press the login button
signInButton = browser.find_element_by_id('LoginBtn')
signInButton.click()
# go to the abroad page
browser.get(('https://biz.partner.co.il/he-il/biz/international/going-abroad'))
But it returns this
=========== RESTART: C:\Program Files (x86)\Python36-32\login2.py ===========
Traceback (most recent call last):
File "C:\Program Files (x86)\Python36-32\login2.py", line 22, in <module>
password.send_keys(passwordStr)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\remote\webelement.py", line 479, in send_keys
'value': keys_to_typing(value)})
File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\remote\webelement.py", line 628, in _execute
return self._parent.execute(command, params)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 312, in execute
self.error_handler.check_response(response)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 237, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=66.0.3359.139)
(Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.14393 x86_64)
回答1:
Your locators are fine. However, when you click or change focus to the password element, there is a StaleElementReference
Exception.
Add this import statement
from selenium.common.exceptions import StaleElementReferenceException
And add this to your code
try:
ActionChains(browser).send_keys(Keys.TAB).send_keys(passwordStr).perform()
password.send_keys(passwordStr)
except StaleElementReferenceException:
pass
With a valid username and password the code would login fine.
回答2:
This error message...
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=66.0.3359.139)
(Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.14393 x86_64)
...implies that while invoking send_keys()
for the password field the element turned stale.
There are multiple facts to be addressed as follows :
Password field
The password
field contains the onfocus
attribute contains the function managePasswordTxt()
. So once you click on the password
field the managePasswordTxt()
JavaScript is called and you have to induce WebDriverWait for the field to be clickable and you can use the following solution :
Code Block :
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC options = Options() options.add_argument("start-maximized") options.add_argument("disable-infobars") options.add_argument("--disable-extensions") driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\WebDrivers\ChromeDriver\chromedriver_win32\chromedriver.exe') driver.get('https://www.partner.co.il/he-il/login/login/?TYPE=100663297&REALMOID=06-f94d9340-8677-4c32-9f36-efd036fe99f0&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=vmwebcms9&TARGET=-SM-HTTPS%3a%2f%2fwww%2epartner%2eco%2eil%2fcopa%2fpages%2fprotected%2fprotectedredirect%2easpx%3foriginal%3dhttps%3a%2f%2fwww%2epartner%2eco%2eil%2faccount_actions') username = driver.find_element_by_xpath("//input[@id='USER']").send_keys("Alex") driver.find_element_by_xpath("//input[@id='PASSWORD']").click() WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='PASSWORD']"))).send_keys("Pruteanu")
Snapshot of Browser Client :
Version Compatibility
An additional issue is the version compatibility between the binaries you are using as follows :
- You are using chromedriver=2.35
- Release Notes of chromedriver=2.35 clearly mentions the following :
Supports Chrome v62-64
- You are using chrome=66.0
- Release Notes of ChromeDriver v2.38 clearly mentions the following :
Supports Chrome v65-67
- Your Selenium Client version is unknown to us.
So there is a clear mismatch between ChromeDriver v2.35 and the Chrome Browser version v66.0
Solution
- Upgrade Selenium to current levels Version 3.11.0.
- Upgrade ChromeDriver to current ChromeDriver v2.38 level.
- Keep Chrome version at Chrome v66.x levels. (as per ChromeDriver v2.38 release notes)
- Clean your Project Workspace through your IDE and Rebuild your project with required dependencies only.
- Use CCleaner tool to wipe off all the OS chores before and after the execution of your test Suite.
- If your base Web Client version is too old, then uninstall it through Revo Uninstaller and install a recent GA and released version of Web Client.
- Take a System Reboot.
- Execute your
@Test
.
回答3:
Modify your code to fill password as follows
# fil the password
password = browser.find_element_by_xpath('//*[@id="PASSWORD"]')
password.click()
password = browser.find_element_by_xpath('//*[@id="PASSWORD"]')
password.send_keys(passwordStr)
StaleElement exception is thrown when you are trying to perform operation on a webElement which is no more available on the page probably because the page has been refreshed and hence your code is holding on to an object which is no more valid. You need to do a lookup again after performing click for the password field and then try to send_keys on it. It might be possible that xpath would have changed after clicking, update your xpath after click if that's the scenario.
回答4:
Switching to FireFox driviver solved the issue for using the same code I have posted here
来源:https://stackoverflow.com/questions/50317447/message-stale-element-reference-element-is-not-attached-to-the-page-document