Category Archives: Setup

Cypress.io advanced setup

In my last projects, I’ve been using Cypress.io as an end to end testing solution (npm-registry-browser / react-fiber-experiments). It makes it easy to write, debug and record e2e tests.

If you want your team to write e2e tests, the dev experience must be straightforward:

  • You shouldn’t have to run more than one command line to launch your tests
  • You should have feedback
  • You should be able to debug your tests
  • You should be able to run your unit and e2e tests in parallel
  • You should be able to run your tests on a CI at some point

I will explain my setup. I won’t talk about how to write tests but how to run them against your code base / server (so there will be NO framework-specific code).

1) Cypress init

Install cypress then init your project. It will create a cypress directory containing default tests.

npm install --save-dev cypress
npx cypress open

Update the cypress.json file that was created and set the following:

{
  "baseUrl": "http://localhost:5000",
  "video": false
}
  • baseUrl: the url of the local server from where we will serve the production build
  • video: by default to true. You might not want to record video when running tests in local – otherwise, leave it to true (I will show on a future post how to setup Cypress on CI to record videos)

You will be ready to write your own tests and run them, but you will quickly feel that it misses some kind of automation …

2) Basics

You will need to install the following packages:

  • serve: use any other package that serves static sites
  • npm-run-all: a cli tool to run multiple npm-scripts in parallel or sequential
  • start-server-and-test: make sure to start testing only when server is ready
  • cross-env: set and use env vars across platforms

Install them:

npm install --save-dev serve npm-run-all start-server-and-test cross-env

3) Run your tests against a development server

You should be able to run your e2e tests while you are coding your project (a little like when you run your unit tests in watch mode). This will let you debug your tests.

We all have some kind of development toolchain, whether you rely on webpack, browserify or any other, I assume that:

  • npm start: starts your development server
  • your development server runs on http://localhost:3000

Here are the npm scripts we will use (change the start task to your own usage – I’m using a create-react-app based project as example):

scripts: {
  "start": "react-scripts start",
  "test:cypress:dev": "npm-run-all --parallel --race start 'cy:open -- --config baseUrl=http://localhost:3000'",
  "cy:open": "cypress open"
}

Running npm run test:cypress:dev will:

  • start your dev server (using npm start)
  • start the Cypress GUI (ready to test on your dev server at http://localhost:3000)

That way, you could choose to develop inside chrome or run your tests in the cypress GUI.

4) Run your tests against a production build

End to end tests should run in an environment that is the closest to production, to avoid the “it works on my machine” problem. So we will run them against a production build.

Here are the npm scripts we will use:

scripts: {
  "build": "react-scripts build",
  "test:cypress": "npm run build && npm run cy:start-server-and-test",
  "cy:start-server-and-test": "npx start-server-and-test serve :5000 cy:run",
  "serve": "npx serve --no-clipboard --single --listen 5000 build"
}

I will assume that you have some npm run build task that generates a production version of your project in the build folder (we all have that kind of task).

Running npm run test:cypress will:

  1. generate a production build (using npm run build)
  2. serve the build folder on http://localhost:5000
  3. finally, run the tests in headless mode

5) Run both your unit and e2e tests

Whatever the test framework you use, I will assume that you have setup your npm tasks to run your unit tests as:

  • test:unit: runs your unit tests in single run mode
  • test:unit:watch: runs your unit tests in watch mode

We will reuse a few tasks from the previous example, adding test, test:unit, test:unit:watch:

scripts: {
  "build": "react-scripts build",
  "test": "npm-run-all --parallel --silent test:unit test:cypress",
  "test:unit": "cross-env CI=true npm run test:unit:watch",
  "test:unit:watch": "react-scripts test --env=jsdom",
  "test:cypress": "npm run build && npm run cy:start-server-and-test",
  "cy:start-server-and-test": "npx start-server-and-test serve :5000 cy:run",
  "serve": "npx serve --no-clipboard --single --listen 5000 build"
}

Running npm test will launch in parallel test:unit and test:cypress, which means that while:

  • a production build is created and then served on http://localhost:5000 to be e2e tested
  • the unit tests will run

That way, you only have to run one command: npm test to run all your tests (unit AND e2e) – without even bothering about generating a production build / launching a test server – everything is included / run as soon as possible.

6) Conclusion

My testing workflow is based on the one I exposed in the following projects:

Check them out to learn more about react and testing.

If you followed all the steps, you should have the following tasks setup:

  • test: run both unit and e2e tests in parallel
  • test:unit: run your unit tests (if you had some)
  • test:cypress: run your e2e tests in headless mode
  • test:cypress:dev: launch your dev server + run your e2e tests in the Cypress GUI

 

A project to help getting into making React apps

Why I made topheman/npm-registry-browser

In software development, a lot of great quality resources are available, often for free. I’ve been getting feedbacks from developers – at work, online, at meetups – who shared that the hard part is not finding the knowledge but picking one library over an other or putting them all together.

Tutorials explaining a specific problem are all over there, what’s missing is projects examples / courses with a wider point of view.

This is what I decided to do in my latest project: topheman/npm-registry-browser. I respect some constraints that you would get, developing a real-world application, such as:

  • external API calls
  • using external libraries (UI kits, router, http clients …)
  • project setup for development with teams
  • code quality (linter, code formatting)
  • tests (unit / end to end)
  • automation / dev pipeline

The project itself is a Single Page Application that lets you search for packages in the npm registry and show details for each one of them such as the readme, the versions, the stats … In fact, this project is just an excuse to expose how to put together all those technologies I mentioned above.

The source code is available on github. You can test a demo online. I will be adding more features in the next weeks.

TRY IT

PS: This project is based on create-react-app and remains unejected. It was a constraint I imposed myself from the start. I never used CRA before (I have my own webpack starter-kit), so I wanted to test it to be able to tell what’s possible to do with it and what is not.

PPS: I chose not to use Redux, at least, not in that first version because … You might not need Redux (explanation) …

📺 Watch video of the talk (fr)

Install nginx with Homebrew on Mac OS X

I needed to install nginx to check my last project’s behavior behind a reverse proxy. This post isn’t about how to configure nginx for production – you’ll find that on Google (and you may use Linux over Mac 😉 ). This post is only about the installation part, like the previous ones as a reminder for future me when I’ll make this install again.

Install nginx

brew update
brew install nginx

Check if it works

  • nginx
  • go to http://localhost:8080
  • nginx -s stop

Version your nginx config with git

This part is optional, but it comes very handy to have your nginx folder config versioned, so that you wont have to make *.bak files 😉 …

Don’t worry, versionning the /usr/local/etc/nginx folder won’t mess with your homebrew git repo, if nano /usr/local/.gitignore you’ll see that basically, anything but the Library folder is not tracked.

cd /usr/local/etc/nginx
git init
git add .
git commit -m "original config"

There you are safe, you can mess all you want with your nginx conf …

Logs

You’ll find the error and access logs here : /usr/local/var/log/nginx/

You’ll find the file containing the nginx’s pid here : /usr/local/var/run/nginx.pid

Notes

Reminder : Homebrew will set the port to 8080 by default in the config so that you could run nginx without sudo. If you bind your server to the port 80, you’ll have to sudo nginx.

Launch Sublime Text from Terminal

I’ve shared my nvm installation and my git config, but there is an other thing I use a lot (and that I’ve been using for a while now) : launching Sublime Text from the Terminal.

I’m not a big fan of nano or vi (I do use them in some cases), but with that config, you’ll be able to do this, anywhere in the terminal :

  • subl foo.js : will open the file in Sublime
  • subl . : will open the folder in Sublime (with a file explorer on the left)

Follow the steps explained in this link https://gist.github.com/artero/1236170.

Note : I called my shortcut subl, not sublime (like in the example in the link above)

My custom git prompt on Mac OS X – v1

Credits

This post is mainly a reminder for future me when I’ll make this configuration again, or share it with other people. I followed those two resources from Christophe Porteneuve, that I recommend you to read if you’re into git :

Why a custom git prompt ?

It’s been a few months since I’ve been using this custom git prompt and I would not leave it for anything :

  • It saves me time
  • It saves me mistakes
  • I get instant access to infos such as :
    • active branch
    • status (untracked files remaining / modified files / stashed files …)
  • git commands completion

Disclaimer

This is about my own current git prompt config on Mac OS X, please take a look at the links I put on the credits section, so that you could have it your own way and make your very own git config.

Configuration on Mac OS X

This post is only about Mac OS X, we’ll need to upgrade the git version shipped with the OS (git 1.9.3 on Yosemite) to the latest stable one : (currently git 2.2.1), to do that, I’ll use Homebrew (feel free to use your own package manager or any other means).

Upgrade git :

$ brew update
$ brew install git

Check the git version in an other prompt : git --version
If not correct (if brew doctor is ok, you shouldn’t have to), run the following command (you may be using an other file than ~/.bash_profile, according to your shell) :

$ echo 'export PATH="/usr/local/bin:/usr/local/sbin:~/bin:$PATH"' >> ~/.bash_profile

Install bash-completion :

$ brew install bash-completion

nano ~/.bash_profile , add the following inside the file :

#bash-completion
if [ -f $(brew --prefix)/etc/bash_completion ]; then
 . $(brew --prefix)/etc/bash_completion
fi
#git-config
#export PS1='\u@\h:\w$(__git_ps1) \$ '
export GIT_PS1_SHOWDIRTYSTATE=1 GIT_PS1_SHOWSTASHSTATE=1 GIT_PS1_SHOWUNTRACKEDFILES=1
export GIT_PS1_SHOWUPSTREAM=verbose GIT_PS1_DESCRIBE_STYLE=branch
export PROMPT_COMMAND='__git_ps1 "\u@\h:\w" " \\\$ "'
export GIT_PS1_SHOWCOLORHINTS=1

For better logs : nano ~/.gitconfig (it may already exist, if not create it) and add the following (source) :

[alias]
 st = status
 ci = commit
 lg = log --graph --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ar)%Creset'
 oops = commit --amend --no-edit

Go to a local git repo and see the magic of your new git prompt !

Other resources :

Update : My gitconfig and some more infos (like how to setup a visual diff/merge tool)