title: Protractor proper way to use browser.wait to control flow of tests
body: <p>I have written a few functions for browser.wait. My problem is when I run my tests, they inconsistently pass due to protractor running too fast. To combat this, I was using browser.sleep. This works, but is not efficient. If I am on a slow connection for example, these browser.sleep statements can become unreliable. So I have started to use browser.wait. Here is an example of a wait function that I use.</p>
  
  <pre><code>EC = Expected Conditions;
  myForm = element(by.id('myForm');
  button1 = element(by.id('btn1');
  waitForBtn = this.EC.elementToBeClickable(button1)
  formIsVisible = this.EC.visibilityOf(myForm)
  
  //Test
  it(should click the button and bring up the form), () =&gt; {
      browser.wait(page.waitForBtn, 3000);
      page.button1.click()
      browser.wait(page.formIsVisible, 3000);
      expect(page.getMyForm().isDisplayed).toBeTruthy(); 
  </code></pre>
  
  <p>This test would work in isoluation, but when combinded with other tests, sometimes a test will fail and return an error<code>"element" is not clickable at point...</code>. Even with these wait functions, I will receive this error. It always seems to be for when an element is being clicked. </p>
  
  <p>My question is this: <strong>When running multiple tests, what is the best way for protractor to wait so that protractor does not execute the test too fast and miss the element?</strong>  Thank you.
  EDIT:
  Here is the solution.</p>
  
  <p>Helper function for clicking elements.</p>
  
  <pre><code> async function sendClick(el: ElementFinder): Promise&lt;void&gt; {
      try {
  
        let result = await forCondition(function() { return el.isDisplayed() });
        if(!result || !await el.isEnabled()) {
          throw new Error('element disabled');
        }
  
        await browser.executeScript('arguments[0].click();', el.getWebElement());
      } catch(error) {
        console.warn('element:', el.locator().toString(), 'is not clickable', error.message);
      }
    }
  
  export async function forCondition(condition: () =&gt; any | PromiseLike&lt;boolean&gt;, timeout = 20000): Promise&lt;boolean&gt; {
  try {
    return await browser.wait(condition, timeout);
  } catch (err) {
    console.log('Condition: false');
    return false;
  }
  </code></pre>
  
  <p>} </p>