e2e
install nightwatch
npm i nightwatch
./node_modules/.bin/selenium-standalone install
check paths of webdriver.chrome.driver and server_path in nightwatch (if you get strange [object Object] error)
run nightwatch
./node_modules/.bin/nightwatch -e chrome
write a test
here presentation/tests/browser
use this
waitForElementVisible(selector)
assert.elementPresent(selector)
click
pause
setValue(selector, value)
for all api http://nightwatchjs.org/api
bonus! we have screenshots here tests/browser/reports if something broken
This is specific to react but you can get a general idea
cosmos (for quick access)
for example you want to check how components/User.js renders and check something in it in general you need to run app made some actions - see e2e section we can avoid this routine running our component in isolation we can do this with little help of cosmos.js
we need pass path to our components src/components and fixtures tests/fixtures
fixtures - resposible to make data for our component
lets run cosmos!
node_modules/.bin/component-playground --components-path src/components --fixtures-path tests/fixtures
go to http://localhost:8989
check out components/User.js it needs user{login, avatarUrl, name} you should not rely on network here so I saved /images/avatar.jpeg
with webpack we can require it and it will be transformed to base64 url so we can simply avatarUrl: require('url!../../images/avatar.jpeg')
now we can go http://localhost:8989/?component=User&fixture=simple
so we can see result of User.js render this helps a lot especially when our app became large it became really hard to follow how this or that component works
unit
okey be can quickly access our component but how about unit tests. Actually they are harder to write then e2e tests, and e2e are more secure you test product not some code so if you have quick access to every part of your app and your app is covered with e2e maybe we don't need unit tests? But no pressure here, look at your project and decide for yourself and decide what is right for your app.
we have right fixture and we can reuse it for tests
test are react specific so it is not realy interesting for wide auditory you can check it here /tests/unit/components/User.spec.js
lets go forward and do something with this test we want:
-
watch mode
-
clear console no nothing extra bullshit just last tests result
-
being notified when tests failed
-
is easy
"test": "mocha tests/unit --compilers js:babel/register --recursive
and
"test:watch": "npm test -- --watch",
Here is magic! we pass flag to "test" task from "test:watch" with "-- " we can do even more complex stuff with npm scripts but I'll talk out it later
but test is failed lets fix it! guess there just wrong props passed check out our /tests/fixtures/User/simple.js ... so we fixed test, but have not got 2) and 3) which is sad I guess we need gulp here (I was hoping that npm-scripts would be enough=( )
gulp (to do more complex stuff)
we need to make these tasks first
- cli-clear
gulp.task('cli-clear', function () {
cliClear()
});
- test
gulp.src([testsDir], {read: false})
.pipe(mocha({
reporter: 'list',
compilers: {
js: babel
}
}
))
- test-session (cli-clear then test)
gulp.task('test-session', function (cb) {
gulpSequence('cli-clear', 'test', cb);
});
- watch:test
gulp.task('watch:test', function () {
gulp.watch(['src/**', testsDir], ['test-session']);
});
okey lets
gulp watch:test
lets add notifications now
.on('error', notify.onError({
message: "Error: <%= error.message %>",
title: "Error running mocha tests"
}))
Great! We can do same thing with linters and e2e
gulp.task('e2e', function () {
return gulp.src([testsDir], {read: false})
.pipe(nightwatch({
configFile: './nightwatch.json',
cliArgs: {
env: 'chrome'
}
}))
.on('error', notify.onError({
message: "Error: <%= error.message %>",
title: "Error running e2e test"
}));
});
gulp.task('lint', function () {
return gulp.src(srcDir, {read: false})
.pipe(eslint())
.pipe(eslint.formatEach('compact'))
.on('error', notify.onError({
message: "Error: <%= error.message %>",
title: "Error running linting"
}))
});
git hooks
but I don't want to run linters and e2e every time e2e are slow and they interupts us with blinking browser window linters are verbose and they not such important as working code *(except you set them properly to catch some errors * missing ";" is not a big deal we can fix it after we do hard work)
so we need git hook there is a great gulp plugin for that - guppy
var guppy = require('git-guppy')(gulp);
gulp.task('pre-commit', ['pre-commit-session']);
gulp.task('pre-commit-session', function (cb) {
gulpSequence('cli-clear', 'mocha', 'e2e', cb);
});
Vooala!
npm-script hacks
I made a simple script /scripts/log.js that log some stuff that npm knows about our package
"log": "node scripts/log.js"
npm run log npm_package_config --olo-proj:msg=foo
Yeah this is ugly but we can pass this way variables and make our npm scripts smarter
for example lets fix some minor bug and commit
"commit": "git commit -m" -this waits for some message at the end
"fix-minor": "git add . && npm run commit \"$npm_package_config_msg\" && npm version patch"
Use semantic release Luke - HOT!
tests