diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
new file mode 100644
index 00000000..676df60f
--- /dev/null
+++ b/.github/workflows/build-and-test.yml
@@ -0,0 +1,101 @@
+name: Build & test
+on:
+ push:
+ branches:
+ - "*"
+ pull_request:
+ branches:
+ - "*"
+env:
+ OPENSEARCH_DASHBOARDS_VERSION: 'main'
+
+jobs:
+ Get-CI-Image-Tag:
+ uses: opensearch-project/opensearch-build/.github/workflows/get-ci-image-tag.yml@main
+ with:
+ product: opensearch-dashboards
+
+ build-and-test-linux:
+ needs: Get-CI-Image-Tag
+ name: Build & test
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ runs-on: ${{ matrix.os }}
+ container:
+ image: ${{ needs.Get-CI-Image-Tag.outputs.ci-image-version-linux }}
+ options: --user root
+
+ steps:
+ - name: Checkout OpenSearch Dashboards
+ uses: actions/checkout@v2
+ with:
+ repository: opensearch-project/OpenSearch-Dashboards
+ ref: ${{ env.OPENSEARCH_DASHBOARDS_VERSION }}
+ path: OpenSearch-Dashboards
+ - name: Checkout plugin
+ uses: actions/checkout@v2
+ with:
+ path: OpenSearch-Dashboards/plugins/dashboards-flow-framework
+ - name: Bootstrap / build / unit test the plugin
+ run: |
+ chown -R 1000:1000 `pwd`
+ cd ./OpenSearch-Dashboards/
+ su `id -un 1000` -c "source $NVM_DIR/nvm.sh && nvm use && node -v && yarn -v &&
+ cd ./plugins/dashboards-flow-framework &&
+ whoami && yarn osd bootstrap && yarn build && yarn run test:jest --coverage"
+ - name: Uploads coverage
+ uses: codecov/codecov-action@v1
+
+ # TODO: once github actions supports windows and macos docker containers, we can
+ # merge these in to the above step's matrix, including adding windows support
+ build-and-test-windows-macos:
+ name: Build & test
+ strategy:
+ matrix:
+ os: [macos-latest]
+ runs-on: ${{ matrix.os }}
+ steps:
+ # Enable longer filenames for windows
+ - name: Enable longer filenames
+ if: ${{ matrix.os == 'windows-latest' }}
+ run: git config --system core.longpaths true
+ - name: Checkout OpenSearch Dashboards
+ uses: actions/checkout@v2
+ with:
+ repository: opensearch-project/OpenSearch-Dashboards
+ ref: ${{ env.OPENSEARCH_DASHBOARDS_VERSION }}
+ path: OpenSearch-Dashboards
+ - name: Setup Node
+ uses: actions/setup-node@v3
+ with:
+ node-version-file: './OpenSearch-Dashboards/.nvmrc'
+ registry-url: 'https://registry.npmjs.org'
+ - name: Install Yarn
+ # Need to use bash to avoid having a windows/linux specific step
+ shell: bash
+ run: |
+ YARN_VERSION=$(node -p "require('./OpenSearch-Dashboards/package.json').engines.yarn")
+ echo "Installing yarn@$YARN_VERSION"
+ npm i -g yarn@$YARN_VERSION
+ - run: node -v
+ - run: yarn -v
+ - name: Checkout plugin
+ uses: actions/checkout@v2
+ with:
+ path: OpenSearch-Dashboards/plugins/dashboards-flow-framework
+ - name: Bootstrap the plugin
+ run: |
+ cd OpenSearch-Dashboards/plugins/dashboards-flow-framework
+ yarn osd bootstrap
+ - name: Build the plugin
+ run: |
+ cd OpenSearch-Dashboards/plugins/dashboards-flow-framework
+ yarn build
+ - name: Run unit tests
+ run: |
+ cd OpenSearch-Dashboards/plugins/dashboards-flow-framework
+ yarn run test:jest --coverage
+ - name: Uploads coverage
+ uses: codecov/codecov-action@v1
+
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 00000000..12a3f644
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+module.exports = {
+ presets: [
+ require('@babel/preset-env'),
+ require('@babel/preset-react'),
+ require('@babel/preset-typescript'),
+ ],
+ plugins: [
+ ['@babel/plugin-transform-modules-commonjs', { allowTopLevelThis: true }],
+ [require('@babel/plugin-transform-runtime'), { regenerator: true }],
+ ],
+};
diff --git a/opensearch_dashboards.json b/opensearch_dashboards.json
index e2eb655f..746a629a 100644
--- a/opensearch_dashboards.json
+++ b/opensearch_dashboards.json
@@ -4,9 +4,7 @@
"opensearchDashboardsVersion": "3.0.0",
"server": true,
"ui": true,
- "requiredBundles": [
- "opensearchDashboardsUtils"
- ],
+ "requiredBundles": [],
"requiredPlugins": [
"navigation"
],
diff --git a/package.json b/package.json
index f93c17e8..2b098fe8 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"opensearch": "../../scripts/use_node ../../scripts/opensearch",
"lint:es": "../../scripts/use_node ../../scripts/eslint -c eslintrc.json",
"lint:es:precommit": "yarn lint:es common/* public/* server/*",
+ "test:jest": "../../node_modules/.bin/jest --config ./test/jest.config.js",
"build": "yarn plugin-helpers build && echo Renaming artifact to $npm_package_config_plugin_zip_name-$npm_package_config_plugin_version.zip && mv ./build/$npm_package_config_plugin_name*.zip ./build/$npm_package_config_plugin_zip_name-$npm_package_config_plugin_version.zip"
},
"repository": {
diff --git a/public/pages/workflows/workflows.test.tsx b/public/pages/workflows/workflows.test.tsx
new file mode 100644
index 00000000..3c12244c
--- /dev/null
+++ b/public/pages/workflows/workflows.test.tsx
@@ -0,0 +1,46 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { render } from '@testing-library/react';
+import { Provider } from 'react-redux';
+
+import {
+ BrowserRouter as Router,
+ RouteComponentProps,
+ Route,
+ Switch,
+} from 'react-router-dom';
+import { store } from '../../store';
+import { Workflows } from './workflows';
+
+jest.mock('../../services', () => {
+ const { mockCoreServices } = require('../../../test');
+ return {
+ ...jest.requireActual('../../services'),
+ ...mockCoreServices,
+ };
+});
+
+const renderWithRouter = () => ({
+ ...render(
+
+
+
+ }
+ />
+
+
+
+ ),
+});
+
+describe('Workflows', () => {
+ test('renders the page', () => {
+ const { getByText } = renderWithRouter();
+ expect(getByText('Workflows')).not.toBeNull();
+ });
+});
diff --git a/test/index.ts b/test/index.ts
new file mode 100644
index 00000000..af422a51
--- /dev/null
+++ b/test/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export * from './mocks';
diff --git a/test/jest.config.js b/test/jest.config.js
new file mode 100644
index 00000000..91b0e142
--- /dev/null
+++ b/test/jest.config.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+module.exports = {
+ rootDir: '../',
+ roots: [''],
+ coverageDirectory: './coverage',
+ // we mock any style-related files and return an empty module. This is needed due to errors
+ // when jest tries to interpret these types of files.
+ moduleNameMapper: {
+ '\\.(css|less|scss|sass)$': '/test/mocks/style_mock.ts',
+ },
+ testEnvironment: 'jest-environment-jsdom',
+ coverageReporters: ['lcov', 'text', 'cobertura'],
+ testMatch: ['**/*.test.js', '**/*.test.jsx', '**/*.test.ts', '**/*.test.tsx'],
+ collectCoverageFrom: [
+ '**/*.ts',
+ '**/*.tsx',
+ '**/*.js',
+ '**/*.jsx',
+ '!**/models/**',
+ '!**/node_modules/**',
+ '!**/index.js',
+ '!/public/app.js',
+ '!/index.js',
+ '!/babel.config.js',
+ '!/test/**',
+ '!/server/**',
+ '!/coverage/**',
+ '!/scripts/**',
+ '!/build/**',
+ '!**/vendor/**',
+ ],
+ clearMocks: true,
+ modulePathIgnorePatterns: ['/offline-module-cache/'],
+ testPathIgnorePatterns: ['/build/', '/node_modules/'],
+ transformIgnorePatterns: ['/node_modules'],
+};
diff --git a/test/mocks/index.ts b/test/mocks/index.ts
new file mode 100644
index 00000000..bd15bcca
--- /dev/null
+++ b/test/mocks/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { mockCoreServices } from './mock_core_services';
diff --git a/test/mocks/mock_core_services.ts b/test/mocks/mock_core_services.ts
new file mode 100644
index 00000000..40b86e08
--- /dev/null
+++ b/test/mocks/mock_core_services.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const mockCoreServices = {
+ getCore: () => {
+ return {
+ chrome: {
+ setBreadcrumbs: jest.fn(),
+ },
+ };
+ },
+ getNotifications: () => {
+ return {
+ toasts: {
+ addDanger: jest.fn().mockName('addDanger'),
+ addSuccess: jest.fn().mockName('addSuccess'),
+ },
+ };
+ },
+};
diff --git a/test/mocks/style_mock.ts b/test/mocks/style_mock.ts
new file mode 100644
index 00000000..acbbabcc
--- /dev/null
+++ b/test/mocks/style_mock.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export default {};
diff --git a/tsconfig.json b/tsconfig.json
index a598d0f4..688020fb 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -54,6 +54,7 @@
"public/**/*.ts",
"public/**/*.tsx",
"server/**/*.ts",
+ "test/**/*",
"../../typings/**/*"
],
"exclude": ["node_modules", "*/node_modules/"]