Search code examples
pythonseleniumselenium-webdriverselenium-chromedriversendkeys

Send_keys() doesn´t send the full string


I´m trying to login to a website with selenium and Chrome in Python. I´m able to locate the user and password field, and the button. The only thing I´m not capable of is filling the password field with all the string. It writes a substring, with varying lengths.

My code

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

browser=webdriver.Chrome(r"C:\Users\Visente\Desktop\Pablito Python\chromedriver.exe")

urlbet='https://www.bet365.es/?&cb=103265469#/HO/'

browser.get(urlbet)

sport=WebDriverWait(browser, 10).until(
        EC.presence_of_element_located((By.XPATH,'//*[@id="dv1"]/a')))

sport.click()

user=WebDriverWait(browser,
10).until(EC.presence_of_element_located((
By.XPATH,'/html/body/div[1]/div/div[1]/div/div[1]/div[2]/div/div[1]/input')))      

passw=browser.find_element_by_xpath(
'/html/body/div[1]/div/div[1]/div/div[1]/div[2]/div/div[2]/input[1]')     


user.send_keys('my_user')
passw.send_keys('password')  

submit=browser.find_element_by_xpath(
'/html/body/div[1]/div/div[1]/div/div[1]/div[2]/div/div[2]/button')`  

submit.click()

So, in short, the line where y use send_keys() on variable passw is not writing the full length of the password and I don´t know why. By the way, how do I get back the text I just sent with sed_keys() in order to know what is being passed and what is missing from the string?


Solution

  • You're not supposed to type the password in the field you've selected. As you've noted in the comments, the xpath switches from input[1] to input[2]. The latter is where you're supposed to put the password. I don't understand the mechanism by which the xpath changes when you try to send keys there, but it does. Depending on how quickly it changes, anything from 0 to a few characters will be sent to the wrong input, which explains why the password field ends up with a substring of your password.

    From the html, we can see there are 3 input fields, all belonging to the class 'hm-Login_InputField'.

    <div class="hm-Login ">
        <div class="hm-Login_UserNameWrapper ">
            <input type="text" class="hm-Login_InputField ">
            <div class="hm-Login_InputText " style="">
                Registrarse
            </div>
        </div>
        <div class="hm-Login_PasswordWrapper ">
            <input type="text" class="hm-Login_InputField Hidden ">
            <input type="password" class="hm-Login_InputField ">
            <button tabindex="0" class="hm-Login_LoginBtn ">
                IR
            </button>
            <div class="hm-Login_InputText ">
                Recordar contraseña
            </div>
        </div>
    </div>
    

    If you collect them all, from top to bottom, they are the username, the field you tried to put the password in and the password field.

    Now, if you try to send the keys directly to the password field, input[2], you will get an error that the element is not visible. You have to first click on input[1] in order to make input[2] visible.

    You can easily do it with xpaths, but I find the following approach cleaner.

    login = WebDriverWait(browser, 10).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'hm-Login')))
    
    fields = login.find_elements_by_css_selector('.hm-Login_InputField')
    button = login.find_element_by_css_selector('.hm-Login_LoginBtn')
    
    fields[0].send_keys('user_name')
    fields[1].click()
    fields[2].send_keys('password')
    button.click()