How to make Protractor's browser.wait() more verbose? - protractor

In Protractor tests I call many times browser.wait method for example to wait once the particular element will appear on the screen or it will be clickable.
In many cases tests passes on my local machine, but does not on other.
I receive very generic information about the timeout which doesn't help me a lot to debug / find a source of issue.
Is it possible to make a browser.wait more verbose, for example:
if at least defaultTimeoutInterval will elapse when waiting for particular element, will it be possible to console.log information about the element that it tried to wait for,
take a screenshot when the timeout error occurs,
provide full call stack when timeout appears in browser.wait

If the main issue is that you don't know for which element the wait timed out, I would suggest writing a helper function for wait and use it instead of wait, something like:
wait = function(variable, variableName,waitingTime){
console.log('Waiting for ' + variableName);
browser.wait(protractor.ExpectedConditions.elementToBeClickable(variablename),waitingTime);
console.log('Success');
}
Because protractor stops executing test after first fail, if wait timed out, console won't print success message after failing to load a certain element.
For screenshots I suggest trying out protractor-jasmine2-screenshot-reporter, it generates an easily readable html report with screenshots and debug information on failed tests (for example, in which code line the failure occured).

Look into using protractor's Expected Condition, you can specify what to wait for and how long to wait for it.
For screenshots there are npm modules out there that can take a screenshot when a test fails. This might help.

browser.wait returns a promise, so catch the error and print/throw something meaningful like:
await browser.wait(ExpectedConditions.visibilityOf(css), waitingTime).catch((error) =>
{
throw new CustomError(`Could not find ${css} ${error.message}`)
});

Related

is there a way to disable a mega-detailed error message in Rundeck's failed executions?

The message that is posted every time an execution fails is too verbose and creates too much noise. Is there a way to disable or hide it somehow? We have our own error messages within the scripts and don't need a red chunk of extra text displayed in the logs. Adding an error handler that will exit with code 0 is not an option because we still need the job to fail if a step fails.
That message is Rundeck standard output in case of failure (you can manipulate the loglevel but that doesn't affect the NonZeroResultCode last line, just the text from your commands/scripts), you can suggest that here. The rest are just workarounds as you mentioned.
This occurs even using the Quiet output.

Webflux: OnErrorResume after repeats are exhausted is not being triggered

I am trying to execute the code after repeat exhaustion using onErrorResume but onErrorResume is not being trigger.
Here is the code sample
Mono.just(request)
.filter(this::isConditionSatified)
.map(aBoolean -> performSomeOperationIfConditionIsSatified(request))
.repeatWhenEmpty(Repeat.onlyIf(i -> true)
.exponentialBackoff(Duration.ofSeconds(5)), Duration.ofSeconds(10))
.timeout(Duration.ofSeconds(30)))
.delaySubscription(Duration.ofSeconds(10)))
.onErrorResume(throwable -> {
log.warn("Max timeout reached", throwable);
return Mono.just(false);
});
onErrorResume is never trigged. I am trying to use it as a fallback. My goal is if the repeat exhaustion is hit, return the false value.
My unit test complains of
expectation "expectNext(false)" failed (expected: onNext(false); actual: onComplete())
Any help or suggestion would be helpful.
since an empty source is valid by itself, repeatWhenEmpty doesn't necessarily propagate an exception after exhausting its attempts. The Repeat util from addons doesn't, even when the "timeout" triggers (as hinted in the timeout parameter's javadoc: "timeout after which no new repeats are initiated", ok that could be clearer).
since you're using repeatWhenEMPTY, I'm guessing that the empty case is always "irrelevant" to you and thus defaultIfEmpty(false) should be the acceptable solution.

Protractor Promise Never Resolved During Debugging

I've started my Protractor debugging session with: node --inspect-brk
When I hit a break point I want to be able to manually execute some Protractor commands. However my promises are never resolved. For example if I enter this into the Chrome console:
$('body').isDisplayed().then((displayed) => {console.log('here i am'});
However all I get returned back is "Promise is Pending" and the promise is never resolved.
Any idea what I'm doing wrong?
I got round this with control flow by attaching a breakpoint to the code i want to jump to, in this case the console.log and continuing to it
you are not actually resolving the promise, and don't need the argument either. Try this:
$('body').isDisplayed()
.then(function(){
return console.log('here i am');
});

ignore.synchronization=true/ browser.waitforAngularEnabled(true) takes so long when compared to browser.sleep()

While executing e2e tests in protractor when we are using ignore.synchronization=true/ browser.waitforAngularEnabled(true) to handle waits is too slow when compared to browser.sleep(10000) to proceed to next step. How to address these kind of wait issues to make the script execution faster?
Difference:
ignore.synchronization=true/ browser.waitforAngularEnabled(true) are used to make protractor wait until all the angular modules are loaded.
browser.sleep(// time in ms) is raw way of stopping the protractor for the given particular ms.
Solution:
To handle wait issues:
use browser.waitforAngularEnabled(false) after getting your base url. Then you can use expected waits which makes the protractor wait until that expectation is completed.
Refer https://www.protractortest.org/#/api?view=ProtractorExpectedConditions for more details
Hope it helps you

protractor what does the timeout in expected conditions stand for?

Protractor: Version 1.8.0
browser.wait(EC.presenceOf(element), 3000);
what exactly does the 3 seconds stand for? and is there an error thrown when 3 seconds have passed and element cannot be found? or does the test just continue?
I ran a test with:
element(by.id('#input')).sendKeys('foo');
browser.wait(EC.presenceOf(element(by.xpath(BAD-LOCATOR)), 3000));
element(by.id('#input')).sendKeys('bar');
BAD-LOCATOR is just a xpath referencing a element that doesn't exists. but upon evaluating this line, the test waits beyond this time until it hits the jasmine defaultTimeoutInterval timeout (I set for 25sec). Why does it not fail in 3 secs since the promise did not get resolved in 3secs? I'm expecting the wait() to fail and the 2nd sendKeys command to execute since its next in control flow.
So the above block of code will print 'foo' into the textbox and on the next command wait until the jasmine timeout to error out (Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.). I'm expecting an error within 3secs. 'bar'never gets printed.
It's the time out, i mean after 3 seconds if the element isn't present until now it will time out.
For the jasmine error you are getting i suggest that you add the call back
describe("long asynchronous specs", function() {
beforeEach(function(done) {
done();
}, 1000);
You can also refer to Jasmine Asynchronous Support