perfect working environment
in 5 days
Who am i?
const ME = Object.freeze({
name: 'Sergey Bolshov',
position: 'Senior Front-end Software Engineer',
workPlace: 'Allegro',
email 'bolszow@gmail.com',
githubUsername: '@bigsergey'
});
DAY 1
First day at work
function additional(a, b) {
return
{
result: a+b
};
}
console.log(additonal(1, 2));
Ups, typo
function additional(a, b) {
return
{
result: a+b
};
}
-console.log(additonal(1, 2));
+console.log(additional(1, 2));
function additional(a, b) {
return
{
result: a+b
};
}
console.log(additional(1, 2));
Bad new line
function additional(a, b) {
- return
- {
+ return {
result: a+b
};
}
console.log(additional(1, 2));
function additional(a, b) {
return {
result: a+b
};
}
console.log(additional(1, 2));
Source: https://steamcommunity.com
Source: https://conservativememes.com
Eslint to rescue
eslint profits
- Eliminate errors
- Consistent code style
- Good practice/'Clean code'
- Easy to use
- IDE/Editors Support
- Pretteer integration
bonus tips
- Enable ESLint in editor
- Keep config updated
- Check for new plugins/configs
- Write your own rules
- Use lint-staged
lint-staged
{
"name": "your-project",
"version": "1.0.0",
"devDependencies": {
"husky": "2.2.0",
"lint-staged": "8.1.6"
},
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}
lint-staged
{
"name": "your-project",
"version": "1.0.0",
"devDependencies": {
"husky": "2.2.0",
"lint-staged": "8.1.6"
},
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}
stylelint
A mighty, modern linter that helps you avoid errors and enforce conventions in your styles.
Source: https://stylelint.io/
lint-staged + stylelint
{
"name": "your-project",
"version": "1.0.0",
"devDependencies": {
"husky": "2.2.0",
"lint-staged": "8.1.6",
"stylelint": "10.0.1"
},
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
],
"*.{css,pcss}": [
"stylelint --fix",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}
lint-staged + ESLINT + stylelint
useful configs
- stylelint-config-standard
- stylelint-config-rational-order (like CSScomb)
- stylelint-declaration-use-variable
- stylelint-high-performance-animation
- eslint-config-airbnb-base
- eslint-plugin-jsx-a11y
- ...
at the end of the DAY 1
+
+
=
ESLint
Prettier
Stylelint
day 2
Just Describe it
function add(a, b) {
return {
result: a + b
};
}
$ npm install mocha chai --save-dev
{
"name": "your-project",
"version": "1.0.0",
"scripts": {
"test": "mocha"
}
}
import { expect } from 'chai';
import add from '../add';
describe('add function', () => {
it('should return object', () => {
expect(add()).to.be.an('object');
});
it('should have result property', () => {
expect(add()).to.have.property('result');
});
it('should add 2 positive numbers together', () => {
expect(add(2, 2)).to.deep.equal({ result: 4 });
});
});
WHich tool should i use?
js testing tools
- Test runners (Karma, Jasmine, Jest, TestCafe, Cypress, Protractor)
- Testing structure (Mocha, Jasmine, Jest, Cucumber, TestCafe, Cypress, Protractor)
- Assertion functions (Chai, Jasmine, Jest, Unexpected, TestCafe, Cypress, Protractor)
- Generate and display test progress and results (Mocha, Jasmine, Jest, Karma, TestCafe, Cypress)
- Mocks, spies, and stubs (Sinon, Jasmine, enzyme, Jest, testdouble)
- Generate code coverage (Istanbul, Jest, Blanket)
Source: State of Javascript 2019
Testing, testing… Is this thing on? Sorry, I Jest, but I would never want to make a Mocha-ry of this section. That would be Jasmine (“just mean”? get it?), and that's bad Karma.
Salary breakdown
Source: State of Javascript 2018
Salary breakdown
Source: State of Javascript 2018
Source: Jasmine and Aladdin
WHICH TOOL SHOULD I USE?
a tool does not matter,
writing and maintaining tests is important
at the end of the DAY 2
+
+
=
Sinon
Day 3
first blood
New feature request
Source: https://giphy.com
Fire in production!
Source: https://giphy.com
e2e tests to rescue!
import { Selector } from 'testcafe';
const dashboard = Selector('#dashboard');
fixture`Authentication`
.page`http://example.com/login`;
test('should redirect to dashboard after login', async (t) => {
await t
.typeText('#login', 'TestUser')
.typeText('#password', 'testpass')
.click('#login')
.expect(dashboard.exists)
.ok();
});
// testcafe puppeteer 'path/to/test/file.js'
$ npm i testcafe testcafe-browser-provider-puppeteer -D
e2e tests tools
- ... and more other tools
at the end of the DAY 3
+
=
DAY 4
in hell
what's easy to break, hard to fix?
Visual Regression Tools are used to compare your site to its previous versions visually by using image comparison techniques.
visual regression tools
- Applitools (Selenium, not free)
- Percy.io (Selenium, not free)
- BackstopJS (Puppeteer, free, 4.8k ⭐️)
- Gemini (Selenium, free, 1.5k ⭐️)
- Differencify (Puppeteer, free, 475 ⭐️)
Wraith (Phantom JS)
More info here: "Awesome Visual Regression Testing"
visual regression tools challenges
- test execution environment
- different version of browsers
- different operation systems
- different screen sizes
- different DPI
- ...
- storing pictures in the repository
- git-lfs
- external storage
- ...
at the end of the DAY 4
some visual regression tool
=
Icon made by Freepik from www.flaticon.com
day 4 overtime
Source: memegenerator.net
Dom nodes number
Deploy
- Jest for React,
- Ava for React,
- Snap-shot-it for Mocha and BDD test runners.
snapshot testing
Source: Jest snapshot testing
bundlesize
$ npm install bundlesize --save-dev
$
{
"name": "your-project",
"version": "1.0.0",
"bundlesize": [{
"path": "./dist/main.css",
"maxSize": "3 kB"
},
{
"path": "./dist/chunk.js",
"maxSize": "10 kB"
}
]
}
at the end of the DAY 4 + overtime
visual regression
snapshot testing
Source: blog.debugme.eu
=
+
Day 5
save your fingers
// icon component
import { html } from 'escape-html-template-tag';
import * as styles from './index.css';
export default function renderIcon(iconUrl) {
return html`
<svg class="${styles.icon}">
<image xlink:href="${html.safe(iconUrl)}"></image>
</svg>
`;
}
// head component
import { html } from 'escape-html-template-tag';
import classnames from '../classnames';
import * as styles from './index.css';
export default function renderHead(title, isAlignRight) {
const headClassNames = classnames([
styles.head,
isAlignRight && styles.headRight,
]);
return html`
<span class="${headClassNames}">${title}</span>
`;
}
COde snippets
VScode extensions
GIT and command line aliases
# ...
[alias]
#LAZY VERSIONS OF BASIC COMMANDS
co = checkout
br = branch
ci = commit
st = status
#BETTER VERSIONS OF BASIC COMMANDS
purr = pull --rebase
puff = pull --ff-only
difff = diff --color-words
bbranch = branch -v
branches = branch -avvl
# ...
Source: git-kurwa
# Git aliases
alias gc="git commit"
alias ga="git add"
alias gr="git rm"
alias gp="git push"
alias gs="git status"
alias gpull="git pull"
alias gpullm="git pull origin master"
alias gpm="git push origin master"
alias clone="git clone"
Source: .bash_aliases
Oh My Zsh
Source: iterm2-solirized
itermocil
Source: Itermocil
NPM check updates
Source: npm-check-updates
greenkeeper
Source: Greenkeeper
at the end of the week
Sinon
VISUAL REGRESSION
SNAPSHOT
TESTS
thank you
Perfect working environment in 5 days (remastered 2020)
By Sergey Bolshov
Perfect working environment in 5 days (remastered 2020)
- 899