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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6104822/pasted-from-clipboard.png)
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));
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6104817/pasted-from-clipboard.png)
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));
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6104892/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6104918/pasted-from-clipboard.png)
Source: https://steamcommunity.com
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6104924/pasted-from-clipboard.png)
Source: https://conservativememes.com
Eslint to rescue
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6104971/pasted-from-clipboard.png)
eslint profits
- Eliminate errors
- Consistent code style
- Good practice/'Clean code'
- Easy to use
- IDE/Editors Support
- Pretteer integration
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6107821/pasted-from-clipboard.png)
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.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6138275/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6138309/pasted-from-clipboard.png)
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"
}
}
}
![](https://media.giphy.com/media/zcCGBRQshGdt6/giphy.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6159673/pasted-from-clipboard.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6138451/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6138456/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6138275/pasted-from-clipboard.png)
+
+
=
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6138474/pasted-from-clipboard.png)
ESLint
Prettier
Stylelint
day 2
Just Describe it
function add(a, b) {
return {
result: a + b
};
}
![](https://media.makeameme.org/created/i-dont-always-plj4xz.jpg)
$ 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 });
});
});
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6148584/pasted-from-clipboard.png)
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.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6937342/pasted-from-clipboard.png)
Salary breakdown
Source: State of Javascript 2018
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6148847/2018.stateofjs.com_testing_overview_.png)
Salary breakdown
Source: State of Javascript 2018
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6148848/2018.stateofjs.com_testing_overview___1_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6148878/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6148881/pasted-from-clipboard.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6149063/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6149081/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6149086/pasted-from-clipboard.png)
+
+
=
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6149100/pasted-from-clipboard.png)
Sinon
Day 3
first blood
New feature request
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6151883/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6151889/pasted-from-clipboard.png)
![](https://media.giphy.com/media/102h4wsmCG2s12/giphy.gif)
Source: https://giphy.com
Fire in production!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6151902/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6151903/pasted-from-clipboard.png)
![](https://media.giphy.com/media/XjlNyeZp5lDri/giphy.gif)
Source: https://giphy.com
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6159571/pasted-from-clipboard.png)
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
![](https://cdn-images-1.medium.com/max/1600/1*UtZzMT32fRMnSN-HmgiSVQ.gif)
e2e tests tools
- ... and more other tools
at the end of the DAY 3
+
=
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152042/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152047/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152048/pasted-from-clipboard.png)
DAY 4
in hell
what's easy to break, hard to fix?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152295/frame-chrome-mac.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152296/codepen.io_bigsergey_full_KLvqZL_iPhone_5_SE___1_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152302/pasted-from-clipboard.png)
![](https://media.giphy.com/media/13FrpeVH09Zrb2/giphy.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152376/login-finished.png)
Visual Regression Tools are used to compare your site to its previous versions visually by using image comparison techniques.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152409/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152417/comparison.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152844/pasted-from-clipboard.png)
Source: memegenerator.net
Dom nodes number
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6156977/pasted-from-clipboard.png)
Deploy
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6937440/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6937441/pasted-from-clipboard.png)
- Jest for React,
- Ava for React,
- Snap-shot-it for Mocha and BDD test runners.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152769/pasted-from-clipboard.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152704/pasted-from-clipboard.png)
Source: blog.debugme.eu
=
+
Day 5
save your fingers
![](https://media.giphy.com/media/RRerwvHrb0nxm/giphy.gif)
// 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
![](https://gist.githubusercontent.com/kevin-smets/9722391f8b3e4fa436b1c1dcf05ecd88/raw/29389beaa891f939e274b8e20622647357e793d4/powerlevel9k.png)
Source: iterm2-solirized
itermocil
![](https://raw.githubusercontent.com/TomAnthony/itermocil/master/itermocil.gif)
Source: Itermocil
NPM check updates
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152921/pasted-from-clipboard.png)
Source: npm-check-updates
greenkeeper
Source: Greenkeeper
at the end of the week
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6138451/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6138456/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6138275/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6149063/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6149081/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6149086/pasted-from-clipboard.png)
Sinon
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152042/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6152047/pasted-from-clipboard.png)
VISUAL REGRESSION
SNAPSHOT
TESTS
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6156903/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6156926/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6157034/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/437224/images/6157047/pasted-from-clipboard.png)
thank you
Perfect working environment in 5 days (remastered 2020)
By Sergey Bolshov
Perfect working environment in 5 days (remastered 2020)
- 977