0

I am working on this automation thing and I am trying to click on this button with selector

<button id="ember2570" class="ember-view btn btn-default btn btn-default" type="button">    <i class="fa fa-upload"></i>
PDMLink<!----></button>

I have tried find_element_by_id but the ID changes with every reload and the class names are also not unique to the button. if I try including wildcard like "ember*" then it clicks somewhere else. Almost all the elements of the web page has id="embersomeRandomNumber" I cannot share the url as it is an intranet site.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Hm, what about the `fa-upload` class of the child? Is it used somewhere else on that page? – h4z3 Jul 31 '19 at 09:40
  • its an icon and yes it is used somewhere else as well. There are 6 buttons and all have same class names. the difference between them is the ID and the button text. – Devbrath_R Jul 31 '19 at 09:54
  • Ugh. What about contents of that button tag? Are there any differences? Because if the 'button with ember and child i.fa-upload' is too broad, we need to dig further! Or is your desired button always n-th in the view? Then we can find all and just take n-th. – h4z3 Jul 31 '19 at 09:57
  • @Devbrath_R if you are looking for the button with the specific text you can use xpath... see the edit in my answer... – Moshe Slavin Jul 31 '19 at 10:11

3 Answers3

1

Using CSS Selector:

The Operator ^ - Match element that starts with the given value.

In your case:

driver.find_element_by_css_selector('button[id^="ember"] i.fa-upload')

Using XPath:

The keyword contains Match element that contains the given value.

driver.find_element_by_xpath("//button[contains(@id,'ember')/i[contains(@class,'fa-upload')]")

Edit:

If you are looking for the button with the text of "PDMLink":

You can use text in the XPath:

driver.find_element_by_xpath("//button[text()='PDMLink']")
Moshe Slavin
  • 5,127
  • 5
  • 23
  • 38
0

So here is how i would approach this simple "problem":

driver.find_element_by_css_selector("button[id^="ember"] i.fa-upload").click() 

If click doesnt work, then you can also import keys and do .send_keys(Keys.RETURN) I havent worked with selenium in quite a bit so give that a try and let me know.

I usually work with my own API i built last year which has functions like type(), find(), find_path(), find_id(), click() and all of them are built to avoid capcha cashe from building and avoiding most of those "im not a robot" things which crash bots. I just use time delays at random intervals. The type() actually recieves the string and types char by char on a small time delay which is always random and that is the main thing

0

As you have mentioned ...the ID changes with every reload and the class names are also not unique to the button... additionally the desired element is a Ember.js enabled element so to click() on the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use the following Locator Strategy:

  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='ember-view btn btn-default btn btn-default' and contains(., 'PDMLink')][.//i[@class='fa fa-upload']]"))).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