sensiolabs / BehatPageObjectExtension

MIT License
116 stars 48 forks source link

Wait till element is presented #69

Closed tikolakin closed 8 years ago

tikolakin commented 8 years ago

Hi there Just wondered how we should wait elements For ex.

 public function openLoginForm() {
        $login_link = $this->findLink('Login');
        if ($login_link) {
            $login_link->click();
        }
        // The next page element will be presented after js is finished.
       // for now. it always ElementNotFoundException
        return $this->getElement('Login Popup');
    }

I used to wait ajax with the following

$this->getSession()->wait(30000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');

but page classes seem are not good places to work with session

What is a suggestion to wait elements on a page?

Thanks

tikolakin commented 8 years ago

One of ideas is using

  public function spin($lambda, $wait = 10) {
    for ($i = 0; $i < $wait; $i++) {
      try {
        if ($lambda($this)) {
          return TRUE;
        }
      }
      catch (Exception $e) {
        // Do nothing.
      }
      sleep(1);
    }
    throw new Exception("Element not found after $wait sec.");
  }

And check with this whether element has been found

public function openLoginForm() {
    $login_link = $this->findLink('Login');
    if ($login_link) {
        $login_link->click();
    }

    if ($this->spin(function() {
        return (bool) $this->getElement('Login Popup');
    })
    ) {
        return $this->getElement('Login Popup');
    }
}

But also the question how to manage waits on different pages Thanks

jakzal commented 8 years ago

Interacting with mink should be done in page objects. That's what they're for. Instead of the session, which might not be available in future mink versions (getSession() is deprecated), use the getDriver() method:

public function openLoginForm()
{
    // ...

    $this->getDriver()->wait(30000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');

    // ...
}

Obviously, there's no good wait to deal with waits and it's best to avoid them.

tikolakin commented 8 years ago

Hi @jakzal , thanks for the advice