Sunday, January 22, 2017

Protractor wait method with error checking

if you ever worked on ui automation or ui tests of automated e2e tests for web application you may experience same problems,ive trying solving here. Solution specific to Chrome browser.

So you need to cover or automate following scenario:

  1. go to app's page and do authorization
  2. search item1 through searh bar. wait for search results
  3. add item to basket, wait for redirect to backet page
  4. create order, wait for success order creation message
  5. done!
Navigation to page and authorization can be done in beforeAll.
Notice each step logically depends on previous and will fail if previous step is failed.
So technically first spec is search, in this step you fill search input and click search button - than you waiting for search results.
You waiting for search results mean you waiting for particular dom element to apear or become visible.
if some of service call is failing and ux experience become broken, you either wait dom element until timing out spec either check failing of call as well as waiting.
Protractor not support check error during wait out of box. You can use standart wait and hit timeout.
if spec dependency done right you following steps will fail straight from start.
But forbidden step will take your time to fail. If you set 3 minutes timeout which i was using for example and you have 10 suites =  you might 30 no needed minutes on fail for some global issues.
You can approach differently here  like override specific timeouts and reduce global timeout and so on.
Anyway you want to fail quickly as possible from moment issue appear to not waste any time or machine or yours to verify functionality, thus my raw approach will just proxy method.

here spec with regular wait will fail with timing out:

 it("1. Searches for ms logo on ms home page", function() {
        browser.get("https://www.microsoft.com/en-us/");
        browser.wait(() => element(by.id("nonExistLogoID")).isPresent())
            .then((callback) => {
                element(by.id("srv_shellHeaderMicrosoftLogo")).getInnerHtml().then((val) =>
                    expect(val).not.toBeNull("shouldn be empty"));
            });
    });

here spec with our custom proxy method:

  it('2. Searches for non exist ms logo on ms home page', function() {
        browser.get('https://www.microsoft.com/en-us/');
        Utils.CheckWait(() => element(by.id('nonExistLogoID')).isPresent())
            .then((callback) => {
                element(by.id('srv_shellHeaderMicrosoftLogo')).getInnerHtml().then((val) =>
                    expect(val).not.toBeNull('shouldn be empty'));
            });
    });


custom wait method:



 export function CheckWait(condition: (dr) => webdriver.promise.Promise,
        timeout?: number, opt_message?: string): webdriver.promise.Promise {
        var gl = global["logs"];
        var errorCheckFunc = (dr) => { gl.verify(); return condition(dr); };
        return browser.wait(errorCheckFunc, timeout, opt_message);
    }

verify method  implementation were taken from there : https://github.com/wix/protractor-browser-logs

my example in typescript can be find here: https://github.com/kostia911/blog_examples

example in progress and will refactored