Change record status: 
Project: 
Introduced in branch: 
8.1.x
Description: 

As part of 8.1.x we introduced a way to test Javascript code in a end-to-end testing way, this means, the entire Drupal site, (exactly like in WebTestBase / BrowserTestBase) is set up.

Execute tests

In order to run it, you need to install Phantomjs, and then execute the following command to start phantomjs:

phantomjs --ssl-protocol=any --ignore-ssl-errors=true ./vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768 2>&1 >> /dev/null &

The next step is to setup some environment variables. Therefore copy the core phpunit.xml.dist file to phpunit.xml and set the following two lines:

<env name="SIMPLETEST_DB" value="sqlite://localhost/sites/default/files/.ht.sqlite"></env>
<env name="SIMPLETEST_BASE_URL" value="http://drupal8.dev"></env>

Now you can execute tests using phpunit (_www is the user of the webserver, needed for permission issues)

sudo -u _www ./vendor/bin/phpunit -c core core/modules/toolbar/tests/src/FunctionalJavascript/ToolbarIntegrationTest.php

Write tests

In order to write your own tests, you add a FunctionalJavascript folder inside yourmodule/tests/src and create a FooTest.php file.
In there ensure to extend \Drupal\FunctionalJavascriptTests\JavascriptTestBase.

In there you can do ordinary HTTP requests using drupalGet, but also click on links / press buttons. The main difference is that things is executed in a real browser, so javascript behaviour is executed, so something like checking visibility is possible, see the following code examples.

$page = $this->getSession()->getPage();
$content = $page->findLink('Content');
$this->assertTrue($content->isVisible());

Ajax form interactions are also supported. The following will ran the Ajax behaviours if there are any attached:

$this->getSession()->getPage()->find('css', '#somebutton')->click();

When clicking a link/button with Ajax behaviour attached, you need to keep in mind that the underlying browser might need a while to deliver changes to the HTML. Use $this->assertSession()->assertWaitOnAjaxRequest() to wait for that.

Debug tests

If you want to see a screenshot to work out what is going on you can do this! (introduced in 8.1.9)

$this->createScreenshot('PATH/TO/screenshot.jpg');

Don't put the screenshot in a path inside the test environment like public://test.jpg as this will be cleaned up at the end of the test.

Read more about the context of these changes at #2807237: PHPUnit initiative.

Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done