@hubspot/ui-extensions-dev-server 0.0.1-prealpha.0 β 0.0.1-prealpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -14
- package/build.js +32 -21
- package/cli.js +65 -0
- package/config.js +20 -16
- package/constants.js +2 -3
- package/dev.js +4 -7
- package/logger.js +0 -3
- package/package.json +26 -3
- package/remoteBuild.js +21 -0
- package/run.js +16 -12
- package/tests/runTests.js +0 -2
- package/tests/testBuild.js +49 -11
- package/tests/testDevServer.js +25 -17
- package/utils.js +0 -3
package/README.md
CHANGED
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
# ui-extensions-dev-server
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
This package contains the cli for running HubSpot UI extensions locally, as well as running a production build for debugging purposes.
|
|
5
|
+
|
|
6
|
+
### Help
|
|
7
|
+
If for any reason you need help with the `ui-extensions-dev-server` you can access the help menu in a few ways:
|
|
8
|
+
|
|
9
|
+
- `hs-ui-extensions-dev-server`
|
|
10
|
+
- `hs-ui-extensions-dev-server -h`
|
|
11
|
+
- `hs-ui-extensions-dev-server --help`
|
|
12
|
+
|
|
13
|
+
### Local Development
|
|
14
|
+
Prompts you which of your extensions you would like to run in local dev mode. Once you have made your selection, it sets up a watcher on the entry point file for that project as well as any child files. Any changes to those files will trigger a local build which will bundle your code and output the bundle in a `dist/` directory inside of your current working directory. To initiate local dev mode in the browser, you just need to navigate to the CRM where your the deployed version of your card lives. The browser will detect that you have the dev server running, and make the connection on your behalf.
|
|
15
|
+
|
|
16
|
+
| Action | Command |
|
|
17
|
+
| - | - |
|
|
18
|
+
| Standard Local Dev | `hs-ui-extensions-dev-server dev` |
|
|
19
|
+
| Bypass Prompt | `hs-ui-extensions-dev-server dev --extension MyEntryPointFile.jsx` <br /> `hs-ui-extensions-dev-server dev -e MyEntryPointFile.jsx`|
|
|
20
|
+
|
|
21
|
+
### Production Build
|
|
22
|
+
This should not be required in the standard development workflow. It is there to aid debugging the output of an extension. This command will run a build similar to what we will run when these extensions are uploaded. The output will be written into a `dist/` directory in the current working directory.
|
|
23
|
+
|
|
24
|
+
| Action | Command |
|
|
25
|
+
| - | - |
|
|
26
|
+
| Build All Extensions | `hs-ui-extensions-dev-server build` |
|
|
27
|
+
| Build a single extension | `hs-ui-extensions-dev-server build --extension MyEntryPointFile.jsx` <br /> `hs-ui-extensions-dev-server build -e MyEntryPointFile.jsx`|
|
package/build.js
CHANGED
|
@@ -1,32 +1,43 @@
|
|
|
1
|
-
/* eslint-disable hubspot-dev/no-async-await */
|
|
2
|
-
/*global module*/
|
|
3
|
-
'use es6';
|
|
4
|
-
|
|
5
1
|
const { build } = require('vite');
|
|
6
2
|
const { ROLLUP_OPTIONS } = require('./constants');
|
|
7
3
|
|
|
8
|
-
async function
|
|
4
|
+
async function buildAllExtensions(config, outputDir) {
|
|
9
5
|
const extensionKeys = Object.keys(config);
|
|
10
|
-
|
|
11
6
|
for (let i = 0; i < extensionKeys.length; ++i) {
|
|
12
7
|
const { data } = config[extensionKeys[i]];
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
rollupOptions: ROLLUP_OPTIONS,
|
|
22
|
-
outDir: outputDir,
|
|
23
|
-
emptyOutDir: i === 0,
|
|
24
|
-
minify: false,
|
|
25
|
-
},
|
|
26
|
-
});
|
|
8
|
+
|
|
9
|
+
await buildSingleExtension(
|
|
10
|
+
data?.module.file,
|
|
11
|
+
data?.output,
|
|
12
|
+
outputDir,
|
|
13
|
+
i === 0
|
|
14
|
+
);
|
|
27
15
|
}
|
|
28
16
|
}
|
|
29
17
|
|
|
18
|
+
async function buildSingleExtension(
|
|
19
|
+
file,
|
|
20
|
+
outputFileName,
|
|
21
|
+
outputDir,
|
|
22
|
+
emptyOutDir = true
|
|
23
|
+
) {
|
|
24
|
+
await build({
|
|
25
|
+
build: {
|
|
26
|
+
lib: {
|
|
27
|
+
entry: file,
|
|
28
|
+
name: outputFileName,
|
|
29
|
+
formats: ['iife'],
|
|
30
|
+
fileName: () => outputFileName,
|
|
31
|
+
},
|
|
32
|
+
rollupOptions: ROLLUP_OPTIONS,
|
|
33
|
+
outDir: outputDir,
|
|
34
|
+
emptyOutDir,
|
|
35
|
+
minify: false,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
module.exports = {
|
|
31
|
-
|
|
41
|
+
buildAllExtensions,
|
|
42
|
+
buildSingleExtension,
|
|
32
43
|
};
|
package/cli.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const logger = require('./logger');
|
|
2
|
+
const commandLineArgs = require('command-line-args');
|
|
3
|
+
const commandLineUsage = require('command-line-usage');
|
|
4
|
+
|
|
5
|
+
function parseArgs() {
|
|
6
|
+
const mainDefinitions = [{ name: 'command', defaultOption: true }];
|
|
7
|
+
const mainOptions = commandLineArgs(mainDefinitions, {
|
|
8
|
+
stopAtFirstUnknown: true,
|
|
9
|
+
});
|
|
10
|
+
const argv = mainOptions._unknown || [];
|
|
11
|
+
const DEV_MODE = mainOptions.command === 'dev';
|
|
12
|
+
const BUILD_MODE = mainOptions.command === 'build';
|
|
13
|
+
|
|
14
|
+
const optionDefinitions = [
|
|
15
|
+
{ name: 'port', alias: 'p', type: Number },
|
|
16
|
+
{ name: 'extension', alias: 'e', type: String },
|
|
17
|
+
{ name: 'help', alias: 'h', type: Boolean },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const options = commandLineArgs(
|
|
21
|
+
optionDefinitions,
|
|
22
|
+
DEV_MODE || BUILD_MODE ? { argv } : {}
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
return { DEV_MODE, BUILD_MODE, ...options };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function showHelp(OUTPUT_DIR) {
|
|
29
|
+
const sections = [
|
|
30
|
+
{
|
|
31
|
+
header: 'HubSpot UI Extensions Local Dev Server',
|
|
32
|
+
content: `Used for local development of HubSpot extensions. Built assets can be found in the ${OUTPUT_DIR} directory`,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
header: 'Available Commands',
|
|
36
|
+
content: [
|
|
37
|
+
{ name: 'dev', summary: 'starts the local development server' },
|
|
38
|
+
{ name: 'build', summary: 'runs a build of your extensions' },
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
header: 'Options',
|
|
43
|
+
optionList: [
|
|
44
|
+
{
|
|
45
|
+
name: 'extension',
|
|
46
|
+
typeLabel: '{underline file}',
|
|
47
|
+
description:
|
|
48
|
+
'The extension entrypoint file build or start local development for',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'help',
|
|
52
|
+
description: 'Print this usage guide.',
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
const usage = commandLineUsage(sections);
|
|
58
|
+
logger.info(usage);
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = {
|
|
63
|
+
parseArgs,
|
|
64
|
+
showHelp,
|
|
65
|
+
};
|
package/config.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
/* eslint-disable hubspot-dev/no-async-await */
|
|
2
|
-
/*global process, module */
|
|
3
|
-
'use es6';
|
|
4
1
|
const prompts = require('prompts');
|
|
5
2
|
const logger = require('./logger');
|
|
6
3
|
const path = require('path');
|
|
7
4
|
const { MAIN_APP_CONFIG, PROJECT_CONFIG } = require('./constants');
|
|
8
5
|
const { getUrlSafeFileName } = require('./utils');
|
|
9
6
|
|
|
10
|
-
async function getExtensionConfig(configuration) {
|
|
11
|
-
if (
|
|
12
|
-
const { data } = configuration[
|
|
7
|
+
async function getExtensionConfig(configuration, extension) {
|
|
8
|
+
if (extension && configuration[extension]) {
|
|
9
|
+
const { data } = configuration[extension];
|
|
13
10
|
return {
|
|
14
|
-
key:
|
|
11
|
+
key: extension,
|
|
15
12
|
name: data.title,
|
|
16
13
|
file: data?.module?.file,
|
|
17
14
|
output: data?.output,
|
|
@@ -82,21 +79,28 @@ function loadConfig() {
|
|
|
82
79
|
}
|
|
83
80
|
|
|
84
81
|
const outputConfig = {};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
|
|
83
|
+
mainAppConfig.extensions.crm.cards.forEach(card => {
|
|
84
|
+
const extensionsRemoved = card.file.replace('extensions/', '');
|
|
85
|
+
const cardPath = path.join(process.cwd(), extensionsRemoved);
|
|
86
|
+
try {
|
|
87
|
+
const cardConfig = require(cardPath);
|
|
89
88
|
const extensionFileName = cardConfig.data?.module?.file;
|
|
90
89
|
outputConfig[extensionFileName] = cardConfig;
|
|
91
90
|
outputConfig[extensionFileName].data.output = getUrlSafeFileName(
|
|
92
91
|
cardConfig.data?.module?.file
|
|
93
92
|
);
|
|
94
93
|
outputConfig[extensionFileName].data.appName = projectConfig.name;
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
} catch (e) {
|
|
95
|
+
let errorMessage = e?.message;
|
|
96
|
+
if (e?.code === 'MODULE_NOT_FOUND') {
|
|
97
|
+
errorMessage = `Unable to load "${cardPath}" file. \nPlease make sure you are running the command from the src/app/extensions directory and that your card JSON config exists within it.`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
logger.error(errorMessage);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
100
104
|
|
|
101
105
|
return outputConfig;
|
|
102
106
|
}
|
package/constants.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
/*global module */
|
|
2
|
-
'use es6';
|
|
3
|
-
|
|
4
1
|
const VITE_DEFAULT_PORT = 5173;
|
|
5
2
|
const MAIN_APP_CONFIG = 'app.json';
|
|
6
3
|
const PROJECT_CONFIG = 'hsproject.json';
|
|
4
|
+
const OUTPUT_DIR = 'dist';
|
|
7
5
|
|
|
8
6
|
const ROLLUP_OPTIONS = {
|
|
9
7
|
// Deps to exclude from the bundle
|
|
@@ -23,4 +21,5 @@ module.exports = {
|
|
|
23
21
|
ROLLUP_OPTIONS,
|
|
24
22
|
MAIN_APP_CONFIG,
|
|
25
23
|
PROJECT_CONFIG,
|
|
24
|
+
OUTPUT_DIR,
|
|
26
25
|
};
|
package/dev.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/* eslint-disable hubspot-dev/no-async-await */
|
|
2
|
-
/*global module, process*/
|
|
3
|
-
'use es6';
|
|
4
1
|
const express = require('express');
|
|
5
2
|
const chokidar = require('chokidar');
|
|
6
3
|
const { WebSocketServer } = require('ws');
|
|
@@ -12,8 +9,8 @@ const fs = require('fs');
|
|
|
12
9
|
const path = require('path');
|
|
13
10
|
const { ROLLUP_OPTIONS } = require('./constants');
|
|
14
11
|
|
|
15
|
-
async function _devBuild(config, outputDir) {
|
|
16
|
-
const extensionConfig = await getExtensionConfig(config);
|
|
12
|
+
async function _devBuild(config, outputDir, extension) {
|
|
13
|
+
const extensionConfig = await getExtensionConfig(config, extension);
|
|
17
14
|
build({
|
|
18
15
|
build: {
|
|
19
16
|
watch: {
|
|
@@ -121,8 +118,8 @@ function _startDevServer(outputDir, port, extensionConfig) {
|
|
|
121
118
|
});
|
|
122
119
|
}
|
|
123
120
|
|
|
124
|
-
async function startDevMode(config, outputDir, port) {
|
|
125
|
-
const extensionConfig = await _devBuild(config, outputDir);
|
|
121
|
+
async function startDevMode(config, outputDir, port, extension) {
|
|
122
|
+
const extensionConfig = await _devBuild(config, outputDir, extension);
|
|
126
123
|
_startDevServer(outputDir, port, extensionConfig);
|
|
127
124
|
}
|
|
128
125
|
|
package/logger.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/ui-extensions-dev-server",
|
|
3
|
-
"version": "0.0.1-prealpha.
|
|
3
|
+
"version": "0.0.1-prealpha.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,9 +9,26 @@
|
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
|
+
"files": [
|
|
13
|
+
"README.md",
|
|
14
|
+
"build.js",
|
|
15
|
+
"cli.js",
|
|
16
|
+
"config.js",
|
|
17
|
+
"constants.js",
|
|
18
|
+
"dev.js",
|
|
19
|
+
"logger.js",
|
|
20
|
+
"remoteBuild.js",
|
|
21
|
+
"run.js",
|
|
22
|
+
"utils.js",
|
|
23
|
+
"tests/runTests.js",
|
|
24
|
+
"tests/testBuild.js",
|
|
25
|
+
"tests/testDevServer.js"
|
|
26
|
+
],
|
|
12
27
|
"license": "MIT",
|
|
13
28
|
"dependencies": {
|
|
14
29
|
"chokidar": "^3.5.3",
|
|
30
|
+
"command-line-args": "^5.2.1",
|
|
31
|
+
"command-line-usage": "^7.0.1",
|
|
15
32
|
"console-log-colors": "^0.4.0",
|
|
16
33
|
"express": "^4.18.2",
|
|
17
34
|
"process": "^0.11.10",
|
|
@@ -20,7 +37,13 @@
|
|
|
20
37
|
"ws": "^8.12.1"
|
|
21
38
|
},
|
|
22
39
|
"bin": {
|
|
23
|
-
"hs-ui-extensions-dev-server": "run.js"
|
|
40
|
+
"hs-ui-extensions-dev-server": "run.js",
|
|
41
|
+
"hs-ui-extensions-remote-build": "remoteBuild.js"
|
|
24
42
|
},
|
|
25
|
-
"
|
|
43
|
+
"eslintConfig": {
|
|
44
|
+
"env": {
|
|
45
|
+
"node": true
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"gitHead": "74dbffa7fe6e4ad7d5029897801c11dc5d5edae1"
|
|
26
49
|
}
|
package/remoteBuild.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { OUTPUT_DIR } = require('./constants');
|
|
3
|
+
const { getUrlSafeFileName } = require('./utils');
|
|
4
|
+
const { buildSingleExtension } = require('./build');
|
|
5
|
+
|
|
6
|
+
// Regular expressions to match files ending in ts, js, tsx, and jsx
|
|
7
|
+
const entryPointRegex = new RegExp(/.*\.(ts|js)[x]?$/);
|
|
8
|
+
|
|
9
|
+
let extension = process.argv[process.argv.length - 1];
|
|
10
|
+
|
|
11
|
+
if (!entryPointRegex.test(extension)) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
'The last argument should be the filename you wish to build. Supported file extensions are [ts, tsx, js, jsx]'
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// The incoming filename may be the full path the the file, so split the string
|
|
18
|
+
// to remove any directory prefix up until the extensions directory
|
|
19
|
+
extension = extension.split('extensions/').pop();
|
|
20
|
+
|
|
21
|
+
buildSingleExtension(extension, getUrlSafeFileName(extension), OUTPUT_DIR);
|
package/run.js
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/* eslint-disable hubspot-dev/no-async-await */
|
|
3
|
-
/*global process*/
|
|
4
|
-
'use es6';
|
|
5
2
|
|
|
6
3
|
const { startDevMode } = require('./dev');
|
|
7
4
|
const { loadConfig } = require('./config');
|
|
8
|
-
const {
|
|
9
|
-
const { VITE_DEFAULT_PORT } = require('./constants');
|
|
5
|
+
const { buildAllExtensions, buildSingleExtension } = require('./build');
|
|
6
|
+
const { VITE_DEFAULT_PORT, OUTPUT_DIR } = require('./constants');
|
|
7
|
+
const { parseArgs, showHelp } = require('./cli');
|
|
8
|
+
const { getUrlSafeFileName } = require('./utils');
|
|
10
9
|
|
|
11
|
-
const DEV_MODE
|
|
12
|
-
const
|
|
13
|
-
const PORT = process.env.PORT || VITE_DEFAULT_PORT;
|
|
10
|
+
const { DEV_MODE, BUILD_MODE, port, extension, help } = parseArgs();
|
|
11
|
+
const PORT = port || VITE_DEFAULT_PORT;
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
if (help || !(DEV_MODE || BUILD_MODE)) {
|
|
14
|
+
showHelp(OUTPUT_DIR);
|
|
15
|
+
}
|
|
16
16
|
|
|
17
17
|
if (DEV_MODE) {
|
|
18
|
-
startDevMode(
|
|
19
|
-
} else {
|
|
20
|
-
|
|
18
|
+
startDevMode(loadConfig(), OUTPUT_DIR, PORT, extension);
|
|
19
|
+
} else if (BUILD_MODE) {
|
|
20
|
+
if (extension) {
|
|
21
|
+
buildSingleExtension(extension, getUrlSafeFileName(extension), OUTPUT_DIR);
|
|
22
|
+
} else {
|
|
23
|
+
buildAllExtensions(loadConfig(), OUTPUT_DIR);
|
|
24
|
+
}
|
|
21
25
|
}
|
package/tests/runTests.js
CHANGED
package/tests/testBuild.js
CHANGED
|
@@ -1,22 +1,15 @@
|
|
|
1
|
-
/*global module, process */
|
|
2
|
-
'use es6';
|
|
3
|
-
|
|
4
1
|
const { execSync } = require('child_process');
|
|
5
2
|
const fs = require('fs');
|
|
6
3
|
const path = require('path');
|
|
7
4
|
const assert = require('assert');
|
|
8
5
|
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
execSync('hs-ui-extensions-dev-server');
|
|
6
|
+
function _testHelper(command, outputDirFiles) {
|
|
7
|
+
execSync(command);
|
|
12
8
|
|
|
13
9
|
// Make sure the files are getting generated in the dist dir
|
|
14
10
|
const distDir = path.join(process.cwd(), 'dist');
|
|
15
11
|
const filesInOutputDir = fs.readdirSync(distDir);
|
|
16
|
-
assert.deepStrictEqual(filesInOutputDir,
|
|
17
|
-
'PhoneLines.js',
|
|
18
|
-
'ProgressBarApp.js',
|
|
19
|
-
]);
|
|
12
|
+
assert.deepStrictEqual(filesInOutputDir, outputDirFiles);
|
|
20
13
|
|
|
21
14
|
// Spot check the file contents to make sure they seem ok
|
|
22
15
|
filesInOutputDir.forEach(file => {
|
|
@@ -35,8 +28,53 @@ function testBuild(logger) {
|
|
|
35
28
|
);
|
|
36
29
|
});
|
|
37
30
|
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function testDefaultBuildPath(logger) {
|
|
34
|
+
logger.warn('- Test default build path started π€');
|
|
35
|
+
_testHelper('hs-ui-extensions-dev-server build', [
|
|
36
|
+
'PhoneLines.js',
|
|
37
|
+
'ProgressBarApp.js',
|
|
38
|
+
]);
|
|
39
|
+
logger.info('- Test default build path passed π');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function testBuildWithExtensionFlag(logger) {
|
|
43
|
+
logger.warn('- Test build with flags started π€');
|
|
44
|
+
_testHelper(
|
|
45
|
+
'hs-ui-extensions-dev-server build --extension ProgressBarApp.tsx',
|
|
46
|
+
['ProgressBarApp.js']
|
|
47
|
+
);
|
|
48
|
+
logger.info('- Test build with flags passed π');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function testDefInfraBuildFileName(logger) {
|
|
52
|
+
logger.warn('- Test build with entrypoint as arg π€');
|
|
53
|
+
_testHelper('hs-ui-extensions-remote-build ProgressBarApp.tsx', [
|
|
54
|
+
'ProgressBarApp.js',
|
|
55
|
+
]);
|
|
56
|
+
logger.info('- Test build with entrypoint as arg π');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function testDevInfraBuildFileNameWithPathPrefix(logger) {
|
|
60
|
+
logger.warn('- Test build with config file as arg π€');
|
|
61
|
+
_testHelper(
|
|
62
|
+
'hs-ui-extensions-remote-build some/super/long/file/path/to/the/extensions/PhoneLines.tsx',
|
|
63
|
+
['PhoneLines.js']
|
|
64
|
+
);
|
|
65
|
+
logger.info('- Test build with config file as arg π');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function testBuild(logger) {
|
|
69
|
+
logger.warn('\nBuild Tests started - External Devs π€');
|
|
70
|
+
testDefaultBuildPath(logger);
|
|
71
|
+
testBuildWithExtensionFlag(logger);
|
|
72
|
+
logger.info('Build Tests passed - External Devsπ');
|
|
38
73
|
|
|
39
|
-
logger.
|
|
74
|
+
logger.warn('\nBuild Tests started - Dev Infra π€');
|
|
75
|
+
testDefInfraBuildFileName(logger);
|
|
76
|
+
testDevInfraBuildFileNameWithPathPrefix(logger);
|
|
77
|
+
logger.info('Build Tests passed - Dev Infra π');
|
|
40
78
|
}
|
|
41
79
|
|
|
42
80
|
module.exports = {
|
package/tests/testDevServer.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/*global module, process */
|
|
2
|
-
'use es6';
|
|
3
|
-
|
|
4
1
|
const { spawn } = require('child_process');
|
|
5
2
|
const fs = require('fs');
|
|
6
3
|
const path = require('path');
|
|
@@ -14,24 +11,32 @@ const testResults = {
|
|
|
14
11
|
webSocketTestPassed: false,
|
|
15
12
|
};
|
|
16
13
|
|
|
14
|
+
const port = 5172;
|
|
15
|
+
|
|
17
16
|
function testDevServer(logger, devServerProcess) {
|
|
18
|
-
logger.
|
|
17
|
+
logger.warn('\nDev Server Tests started π€');
|
|
19
18
|
|
|
20
19
|
// We need to use spawn here because it will put the process into the background,
|
|
21
20
|
// which is required because dev mode is a blocking process and we want to test that
|
|
22
21
|
// the express server and websocket server are starting properly
|
|
23
|
-
devServerProcess = spawn('hs-ui-extensions-dev-server',
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
devServerProcess = spawn('hs-ui-extensions-dev-server', [
|
|
23
|
+
'dev',
|
|
24
|
+
'--extension',
|
|
25
|
+
'PhoneLines.tsx',
|
|
26
|
+
'--port',
|
|
27
|
+
`${port}`,
|
|
28
|
+
]);
|
|
26
29
|
|
|
27
30
|
devServerProcess.stdout.on('data', buffer => {
|
|
28
31
|
const data = buffer.toString().toLowerCase();
|
|
29
32
|
if (data.includes('built in')) {
|
|
30
|
-
testBuild(testResults);
|
|
33
|
+
testBuild(testResults, logger);
|
|
31
34
|
}
|
|
32
|
-
if (data.includes('listening') && data.includes(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
if (data.includes('listening') && data.includes(`localhost:${port}`)) {
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
testExpressServer(testResults, logger);
|
|
38
|
+
testWebSocketServer(testResults, logger);
|
|
39
|
+
}, 1000);
|
|
35
40
|
}
|
|
36
41
|
});
|
|
37
42
|
|
|
@@ -74,7 +79,7 @@ function metConditions() {
|
|
|
74
79
|
|
|
75
80
|
// Test that the files were built in the proper location and spot
|
|
76
81
|
// check the contents of the files.
|
|
77
|
-
function testBuild(results) {
|
|
82
|
+
function testBuild(results, logger) {
|
|
78
83
|
// // Make sure the files are getting generated in the dist dir
|
|
79
84
|
const distDir = path.join(process.cwd(), 'dist');
|
|
80
85
|
const filesInOutputDir = fs.readdirSync(distDir);
|
|
@@ -95,41 +100,44 @@ function testBuild(results) {
|
|
|
95
100
|
`File ${filesInOutputDir[0]} contents should contain: "${stringToCheck}"`
|
|
96
101
|
);
|
|
97
102
|
});
|
|
103
|
+
logger.info('- Build succeeded π');
|
|
98
104
|
results.buildTestPassed = true;
|
|
99
105
|
}
|
|
100
106
|
|
|
101
107
|
// Test that the express server is running on the expected port
|
|
102
108
|
// and that it is serving the files as expected.
|
|
103
|
-
function testExpressServer(results) {
|
|
109
|
+
function testExpressServer(results, logger) {
|
|
104
110
|
http.get(
|
|
105
111
|
{
|
|
106
112
|
host: 'localhost',
|
|
107
|
-
port
|
|
113
|
+
port,
|
|
108
114
|
path: '/PhoneLines.js',
|
|
109
115
|
},
|
|
110
116
|
response => {
|
|
111
117
|
if (response.statusCode !== 200) {
|
|
112
118
|
throw Error('Error with express server');
|
|
113
119
|
}
|
|
120
|
+
logger.info('- Express server connected and serving files π');
|
|
114
121
|
results.expressTestPassed = true;
|
|
115
122
|
}
|
|
116
123
|
);
|
|
117
124
|
}
|
|
118
125
|
|
|
119
126
|
// Test the the web socket server is running on the expected port and
|
|
120
|
-
// that we are able to
|
|
121
|
-
function testWebSocketServer(results) {
|
|
127
|
+
// that we are able to receive messages from it.
|
|
128
|
+
function testWebSocketServer(results, logger) {
|
|
122
129
|
const fileContents = fs
|
|
123
130
|
.readFileSync(path.join('dist', 'PhoneLines.js'))
|
|
124
131
|
.toString('base64');
|
|
125
132
|
|
|
126
|
-
const ws = new WebSocket(
|
|
133
|
+
const ws = new WebSocket(`ws://localhost:${port}`);
|
|
127
134
|
ws.on('message', messageBuffer => {
|
|
128
135
|
const message = JSON.parse(messageBuffer.toString());
|
|
129
136
|
assert(message.event === 'start' || message.event === 'update');
|
|
130
137
|
assert(message.appName === 'example-app');
|
|
131
138
|
assert.strictEqual(message.extension, 'Phone Lines');
|
|
132
139
|
assert(message.callback, `data:text/javascript;base64,${fileContents}`);
|
|
140
|
+
logger.info('- WebSocket server connected and sending messages π');
|
|
133
141
|
results.webSocketTestPassed = true;
|
|
134
142
|
});
|
|
135
143
|
}
|