Tutorial: Using Docker_Puppeteer_Jest to execute a headless Chrome End-to-End (user/acceptance) testing suites.

The problem:

We know that unit testing is an essential part of software engineering (at least we should all know that). Integration testing assure us that all the pieces work well together properly. At the very top of the pyramid is end-to-end (sometimes called user or acceptance) testing. This is the test set that loads the application, clicks buttons, submits data, reads data. In general, it acts like a user and assures us the applications works in the eyes of the user as it is intended to. Unfortunately in order to emulate the user experience archaic and many time s complicated system were used. These system were expensive to setup, costly to maintain, and fragile to run.

Herein I will show you in less than 6 steps how to use Chrome to emulate a user visiting a number of social media services and provide visual feedback as to what was rendered in the browser.

Pre-flight requirements:

Basic CLI / Terminal abilities


How to do it:

1) Download the image from Docker Hub via the CLI: docker pull davidjeddy/docker_puppeteer_jest

2) Clone the source repository so we can use the example test suites: git clone git@github.com:davidjeddy/docker_puppeteer_jest.git

3) Now lets change into newly created directory: `cd docker_puppeteer_jest`

4) Finally we execute the image: docker run -t -v $(pwd):/app --name dpr --rm davidjeddy/docker_puppeteer_jest. In this example we are mounting the code repository into the container at the /app directory location.

5) If all went well we should see the following in the terminal:

Congratulations, you have just executed your first user acceptance test suite using headless Chrome in a container.

To make it even easier, lets make an alias the execute the custom docker run command. Something like alias 'dta'='docker run -t -v $(pwd):/app --name dpr --rm davidjeddy/docker_puppeteer_jest'. Now type dta and press enter.

Next Steps:

To map your project into the container replace -v $(pwd):/app in the docker run command with -v {Your projects absolute path here}:/app.

Under the hood:

Docker starts a container with Chrome as the browser, Puppeteer starts a headless Chrome session. All of this isolated from the host machine as is the nature of containers. The Jest testing framework is then triggered and the test suites are auto-detected due to there directory location and naming scheme. Jest then executes the tests providing output and screen capture images to ./tests/_ouput/ which is volume mounted to the host machine.



This process can be used with a number of frontend architectures. React, Vue, jQuery, static content, DOM manipulation, and any other material rendered a client browser. The world, as it is said, is your oyster.

I hope you enjoy your acceptance testing using a headless browser and all the assurances that come with it. Hopefully you found this useful to increasie assurance that you changes get to production without negatively affecting the quality of your projects.

Yii2 2.0.14 released; bringing with it some excellent changes.

  • The Yii2 team has release the latest version of the Yii2 framework. With it comes improvements in the following (but not limited to) areas:
  • Scalability and concurrency
  • Validator enhancements
  • Behaviors
  • Databases and ActiveRecord
    • Custom data types and object conditions
    • Query Builder flexibility
    • Upserts
    • Schema builder and migrations
    • New query caching syntax
    • Active Record relations
  • Security
  • Events
  • APIs, serializers and filters

… and much more. Head over to the release notes to read about it all the changes. It is defiantly worth the update.

I dont often post about design tools, but when I do…

…I insist, as part of an everyday workflow, business and designers PLEASE use some mock / prototyping tooling. For the love of all that is web. Developers, this is also your call to arms. Use the results of the tool as effectively as possible, and feedback to the business how much it makes your life bearable.


To that end, here is a short list of tools worth a look.


RE-post: My personal experience migrating a module rom Yii1.x to Yii2.x

(Originally posted on the Sourcetoad Blog circa 20015)

Yii is an amazing framework. As it has been iterated on version 2 is now out and is quickly picking up adoption. With this comes the need to migrate components, modules, and a whole slew of other logic. This blog is a few pointers that we picked up along the way while doing a forum migration. This was the first feature migration we did in house, it was an interesting experience.

RTFM, this may seem a no brainer but read the manual, specifically about the Yii1->2 changes. http://www.yiiframework.com/doc-2.0/guide-intro-upgrade-from-v1.html
Use a source control system. GiT, SVN, Mercurial, etc.
Run the tests, make change, run tests, refactor, run tests, commit, run tests
Pick a specific part of logic / cord to replace. GridViews, DetailList, etc. Do one chunk at a time.
Give back to the community, no one like that guy that takes and takes and never gives back.

One of the most obvious changes has been the inclusion of autoloading classes. Good bye require_once(‘composer/autoloader.php’), hello namespacing. With this change the class names have become much more sane. No more ‘CBaseModel’, now \BaseModel.

The model level logic has seen a substantial change as well. “…In 1.1, query building was scattered among several classes, including CDbCommand, CDbCriteria, and CDbCommandBuilder. Yii 2.0 represents a DB query in terms of a Query object that can be turned into a SQL statement with the help of QueryBuilder behind the scene…” (Yii2 documentation). Now queries are similar this example:

$modelData = \packageName\common\models\ModelName::find()->andWhere([‘id’ => $userId])->one();

Idealy this would return the user’s data from the specified model.

Moving on the view level widgets have had a measurable change as well:

$this->widget('yii.widgets.grid.CGridView', array(
    'columns'=> array(
        'title',         // display the 'title' attribute
        'category.name', // display the 'name' attribute of the 'category' relation
        'content:html',  // display the 'content' attribute as purified HTML
        array(           // display 'create_time' using an expression
            'value'=>'date("M j, Y", $data->create_time)',
        array(// display 'author.username' using an expression
        array(// display a column with "view", "update" and "delete" buttons


    'dataProvider' => $dataProvider,
    'columns'       => [
            'class' => 'yii\grid\SerialColumn'
        'title',        // display the 'title' attribute
        'category.name',// display the 'name' attribute of the 'category' relation
        'content:raw',  // display the 'content' attribute as purified HTML
        [               // display 'create_time' using an expression
            'name' => 'create_time',
            'value' => 'date("M j, Y", $data->create_time)',
    [// display 'author.username' using an expression
        'name' => 'authorName',
        'value' => '$data->author->username',
        'class' => 'yii\grid\ActionColumn'], //CRUD UI elements

The astute eye will notice that the base code has simply been updated to the current recommendations. the main change being how the widget is instantiated. The astute will also notice the new column’s `SerialColumn` and `ActionColumn`. These two handy classes provide serialized numbering and CRUD UI elements for the column data. DetailView, ItemView, etc have all been iterated on in this way.

That is all the time we have for today but we hope this has provided insightful. It is highly recommended you take a look at the documentation provided by the Yii team for even more details. http://www.yiiframework.com/doc-2.0/guide-intro-upgrade-from-v1.html