[Search Sessions] Search session example app functional test (#92133)

This commit is contained in:
Anton Dosov 2021-03-15 14:47:14 +01:00 committed by GitHub
parent c062b04691
commit bd9170f7dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 196 additions and 42 deletions

View file

@ -247,6 +247,12 @@ export const SearchSessionsExampleApp = ({
<EuiSpacer />
</>
)}
{!indexPattern && (
<>
<NoIndexPatternsCallout />
<EuiSpacer />
</>
)}
<EuiText>
<p>
This example shows how you can use <EuiCode>data.search.session</EuiCode> service to
@ -332,7 +338,8 @@ export const SearchSessionsExampleApp = ({
size="xs"
onClick={() => search()}
iconType="play"
disabled={isSearching}
disabled={isSearching || !indexPattern || !numericFieldName}
data-test-subj={'startSearch'}
>
Start the search from low-level client (data.search.search)
</EuiButtonEmpty>
@ -401,6 +408,7 @@ export const SearchSessionsExampleApp = ({
onClick={() => {
search(data.search.session.getSessionId());
}}
data-test-subj={'restoreSearch'}
>
Restore the search session
</EuiButtonEmpty>
@ -493,7 +501,7 @@ function SearchInspector({
tookMs: number | null;
}) {
return (
<div>
<div data-test-subj={`searchResults-${accordionId}`}>
The search took: {tookMs ? Math.round(tookMs) : 'unknown'}ms
<EuiAccordion id={accordionId} buttonContent="Request / response">
<EuiFlexGroup>
@ -582,11 +590,24 @@ function useAppState({ data }: { data: DataPublicPluginStart }) {
useEffect(() => {
let canceled = false;
const loadIndexPattern = async () => {
const loadedIndexPattern = state.indexPatternId
// eslint-disable-next-line no-console
console.warn('Loading default index pattern');
let loadedIndexPattern = state.indexPatternId
? await data.indexPatterns.get(state.indexPatternId)
: await data.indexPatterns.getDefault();
if (!loadedIndexPattern) {
// try to find any available index pattern
const [id] = await data.indexPatterns.getIds(true);
if (id) {
loadedIndexPattern = await data.indexPatterns.get(id);
}
}
if (canceled) return;
if (!loadedIndexPattern) return;
if (!loadedIndexPattern) {
// eslint-disable-next-line no-console
console.warn('No index patterns to pick from');
return;
}
if (!state.indexPatternId) {
setState({
indexPatternId: loadedIndexPattern.id,
@ -766,3 +787,11 @@ function NoShardDelayCallout() {
</EuiCallOut>
);
}
function NoIndexPatternsCallout() {
return (
<EuiCallOut title={<>Missing index patterns!</>} color="warning" iconType="help">
<p>This demo requires at least one index pattern.</p>
</EuiCallOut>
);
}

View file

@ -21,6 +21,7 @@ require('@babel/register')({
Path.resolve(REPO_ROOT, 'x-pack/examples'),
// TODO: should should probably remove this link back to the source
Path.resolve(REPO_ROOT, 'x-pack/plugins/task_manager/server/config.ts'),
Path.resolve(REPO_ROOT, 'src/core/utils/default_app_categories.ts'),
],
babelrc: false,
presets: [require.resolve('@kbn/babel-preset/node_preset')],

View file

@ -14,6 +14,7 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid
const PageObjects = getPageObjects(['common', 'header']);
describe('bfetch explorer', function () {
this.tags('ciGroup2');
before(async () => {
await browser.setWindowSize(1300, 900);
await PageObjects.common.navigateToApp('bfetch-explorer', { insertTimestamp: false });

View file

@ -6,12 +6,20 @@
* Side Public License, v 1.
*/
import path from 'path';
import path, { resolve } from 'path';
import { services } from '../plugin_functional/services';
import fs from 'fs';
import { KIBANA_ROOT } from '@kbn/test';
export default async function ({ readConfigFile }) {
const functionalConfig = await readConfigFile(require.resolve('../functional/config'));
// Find all folders in /examples and /x-pack/examples since we treat all them as plugin folder
const examplesFiles = fs.readdirSync(resolve(KIBANA_ROOT, 'examples'));
const examples = examplesFiles.filter((file) =>
fs.statSync(resolve(KIBANA_ROOT, 'examples', file)).isDirectory()
);
return {
testFiles: [
require.resolve('./embeddables'),
@ -50,9 +58,11 @@ export default async function ({ readConfigFile }) {
...functionalConfig.get('kbnTestServer'),
serverArgs: [
...functionalConfig.get('kbnTestServer.serverArgs'),
'--run-examples',
// Required to run examples
// Required to load new platform plugins via `--plugin-path` flag.
'--env.name=development',
...examples.map(
(exampleDir) => `--plugin-path=${resolve(KIBANA_ROOT, 'examples', exampleDir)}`
),
],
},
};

View file

@ -18,6 +18,7 @@ export default function ({
const PageObjects = getPageObjects(['common', 'header']);
describe('embeddable explorer', function () {
this.tags('ciGroup2');
before(async () => {
await browser.setWindowSize(1300, 900);
await PageObjects.common.navigateToApp('embeddableExplorer');

View file

@ -18,6 +18,7 @@ export default function ({
const PageObjects = getPageObjects(['common', 'header']);
describe('expressions explorer', function () {
this.tags('ciGroup2');
before(async () => {
await browser.setWindowSize(1300, 900);
await PageObjects.common.navigateToApp('expressionsExplorer');

View file

@ -17,6 +17,7 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid
describe('routing examples', function () {
before(async () => {
this.tags('ciGroup2');
await PageObjects.common.navigateToApp('routingExample');
});

View file

@ -17,6 +17,7 @@ export default function ({
const browser = getService('browser');
describe('state sync examples', function () {
this.tags('ciGroup2');
before(async () => {
await browser.setWindowSize(1300, 900);
});

View file

@ -18,6 +18,7 @@ export default function ({
const PageObjects = getPageObjects(['common', 'header']);
describe('ui actions explorer', function () {
this.tags('ciGroup2');
before(async () => {
await browser.setWindowSize(1300, 900);
await PageObjects.common.navigateToApp('uiActionsExplorer');

View file

@ -8,5 +8,6 @@ node scripts/build_kibana_platform_plugins \
--scan-dir "$KIBANA_DIR/test/plugin_functional/plugins" \
--scan-dir "$KIBANA_DIR/test/interpreter_functional/plugins" \
--scan-dir "$KIBANA_DIR/test/common/fixtures/plugins" \
--scan-dir "$KIBANA_DIR/examples" \
--workers 6 \
--verbose

View file

@ -14,7 +14,6 @@ if [[ -z "$CODE_COVERAGE" ]]; then
if [[ ! "$TASK_QUEUE_PROCESS_ID" && "$CI_GROUP" == "1" ]]; then
source test/scripts/jenkins_build_kbn_sample_panel_action.sh
./test/scripts/test/plugin_functional.sh
./test/scripts/test/example_functional.sh
./test/scripts/test/interpreter_functional.sh
fi
else

View file

@ -11,5 +11,4 @@ cd -;
pwd
./test/scripts/test/plugin_functional.sh
./test/scripts/test/example_functional.sh
./test/scripts/test/interpreter_functional.sh

View file

@ -13,5 +13,7 @@ node scripts/build_kibana_platform_plugins \
--scan-dir "$XPACK_DIR/test/plugin_api_perf/plugins" \
--scan-dir "$XPACK_DIR/test/licensing_plugin/plugins" \
--scan-dir "$XPACK_DIR/test/usage_collection/plugins" \
--scan-dir "$KIBANA_DIR/examples" \
--scan-dir "$XPACK_DIR/examples" \
--workers 12 \
--verbose

View file

@ -1,9 +0,0 @@
#!/usr/bin/env bash
source test/scripts/jenkins_test_setup_oss.sh
checks-reporter-with-killswitch "Example Functional Tests" \
node scripts/functional_tests \
--config test/examples/config.js \
--bail \
--debug

View file

@ -7,16 +7,19 @@
import { Plugin, CoreSetup } from 'kibana/server';
import { i18n } from '@kbn/i18n';
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server';
// import directly to support examples functional tests (@kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.js)
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils/default_app_categories';
import { PluginSetupContract as AlertingSetup } from '../../../plugins/alerting/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../../plugins/features/server';
import { alertType as alwaysFiringAlert } from './alert_types/always_firing';
import { alertType as peopleInSpaceAlert } from './alert_types/astros';
import { INDEX_THRESHOLD_ID } from '../../../plugins/stack_alerts/server';
// can't import static code from another plugin to support examples functional test
const INDEX_THRESHOLD_ID = '.index-threshold';
import { ALERTING_EXAMPLE_APP_ID } from '../common/constants';
// this plugin's dependendencies
// this plugin's dependencies
export interface AlertingExampleDeps {
alerting: AlertingSetup;
features: FeaturesPluginSetup;

View file

@ -76,6 +76,7 @@ const onlyNotInCoverageTests = [
require.resolve('../test/send_search_to_background_integration/config.ts'),
require.resolve('../test/saved_object_tagging/api_integration/security_and_spaces/config.ts'),
require.resolve('../test/saved_object_tagging/api_integration/tagging_api/config.ts'),
require.resolve('../test/examples/config.ts'),
];
require('../../src/setup_node_env');

View file

@ -0,0 +1,53 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
import { resolve } from 'path';
import fs from 'fs';
import { KIBANA_ROOT } from '@kbn/test';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const xpackFunctionalConfig = await readConfigFile(require.resolve('../functional/config'));
// Find all folders in /examples and /x-pack/examples since we treat all them as plugin folder
const examplesFiles = fs.readdirSync(resolve(KIBANA_ROOT, 'examples'));
const examples = examplesFiles.filter((file) =>
fs.statSync(resolve(KIBANA_ROOT, 'examples', file)).isDirectory()
);
const xpackExamplesFiles = fs.readdirSync(resolve(KIBANA_ROOT, 'x-pack/examples'));
const xpackExamples = xpackExamplesFiles.filter((file) =>
fs.statSync(resolve(KIBANA_ROOT, 'x-pack/examples', file)).isDirectory()
);
return {
// default to the xpack functional config
...xpackFunctionalConfig.getAll(),
junit: {
reportName: 'X-Pack Example plugin functional tests',
},
testFiles: [require.resolve('./search_examples')],
kbnTestServer: {
...xpackFunctionalConfig.get('kbnTestServer'),
serverArgs: [
...xpackFunctionalConfig.get('kbnTestServer.serverArgs'),
// Required to load new platform plugins via `--plugin-path` flag.
'--env.name=development',
...examples.map(
(exampleDir) => `--plugin-path=${resolve(KIBANA_ROOT, 'examples', exampleDir)}`
),
...xpackExamples.map(
(exampleDir) => `--plugin-path=${resolve(KIBANA_ROOT, 'x-pack/examples', exampleDir)}`
),
],
},
};
}

View file

@ -0,0 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { PluginFunctionalProviderContext } from 'test/plugin_functional/services';
// eslint-disable-next-line import/no-default-export
export default function ({ getService, loadTestFile }: PluginFunctionalProviderContext) {
const esArchiver = getService('esArchiver');
describe('search examples', function () {
this.tags('ciGroup13');
before(async () => {
await esArchiver.emptyKibanaIndex();
await esArchiver.loadIfNeeded('logstash_functional');
await esArchiver.loadIfNeeded('lens/basic'); // need at least one index pattern
});
after(async () => {
await esArchiver.unload('lens/basic');
});
loadTestFile(require.resolve('./search_session_example'));
});
}

View file

@ -0,0 +1,47 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { FtrProviderContext } from '../../functional/ftr_provider_context';
// eslint-disable-next-line import/no-default-export
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['common']);
const log = getService('log');
const es = getService('es');
const searchSessions = getService('searchSessions');
describe('Search session example', () => {
const appId = 'searchExamples';
before(async function () {
const { body } = await es.info();
if (!body.version.number.includes('SNAPSHOT')) {
log.debug('Skipping because this build does not have the required shard_delay agg');
this.skip();
return;
}
await PageObjects.common.navigateToApp(appId, { insertTimestamp: false });
await testSubjects.click('/search-sessions');
});
after(async () => {
await searchSessions.deleteAllSearchSessions();
});
it('should start search, save session, restore session using "restore" button', async () => {
await testSubjects.clickWhenNotDisabled('startSearch');
await testSubjects.find('searchResults-1');
await searchSessions.expectState('completed');
await searchSessions.save();
await searchSessions.expectState('backgroundCompleted');
await testSubjects.click('restoreSearch');
await testSubjects.find('searchResults-2');
});
});
}

View file

@ -58,6 +58,7 @@ import {
DashboardDrilldownsManageProvider,
DashboardPanelTimeRangeProvider,
} from './dashboard';
import { SearchSessionsProvider } from './search_sessions';
// define the name and providers for services that should be
// available to your tests. If you don't specify anything here
@ -106,4 +107,5 @@ export const services = {
dashboardDrilldownPanelActions: DashboardDrilldownPanelActionsProvider,
dashboardDrilldownsManage: DashboardDrilldownsManageProvider,
dashboardPanelTimeRange: DashboardPanelTimeRangeProvider,
searchSessions: SearchSessionsProvider,
};

View file

@ -7,8 +7,7 @@
import { resolve } from 'path';
import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
import { services as functionalServices } from '../functional/services';
import { services } from './services';
import { services } from '../functional/services';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const xpackFunctionalConfig = await readConfigFile(require.resolve('../functional/config'));
@ -35,9 +34,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
'--xpack.data_enhanced.search.sessions.enabled=true', // enable WIP send to background UI
],
},
services: {
...functionalServices,
...services,
},
services,
};
}

View file

@ -7,6 +7,6 @@
import { GenericFtrProviderContext } from '@kbn/test/types/ftr';
import { pageObjects } from '../functional/page_objects';
import { services } from './services';
import { services } from '../functional/services';
export type FtrProviderContext = GenericFtrProviderContext<typeof services, typeof pageObjects>;

View file

@ -1,14 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { services as functionalServices } from '../../functional/services';
import { SearchSessionsProvider } from './search_sessions';
export const services = {
...functionalServices,
searchSessions: SearchSessionsProvider,
};