7

I'm doing this in my page object:

try{
    I.selectOption(this.SELECT, this.OPTION);
}
catch(error){
    I.say('Option missing, but thats sometimes expected ' + error);
}

But it still fails the test when the locator doesn't match an option element.

I want to catch and continue the test, without failing.

UPDATE:

It looks like it depends on what's in the try block.

If I put an assertion there, like I.see('something'); Then the catch block is not skipped. But non-assertions in the try block, like I.selectOption('something') throw errors which are not caught by the catch.

Dingredient
  • 2,011
  • 17
  • 46
  • This sounds strange "Option missing, but thats sometimes expected". But since you catch, this should not fail? – Lorenz Meyer Aug 03 '17 at 19:20
  • @lorenz, that's just an arbitrary string for the error log. I could pass 'ABCD' in there. But I don't think that's causing my catch block to be skipped. – Dingredient Aug 03 '17 at 21:37
  • @PatMeeker were you ever able to figure out a solution or workaround? I'm hitting the same problem. Some thoughts, though: (1) Since I.* functions usually return promises, you need to put `await` before the `I.selectOption` call in order for the failure to be caught by the `catch`. (2) I have a hunch that this is because CodeceptJS uses a global promise chain. So the internal global promise fails if the I.* fails, regardless of whether it's caught. – drmercer Sep 12 '18 at 19:29
  • @drmercer unfortunately no. In my case, it was possible to pass contextual information to my method which I used to conditionally select the option, which wasnt as clean looking as my lazy approach above - to try selecting first and then react. Anyway, I suppose another approach might be to use JS Executor, and duplicate the functionality of whichever non-assertion methods you need into your own custom JS functions, if you REALLY want to make this flow work. – Dingredient Sep 12 '18 at 23:11

2 Answers2

1

Try-catch should be performed on a promise chain. I think you can get it this way:

I.selectOption(this.SELECT, this.OPTION).catch(() => I.say(''));
Davert
  • 294
  • 1
  • 5
  • 1
    I'm actually seeing the log from I.say() when I try your way, so that's an improvement. The catch block was not skipped. However, the exception was not caught. It still failed my test.... – Dingredient Aug 03 '17 at 21:41
  • As with my original code, you answer also works as expected when the error is thrown from an assertion like I.see(), but still doesn't work with I.selectOption() – Dingredient Aug 03 '17 at 22:19
0
I.selectOption(this.SELECT, this.OPTION)
.then(() => I.say('try block'))
.catch(() => I.say('catch block'));