1

here is my testing stack:
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"cucumber": "^1.3.3",
"protractor": "~5.1.2",
"protractor-cucumber-framework": "^3.1.0",
+ selenium-server-standalone-3.4.0.jar

When I run my scenario and an element is not found (the DOM have changed since last time I ran the tests), all steps are green, but the test ends with an exception:

[15:51:49] E/launcher - No element found using locator: by.cssContainingText("checkbox", "énergie")
[15:51:49] E/launcher - NoSuchElementError: No element found using locator: by.cssContainingText("checkbox", "énergie")

I expect the test to fail with a red result and the failing step should throw an exception message. It was the behavior when I was using Behat. Is there something bad configured with protractor or cucumber-js?

EDIT:

here is my implementation:

this.When(/^I fill "([^"]*)" step$/, function (step) {    
    element(by.cssContainingText("checkbox", "Électricité")).click();  
    element(by.cssContainingText("checkbox-multi", "Chauffage")).click();  
    element(by.buttonText("Suivant")).click();  
});
nitche
  • 121
  • 3
  • 13
  • Based on your new info. Have you searched the git of Protractor, there you will find for example [this](https://github.com/angular/protractor/issues/631). It's "default" behaviour. If this happens on specific elements then you can `catch` them. By the way, is `checkbox` a custom tag, because a checkbox itself doesn't have text so `cssContainingText` won't work – wswebcreation May 22 '17 at 15:56
  • ok, so I should write all the "try ... catch" code for all elements to see error messages in reports. That is not a good news. Thank you for making it clear. (and yes, here "checkbox" is a custom class, so it have a text related). – nitche May 23 '17 at 09:33

3 Answers3

1

If the process is exiting with a 199 return code it is protractor capturing that exception and ending the process. You'll need to tell it to ignore uncaught exceptions as show here.

EDIT:

You also need to return that last promise so cucumber knows when the step is actually finished. In your step definition that's doing nothing more than scheduling those clicks to happen and then returning.

return element(by.buttonText("Suivant")).click(); 
Darrin Holst
  • 696
  • 5
  • 7
  • 1
    When I add "ignoreUncaughtExceptions: true", the test is still green: 1 scenario (1 passed), but it has exited if the element is not found. For me, the behavior is not consistent. – nitche May 22 '17 at 14:59
0

I haven't seen your step implementation, but I think you have a "bug" in your code. What we usually see with this errors are:

  • step implementation has been done with callbacks, but the callback hasn't been returned
  • step implementation has been done with promises, but the promises are not resolved.

Here you will find an example implementation of both. Please try this an see if it helps, else paste your step implementation here to let us help you better.

// With Callbacks
this.Then(/^I expect it to become green$/, function(callback) {
  expect(element(by.css('#selector')).getText())
    .to.eventually.equal('I am green').and.notify(callback);
});

// With Promises
this.Then(/^I expect it to become green$/, function() {
  return expect(element(by.css('#selector')).getText())
    .to.eventually.equal('I am green');
});
wswebcreation
  • 2,365
  • 2
  • 10
  • 18
  • I am not asserting on this part of the scenario, I am just filling steps on my form. Do I have to explicitely write all chai assertions on all element to have a message if the element change or is missing? – nitche May 22 '17 at 15:05
  • I edited my post with my implementation. thanks for your answers. – nitche May 22 '17 at 15:14
0

this solved my problem. Now it's clear that I have to code all possible errors in the DOM. It add a lot of code, and I suspect it will slow my tests too...

nitche
  • 121
  • 3
  • 13
  • no, you don't have to explicitly handle the promise rejections and rethrow. Returning the promise will allow cucumber to handle it and fail the step. The key is returning the promise though. – Darrin Holst May 24 '17 at 12:53
  • @darrin: your way is working too. The choice now is keeping the default error messages or writing more friendly ones, and then I have to throw errors. – nitche May 30 '17 at 08:54
  • You can write your own messages in the expect statements: return expect(element.getAttribute('foo'), 'this message appears at failure').to.eventually.equal('bar') ... the original problem may be that protractor does not wait for your promises to resolve if you do not tell it to, so it will pass the step before executing all of it (clicking an element also returns a promise!) ==> function thisStep(callback) { element.click().then(function(){anotherElement.click()}).then(callback) } – Chai Jul 26 '17 at 20:38