Skip to content

Commit d66faeb

Browse files
committed
chore(build): refactor getMarkupAndStyle
1 parent 2af14fc commit d66faeb

12 files changed

+187
-96
lines changed

jest.helpers.js

+77-86
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import { assertMatchesDOM } from '@salesforce-ux/instant-vrt/matcher';
88
import childProcess from 'child_process';
99
import express from 'express';
10-
import openport from 'openport';
10+
import fetch from 'isomorphic-fetch';
1111
import path from 'path';
1212
import puppeteer from 'puppeteer';
1313
import React from 'react';
@@ -16,42 +16,76 @@ import ReactDOM from 'react-dom/server';
1616
import { beautify } from './shared/utils/beautify';
1717
import { renderWithBetterError } from './shared/utils/react';
1818

19-
const getMarkupAndStyle = selector => `
20-
(function() {
21-
const el = document.querySelector("${selector}")
22-
const kids = Array.from(el.querySelectorAll('*'))
23-
const extractCSS = el => getComputedStyle(el).cssText;
24-
return {
25-
html: el.outerHTML,
26-
style: [extractCSS(el)].concat(kids.map(extractCSS))
27-
}
28-
})()
29-
`;
19+
// const getMarkupAndStyle = selector => `
20+
// (function() {
21+
// const el = document.querySelector("${selector}")
22+
// const kids = Array.from(el.querySelectorAll('*'))
23+
// const extractCSS = el => getComputedStyle(el).cssText;
24+
// return {
25+
// html: el.outerHTML,
26+
// style: [extractCSS(el)].concat(kids.map(extractCSS))
27+
// }
28+
// })()
29+
// `;
3030

31-
const delay = delay =>
32-
new Promise(resolve => {
33-
setTimeout(resolve, delay);
34-
});
31+
// const startServer = p =>
32+
// new Promise((resolve, reject) => {
33+
// const server = app.listen(p, () => resolve(server)).on('error', reject);
34+
// });
3535

36-
const app = express();
36+
// const delay = delay =>
37+
// new Promise(resolve => {
38+
// setTimeout(resolve, delay);
39+
// });
3740

38-
app.get('/', (req, res) => {
39-
res.send(`
40-
<!doctype>
41-
<html>
42-
<head>
43-
<link type="text/css" rel="stylesheet" href="/assets/styles/index.css" />
44-
</head>
45-
<body></body>
46-
</html>
47-
`);
48-
});
49-
app.use('/assets', express.static(path.resolve(__dirname, 'assets')));
41+
// const app = express();
42+
//
43+
// app.get('/', (req, res) => {
44+
// res.send(`
45+
// <!doctype>
46+
// <html>
47+
// <head>
48+
// <link type="text/css" rel="stylesheet" href="/assets/styles/index.css" />
49+
// <style type="text/css"
50+
// </head>
51+
// <body></body>
52+
// </html>
53+
// `);
54+
// });
55+
//
56+
// app.use('/assets', express.static(path.resolve(__dirname, 'assets')));
5057

51-
let server;
52-
let browser;
53-
let page;
5458
let CURRENT_TEST_NAME;
59+
// let server;
60+
// let browser;
61+
// let page;
62+
63+
// beforeAll(async () => {
64+
// server = await startServer(12345);
65+
// browser = await puppeteer.launch({ args: ['--no-sandbox'] });
66+
// page = await browser.newPage();
67+
// await page.emulate({
68+
// userAgent:
69+
// 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36',
70+
// viewport: {
71+
// width: 1280,
72+
// height: 800,
73+
// deviceScaleFactor: 1,
74+
// isMobile: false,
75+
// hasTouch: false,
76+
// isLandscape: false
77+
// }
78+
// });
79+
// await page.goto(`http://localhost:12345`);
80+
// });
81+
82+
// afterAll(async () => {
83+
// await page.close();
84+
// await browser.close();
85+
// await new Promise(resolve => {
86+
// server.close(() => resolve());
87+
// });
88+
// });
5589

5690
export default (dirname, port) => {
5791
jasmine.getEnv().addReporter({
@@ -60,56 +94,6 @@ export default (dirname, port) => {
6094
}
6195
});
6296

63-
const getPort = () =>
64-
new Promise((resolve, reject) => {
65-
openport.find(function(err, port) {
66-
err ? reject(err) : resolve(port);
67-
});
68-
});
69-
70-
const startServer = p =>
71-
new Promise((resolve, reject) => {
72-
const server = app.listen(p, () => resolve(server)).on('error', reject);
73-
});
74-
75-
beforeAll(async () => {
76-
// Server gets started before each suite and then closed afterwards
77-
// This needs to be here so that matchesMarkupAndStyle() will work even when
78-
// not using the watcher
79-
port = port || (await getPort());
80-
console.log('running on port', port);
81-
try {
82-
server = await startServer(port);
83-
} catch (e) {
84-
console.log('failed to start server', e);
85-
port = await getPort();
86-
console.log('trying new port', port);
87-
server = await startServer(port); // only try twice
88-
}
89-
browser = await puppeteer.launch({ args: ['--no-sandbox'] });
90-
page = await browser.newPage();
91-
await page.emulate({
92-
userAgent:
93-
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36',
94-
viewport: {
95-
width: 1280,
96-
height: 800,
97-
deviceScaleFactor: 1,
98-
isMobile: false,
99-
hasTouch: false,
100-
isLandscape: false
101-
}
102-
});
103-
await page.goto(`http://localhost:${port}`);
104-
});
105-
106-
afterAll(async () => {
107-
browser.close();
108-
await new Promise(resolve => {
109-
server.close(() => resolve());
110-
});
111-
});
112-
11397
return {
11498
matchesMarkupAndStyle: async element => {
11599
const renderedMarkup =
@@ -119,10 +103,17 @@ export default (dirname, port) => {
119103
element,
120104
`${CURRENT_TEST_NAME} failed on ${element}`
121105
);
122-
await page.evaluate(`document.body.innerHTML = \`${renderedMarkup}\``);
123-
await delay(750);
124-
const markupAndStyle = await page
125-
.evaluate(getMarkupAndStyle('body > *'))
106+
const markupAndStyle = await fetch(
107+
'http://localhost:12345/api/getMarkupAndStyle',
108+
{
109+
method: 'POST',
110+
headers: {
111+
'Content-Type': 'text/plain'
112+
},
113+
body: renderedMarkup
114+
}
115+
)
116+
.then(res => res.json())
126117
.then(diff => ({ html: beautify(renderedMarkup), style: diff.style }));
127118
assertMatchesDOM(dirname, CURRENT_TEST_NAME, markupAndStyle);
128119
}

jest.setup.global.js

+88
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,99 @@
11
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved
22
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license
33

4+
/* eslint-env jest */
5+
6+
import bodyParser from 'body-parser';
7+
import express from 'express';
8+
import path from 'path';
9+
import puppeteer from 'puppeteer';
410
import { argv } from 'yargs';
511

612
import { watch } from './gulpfile';
713

14+
const startServer = port =>
15+
new Promise((resolve, reject) => {
16+
const server = app
17+
.listen(port, () => {
18+
console.log(`server started on port ${port}`);
19+
resolve(server);
20+
})
21+
.on('error', reject);
22+
});
23+
24+
const delay = delay =>
25+
new Promise(resolve => {
26+
setTimeout(resolve, delay);
27+
});
28+
29+
const createPage = async () => {
30+
const page = await browser.newPage();
31+
await page.emulate({
32+
userAgent:
33+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36',
34+
viewport: {
35+
width: 1280,
36+
height: 800,
37+
deviceScaleFactor: 1,
38+
isMobile: false,
39+
hasTouch: false,
40+
isLandscape: false
41+
}
42+
});
43+
await page.goto(`http://localhost:12345`);
44+
return page;
45+
};
46+
47+
const getMarkupAndStyle = selector => {
48+
const node = document.querySelector(selector);
49+
const nodes = Array.from(node.querySelectorAll('*'));
50+
const extractCSS = n => window.getComputedStyle(n).cssText;
51+
return {
52+
html: node.outerHTML,
53+
style: [extractCSS(node)].concat(nodes.map(extractCSS))
54+
};
55+
};
56+
57+
const app = express();
58+
const pages = [];
59+
60+
let server;
61+
let browser;
62+
63+
app.use('/assets', express.static(path.resolve(__dirname, 'assets')));
64+
65+
app.get('/', (req, res) => {
66+
res.send(`
67+
<!doctype>
68+
<html>
69+
<head>
70+
<link type="text/css" rel="stylesheet" href="/assets/styles/index.css" />
71+
<style type="text/css"
72+
</head>
73+
<body></body>
74+
</html>
75+
`);
76+
});
77+
78+
app.get('/api/jest/teardown', async (req, res) => {
79+
await Promise.all(pages.map(page => page.close()));
80+
await browser.close();
81+
await server.close();
82+
res.sendStatus(200);
83+
});
84+
85+
app.post('/api/getMarkupAndStyle', bodyParser.text(), async (req, res) => {
86+
const page = pages.pop() || (await createPage());
87+
await page.evaluate(html => (document.body.innerHTML = html), req.body);
88+
await delay(200);
89+
const markupAndStyle = await page.evaluate(getMarkupAndStyle, 'body > *');
90+
res.json(markupAndStyle);
91+
pages.push(page);
92+
});
93+
894
// Jest can't handle exports.default
995
module.exports = async () => {
96+
server = await startServer(12345);
97+
browser = await puppeteer.launch({ args: ['--no-sandbox'] });
1098
if (argv.watch) watch();
1199
};

jest.teardown.global.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved
2+
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license
3+
4+
import fetch from 'isomorphic-fetch';
5+
6+
// Jest can't handle exports.default
7+
module.exports = async () => {
8+
await fetch('http://localhost:12345/api/jest/teardown');
9+
};

package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@
3737
"babel-cli": "6.23.0",
3838
"babel-core": "6.24.0",
3939
"babel-eslint": "7.2.1",
40-
"babel-jest": "22.0.6",
40+
"babel-jest": "22.4.1",
4141
"babel-loader": "7.1.3",
4242
"babel-plugin-transform-es2015-modules-commonjs": "6.24.1",
4343
"babel-plugin-transform-object-rest-spread": "6.23.0",
4444
"babel-preset-es2015": "6.18.0",
4545
"babel-preset-react": "6.23.0",
4646
"babel-register": "6.24.0",
47+
"body-parser": "1.18.2",
4748
"chai": "3.5.0",
4849
"cheerio": "0.22.0",
4950
"classnames": "2.2.5",
@@ -98,7 +99,8 @@
9899
"husky": "0.14.3",
99100
"immutable": "3.8.1",
100101
"invariant": "2.2.2",
101-
"jest": "22.0.6",
102+
"isomorphic-fetch": "2.2.1",
103+
"jest": "22.4.2",
102104
"js-beautify": "1.6.12",
103105
"js-yaml": "3.8.3",
104106
"json-stable-stringify": "1.0.1",
@@ -186,6 +188,7 @@
186188
"jest": {
187189
"testRegex": "(/__tests__/.*(test|spec))\\.jsx?$",
188190
"globalSetup": "./jest.setup.global.js",
191+
"globalTeardown": "./jest.teardown.global.js",
189192
"setupTestFrameworkScriptFile": "./jest.setup.js",
190193
"moduleNameMapper": {
191194
"\\.(scss)$": "<rootDir>/shared/vendor/prism/"

ui/components/cards/__tests__/snapshot.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Card, CardBody, CardFooter } from '../base/example';
55

66
import createHelpers from '../../../../jest.helpers';
77

8-
const { matchesMarkupAndStyle } = createHelpers(__dirname, 8080);
8+
const { matchesMarkupAndStyle } = createHelpers(__dirname);
99

1010
xit('renders an einstein card', () =>
1111
matchesMarkupAndStyle(

ui/components/global-header/__tests__/index.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import createHelpers from '../../../../jest.helpers';
77
import { GlobalHeaderDeprecated } from '../base/example';
88
import GlobalHeader from '../';
99

10-
const { matchesMarkupAndStyle } = createHelpers(__dirname, 8888);
10+
const { matchesMarkupAndStyle } = createHelpers(__dirname);
1111

1212
describe('render global header', () => {
1313
it('renders the deprecated global header', () => {

ui/components/popovers/__tests__/snapshot.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { FeedbackHeader, FeedbackFooter } from '../error/example';
88

99
import createHelpers from '../../../../jest.helpers';
1010

11-
const { matchesMarkupAndStyle } = createHelpers(__dirname, 8080);
11+
const { matchesMarkupAndStyle } = createHelpers(__dirname);
1212
const headingUniqueId = 'dialog-heading-id-01';
1313

1414
// These tests are temporarily skipped. They fail on Travis since we're using tokens to bring in image paths.

0 commit comments

Comments
 (0)