Skip to content

Commit

Permalink
add CI integration for karma/jasmine test harness for React components
Browse files Browse the repository at this point in the history
  • Loading branch information
jkafader-esnet committed Nov 5, 2024
1 parent cc4368f commit 64f8a8c
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ playwright*
test-results
tests-examples

# webpack test junk
test/dist/*

# autogenerated by Makefile for e2e
e2e/grafana-docker.json

Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ test\:component:
@echo "Starting component tests..."
yarn test
yarn test:react
yarn test:react-karma

.PHONY: test\:e2e
test\:e2e: compose
Expand Down Expand Up @@ -102,4 +103,4 @@ publish: check_version prod testignore confirm push
clean:
@rm -rf ${PROJECT_DIR}.config/env
@if test "$(strip $(INSTANCES))" = ""; then echo "No instances to cleanup."; else docker rm -v -f $(INSTANCES); fi
@if test "$(strip $(NETWORKS))" = ""; then echo "No network $(NETWORK_NAME) found to remove."; else docker network rm $(NETWORKS); fi
@if test "$(strip $(NETWORKS))" = ""; then echo "No network $(NETWORK_NAME) found to remove."; else docker network rm $(NETWORKS); fi
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { grafanaESModules, nodeModulesToTransform } = require('./.config/jest/uti
const baseConfig = require('./.config/jest.config');
const { testMatch } = baseConfig;

testMatch.push('<rootDir>/test/react/**/*.{js,jsx,ts,tsx}');
testMatch.push('<rootDir>/test/react/CustomTextArea.spec.tsx');

/** @type {import('ts-jest').JestConfigWithTsJest} **/
module.exports = {
Expand Down
130 changes: 130 additions & 0 deletions karma.webpack.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
const Path = require( "path" );
const os = require("os");
var webpack = require('webpack');

console.log("resolved dirname")
console.log(Path.resolve(__dirname, './.config/webpack/webpack.config.ts'));

module.exports = function( config ) {
config.set( {
frameworks: [
"jasmine",
"webpack",
],
client: {
jasmine: {
random: false
}
},
files: ['test/react/webpack.tests.js'],
preprocessors: {
"test/react/webpack.tests.js": ["webpack", "sourcemap"],
},
webpack: {
mode: "development",
devtool: 'inline-source-map', // sourcemap support
output: {
filename: '[name].js',
path: Path.join(__dirname, 'test/dist/_karma_webpack_') + Math.floor(Math.random() * 1000000),
},
externals: [
'emotion',
'@emotion/react',
'@emotion/css',
'@grafana/runtime',
'@grafana/slate-react',
'react-redux',
'redux',
'react-router',
'react-router-dom',
'd3',
'slate',
'slate-plain-serializer',
'prismjs',
'@grafana/ui',
'jquery',
'moment',
'lodash',
'rxjs',
'angular',
],
module: {
rules: [
{
test: /src\/(?:.*\/)?module\.tsx?$/,
use: [
{
loader: 'imports-loader',
options: {
imports: `side-effects grafana-public-path`,
},
},
],
},
{
exclude: /(node_modules)/,
test: /\.[tj]sx?$/,
use: {
loader: 'swc-loader',
options: {
jsc: {
baseUrl: Path.resolve(process.cwd(), "./src"),
target: 'es2015',
loose: false,
parser: {
syntax: 'typescript',
tsx: true,
decorators: false,
dynamicImport: true,
},
},
},
},
},
],
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
// handle resolving "rootDir" paths
modules: [Path.resolve(process.cwd(), 'src'), 'node_modules'],
fallback: {
"fs": false,
"util": false,
"stream": false,
"tty": require.resolve("tty-browserify"),
}
},
stats: {
modules: false,
colors: true,
},
watch: false,
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
minSize: 0,
cacheGroups: {
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 1,
},
},
},
}
},
client: {
captureConsole: true,
},
reporters: ['dots'],
exclude: [
"src/components/lib/leaflet.js",
"src/components/old/*"
],
browsers: ["ChromeHeadless"],
singleRun: true,
webpackMiddleware: { noInfo: true },
browserNoActivityTimeout: 60000 // 60s; wait for webpack to compile :-(
} );
};
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"start": "yarn watch",
"test": "karma start --single-run --browsers ChromeHeadless",
"test:react": "jest --coverage",
"test:react-karma": "karma start --single-run --browsers Chrome karma.webpack.conf.js",
"test:ci": "karma start --single-run --browsers ChromeHeadless",
"typecheck": "tsc --noEmit"
},
Expand Down Expand Up @@ -64,6 +65,8 @@
"karma": "^6.4.0",
"karma-chrome-launcher": "^3.1.1",
"karma-jasmine": "^5.1.0",
"karma-sourcemap-loader": "^0.4.0",
"karma-webpack": "^5.0.1",
"prettier": "^2.8.7",
"replace-in-file-webpack-plugin": "^1.0.6",
"sass": "1.63.2",
Expand All @@ -75,6 +78,7 @@
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"tty-browserify": "^0.0.1",
"typescript": "5.5.4",
"webpack": "^5.94.0",
"webpack-cli": "^5.1.4",
Expand Down
16 changes: 9 additions & 7 deletions src/components/CustomTextArea.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react';

import { StandardEditorProps, StringFieldConfigSettings } from '@grafana/data';
import { TextArea } from '@grafana/ui';
import { monospacedFontSize } from '../options';

interface CustomTextAreaSettings extends StringFieldConfigSettings {
Expand Down Expand Up @@ -143,17 +142,20 @@ export const CustomTextArea: React.FC<Props> = ({ value, onChange, item, suffix
setCurrentEditorValue(value);
}, [value])

const attribs = {};
let attribs = {
style: {
width: "100%",
resize: "none",
}
} as any;
if (item.settings?.isMonospaced) {
attribs['style'] = {
fontFamily: "monospace",
fontSize: item.settings?.fontSize || monospacedFontSize
};
attribs.style.fontFamily = "monospace";
attribs.style.fontSize = item.settings?.fontSize || monospacedFontSize;
}

return (
<div>
<TextArea
<textarea
{...attribs}
placeholder={item.settings?.placeholder}
defaultValue={currentEditorValue || ''}
Expand Down
4 changes: 3 additions & 1 deletion src/exports.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { MapCanvas } from './components/MapCanvas.component.js';
import { PubSub } from './components/lib/pubsub.js';
import { signals } from './signals.js';
import { CustomTextArea } from './components/CustomTextArea';

export { MapCanvas };
export { PubSub };
export { signals };
export { signals };
export { CustomTextArea };
1 change: 1 addition & 0 deletions test/dist/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This folder will be used to store webpack build files for tests. Committed this readme to ensure it is created.
1 change: 1 addition & 0 deletions test/react/CustomTextArea.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("loaded the customTextArea test");
2 changes: 0 additions & 2 deletions test/react/CustomTextArea.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import '@testing-library/dom';
import { CustomTextArea, CustomTextAreaSettings } from '../../src/components/CustomTextArea';
import { StandardEditorsRegistryItem } from '@grafana/data';

import renderer from 'react-test-renderer';

const mockItem: StandardEditorsRegistryItem<string, CustomTextAreaSettings> = {
editor: CustomTextArea,
id: 'some-mock-id',
Expand Down
25 changes: 25 additions & 0 deletions test/react/webpack.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// low-key polyfill for process
window.process = {
env: { DEBUG: true },
stderr: { fd: 1 },
}

const { MapCanvas, PubSub, signals, CustomTextArea } = require("../../src/exports.ts");

const React = require("react");

const ReactDOM = require("react-dom/client");

const rootElem = document.createElement("div");

document.body.appendChild(rootElem);

const root = ReactDOM.createRoot(rootElem);

const props = {
item: { settings: { useTextArea: true } }
};

root.render(React.createElement(CustomTextArea, props));

console.log(document.getElementsByTagName("textarea"))

0 comments on commit 64f8a8c

Please sign in to comment.