简体   繁体   中英

Selenium finds element but can't send text to it

I'm trying to send text to google flights departure city input box. I am able to find it but when I try and send it text with send_keys I get the error element not visible . How is it possible that selenium is able to find the input box but when I send it keys it is not available. I did not have this error until I switched from firefox to chrome as my webdriver. My code is below

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

class Bot:

    def __init__(self):
        # self.browser = webdriver.Firefox(executable_path='./geckodriver')
        self.browser = webdriver.Chrome('./chromedriver')
        self.departure_city = "COU"
        self.destination_city = "HND"
        self.departure_day = "December 1"
        self.return_day = "December 10"
        self.prices = []
        self.Run()

    def Run(self):
        try:
            self.SetFlight()
            self.SetDates()
            self.FindPrices()
            self.SendText()
            time.sleep(10)
            self.browser.quit()


        except Exception as ex:
            print(ex)
            self.browser.quit()

    def SetFlight(self):
        self.browser.get('https://www.google.com/flights/');
        departure_take_off_boxes = self.browser.execute_script(
            "return document.querySelectorAll('.EIGTDNC-Kb-f.EIGTDNC-Kb-b')")
        print(departure_take_off_boxes[0].get_attribute('outerHTML'))
        print(departure_take_off_boxes[1].get_attribute('outerHTML'))
        self.browser.implicitly_wait(20)
        departure_take_off_boxes[0].send_keys(self.departure_city)
        departure_take_off_boxes[0].send_keys(Keys.RETURN)
        time.sleep(1)
        # departure_take_off_boxes[1].send_keys(self.destination_city)
        # departure_take_off_boxes

Analysis:

Selenium can find element from page, only means the element has html code in the page source, not equal the element is visible on page. like the difference between isPresent() and isDisplay().

For selenium how to determine an element is visible, I knwo some rules as below:
1. element size not be zero
2. element 'display' css value not be 'none'

I feel very strange why you can run pass with firefox driver but on chrome driver, i guess even the webdirver specification on W3C had defined that, maybe firefox and chrome implement that with difference in their webdriver.

Back to the reason why that input box not visible, I look into the html code round that input box, I noticed there is a div layer cover on top on the input box, and the input box size set to 1x1 in css style.

在此处输入图片说明

I tried hidden the covered div layer and uncheck the width and height setting in css, after that you can see it and I can input value.

I'm not sure t, Selenium used following rule to determine element is visible:

If there is something cover the element, the element will be not visible.

But from user experience, user can't see that element, and selenium API is try best to close to user experience.

Solution:

Even you make the element up to the div layer, but its size is too small, even you input some value, you sitll can't see the text you input.

And this is a UI design issue, you need to communicate with dev team.

Try the below:

element = driver.find_element_by_id("id")
actions = ActionChains(driver)
actions.move_to_element(element).perform()
element.Clear() //if needed
element.SendKeys("sendKeysHere")

For more information, see section 7.2 of the following documentation: http://selenium-python.readthedocs.io/api.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM