Shivam Sahil
Shivam Sahil

Reputation: 4921

How to locate tag-button (Angular Component) in Selenium?

Here is the HTML of the button I am trying to locate, it appears to me as an angular component:

<tab-button class="tab-button _ngcontent-jne-2 _nghost-jne-3" focusitem="" role="tab" aria-selected="false" tabindex="-1" aria-disabled="false" aria-label="Offline Reporting">
    <!---->
    <div class="content displayed-value _ngcontent-jne-3">Offline Reporting</div>
    <!---->
    <material-ripple class="_ngcontent-jne-3">
        <div class="__acx-ripple" style="top: -103px; left: -45px; transform: translate(17px, -1px) scale(0.88156);"></div>
        <div class="__acx-ripple" style="top: -101px; left: -62px; transform: translate(34px, -3px) scale(0.88156);"></div>
    </material-ripple>
</tab-button>

Note that I want to locate tab-button which has aria-label = Offline Reporting. Here's what all I have tried:

element = driver.find_element_by_xpath("//tab-button[@aria-label='Offline Reporting']")

element = driver.find_element_by_tag("tab-button")

element = driver.find_element_by_tag_name("tab-button")

element = driver.find_element_by_css_selector("tab-button")

None of the above actually worked. Can you point out the right way to do the same? I have to locate the tab-button (Out of many) which has aria-label as Offline Reporting

Quick Edit

Note that I am using Selenium Web Driver for the same purpose and the page I am trying to load is an Angular page. From my understanding, the content is dynamically rendered here and so even though I can see it in element inspector, It's not getting located with find_element function.

Here is the snapshot of the same: enter image description here

Note that I have tried everything that's mentioned in the current answers... that is waiting for the page to load completely and even if it loads completely I tried a delay of 50s as shown below:

WebDriverWait(driver, 50).until(EC.visibility_of_element_located((By.XPATH, "//tab-button[contains(@class, 'tab-button') and @aria-label='Offline Reporting']")))

But this ended up in timeout as well. The point I am trying to raise through these lines is that this is a dynamically rendered page and so to handle it there's some other middleware mechanicsm needed like scrapy-selenium

Upvotes: 1

Views: 305

Answers (2)

undetected Selenium
undetected Selenium

Reputation: 193088

To locate the element with text as Offline Reporting you can use either of the following Locator Strategies:

  • Using css_selector:

    element = driver.find_element_by_css_selector("tab-button.tab-button[aria-label='Offline Reporting']")
    
  • Using xpath:

    element = driver.find_element_by_xpath("//tab-button[contains(@class, 'tab-button') and @aria-label='Offline Reporting']")
    

As the element is an Angular element, ideally to locate 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:

    element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "tab-button.tab-button[aria-label='Offline Reporting']")))
    
  • Using XPATH:

    element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//tab-button[contains(@class, 'tab-button') and @aria-label='Offline Reporting']")))
    
  • 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
    

Upvotes: 0

DonnyFlaw
DonnyFlaw

Reputation: 690

Try to wait for button to be become visible and clickable:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//tab-button[@aria-label='Offline Reporting']")))
button.click()

Upvotes: 1

Related Questions