2

I am trying to fill this form with selenium in python: https://ing.ingdirect.es/app-login/

Using this code:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

browser = webdriver.Firefox(executable_path = '/usr/local/bin/geckodriver')
browser.get('https://ing.ingdirect.es/pfm/#login')

WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#aceptar'))).click()

browser.find_element_by_css_selector('#ing-uic-native-input_0').send_keys('xx')

But I get this error:

NoSuchElementException: Message: Unable to locate element: #ing-uic-native-input_0

inspection screenshot

I have tried unsuccessfully to find frames and other ways to find the element: xpath, id, etc.

Any suggestions?

vitaliis
  • 4,082
  • 5
  • 18
  • 40
Antonio
  • 21
  • 6

3 Answers3

3

I guess, here's your solution Does anybody know how to identify shadow dom web elements using selenium webdriver?

you're trying to get element with shadow DOM webelements.

or try to use install pyshadow library:

pip install pyshadow

and use like that:

from pyshadow.main import Shadow
from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://ing.ingdirect.es/pfm/#login')
shadow = Shadow(browser)

shadow.set_explicit_wait(20, 5)
shadow.find_element("#aceptar").click()
element = shadow.find_element("#ing-uic-native-input_0")
element.send_keys('xx')

don't like using all of the wrappers, but seems like shadow elements require some wrapper work and guys from google already did it.

second, to skip the step with clicking on accept cookies, there's quite good way to store cookies of that step and replace them each time:

run that first time:

import pickle
cookies = browser.get_cookies()
with open("cookies.pkl", "wb") as f:
    pickle.dump(browser.get_cookies(), f)

then remove and run that each next time:

cookies = pickle.load(open("cookies.pkl", "rb"))
for cookie in cookies:
    browser.add_cookie(cookie)
Vova
  • 3,117
  • 2
  • 15
  • 23
  • 1
    This is perfect. I was not aware of the shadow DOM web elements. Also, the cookies trick is nice. Thanks a lot!! – Antonio Apr 11 '21 at 11:07
  • 1
    @Antonio more over, you can skipp login step with cookies feature as well and move to the page like already logged in user – Vova Apr 11 '21 at 12:12
  • 1
    thanks @Vova ! I still need to learn how to do it. That's next step :) ! – Antonio Apr 11 '21 at 12:13
0

First, accept cookies once in the beginning of all tests steps.

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

wait = WebDriverWait(driver, 30)
wait.until(EC.element_to_be_clickable(
            (By.CSS_SELECTOR, "#aceptar")))
accept_cookies = driver.find_element_by_css_selector("#aceptar")
accept_cookies.click()

Second, after accepting cookies a user is redirected to https://ing.ingdirect.es/app-login/ There is no #ing-uic-native-input_0 CSS element. As an example, if you are looking for Número de documento use:

driver.find_element_by_id("input")

Also, before making an input use visibility_of_element_located instead of presence_of_element_located. It should be more reliable.

vitaliis
  • 4,082
  • 5
  • 18
  • 40
0
wait=WebDriverWait(browser, 20)
browser.get('https://ing.ingdirect.es/app-login/')
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#aceptar'))).click()
root1 = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'body > ing-app-login-sca-es')))
root1 = driver.execute_script('return arguments[0].shadowRoot', root1)
root2 = root1.find_element_by_css_selector('div > div.wrapper-login > ing-orange-login-sca-es')
root2 = driver.execute_script('return arguments[0].shadowRoot', root2)
root3 = root2.find_element_by_css_selector('#loginSteps > ing-uic-login-sca-es-step-credentials')
root3 = driver.execute_script('return arguments[0].shadowRoot', root3)
root4 = root3.find_element_by_css_selector('#credentialsForm > form > div:nth-child(2) > div > ing-uic-login-sca-es-el-input')
root4 = driver.execute_script('return arguments[0].shadowRoot', root4)
root4.find_element_by_css_selector('#ing-uic-native-input_0').send_keys('xx')

Here's what it would look manually. It looks pretty bad getting the shadow root manually for 4 elements. Also your login url is pretty hard to login.

Arundeep Chohan
  • 9,779
  • 5
  • 15
  • 32