0

I'm hoping someone might be able to point me in the right direction here. I'm trying to use selenium to automate entering details for media files after they've been uploaded to a website. I'm able to navigate to the media library and parse the list for the files in question, but I'm hung up on how to send input to the fields.

It looks like the website was built with React Material UI, and I'm having to use xpath exclusively, which is actually working pretty well. I'm able to get to the media details page, but that's where I've hit the wall.

Here's the exact html for the input field I'm trying to interact with and what the page looks like.

<div class="MuiFormControl-root MuiFormControl-marginNormal MuiFormControl-fullWidth">
    <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink" data-shrink="true" for="formatted-text-mask-input">Subtitle</label>
        <div class="MuiInputBase-root MuiInput-root MuiInput-underline MuiInputBase-formControl MuiInput-formControl" title="Subtitle">
            <input aria-invalid="false" type="text" class="MuiInputBase-input MuiInput-input" value="" data-np-intersection-state="visible">
        </div>
        <p class="MuiFormHelperText-root"></p>
    </div>
</div>

enter image description here

I've tried to get the input field by xpath and css selector using:

driver.find_element(By.XPATH('//*[@id="app"]/div/div/div[2]/div/div/div[4]/div/div[2]/div[1]/div[3]/div/div/input'))

But this gets the text property not the element and throws a TypeError. I read values can't be set directly with selenium because it's meant to simulate user input.

Can this need to be done with webdriver.execute_script("set_attribute(arguments?)")? If so, how do I pass my text using execute_script?

Or is there some other browser automation that would work with React/Material UI websites?

Thanks!

dbarnes
  • 439
  • 1
  • 3
  • 11

2 Answers2

0

I think your problem is that By.XPATH is not a function, and when you are trying to pass arguments to it, you get TypeError

Correct syntax is

driver.find_element(By.XPATH, 'yourXpath)`

Yaroslavm
  • 1,762
  • 2
  • 7
  • 15
  • 1
    It turns out I'm just dumb and should've copy/pasted from one of my other find_element() lines. Was a syntax problem and is working perfectly now. Now I'm onto a whole lot of string parsing to make the rest of it work...fun – dbarnes Aug 12 '23 at 01:39
0

You are seeing a TypeError as the line of code is not understandable by the Python interpreter.


Solution

Using Selenium clients to invoke find_element() you need to use a Tuple as follows:

driver.find_element(By.XPATH, "//*[@id="app"]/div/div/div[2]/div/div/div[4]/div/div[2]/div[1]/div[3]/div/div/input")

However, the desired element is a Material UI react element, so to click on the clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.MuiInputBase-root.MuiInput-root.MuiInput-underline.MuiInputBase-formControl.MuiInput-formControl[title='Subtitle'] > input.MuiInputBase-input.MuiInput-input"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='MuiInputBase-root MuiInput-root MuiInput-underline MuiInputBase-formControl MuiInput-formControl' and @title='Subtitle']/input[@class='MuiInputBase-input MuiInput-input']"))).click()
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352