Q:

Async nature of Angular Protractor tests with waits

I have the following typescript class I use for protractor tests.  An OpenAM server is running for the auth.
import { element, by, ElementFinder, browser, ExpectedConditions} from 'protractor';
import { BasePage } from './base.pageobject';
import { SelectSitePage } from './select-site.pageobject';

export class AuthPage extends BasePage {
    readonly url: string = '/';

    readonly loginMenu: ElementFinder = element(by.css('nav.profile-menu'));
    readonly loginLink: ElementFinder = element(by.cssContainingText('a', 'Login'));
    readonly logoutLink: ElementFinder = element(by.cssContainingText('a', 'Logout'));

    // On OpenAM login page
    readonly userNameField: ElementFinder = element(by.id('idToken1'));
    readonly passwordField: ElementFinder = element(by.id('idToken2'));
    readonly loginButton: ElementFinder = element(by.id('loginButton_0'));
    readonly aintExist: ElementFinder = element(by.id('loginButton_666'));

    private selectSitePage: SelectSitePage = new SelectSitePage();

    /**
     * Log in if are not already
     */
    public logIn() {
        this.loginMenu.click();
        this.loginLink.isPresent().then((isPresent: boolean) => {
            if (isPresent) {
                this.loginLink.click();

                this.disableWaitingForAngular();
                var EC = ExpectedConditions;
                let loginButtonExpected = EC.presenceOf(this.loginButton);
                console.log('wait for login button ...');
                browser.driver.wait(loginButtonExpected, 2000);
                console.log('login button present');
                this.userNameField.clear();
                this.userNameField.sendKeys('user');
                this.passwordField.clear();
                this.passwordField.sendKeys('pw');
                this.loginButton.click();

                let searchBoxExpected = EC.presenceOf(this.selectSitePage.searchBox);
                console.log('wait for searchBox ...');
                browser.driver.wait(searchBoxExpected, 2000);
                console.log('searchBox present');

                this.enableWaitingForAngular();
            } else {
                console.log('AuthPage / logIn - already logged in');
            }
        });
    }

This runs fine, however the console.logs come out almost immediately as if the wait()s have no effect on them.  However the test fails if removed so it seems they are relevant.
Is it that the waits are only for WebDriver objects?  The doco doesn't make this clear.

A:

Almost all commands in Protractor are async. This means that they first needs to be resolved. This also counts for the wait, see the docs.
So in your case the commands are all executed after each other, but because the console.log() is sync it will log a result sooner than the promis of the previous line has been resolved.
Maybe this article can help you with promises if you are having troubles with them.
If you want the console.log() to take place after the previous line you can do something like this
var EC = ExpectedConditions;
let loginButtonExpected = EC.presenceOf(this.loginButton);
console.log('wait for login button ...');
browser.driver.wait(loginButtonExpected, 2000)
    .then(() => {
       console.log('login button present');
    });

By the way. You are using TypeScript. That means that you can also use the methods async / await, that will make your code more "sync" and the await will "hold" executing the next line before the previous line has been resolved. See also an example project on protractor github
Hope it helps

