forked from salesforce-ux/design-system
-
Notifications
You must be signed in to change notification settings - Fork 0
/
jest.setup.js
129 lines (118 loc) · 3.39 KB
/
jest.setup.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license
/* global jasmine */
/* eslint-env jest */
const childProcess = require('child_process');
const express = require('express');
const { html: htmlBeautify } = require('js-beautify');
const path = require('path');
const openport = require('openport');
const puppeteer = require('puppeteer');
const React = require('react');
const ReactDOM = require('react-dom/server');
const { assertMatchesDOM } = require('@salesforce-ux/instant-vrt/matcher');
const beautify = html =>
htmlBeautify(html, {
indent_size: 2,
indent_char: ' ',
unformatted: ['a'],
'wrap_line_length ': 78,
indent_inner_html: true
});
const getMarkupAndStyle = selector => `
(function() {
const el = document.querySelector("${selector}")
const kids = Array.from(el.querySelectorAll('*'))
const extractCSS = el => getComputedStyle(el).cssText;
return {
html: el.outerHTML,
style: [extractCSS(el)].concat(kids.map(extractCSS))
}
})()
`;
const delay = delay =>
new Promise(resolve => {
setTimeout(resolve, delay);
});
const app = express();
app.use(express.static(path.resolve(__dirname, 'assets')));
let server;
let port;
let browser;
let page;
let CURRENT_TEST_NAME;
beforeAll(async () => {
// Server gets started before each suite and then closed afterwards
// This needs to be here so that matchesMarkupAndStyle() will work even when
// not using the watcher
port = await new Promise((resolve, reject) => {
openport.find(function(err, port) {
err ? reject(err) : resolve(port);
});
});
console.log('Running on port', port);
server = await new Promise(resolve => {
const server = app.listen(port, () => {
resolve(server);
});
});
browser = await puppeteer.launch();
page = await browser.newPage();
await page.emulate({
userAgent:
'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',
viewport: {
width: 400,
height: 400,
deviceScaleFactor: 1,
isMobile: false,
hasTouch: false,
isLandscape: false
}
});
await page.setContent(`
<!doctype>
<html>
<head></head>
<body></body>
</html>
`);
const href = `http://localhost:${port}/styles/index.css`;
await page.evaluate(
h =>
new Promise((resolve, reject) => {
const link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = h;
link.onload = resolve;
link.onerror = reject;
document.head.appendChild(link);
}),
href
);
await delay(450);
});
jasmine.getEnv().addReporter({
specStarted: function(result) {
CURRENT_TEST_NAME = result.fullName;
}
});
afterAll(async () => {
browser.close();
await new Promise(resolve => {
server.close(() => resolve());
});
});
module.exports = dirname => ({
matchesMarkupAndStyle: async element => {
await page.evaluate(
`document.body.innerHTML = \`${ReactDOM.renderToStaticMarkup(element)}\``
);
await delay(250);
const markupAndStyle = await page
.evaluate(getMarkupAndStyle('body > *'))
.then(diff => ({ html: beautify(diff.html), style: diff.style }));
assertMatchesDOM(dirname, CURRENT_TEST_NAME, markupAndStyle);
}
});