i am trying to log in in a particular website , i fill out email and password and then i click on "login " , but actually it does not login but it redirects me to the home page, i studied the situation and noticed that some websites has a "callback" function, that you can find trought console ,in fact , when i have to register (no login, but sign up) it asks me for captcha, and trought console i found that captcha has a call back function that - if called - it simulates the " register now " button (i easly found this function trought a script that find callback linked to captcha ).
the point is : how can i find this callback function in case of login that has no captcha ? i dont know how to start, any suggestions or guide to study? thats my simply script by the way
driver.get("https://www.streetmachine.com/login")
time.sleep(1)
el=driver.find_element_by_name("email")
el.send_keys(lf[0])
el=driver.find_element_by_name("password")
el.send_keys(lf[1])
time.sleep(3)
el=driver.find_element_by_id("login-form-submit")
driver.execute_script("arguments[0].click();", el)
as you can see the website is the one called in get() , thanks !
You could try to use the "ActionChains"; find the element first and then perform the click.
For example as the following code:
def click_login_button(self, **kargs):
try:
button = WebDriverWait(self.driver, 3).until(
lambda x: x.find_element_by_id("login-form-submit")
)
except TimeoutException:
pass
if not button.is_enabled():
pass
webdriver.ActionChains(self.driver).move_to_element(button).click().perform()
Reference:
Mouse actions in detail, https://www.selenium.dev/documentation/en/support_packages/mouse_and_keyboard_actions_in_detail/
Related
I have this webpage https://account.proton.me/login?language=en where I am trying to switch to modal after logging in to the page. Please note that the modal appears even if you give wrong id and password, so to reproduce you can use the same code below
driver.get('https://account.proton.me/login?language=en')
usernameField = driver.find_element(By.XPATH,'//*[#id="username"]')
usernameField.send_keys("kuchbhirandom#some.thing")
passwordField = driver.find_element(By.XPATH,'//*[#id="password"]')
passwordField.send_keys("yehbhikuchbhi")
loginbutton = driver.find_element(By.XPATH,'//button[#type="submit"]')
loginbutton.click()
The above code gives us the modal
I ttried checking the window handles and switching to them one by one which gives me
driver.window_handles
['CDwindow-34B695696D2295F87F84F06321D10117', 'CDwindow-212C47AEC0CCD8240A4F9675D5B5BEF2', 'CDwindow-5A39DFE9B9C75CFA7316BF2098765D05', 'CDwindow-796B9EF6777039A036CCF7C3D452807A', 'CDwindow-1DF355426CF56902DC339955FF55C9AE', 'CDwindow-1B700B499C716086FA269E89B0ED3835']
for handle in driver.window_handles:
driver.switch_to.window(handle)
try:
checkbox = driver.find_element(By.XPATH,'//div[#id="checkbox"]')
print('found')
except:
pass
but I get the same error "No such element"
Talking about solving the captch : I have an external API that does it for me, but I need to click that check box here, but stuck in switching to the modal part
Note that : to reproduce issue you can use same code above, no need to create account.
Problem is that you have 2 nested iframes in the site,
You'll have to perform driver.switch_to.frame() for each of them:
# After pressing "sign-in"
captcha_iframe = driver.find_element(By.CSS_SELECTOR, '[title="Captcha"]')
driver.switch_to.frame(captcha_iframe)
inner_iframe = driver.find_element(By.CSS_SELECTOR, 'iframe')
driver.switch_to.frame(inner_iframe)
# Perform captcha check
driver.find_element(By.CSS_SELECTOR, '#checkbox').click()
Notice that after each switch_to, I directly use the new driver's context, and I do not perform a search under the element I found.
I am using Selenium to simulate login with Chrome browser. The login page has Slider button which needs to be dragged to complete the login process.
The weird thing is that if I open the web page using driver.get(page). Then sliding verification code will always fail even I manually enter the username, pwd and drag the slider.
I tried to add user-agent but no help.
Is there any other way? I understand that we can add user-data to skip this part but I just want to figure it out first.
The slider verification code will display if you try to log in more than once. It seems that the web page just detect you are using the script to log in.
The error will be like:" ops, failed to verify. Please refresh again". Then I use driver.find_element_by_xpath("//*[#id='nocaptcha']/div/span/a").click() to refresh the slider.
Thanks in advance.
driver = webdriver.Chrome()
driver.get("https://login.taobao.com/member/login.jhtml?spm=a21bo.2017.754894437.1.5af911d95pqPfs&f=top&redirectURL=https%3A%2F%2Fwww.taobao.com%2F")
action = ActionChains(driver)
login()
def login():
driver.find_element_by_class_name("login-switch").click()
driver.find_element_by_id('TPL_username_1').clear()
driver.find_element_by_id('TPL_username_1').send_keys('xxx')
driver.find_element_by_id('TPL_password_1').clear()
driver.find_element_by_id('TPL_password_1').send_keys("xxx")
time.sleep(1.5)
# driver.find_element_by_id('J_SubmitStatic').click()
Slider()
def Slider():
#Sliding verification code
while True:
try:
slip=driver.find_element_by_xpath("//*[#id='nc_1_n1z']")
action.click_and_hold(slip).perform()
action.move_by_offset(150,0)
time.sleep(0.8)
action.move_by_offset(148,0)
action.release().perform()
time.sleep(2)
text = driver.find_element_by_xpath("//*[#id='nc_1__scale_text']/span")
if text.text.startswith("请在下方"):
print("Successful")
break
if text.text.startswith("请点击"):
print("Successful")
break
if text.text.startswith("请按住"):
print("Failed. Try again")
continue
except Exception:
##Error occurs, click the "Refresh" button to refresh the sliding verification code again
driver.find_element_by_xpath("//*[#id='nocaptcha']/div/span/a").click()
driver.find_element_by_id('J_SubmitStatic').click()
i used this code to check splinter's clicking button option:
from splinter import Browser
with Browser() as browser:
# Visit URL
url = "http://www.google.com"
browser.visit(url)
browser.fill('q', 'splinter - python acceptance testing for web applications')
# Find and click the 'search' button
button = browser.find_by_name('btnG')
# Interact with elements
button.click()
if browser.is_text_present('splinter.readthedocs.org'):
print("Yes, the official website was found!")
else:
print("No, it wasn't found... We need to improve our SEO techniques")
and i got exception:
Element is not currently visible ans so may not be interacted.
waiting for the browser is not the solution (becuase i made sleep method for long time and still doesnt work).
this is sample code shown in https://splinter.readthedocs.org/en/latest/#sample-code , but is doesnt work for me
If you want to wait for an element to become invisible, you can use wait function:
wait = WebDriverWait(self.driver, 30)
wait.until(EC.invisibility_of_element_located((By.XX, "something")))
I am working on a personal project to make a python script to log in to a site and do few tasks for me, and I've decided to use the Selenium web driver. Currently I am stuck on the log in part.
driver = webdriver.Chrome()
driver.get("https://pucatrade.com")
puca_username = "example#username"
user_fieldID = "login"
user_fieldelement = driver.find_element_by_id(user_fieldID)
user_fieldelement.send_keys(puca_username)
However, it gives me selenium.common.exceptions.ElementNotVisibleException: Message: element not visible on the send_keys call. I know that find_element_by_id finds the element because I've tested with print user_fieldelement.get_attribute('id'), and it prints login. So if find_element_by_id works can find the element, how come send_keys can't?
There are multiple inputs having id="login". You are interested in the one located in the login form on the very right which is inside the div with id="home-login":
form = driver.find_element_by_id("home-login")
# login
user_fieldelement = form.find_element_by_id(user_fieldID)
user_fieldelement.send_keys(puca_username)
# password
passwd_fieldelement = form.find_element_by_id(passwd_fieldID)
user_fieldelement.send_keys(puca_password)
I'm still not sure why some websites has many fields with same name and id... but as I was only interested on the visible ones, I did this little function to get the right field.
def find_visible_element_by_name(name):
# Websites, for some reason, has many fields with the sama name and ID! This gets the first one that is visible.
# http://stackoverflow.com/questions/32462116/selenium-webdriver-element-can-be-found-but-is-not-visible
fields = self.sel.find_elements_by_name(name)
for f in fields:
if f.is_displayed():
return f
return None
self.sel is the Selenium driver object.
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.