25

I have the below html code.

<div align="center">
    <input type="file" name="filePath"><br>
    <input type="Submit" value="Upload File"><br>
</div>

I am trying to find the two elements "file" and "submit" using Selenium with Python. Below is the code I have tried to use.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

# create a new Firefox session
driver = webdriver.Chrome()

# Maximize the browser window
driver.maximize_window()

# Enter the url to load
driver.get("<<MY PAGE TO LOAD>>")

# Wait for the page to load
driver.implicitly_wait(5)

# find the upload file type and pass a test value
upload_field = driver.find_element_by_partial_link_text('file')
upload_field.clear()
upload_field.send_keys("test")

When I run this code, I am able to load the page successfully in the Chrome browser but I get the below exception.

# Exception when trying to get element by type
Traceback (most recent call last):
  File "C:\Users\TEST\Desktop\Test.py", line 33, in <module>
    upload_field = driver.find_element_by_partial_link_text('file')
  File "C:\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 453, in find_element_by_partial_link_text
    return self.find_element(by=By.PARTIAL_LINK_TEXT, value=link_text)
  File "C:\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 955, in find_element
    'value': value})['value']
  File "C:\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 312, in execute
    self.error_handler.check_response(response)
  File "C:\Python\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 237, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"partial link text","selector":"file"}
  (Session info: chrome=63.0.3239.132)
  (Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.14393 x86_64)

I looked at the solution provided here but this too is throwing an error. I am currently using Python 3.6.4 x64 with Selenium 3.8.1. My OS is Windows 7 x64 bit. How can I get elements with 'type' in html?

Code_Sipra
  • 1,571
  • 4
  • 19
  • 38
  • Why don't you try the complete xpath(//input[@name='filePath']) , instead of partial text. – Pradeep hebbar Jan 21 '18 at 09:12
  • A bit off-topic, but instead of using `implicitly_wait` use [explicit wait](http://selenium-python.readthedocs.io/waits.html#explicit-waits). It'll be faster and more reliable. – Keyur Potdar Jan 21 '18 at 12:26

4 Answers4

32

Checkout the docs on finding elements. I find xpaths or css selectors particularly powerful because they are extremely generalizable.

xpath

upload_field = driver.find_element_by_xpath("//input[@type='file']")

css selector

upload_field = driver.find_element_by_css_selector("input[name='filePath'][type='file']")
rvictordelta
  • 630
  • 2
  • 8
  • 23
Alex
  • 18,484
  • 8
  • 60
  • 80
  • Thanks @Alex. I used the `driver.find_element_by_xpath` method for finding both elements `file` and `Submit`. It worked flawlessly. I do have one more follow up query. The `file` element expects a file to be passed. What if I wanted the user to select the file of his choice rather than hardcoding it in the code? – Code_Sipra Jan 21 '18 at 09:30
  • @Code_Sipra This should pop up a dialog where the user can select a file... You might want to ask a new question if you are having trouble with it! – Alex Jan 21 '18 at 09:34
  • Well it does not seem to be popping up the dialog box. But as you suggested, I can use 'tkinter` to make the user provide the path of the upload file separately. Thanks for the inputs and guidance. This solves all my problems with reading elements in selenium. – Code_Sipra Jan 21 '18 at 09:44
  • @Code_Sipra Glad to hear it! – Alex Jan 21 '18 at 09:45
  • sorry but I have another query. Normally, the file to be uploaded would be huge. ~50-100mb size. The system does not show any 'upload completed' message once a file is uploaded. How to I ensure that the entire file is completely uploaded before I click the submit button? Do I need to raise this as a separate question in SO? – Code_Sipra Jan 21 '18 at 10:16
  • @Code_Sipra I don't know. You probably want to post a new question as this one is about selenium... You will get better responses if you have a question tagged with `html`. – Alex Jan 21 '18 at 10:18
4

find_element_by_partial_link_text looks for the element text. In addition, it works only on <a> tags. For example, driver.find_element_by_partial_link_text('file') will match the following html

<a type="file" name="filePath">file</a>

But not your html as the element has no text.

You could locate the element by the name attribute instead

driver.find_element_by_name('filePath')
dmmfll
  • 2,666
  • 2
  • 35
  • 41
Guy
  • 46,488
  • 10
  • 44
  • 88
  • Thanks @Guy, this works for the element `file`. It does not work for the element `Submit`. – Code_Sipra Jan 21 '18 at 09:32
  • @Code_Sipra Because submit doesn't have `name` attribute. You can use `css_selector` to locate by `value`, `driver.find_element_by_css_selector('[value="Upload File"]')` – Guy Jan 21 '18 at 09:35
  • `find_element_by_partial_link_text()` works with **links only (e.g. `...`)**! Update your answer appropriately to not confuse OP – Andersson Jan 21 '18 at 10:05
1

Its not the proper way to use the partial text in selenium . Please go through the link to understand how to use partial link https://www.softwaretestingmaterial.com/how-to-locate-element-by-link-text-and-partial-link-text-locator/

Answer to your question. Use the other attribute like name to identify the locator.

Otherwise try this locator "//input[@name='filePath']"

Pradeep hebbar
  • 2,147
  • 1
  • 9
  • 14
  • thanks for the inputs @Pradeep hebbar. I used the `driver.find_element_by_partial_link_text` incorrectly in this case. Appreciate you sharing the link on how it can be used correctly. It may help me in the future. – Code_Sipra Jan 21 '18 at 09:38
0

Method driver.find_element_by_css_selector is now deprecated in selenium >=4.3.0

From https://github.com/SeleniumHQ/selenium/blob/a4995e2c096239b42c373f26498a6c9bb4f2b3e7/py/CHANGES

Selenium 4.3.0

  • Deprecated find_element_by_* and find_elements_by_* are now removed (#10712)

New method is:

driver.find_element('xpath', '//button[text()="Some text"]')

From https://selenium-python.readthedocs.io/locating-elements.html

Reda E.
  • 653
  • 3
  • 16