Behat Mink: 11 - JavaScript 01

Javascript Evaluation

The session allows you to execute or evaluate Javascript.

// Execute JS
$session->executeScript('document.body.firstChild.innerHTML = "";');

// evaluate JS expression:
echo $session->evaluateScript(
    "return 'something from browser';"
);

Note

The difference between these methods is that Session::evaluateScript returns the result of the expression. When you don’t need to get a return value, using Session::executeScript is better.

You can also wait until a given JS expression returns a truthy value or the timeout is reached:

// wait for n milliseconds or
// till JS expression becomes truthy:
$session->wait(
    5000,
    "$('.suggestions-results').children().length"
);

Note

The Session::wait method returns true when the evaluation becomes truthy. It will return false when the timeout is reached.

 

 


 

Need to look into this code for other purposes

BehatMink will NOT wait if JavaScript is causing things to happen

 

"

Here's the secret: if you click a link or submit a form and it causes a full page refresh, Mink and Selenium will wait for that page refresh. But, if you do something in JavaScript, Selenium does not wait. It clicks the "New Products" link and immediately looks for the "Name" field. If that field isn't there almost instantly, it fails. We have to make Selenium wait after clicking the link.

"

 

Waiting the Right Way

The second argument to wait() is a JavaScript expression that will run on your page every 100 milliseconds. As soon as it equates to true, Mink will stop waiting and move onto the next step. I'm using Bootstrap's modal, and when it opens, an element with the class modal becomes visible. In your browser's console, try running $('.modal:visible').length. Because the modal is open, that returns one. Now close it: it returns zero. Pass this as the second argument to wait():

 

$this->getSession()->wait(
5000,
"$('.modal:visible').length > 0"
);

 

This now says: "Wait until this JavaScript expression is true or wait a maximum of 5 seconds." Why am I allowed to use jQuery here? Because this runs on your page and you have access to any JavaScript loaded by your app.

Run it again:

Tags