34

I have a button on a page that looks like:

<button ng-click="myFunction()" ng-show="flag">
    Submit
</button>

The element has no ID.

Is there a way to find this element using the function bound to Ng-Click? Or do I have to assign an ID to this element to locate it using Jasmine / Protractor?

Lloyd Banks
  • 35,740
  • 58
  • 156
  • 248

4 Answers4

71

Just tested this and it works:

element(by.css('[ng-click="myFunction()"]'))
Ted Warner
  • 711
  • 1
  • 4
  • 3
  • 3
    confirm this. escape quotes (\") might be necessary. – mojjj Oct 20 '14 at 14:44
  • 5
    IMHO, I think Lloyd Banks anwser is better. __E2E tests are meant to test UI__. They should rely on __things visible to user__, like button label "Submit", not the logic hidden in HTML attributes. – matewka Feb 09 '15 at 15:45
  • 19
    @matewka I would disagree, making it rely on text in the UI will be very fragile... And weather the user sees Submit, SUBMIT should not matter, and a simple uppercase can then break all your tests in a single go... Not to mention localisation... Ofc. on the flipside we need to ensure ng-click="submit()" isn't bound to our Cancel button... – Jens Mar 11 '15 at 10:02
  • I find the click then test that it has the text I expect to be displayed to the user. That way I fewer fragile UI-text based tests and get the back-end wiring validated. – Jacob Brewer Jun 22 '15 at 20:54
  • If the function has parameters in the code, does my protractor test need to include those as well? – Erik Jul 23 '15 at 00:05
  • The nice thing about this solution is that it works for elements that are not defined as an HTML – Ken Palmer Dec 01 '15 at 13:56
  • Hi, i have just tried it, but my test is passed and the click action isn't done ! Here my question : http://stackoverflow.com/questions/37225676/click-into-an-icon-isnt-working-on-protractor – Emna Ayadi May 14 '16 at 13:34
  • who supports only one language? Never trust on UI text – canbax Mar 08 '18 at 05:30
33

I went through the Protractor API and didn't find anything related to finding an element through ng-click. I did find

element(by.buttonText("Submit"));

Not quite the same, but does the job in my environment.

Lloyd Banks
  • 35,740
  • 58
  • 156
  • 248
  • 2
    Although this works, it's worth noting that this [isn't recommended by the protractor style guide](http://www.protractortest.org/#/style-guide#http://www.protractortest.org/#/style-guide#prefer-by-id-and-by-css-when-no-protractor-locators-are-available). I think I would assign an ID to it so that it can be found easily. – Tom Spencer Sep 03 '16 at 19:21
  • It won't work if your button is a `div` or any non-button-type button. – Ethan Chen Jul 26 '17 at 18:31
  • @YuxuanChen Who said anything about a `
    ` or any other non `
    – Lloyd Banks Jul 26 '17 at 19:17
  • Exactly what I needed. I had a list of dynamic buttons being generated from a DB and my case required clicking a button by specific text as the text in question was not unique. i.e. [Admin] button vs [Administrator]. Finding a button by 'Admin' was troublesome. thank you – jgritten Dec 22 '17 at 17:06
1

If you want to use ng-show, you could try this:

element(by.Css("button[ng-show]")); // Get element with tag < button > and has ng-show attribute

or:

element(by.Css("button[ng-show*=flag]")); // Get element with tag < button > and has ng-show attribute which contains word flag
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
Nguyen Vu Hoang
  • 1,570
  • 14
  • 19
0

Rather than adding an ID, which I don't like to do just to provide a test hook, I would add type="submit" to the button and then you can search By.css('[type="submit"]')

redOctober13
  • 3,662
  • 6
  • 34
  • 61