0

I need to click a button for a drop-down menu.

This is drop-down button for toggle. If I click on the button, it will drop-down and show an option. If the button is clicked again, the display will change back to original.

...

<div f-menu-item-submenu="$parent.createMenu" ng-if="!$root.ADMIN_RO &amp;&amp; menu.menuBar" class="ng-scope ng-isolate-scope menu-item menu-item-submenu">
    <button type="button" ng-class="{'selected': selected}" ng-disabled="disabled()" ng-click="onClick($event)">
        <div class="flex-button-content" ng-transclude="">
            <f-icon class="ftnt-add ng-scope"></f-icon><span class="ng-binding ng-scope">
                Create New
            </span><span class="flex-filler"></span><f-icon class="fa-caret-down toggle-indicator">
            </f-icon>
        </div>
    </button>
</div>

First I try to find the element by using xpath:

elem = driver.find_element_by_xpath("/html/body/section/nav/ul/li[4]/div/ul/li[2]/div/ul/li[1]/a/span")

The Python says:

"Unable to locate element".

Then I try to find the element by using CSS slector:

elem = driver.find_element_by_css_selector(".left-menu-items > div.ng-scope.ng-isolate-scope.menu-item.menu-item-submenu > button > div > span.ng-binding.ng-scope")

The selenium still says:

"Unable to locate element"
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Locus
  • 13
  • 3

3 Answers3

1

Seems you were pretty close with the css_selector.

The desired element is an Angular element so to locate and click() on the element you have 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.ng-scope.ng-isolate-scope.menu-item.menu-item-submenu > button > div.flex-button-content span.ng-binding.ng-scope"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='ng-scope ng-isolate-scope menu-item menu-item-submenu']/button/div[@class='flex-button-content']//span[@class='ng-binding ng-scope' and contains(., 'Create New')]"))).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
0

You can use XPath selector which will rely on this Create New text via normalize-space() function like:

//span[normalize-space()='Create New']

Demo:

enter image description here

More information: XPath Operators & Functions

Dmitri T
  • 159,985
  • 5
  • 83
  • 133
0

The correct XPATH is:

//div[@class='ng-scope ng-isolate-scope menu-item menu-item-submenu']/button

You'll need just that to click the button.