0

I have to click on an element that has several of the same, the way to differentiate is by the "onclick" attribute but I can't click on it. How would xpath be?

<button onclick="VxManager.getWidget('DirectQuoteLineItemList_inner').filterApply('4', 'DirectQuoteLineItemList_inner_COL_4');" id="Button" type="button" title="OK" class="VButton  default-true">OK</button>

I think that is something like this:

WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="Button"][@title="OK"][@onclick="VxManager.getWidget('DirectQuoteLineItemList_inner').filterApply('4', 'DirectQuoteLineItemList_inner_COL_4');"]))).click()

But this doesn't work and in the page has others titles, ids and classes.

Thank you in advance.

JeffC
  • 22,180
  • 5
  • 32
  • 55
LUCAS XX
  • 65
  • 4
  • Have you tried getting the XPath from your browser's developer tools? – MattDMo Aug 21 '22 at 14:42
  • @MattDMo That is generally a really bad idea unless you are trying to learn XPath. The XPaths made using the tool are usually long and brittle and don't guarantee that they are unique on the page. – JeffC Aug 21 '22 at 14:44
  • Are you sure that the ID isn't unique on the page? By HTML standards it's supposed to be... but isn't always, sadly... – JeffC Aug 21 '22 at 14:44
  • @JeffC you can see yourself the id here is `Button`. Not seems to be unique value... – Prophet Aug 21 '22 at 14:46
  • @Prophet I see that the posted HTML has an ID of "Button"... but since we don't have the HTML of the page I was wondering if OP had verified that the ID is NOT unique on the page. If it is, this whole discussion is moot. – JeffC Aug 21 '22 at 14:49

2 Answers2

2

We can't give you a 100% correct answer before seeing the page you are working on, but I can guess it could be something like this:

WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'//button[@id="Button"][@title="OK"][contains(@onclick,"DirectQuoteLineItemList_inner")]'))).click() 

I guess the DirectQuoteLineItemList_inner part there should be fixed value.
Or maybe this, as suggested by @JeffC:

WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'//button[@id="Button"][@title="OK"][contains(@onclick,"DirectQuoteLineItemList_inner_COL_4")]'))).click() 
Matt Popovich
  • 236
  • 1
  • 2
  • 14
Prophet
  • 32,350
  • 22
  • 54
  • 79
  • 2
    If you know it's a BUTTON use `//BUTTON` instead of `//*`... it should be faster to find. – JeffC Aug 21 '22 at 14:46
  • 1
    I'm going to guess that there are a lot of similar OK buttons on the page and that "DirectQuoteLineItemList_inner_COL_4" is the most important/unique bit in there. – JeffC Aug 21 '22 at 14:47
  • Thank you so much for your answer! Maybe there is something with the quotes? – LUCAS XX Aug 21 '22 at 22:08
1

As you mentioned, the only way to differentiate is by the onclick attribute you can use it exclusively.

However as the desired element is a dynamic element, so to click on the 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, "button.VButton.default-true#Button[onclick*='VxManager'][onclick*='DirectQuoteLineItemList_inner']"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@onclick, 'VxManager') and contains(@onclick, 'DirectQuoteLineItemList_inner')][@class='VButton  default-true' and @id='Button']"))).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