0

What I want to do is to click on specific button/span/input written in Angular using Selenium in python. The propery of search is activated when span containing value of test search... is clicked. After typing the search phrase the combobox will show a list of related results.

Problem explanation with picture:

1. test search

2. selection 3. Select the first result and click it.

For this purpose I have implemented the following piece of code:

buy_container = driver.find_elements_by_xpath("//div[@class='instrument-search-box ng-isolate-scope']/button[@ng-click='titleClicked()']")
buy_container.click()
buy_container.send_keys('Mostafa')

AttributeError: 'list' object has no attribute 'click'

I have searched the whole source code for finding whether there is a class with the same type function of ng-click='titleClicked()' but I didn't find any!

Source Code

<div
  class="instrument-search-box ng-isolate-scope"
  focus-me="page.doSearch"
  show-btns="true"
  show-search="page.myList != 2"
  show-add-to-watch="page.myList == 1"
  select="getThisInstrument(instrument)"
  empty="emptyFirstInstrument()"
  add="marketWatch.addToWatch(instrument)"
  parent="theScope"
>
  <!-- ngIf: showWatchListCombo && $root.setting.closeRightBar && $root.changeLayout!==1 --><!-- ngIf: showWatchListCombo && $root.setting.closeRightBar && $root.changeLayout!==1 -->
  <div
    class="search-part searchable"
    ng-class="{'select-watch-list': showWatchListCombo &amp;&amp; $root.setting.closeRightBar &amp;&amp; $root.changeLayout!==1}"
  >
    <i
      class="question"
      ng-click="$root.showHelpModal('searchInstrument', $event)"
    ></i
    ><i class="Font Ico-search" ng-click="titleClicked()"></i>
    <div
      class="typeahead ng-isolate-scope ng-valid ng-hide ng-not-empty"
      ng-show="ins.doSearch"
      focus-me="focusMe"
      instrument-combo=""
      ng-model="ins.instrumentName"
      select="getInstrument(item)"
      empty="emptyInstrument()"
    >
      <input
        ng-disabled="ngDisabled"
        ng-model="ngModel"
        ng-change="query()"
        type="search"
        autocomplete="off"
        style="width: 100%;"
        placeholder="جستجوی نماد"
        class="ng-pristine ng-untouched ng-valid ng-not-empty"
        ng-show="ins.doSearch"
        focus-me="focusMe"
        instrument-combo=""
      /><!-- ngIf: isLoading -->
      <div class="combo" style="display: none;">
        <table class="table">
          <thead>
            <tr>
              <th>عنوان</th>
              <th>شرکت</th>
              <th>بازار</th>
            </tr>
          </thead>
          <tbody>
            <!-- ngRepeat: instrument in items -->
          </tbody>
        </table>
      </div>
    </div>
    <span
      ng-click="titleClicked()"
      ng-show="$root.selectedInstrument &amp;&amp; $root.selectedInstrument.Isin &amp;&amp; !ins.doSearch"
      title="با کلیک روی این قسمت امکان جستجوی نماد برای شما فراهم میگردد"
      class="ng-binding"
    >
      test search... </span
    ><!-- ngIf: (!$root.selectedInstrument || !$root.selectedInstrument.Isin) && !ins.doSearch -->
  </div>
  <div class="action">
    <!-- ngIf: showAddToWatch && ins.instrument && ins.instrument.Isin && $root.firstInstrument && ins.instrument.Isin == $root.firstInstrument.Isin --><!-- ngIf: showEmpty --><!-- ngIf: showBtns --><button
      class="btn-buy ng-scope"
      ng-if="showBtns"
      ng-click="$root.showOrderEntryModal('buy', 'SearchBar')"
    >
      خرید</button
    ><!-- end ngIf: showBtns --><!-- ngIf: showBtns --><button
      class="btn-Sell ng-scope"
      ng-if="showBtns"
      ng-click="$root.showOrderEntryModal('sell', 'SearchBar')"
    >
      فروش</button
    ><!-- end ngIf: showBtns -->
  </div>
  <!-- ngIf: !ins.doSearch && $root.selectedInstrument && $root.selectedInstrument.Isin && checkTime() --><!-- ngIf: !ins.doSearch && $root.selectedInstrument && $root.selectedInstrument.Isin && !checkTime() --><span
    title="قیمت پایانی"
    class="field ng-binding ng-scope green"
    ng-if="!ins.doSearch &amp;&amp; $root.selectedInstrument &amp;&amp; $root.selectedInstrument.Isin &amp;&amp; !checkTime()"
    ng-class="{green: $root.selectedInstrument.FinalPrice > 0, red: $root.selectedInstrument.FinalPrice < 0}"
    ><i class="question" ng-click="$root.showHelpModal('order', $event)"></i
    >
</div>

PS: I have also tried the following but faced with another error:

buy_container = WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH,"//div[@class='instrument-search-box ng-isolate-scope']/button[@ng-click='titleClicked()']")))
buy_container.click()
43 buy_container = WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH,"//div[@class='instrument-search-box ng-isolate-scope']/button[@ng-click='titleClicked()']")))
     44 buy_container.click()
     45 # buy_container.send_keys('Mostafa')

/home/mostafa/.local/lib/python3.6/site-packages/selenium/webdriver/support/wait.py in until(self, method, message)
     78             if time.time() > end_time:
     79                 break
---> 80         raise TimeoutException(message, screen, stacktrace)
     81 
     82     def until_not(self, method, message=''):
TimeoutException: Message:  

It doesn't have unique identifier or attribute like name, how can I solve this problem?

1 Answer 1

2

find_elements_by_xpath returns a list, use find_element_by_xpath. Since angular is updating the DOM I wouls suggest something like below with a "wait" strategy.

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

driver = webdriver.Chrome("PATH_TO_CHROMEDRIVER")

buy_container = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//span[contains(., 'test search...')]")))
#(By.XPATH,"//i[@ng-click='titleClicked()']")
buy_container.click()
Sign up to request clarification or add additional context in comments.

6 Comments

I have faced to the following Error: TimeoutException: Message:
@Mostafa Ghadimi The timeout means we need to change the xpath, since I do not have access to the page you are looking at this might take a few ties. See the updated xpath.
Can I have a connection to send the login information for you?
Mostafa Ghadimi, not sure how to do that on here maybe just connect on Linkedin: linkedin.com/in/ortegajohn
Edited the answer again to add another xpath option to try.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.