6

I'm trying to find an element using Selenium and I'm not getting it. Follow the HTML code:

<div aria-disabled="false"
     data-tb-test-id="DownloadCrosstab-Button"
     role="button"
     tabindex="0"
     style="font-size: 12px; font-weight: normal; color: rgba(0, 0, 0, 0.7); display: inline-block; padding: 0px 24px; position: relative; text-align: center; border-style: solid; border-width: 1px; border-radius: 1px; height: 24px; line-height: 22px; min-width: 90px; box-sizing: border-box; outline: none; white-space: nowrap; user-select: none; cursor: default; background-color: rgba(0, 0, 0, 0); border-color: rgb(203, 203, 203); margin-top: 8px; width: 100%; -webkit-tap-highlight-color: transparent;"
>Tabela de referência cruzada</div>

I've tried the following codes:

x = browser.find_element_by_id("Downloadcrosstab")
x = browser.find_element_by_link_text("Downloadcrosstab-Button")
x = browser.find_element_by_class_name('Crosstab')

But I got the same error:

NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":".Crosstab"}
  (Session info: chrome=75.0.3770.142)
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Rafael Schettini
  • 65
  • 1
  • 1
  • 7
  • 1
    the attribute `data-tb-test-id` is not the same `id` so you can't get it by id – painor Jul 18 '19 at 19:27
  • Above and beyond there being no `id` (much less one with a value of `Downloadcrosstab`), there is no `class="Crosstab"`, so I don't know why `by_class_name` would be expected to work. Similarly, there's no link here at all, so searching by link text doesn't make sense either. – Charles Duffy Jul 18 '19 at 19:28
  • This element does not have any ID, any link text, or any classes. Furthermore, the text you're looking for doesn't match anything in the element. – Michael Kolber Jul 18 '19 at 19:28

3 Answers3

12

The element appears to be a dynamic element and to identify the element you need to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:

  • Using CSS_SELECTOR:

    x = WebDriverWait(browser, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div[data-tb-test-id='DownloadCrosstab-Button'][role='button']"))).click()
    
  • Using XPATH:

    x = WebDriverWait(browser, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@data-tb-test-id='DownloadCrosstab-Button' and text()='Tabela de referência cruzada']")))
    
  • 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
    

Note: You can find a relevant discussion in Selenium “selenium.common.exceptions.NoSuchElementException” when using Chrome

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
5

I actually like to add a custom html attribut for my test locators.

You can then use xpath to locate them, like //*[@data-tb-test-id="DownloadCrosstab-Button"]

Arnaud Claudel
  • 3,000
  • 19
  • 25
  • for specific instances in this case I think xpath is definitely the right way to go . Not to mention there is a google chrome extension called 'xpath helper' to make these a lot quicker! https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl?hl=en – Taku_ Jul 18 '19 at 19:36
  • 1
    @Taku_ Not necessary for specific instances, I've seen some projects where it was the way to do it. They defined a naming strategy between the dev / test team so they can easily write their test. They were even doing TDD with this – Arnaud Claudel Jul 19 '19 at 08:40
1

Use a CSS selector, specifically attribute selector like so:

https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

x = browser.find_element_by_css_selector('[data-tb-test-id="DownloadCrosstab-Button"]')

This should select an item whose data-tb-test-id is set to DownloadCrosstab-Button. If this element is not unique it will give you the first occurrence of it, so you need a more specific selector in that case

abdusco
  • 9,700
  • 2
  • 27
  • 44