4

I m building an angular 2 application and I need some informations concerning unit tests with protractor.

In fact, with angular 1, we were able to make some stuff like :

element(by.css('[ng-click="myFunction()"]'))

in our tests to validate the fact that we have an ng-click attribute on the current page.

I've tried the following with angular 2 :

element(by.css('[(click)="alert(\'test\')"]'))

But it doesn't seems to work.

Any body knows how can I test the fact that I have a clic event with angular 2 and protractor ?

EDIT : Here's the HTML I m using in my HomeComponent.html file :

<button (click)="alert('test')">Hello</button>

Thanks for your help

mfrachet
  • 8,772
  • 17
  • 55
  • 110

2 Answers2

1

You can locate all elements having (click) attribute and check the .count():

expect($$("[\(click\)]").count()).toBeGreaterThan(0);

where $$ is a shortcut to element.all(by.css()). [\(click\)] CSS selector would match all elements having (click) attribute. Note that you have to escape parenthesis since they have a special meaning in CSS selectors.


Another option would be to use .filter():

var elements = $$("*").filter(function (elm) {
    return elm.getAttribute("(click)").then(function (attributeValue) {
        return !!attributeValue;
    });
});
expect(elements.count()).toBeGreaterThan(0);

Or, use an XPath to match all elements having a (click) attribute:

var elements = element.all(by.xpath('//*[@*[name() = "(click)"]]'))
expect(elements.count()).toBeGreaterThan(0);

Another weird option would be to use the fresh by.js() locator:

var elements = element.all(by.js(function() {
    function getAllElementsWithAttribute(attribute)
    {
      var matchingElements = [];
      var allElements = document.getElementsByTagName('*');
      for (var i = 0, n = allElements.length; i < n; i++)
      {
        if (allElements[i].getAttribute(attribute) !== null)
        {
          // Element exists with attribute. Add to array.
          matchingElements.push(allElements[i]);
        }
      }
      return matchingElements;
    }
    return getAllElementsWithAttribute("(click)");
}));
expect(elements.count()).toBeGreaterThan(0);

getAllElementsWithAttribute() taken from here.

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
1

Escape the parenthesis with a double backslash:

element(by.css('[\\(click\\)="alert(\'test\')"]')).click();
Florent B.
  • 41,537
  • 7
  • 86
  • 101
  • If I try expect(item.isPresent()).toBe(true); with your solution, I get a false. It seems to not be working :-/. Thanks for your help – mfrachet Jun 16 '16 at 05:54
  • I tested it with Chrome and Firefox with this example and the element is present. It could be another issue. Can you provide the exact HTML of the targeted element? Do you get a result in the console of the browser? – Florent B. Jun 16 '16 at 06:02
  • Nothing in the console, but the following test result : 1) Home page Button add board should have a validation button Message: Expected false to be true. – mfrachet Jun 16 '16 at 06:36
  • It could be a timing issue. Try the button in a static page and you'll see that the locator returns an element. – Florent B. Jun 16 '16 at 06:58