Skip to content

Commit bf62766

Browse files
authored
test: Preact CLI tests (#107)
* test: Preact CLI tests [WIP] * test: Preact CLI tests [WIP] Refactor, testing build size * test: Preact CLI tests Headless chrome, all commands tested * Remove yarn.lock * refactor: Preact CLI tests CR changes * chore: Setup Travis CI * fix: Setup test timeouts for travis Try no 1 * chore: Travis setup chrome path [WIP] * fix: Setup test timeouts for travis Try no 2 * chore: Debug Chrome errors on Travis * Revert "chore: Debug Chrome errors on Travis" This reverts commit 266443b. * chore: Travis setup chrome * chore: Travis setup chrome * chore: Travis setup chrome * chore: Travis setup chrome * chore: Travis setup chrome * chore: Travis setup chrome * chore: Travis setup chrome * refactor: Preact CLI tests * test: Preact CLI increase build timeout * test: Increase robustness of serve test * test: Don't fail when page can't be loaded * Revert "test: Don't fail when page can't be loaded" This reverts commit 9395884. * test: Increase robustness of serve test * tests: Use chrome-launcher npm package instead of lighthouse * tests: Remove cert install * tests: New way of handling SSL certificates * tests: New way of handling SSL certificates * tests: Add delay to page interactive check for serve.test.js
1 parent 2175efc commit bf62766

File tree

16 files changed

+670
-37
lines changed

16 files changed

+670
-37
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
/node_modules
22
/lib
33
/examples/*/build
4+
/tests/output
45
.DS_Store
56
npm-debug.log
67
key.pem
78
cert.pem
9+
lighthouse.*/
10+
tmp-*.json

.travis.yml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
dist: trusty
2+
sudo: required
3+
addons:
4+
chrome: stable
5+
apt:
6+
packages: libnss3-tools
7+
18
language: node_js
29
node_js:
3-
- "7.0"
10+
- "6"
11+
- "7"
12+
- "8"
13+
cache:
14+
npm: true
15+
16+
before_script:
17+
- export LIGHTHOUSE_CHROMIUM_PATH=`which google-chrome-stable`
18+
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
19+
20+
script:
21+
- npm run lint
22+
- npm run test

package.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
"build": "babel src -d lib -D",
1111
"prepublish": "npm run -s build",
1212
"dev": "babel-node src",
13-
"lint": "eslint src",
14-
"test": "npm run -s lint",
13+
"lint": "eslint src tests",
14+
"pretest": "npm run -s build",
15+
"test": "tape -r babel-register tests/*.test.js",
1516
"test:build": "babel-node src build --cwd examples/root",
1617
"test:serve": "npm run -s test:build && babel-node src serve --port 3000 --cwd examples/root",
1718
"test:serve:config": "npm run -s test:build && babel-node src serve --server config --cwd examples/root",
@@ -72,8 +73,14 @@
7273
"devDependencies": {
7374
"babel-cli": "^6.24.0",
7475
"babel-eslint": "^7.2.1",
76+
"chrome-launcher": "^0.1.1",
77+
"chrome-remote-interface": "^0.23.2",
7578
"eslint": "^3.19.0",
76-
"eslint-plugin-react": "^7.0.1"
79+
"eslint-plugin-react": "^7.0.1",
80+
"html-looks-like": "^1.0.2",
81+
"lodash": "^4.17.4",
82+
"tape": "^4.6.3",
83+
"uuid": "^3.0.1"
7784
},
7885
"dependencies": {
7986
"@webpack-blocks/css-modules": "^0.4.0",
@@ -98,7 +105,6 @@
98105
"devcert-san": "^0.3.3",
99106
"ejs-loader": "^0.3.0",
100107
"es6-promisify": "^5.0.0",
101-
"eslint": "^3.19.0",
102108
"file-loader": "^0.11.1",
103109
"fs.promised": "^3.0.0",
104110
"html-webpack-plugin": "^2.28.0",

src/commands/create.js

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ export default asyncCommand({
4747
description: 'Pre-install SASS/SCSS support',
4848
type: 'boolean',
4949
default: false
50+
},
51+
install: {
52+
description: 'Install dependencies',
53+
type: 'boolean',
54+
default: true
5055
}
5156
},
5257

@@ -110,38 +115,40 @@ export default asyncCommand({
110115

111116
await fs.writeFile(path.resolve(target, 'package.json'), JSON.stringify(pkg, null, 2));
112117

113-
spinner.text = 'Installing dev dependencies';
114-
115-
await npm(target, [
116-
'install', '--save-dev',
117-
'preact-cli',
118-
'if-env',
119-
'eslint',
120-
'eslint-config-synacor',
121-
122-
// install sass setup if --sass
123-
...(argv.sass ? [
124-
'node-sass',
125-
'sass-loader'
126-
] : []),
127-
128-
// install less setup if --less
129-
...(argv.less ? [
130-
'less',
131-
'less-loader'
132-
] : [])
133-
].filter(Boolean));
134-
135-
spinner.text = 'Installing dependencies';
136-
137-
await npm(target, [
138-
'install', '--save',
139-
'preact',
140-
'preact-compat',
141-
'preact-router'
142-
]);
143-
144-
spinner.succeed('Done!\n');
118+
if (argv.install) {
119+
spinner.text = 'Installing dev dependencies';
120+
121+
await npm(target, [
122+
'install', '--save-dev',
123+
'preact-cli',
124+
'if-env',
125+
'eslint',
126+
'eslint-config-synacor',
127+
128+
// install sass setup if --sass
129+
...(argv.sass ? [
130+
'node-sass',
131+
'sass-loader'
132+
] : []),
133+
134+
// install less setup if --less
135+
...(argv.less ? [
136+
'less',
137+
'less-loader'
138+
] : [])
139+
].filter(Boolean));
140+
141+
spinner.text = 'Installing dependencies';
142+
143+
await npm(target, [
144+
'install', '--save',
145+
'preact',
146+
'preact-compat',
147+
'preact-router'
148+
]);
149+
150+
spinner.succeed('Done!\n');
151+
}
145152

146153
return `
147154
To get started, cd into the new directory:

tests/async-test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import test from 'tape';
2+
3+
const defaultTestTimeout = 10 * 1000;
4+
5+
const asyncTest = (...args) => {
6+
let { fn, tapeArgs, hasTimeout } = parseArgs(args);
7+
8+
test(...tapeArgs, (t) => {
9+
if (!hasTimeout) t.timeoutAfter(defaultTestTimeout);
10+
fn(t)
11+
.then(() => t.end())
12+
.catch(e => t.end(e));
13+
});
14+
};
15+
16+
asyncTest.only = (...args) => {
17+
let { fn, tapeArgs, hasTimeout } = parseArgs(args);
18+
19+
test.only(...tapeArgs, t => {
20+
if (!hasTimeout) t.timeoutAfter(defaultTestTimeout);
21+
fn(t)
22+
.then(() => t.end())
23+
.catch(e => t.end(e));
24+
});
25+
};
26+
27+
export default asyncTest;
28+
29+
const parseArgs = args => {
30+
let fn = args[args.length - 1];
31+
let tapeArgs = args.slice(0, args.length - 1);
32+
let opts = tapeArgs[1];
33+
34+
return {
35+
fn,
36+
tapeArgs,
37+
hasTimeout: opts && opts.timeout !== undefined
38+
};
39+
};

tests/build.snapshot.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
export const normalize = obj => {
2+
let keys = Object.keys(obj);
3+
4+
if (keys.length === 1 && keys[0] === 'size' && typeof keys[0] === 'number') {
5+
return { size: Math.round(obj.size / 10) * 10 };
6+
}
7+
8+
return keys.reduce((agg, key) => {
9+
let newKey = key.replace(/\.chunk\.\w+\./, '.chunk.*.');
10+
agg[newKey] = normalize(obj[key]);
11+
return agg;
12+
}, {});
13+
};
14+
15+
const smallBuildCommons = {
16+
assets: {
17+
'favicon.ico': { size: 15086 },
18+
'icon.png': { size: 51484 }
19+
},
20+
'polyfills.chunk.*.js': { size: 4068 },
21+
'favicon.ico': { size: 15086 },
22+
'sw.js': { size: 3378 },
23+
'manifest.json': { size: 298 },
24+
'push-manifest.json': { size: 2 },
25+
};
26+
27+
const fullBuildCommons = {
28+
assets: {
29+
'favicon.ico': { size: 15086 },
30+
icons: {
31+
'android-chrome-192x192.png': { size: 14058 },
32+
'android-chrome-512x512.png': { size: 51484 },
33+
'apple-touch-icon.png': { size: 12746 },
34+
'favicon-16x16.png': { size: 626 },
35+
'favicon-32x32.png': { size: 1487 },
36+
'mstile-150x150.png': { size: 9050 }
37+
}
38+
},
39+
'polyfills.chunk.*.js': { size: 4066 },
40+
'push-manifest.json': { size: 303 },
41+
'favicon.ico': { size: 15086 },
42+
'manifest.json': { size: 426 },
43+
'sw.js': { size: 3905 }
44+
};
45+
46+
export const expectedOutputs = normalize({
47+
empty: {
48+
...smallBuildCommons,
49+
'bundle.js': { size: 10694 },
50+
'index.html': { size: 534 },
51+
'style.css': { size: 131 },
52+
'style.css.map': { size: 359 },
53+
},
54+
simple: {
55+
...smallBuildCommons,
56+
'bundle.js': { size: 11336 },
57+
'index.html': { size: 548 },
58+
'style.css': { size: 296},
59+
'style.css.map': { size: 621 },
60+
},
61+
root: {
62+
...fullBuildCommons,
63+
'bundle.js': { size: 18739 },
64+
'route-home.chunk.*.js': { size: 959 },
65+
'route-profile.chunk.*.js': { size: 1595 },
66+
'index.html': { size: 775 },
67+
'style.css': { size: 1065 },
68+
'style.css.map': { size: 2246 },
69+
},
70+
'default': {
71+
...fullBuildCommons,
72+
'bundle.js': { size: 19661 },
73+
'route-home.chunk.*.js': { size: 961 },
74+
'route-profile.chunk.*.js': { size: 1597 },
75+
'index.html': { size: 775 },
76+
'style.css': { size: 1065 },
77+
'style.css.map': { size: 2345 },
78+
}
79+
});

tests/build.test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import test from './async-test';
2+
import { resolve } from 'path';
3+
import { create, build } from './lib/cli';
4+
import lsr from './lib/lsr';
5+
import { setup, clean } from './lib/output';
6+
import { normalize, expectedOutputs } from './build.snapshot';
7+
8+
const options = { timeout: 45 * 1000 };
9+
10+
test('preact build - before', async () => {
11+
await setup();
12+
});
13+
14+
['empty', 'simple', 'root', 'default'].forEach(template =>
15+
test(`preact build - should produce output. Veryfing ${template}`, options, async t => {
16+
let app = await create('app', template);
17+
await build(app);
18+
19+
let output = await lsr(resolve(app, 'build'));
20+
21+
t.isEquivalent(normalize(output), expectedOutputs[template]);
22+
})
23+
);
24+
25+
test('preact build - after', async () => {
26+
await clean();
27+
});

tests/create.test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import test from './async-test';
2+
import { resolve } from 'path';
3+
import { create } from './lib/cli';
4+
import lsr from './lib/lsr';
5+
import { setup, clean } from './lib/output';
6+
7+
const listTemplate = async dir => await lsr(resolve(__dirname, '../examples', dir), ['.gitkeep', 'package.json']);
8+
const listOutput = async dir => await lsr(dir, ['.gitkeep', 'package.json']);
9+
10+
test('preact create - before', async () => {
11+
await setup();
12+
});
13+
14+
test('preact create - should create project using full template by default.', async t => {
15+
let fullExample = await listTemplate('full');
16+
let app = await create('app');
17+
let generated = await listOutput(app);
18+
19+
t.isEquivalent(generated, fullExample);
20+
});
21+
22+
['root', 'simple', 'empty'].forEach(template =>
23+
test(`preact create - should create project using provided template. Verifying ${template}`, async t => {
24+
let example = await listTemplate(template);
25+
let app = await create('app', template);
26+
let generated = await listOutput(app);
27+
28+
t.isEquivalent(generated, example);
29+
})
30+
);
31+
32+
test('preact build - after', async () => {
33+
await clean();
34+
});

0 commit comments

Comments
 (0)