diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 898597eabce5d..5e3394b9add9f 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -10,6 +10,7 @@ Review important information about the {kib} 8.x releases. +* <> * <> * <> * <> @@ -46,6 +47,269 @@ Review important information about the {kib} 8.x releases. * <> -- +[[release-notes-8.10.0]] +== {kib} 8.10.0 + +coming::[8.10.0] + +For information about the {kib} 8.10.0 release, review the following information. + +[float] +[[breaking-changes-8.10.0]] +=== Breaking changes + +Breaking changes can prevent your application from optimal operation and performance. +Before you upgrade to 8.10.0, review the breaking changes, then mitigate the impact to your application. + +[discrete] +[[breaking-162665]] +.New summary search capabilities +[%collapsible] +==== +*Details* + +New summary search capabilities introduce breaking changes in various places, and we have decided to not handle backward compatibility: + +* SLO find API body parameters have changed +* The index mapping used by the rollup data has changed, and we have added a summary index that becomes the new source of truth for search +* The rollup transform have been updated, but existing SLO with their transform won't be updated. + +If some SLOs have been installed in a prior version at 8.10, the user will need to remove them manually from the UI, or by deleting the Saved Object and the associated Transform. +==== + +[discrete] +[[breaking-162506]] +.Get case metrics APIs now internal +[%collapsible] +==== +*Details* + +The get case metrics APIs are now internal. For more information, refer to ({kibana-pull}162506[#162506]). +==== + +[discrete] +[[breaking-162492]] +.Case limits +[%collapsible] +==== +*Details* + +Limits are now imposed on the number of objects cases can process or the amount of data those objects can store. +//// +For example: +* Updating a case comment is now included in the 10000 user actions restriction. ({kibana-pull}163150[#163150]) +* Updating a case now fails if the operation makes it reach more than 10000 user actions. ({kibana-pull}161848[#161848]) +* The total number of characters per comment is limited to 30000. ({kibana-pull}161357[#161357]) +* The getConnectors API now limits the number of supported connectors returned to 1000. ({kibana-pull}161282[#161282]) +* There are new limits and restrictions when retrieving cases. ({kibana-pull}162411[#162411]), ({kibana-pull}162245[#162245]), ({kibana-pull}161111[#161111]), ({kibana-pull}160705[#160705]) +* A case can now only have 100 external references and persistable state(excluding files) attachments combined. ({kibana-pull}162071[#162071]). +* New limits on titles, descriptions, tags and category. ({kibana-pull}160844[#160844]). +* The maximum number of cases that can be updated simultaneously is now 100. The minimum is 1. ({kibana-pull}161076[#161076]). +* The Delete cases API now limits the number of cases to be deleted to 100.({kibana-pull}160846[#160846]). +//// +For the full list, refer to {kib-issue}146945[#146945]. +==== + +[discrete] +[[breaking-159041]] +.`addProcessorDefinition` is removed +[%collapsible] +==== +*Details* + +The function `addProcessorDefinition` is removed from the Console plugin start contract (server side). For more information, refer to ({kibana-pull}159041[#159041]). +==== + +[float] +[[deprecations-8.10.0]] +=== Deprecations + +The following functionality is deprecated in 8.10.0, and will be removed in 9.0.0. +Deprecated functionality does not have an immediate impact on your application, but we strongly recommend +you make the necessary updates after you upgrade to 8.10.0. + +[discrete] +[[deprecation-161136]] +.Action variables in the UI and in tests that were no longer used have been replaced +[%collapsible] +==== +*Details* + +The following rule action variables have been deprecated; use the recommended variables (in parentheses) instead: + +* alertActionGroup (alert.actionGroup) +* alertActionGroupName (alert.actionGroupName) +* alertActionSubgroup (alert.actionSubgroup) +* alertId (rule.id) +* alertInstanceId (alert.id) +* alertName (rule.name) +* params (rule.params) +* spaceId (rule.spaceId) +* tags (rule.tags) + +For more information, refer to ({kibana-pull}161136[#161136]). +==== + +[float] +[[features-8.10.0]] +=== Features +{kib} 8.10.0 adds the following new and notable features. + +Alerting:: +* Adds support for self-signed SSL certificate authentication in webhook connector ({kibana-pull}161894[#161894]). +* Allow runtime fields to be selected for {es} query rule type 'group by' or 'aggregate over' options ({kibana-pull}160319[#160319]). +APM:: +* Adds KQL filtering in APM rules ({kibana-pull}163825[#163825]). +* Make service group saved objects exportable ({kibana-pull}163569[#163569]). +* Added ability to manage Cross-Cluster API keys ({kibana-pull}162363[#162363]). +* Enable Trace Explorer by default ({kibana-pull}162308[#162308]). +* Adds error.grouping_name to group alerts in Error Count rule ({kibana-pull}161810[#161810]). +* Adds query to check for overflow bucket in service groups ({kibana-pull}159990[#159990]). +Elastic Security:: +For the Elastic Security 8.10.0 release information, refer to {security-guide}/release-notes.html[_Elastic Security Solution Release Notes_]. +Enterprise Search:: +For the Elastic Enterprise Search 8.10.0 release information, refer to {enterprise-search-ref}/changelog.html[_Elastic Enterprise Search Documentation Release notes_]. +Fleet:: +* Only enable secret storage once all fleet servers are above 8.10.0 ({kibana-pull}163627[#163627]). +* Kafka integration API ({kibana-pull}159110[#159110]). +Machine Learning:: +* AIOps: Adds/edits change point charts embeddable from the Dashboard app ({kibana-pull}163694[#163694]). +* AIOps: Adds change point detection charts embeddable ({kibana-pull}162796[#162796]). +* Adds ability to deploy trained models for data frame analytics jobs ({kibana-pull}162537[#162537]). +* Adds map view for models in Trained Models and expands support for models in Analytics map ({kibana-pull}162443[#162443]). +* Adds new Data comparison view ({kibana-pull}161365[#161365]). +Management:: +* Added ability to create a remote cluster with the API key based security model ({kibana-pull}161836[#161836]). +* REST endpoint for swapping saved object references ({kibana-pull}157665[#157665]). +Maps:: +* Maps tracks layer now uses group by time series logic ({kibana-pull}159267[#159267]). +Observability:: +* SLO definition and computed values are now summarized periodically into a summary search index, allowing users to search by name, tags, SLO budgeting type or time window, and even by and sort by error budget consumed, error budget remaining, SLI value or status ({kibana-pull}162665[#162665]). +* Adds indicator to support histogram fields ({kibana-pull}161582[#161582]). + +For more information about the features introduced in 8.10.0, refer to <>. + +[[enhancements-and-bug-fixes-v8.10.0]] +=== Enhancements and bug fixes + +For detailed information about the 8.10.0 release, review the enhancements and bug fixes. + +[float] +[[enhancement-v8.10.0]] +=== Enhancements +Alerting:: +* Fixes the event log data stream to use Data stream lifecycle instead of Index Lifecycle Management. If you had previously customized the Kibana event log ILM policy, you should now update the lifecycle of the event log data stream itself. ({kibana-pull}163210[#163210]). +* KQL search bar for Rules page ({kibana-pull}158106[#158106]). +APM:: +* Lens function ({kibana-pull}163872[#163872]). +* Adds several function implementations to the AI Assistant ({kibana-pull}163764[#163764]). +* Feature controls ({kibana-pull}163232[#163232]). +* Added improved JVM runtime metrics dashboard ({kibana-pull}162460[#162460]). +* Move to new plugin, update design and use connectors ({kibana-pull}162243[#162243]). +* Adding endpoint to upload android map files ({kibana-pull}161252[#161252]). +* Navigate from the transaction details view into the Profiling ({kibana-pull}159686[#159686]). +Dashboard:: +* Change badge color in options list ({kibana-pull}161401[#161401]). +* Edit title, description, and tags from dashboard listing page ({kibana-pull}161399[#161399]). +* Editing toolbar update ({kibana-pull}154966[#154966]). +Discover:: +* Inline shard failures warnings ({kibana-pull}161271[#161271]). +* Improve shard error message formatting ({kibana-pull}161098[#161098]). +Elastic Security:: +For the Elastic Security 8.10.0 release information, refer to {security-guide}/release-notes.html[_Elastic Security Solution Release Notes_]. +Enterprise Search:: +For the Elastic Enterprise Search 8.10.0 release information, refer to {enterprise-search-ref}/changelog.html[_Elastic Enterprise Search Documentation Release notes_]. +Fleet:: +* Adds support for runtime fields ({kibana-pull}161129[#161129]). +Lens & Visualizations:: +* Migrate range slider to `EuiDualRange` and make styling consistent across all controls ({kibana-pull}162651[#162651]). +* Introduce new duration formatter in *Lens* ({kibana-pull}162246[#162246]). +* Create a filter with field:value when last value metric is used on a data table in *Lens* ({kibana-pull}160509[#160509]). +* Adds tooltip for partition and heatmap filtering ({kibana-pull}162716[#162716]). +Machine Learning:: +* Hides paging controls in anomaly swim lane if only one page is available ({kibana-pull}163931[#163931]). +* Adds a throughput description in the Trained Models Deployment stats table ({kibana-pull}163481[#163481]). +* Provides hints for empty fields in dropdown options in Anomaly detection & Transform creation wizards, Change point detection view ({kibana-pull}163371[#163371]). +* AIOps: Adds dip support to log rate analysis in ML AIOps Labs ({kibana-pull}163100[#163100]). +* AIOps: Improves table hovering for log rate analysis ({kibana-pull}162941[#162941]). +* AIOps: Adds dip support for log rate analysis in observability alert details page ({kibana-pull}162476[#162476]). +* Adds validation of field selected for log pattern analysis ({kibana-pull}162319[#162319]). +* AIOps: Renames Explain Log Rate Spikes to Log Rate Analysis ({kibana-pull}161764[#161764]). +* Adds new Data comparison view ({kibana-pull}161365[#161365]). +* Adds test UI for text expansion models ({kibana-pull}159150[#159150]). +* Adds update index mappings step to ML pipeline config workflow ({kibana-pull}163723[#163723]). +Management:: +* Adds multiple formats for geo_point fields and make geo conversion tools part of field_format/common/utils ({kibana-pull}147272[#147272]). +Maps:: +* Support time series split for top hits per entity source ({kibana-pull}161799[#161799]). +Observability:: +* Adds support for group by to SLO burn rate rule ({kibana-pull}163434[#163434]). +* Applying consistent design to Histogram and Custom Metric forms ({kibana-pull}162083[#162083]). +* Adds preview chart to custom metric indicator ({kibana-pull}161597[#161597]). +* Support filters for good/total custom metrics ({kibana-pull}161308[#161308]). +Reporting:: +* Increase max size bytes default to 250mb ({kibana-pull}161318[#161318]). +Security:: +* Change the default value of `session.idleTimeout` from 8 hours to 3 days ({kibana-pull}162313[#162313]). +* User roles displayed on the user profile page ({kibana-pull}161375[#161375]). +Uptime:: +* Implement private location run once ({kibana-pull}162582[#162582]). + +[float] +[[fixes-v8.10.0]] +=== Bug Fixes +APM:: +* Fixes styling and port issue with new onboarding ({kibana-pull}163922[#163922]). +* Fixes missing alert index issue ({kibana-pull}163600[#163600]). +* Fixes trace waterfall loading logic to handle empty scenarios ({kibana-pull}163397[#163397]). +* Fixes the action menu overlapping the 'Create custom link' flyout ({kibana-pull}162664[#162664]). +* Improve service groups error messages and validations ({kibana-pull}162556[#162556]). +* Fixes throwing appropriate error when user is missing necessary permission ({kibana-pull}162466[#162466]). +* Hide components when there is no support from agents ({kibana-pull}161970[#161970]). +* Fixes link to onboarding page in the Observability Onboarding plugin ({kibana-pull}161847[#161847]). +Dashboard:: +* Disables top navigation actions when cloning or overlay is showing ({kibana-pull}162091[#162091]). +Discover:: +* Fixes document failing to load when the ID contains a slash ({kibana-pull}160239[#160239]). +* Fixes NoData screen in alignment with Dashboard and Lends behavior ({kibana-pull}160747[#160747]). +Elastic Security:: +For the Elastic Security 8.10.0 release information, refer to {security-guide}/release-notes.html[_Elastic Security Solution Release Notes_]. +Enterprise Search:: +For the Elastic Enterprise Search 8.10.0 release information, refer to {enterprise-search-ref}/changelog.html[_Elastic Enterprise Search Documentation Release notes_]. +Fleet:: +* Only show agent dashboard links if there is more than one non-server agent and if the dashboards exist ({kibana-pull}164469[#164469]). +* Exclude Synthetics from per-policy-outputs ({kibana-pull}161949[#161949]). +* Fixing the path for hint templates for auto-discover ({kibana-pull}161075[#161075]). +Lens & Visualizations:: +* Fixes params._interval conversion to Lens formula ({kibana-pull}164150[#164150]). +* Fixes issues with field name that contains the `:` character in it in *Lens* ({kibana-pull}163626[#163626]). +* Fixes other request merge behavior when empty string key is retrieved ({kibana-pull}163187[#163187]). +* Fixes editing of multi values filters when adding a custom item ({kibana-pull}161940[#161940]). +* Allow setting custom colors to be collapsed by slices pie's multiple metrics in *Lens* ({kibana-pull}160592[#160592]). +* Fixes data table sorting for keyword values in *Lens* ({kibana-pull}160163[#160163]). +* Fixes override parameter when creating data views ({kibana-pull}160953[#160953]). +Logs:: +* Amend lazy imports in logs_shared plugin ({kibana-pull}164102[#164102]). +Machine Learning:: +* Fixes Trained models list crashes on browser refresh if not on page 1 ({kibana-pull}164163[#164163]). +* Fixes query bar not switching from KQL to Lucene and vice versa in Anomaly explorer ({kibana-pull}163625[#163625]). +* Data Frame Analytics creation wizard: ensures validation works correctly ({kibana-pull}163446[#163446]). +* Fixes capabilities polling in manage page ({kibana-pull}163399[#163399]). +* Fixes unhandled promise rejection from ML plugin ({kibana-pull}163129[#163129]). +* AIOps: Uses Kibana's http service instead of fetch and fixes throttling ({kibana-pull}162335[#162335]). +* Uses model supplied mask token for testing trained models ({kibana-pull}162168[#162168]). +Management:: +* Fixes how a bulk request body with variables are processed in Console ({kibana-pull}162745[#162745]). +* Improves a way of variable substitution and its documentation in Console ({kibana-pull}162382[#162382]). +* Transforms: Reduces rerenders and multiple fetches of source index on transform wizard load ({kibana-pull}160979[#160979]). +Maps:: +* Fixes Map layer preview blocks adding layer until all tiles are loaded ({kibana-pull}161994[#161994]). +Monitoring:: +* Rewrite CPU usage rule to improve accuracy ({kibana-pull}159351[#159351]). +Observability:: +* Fixes email connector rule URL ({kibana-pull}162954[#162954]). +* Disable the 'View rule details' option from the Alert Details' Actions list when the rule is deleted ({kibana-pull}163183[#163183]). +Reporting:: +* Fixes a bug where Kibana Reporting would not work in Elastic Docker without adding a special setting in kibana.yml to disable the Chromium sandbox. ({kibana-pull}149080[#149080]). +* Fixes an issue where certain international characters would not appear correctly in the contents of a print-optimized PDF report of a dashboard ({kibana-pull}161825[#161825]). +Uptime:: +* Fixes auto-expand feature for failed step detail ({kibana-pull}162747[#162747]). + [[release-notes-8.9.1]] == {kib} 8.9.1 diff --git a/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts b/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts index 2c23eec3ca2aa..42df7340c1853 100644 --- a/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts +++ b/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts @@ -8,25 +8,15 @@ import type { Client } from '@elastic/elasticsearch'; import { ToolingLog } from '@kbn/tooling-log'; -import { KbnClient } from '@kbn/test'; import { ALL_SAVED_OBJECT_INDICES } from '@kbn/core-saved-objects-server'; -import { migrateSavedObjectIndices, createStats, cleanSavedObjectIndices } from '../lib'; +import { createStats, cleanSavedObjectIndices } from '../lib'; -export async function emptyKibanaIndexAction({ - client, - log, - kbnClient, -}: { - client: Client; - log: ToolingLog; - kbnClient: KbnClient; -}) { +export async function emptyKibanaIndexAction({ client, log }: { client: Client; log: ToolingLog }) { const stats = createStats('emptyKibanaIndex', log); await cleanSavedObjectIndices({ client, stats, log }); - await migrateSavedObjectIndices(kbnClient); await client.indices.refresh({ index: ALL_SAVED_OBJECT_INDICES }); - ALL_SAVED_OBJECT_INDICES.forEach((indexPattern) => stats.createdIndex(indexPattern)); + return stats.toJSON(); } diff --git a/packages/kbn-es-archiver/src/es_archiver.ts b/packages/kbn-es-archiver/src/es_archiver.ts index 65de41148d8db..d5c989f080486 100644 --- a/packages/kbn-es-archiver/src/es_archiver.ts +++ b/packages/kbn-es-archiver/src/es_archiver.ts @@ -154,14 +154,12 @@ export class EsArchiver { } /** - * Delete any Kibana indices, and initialize the Kibana index as Kibana would do - * on startup. + * Cleanup saved object indices, preserving the space:default saved object. */ async emptyKibanaIndex() { return await emptyKibanaIndexAction({ client: this.client, log: this.log, - kbnClient: this.kbnClient, }); } diff --git a/packages/kbn-text-based-editor/src/__stories__/text_based_editor.stories.mdx b/packages/kbn-text-based-editor/src/__stories__/text_based_editor.stories.mdx index ec38fe6296855..f6e0a751e7755 100644 --- a/packages/kbn-text-based-editor/src/__stories__/text_based_editor.stories.mdx +++ b/packages/kbn-text-based-editor/src/__stories__/text_based_editor.stories.mdx @@ -110,6 +110,27 @@ The editor also works on the expanded mode: +The editor also works on the expanded mode with the minimize button hidden: + + + + {Template.bind({})} + + + ## Component props The component exposes the following properties: diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx index 91c963e022332..4e3853970d7a2 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx @@ -182,6 +182,28 @@ describe('TextBasedLanguagesEditor', () => { ); }); + it('should not render the minimize button for the expanded code editor mode if the prop is set to true', async () => { + const newProps = { + ...props, + isCodeEditorExpanded: true, + hideMinimizeButton: true, + }; + let component: ReactWrapper; + await act(async () => { + component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps })); + }); + component!.update(); + await act(async () => { + expect( + component.find('[data-test-subj="TextBasedLangEditor-toggleWordWrap"]').length + ).not.toBe(0); + expect(component.find('[data-test-subj="TextBasedLangEditor-minimize"]').length).toBe(0); + expect( + component.find('[data-test-subj="TextBasedLangEditor-documentation"]').length + ).not.toBe(0); + }); + }); + it('should call the expand editor function when minimize button is clicked', async () => { const expandCodeEditorSpy = jest.fn(); const newProps = { diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx index 42c1b609f45b2..5eb83f625493a 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx @@ -74,6 +74,7 @@ export interface TextBasedLanguagesEditorProps { isDisabled?: boolean; isDarkMode?: boolean; dataTestSubj?: string; + hideMinimizeButton?: boolean; } interface TextBasedEditorDeps { @@ -118,6 +119,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ warning, isDisabled, isDarkMode, + hideMinimizeButton, dataTestSubj, }: TextBasedLanguagesEditorProps) { const { euiTheme } = useEuiTheme(); @@ -547,33 +549,35 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ - - - + { - expandCodeEditor(false); - updateLinesFromModel = false; - }} - /> - - + > + { + expandCodeEditor(false); + updateLinesFromModel = false; + }} + /> + + + )} {documentationSections && ( diff --git a/test/examples/search/warnings.ts b/test/examples/search/warnings.ts index 24656ed68285c..c1c86863ad7a8 100644 --- a/test/examples/search/warnings.ts +++ b/test/examples/search/warnings.ts @@ -167,6 +167,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // click "see full error" button in the toast const [openShardModalButton] = await testSubjects.findAll('openShardFailureModalBtn'); await openShardModalButton.click(); + await testSubjects.exists('shardFailureModalTitle'); const modalHeader = await testSubjects.find('shardFailureModalTitle'); expect(await modalHeader.getVisibleText()).to.be('2 of 4 shards failed'); // request diff --git a/test/functional/apps/console/_autocomplete.ts b/test/functional/apps/console/_autocomplete.ts index d06c84e0629a2..f2bb76359047c 100644 --- a/test/functional/apps/console/_autocomplete.ts +++ b/test/functional/apps/console/_autocomplete.ts @@ -14,7 +14,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const log = getService('log'); const retry = getService('retry'); - const PageObjects = getPageObjects(['common', 'console']); + const PageObjects = getPageObjects(['common', 'console', 'header']); const find = getService('find'); describe('console autocomplete feature', function describeIndexTests() { @@ -44,6 +44,155 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(PageObjects.console.isAutocompleteVisible()).to.be.eql(true); }); + describe('Autocomplete behavior', () => { + beforeEach(async () => { + await PageObjects.console.clearTextArea(); + await PageObjects.console.pressEnter(); + }); + + it('HTTP methods', async () => { + const suggestions = { + G: ['GET'], + P: ['PUT', 'POST'], + D: ['DELETE'], + H: ['HEAD'], + }; + for (const [char, methods] of Object.entries(suggestions)) { + await PageObjects.console.sleepForDebouncePeriod(); + log.debug('Key type "%s"', char); + await PageObjects.console.enterText(char); + + await retry.waitFor('autocomplete to be visible', () => + PageObjects.console.isAutocompleteVisible() + ); + expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true); + + for (const [i, method] of methods.entries()) { + expect(await PageObjects.console.getAutocompleteSuggestion(i)).to.be.eql(method); + } + + await PageObjects.console.pressEscape(); + await PageObjects.console.pressEnter(); + } + }); + + it('ES API endpoints', async () => { + const suggestions = { + 'GET _': ['_alias', '_all'], + 'PUT _': ['_all'], + 'POST _': ['_aliases', '_all'], + 'DELETE _': ['_all'], + 'HEAD _': ['_alias', '_all'], + }; + for (const [text, endpoints] of Object.entries(suggestions)) { + for (const char of text) { + await PageObjects.console.sleepForDebouncePeriod(); + log.debug('Key type "%s"', char); + await PageObjects.console.enterText(char); + } + + await retry.waitFor('autocomplete to be visible', () => + PageObjects.console.isAutocompleteVisible() + ); + expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true); + + for (const [i, endpoint] of endpoints.entries()) { + expect(await PageObjects.console.getAutocompleteSuggestion(i)).to.be.eql(endpoint); + } + + await PageObjects.console.pressEscape(); + await PageObjects.console.pressEnter(); + } + }); + + it('JSON autocompletion with placeholder fields', async () => { + await PageObjects.console.enterText('GET _search\n{'); + await PageObjects.console.pressEnter(); + + for (const char of '"ag') { + await PageObjects.console.sleepForDebouncePeriod(); + log.debug('Key type "%s"', char); + await PageObjects.console.enterText(char); + } + await retry.waitFor('autocomplete to be visible', () => + PageObjects.console.isAutocompleteVisible() + ); + expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true); + await PageObjects.console.pressEnter(); + await PageObjects.console.sleepForDebouncePeriod(); + + expect(await PageObjects.console.getAllVisibleText()).to.be.eql( + ` +GET _search +{ + "aggs": { + "NAME": { + "AGG_TYPE": {} + } + } +} +`.replace(/\n/g, '') + ); + // cursor should be located between '"' and 'N' + expect(await PageObjects.console.getCurrentLineNumber()).to.be.eql(5); + + await PageObjects.console.pressDown(); + await PageObjects.console.pressRight(); + await PageObjects.console.pressRight(); + for (let i = 0; i < 8; i++) { + await PageObjects.console.pressRight(true); // select 'AGG_TYPE' + } + + for (const char of 'ter') { + await PageObjects.console.sleepForDebouncePeriod(); + log.debug('Key type "%s"', char); + await PageObjects.console.enterText(char); + } + await retry.waitFor('autocomplete to be visible', () => + PageObjects.console.isAutocompleteVisible() + ); + expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true); + await PageObjects.console.pressEnter(); + await PageObjects.console.sleepForDebouncePeriod(); + + expect(await PageObjects.console.getAllVisibleText()).to.be.eql( + ` +GET _search +{ + "aggs": { + "NAME": { + "terms": { + "field": "" + } + } + } +} +`.replace(/\n/g, '') + ); + }); + + it('Dynamic autocomplete', async () => { + await PageObjects.console.enterRequest('POST test/_doc\n{}'); + await PageObjects.console.clickPlay(); + + await PageObjects.header.waitUntilLoadingHasFinished(); + expect(await PageObjects.console.getResponseStatus()).to.be('201'); + + await PageObjects.console.pressEnter(); + for (const char of 'POST t') { + await PageObjects.console.sleepForDebouncePeriod(); + log.debug('Key type "%s"', char); + await PageObjects.console.enterText(char); + } + await retry.waitFor('autocomplete to be visible', () => + PageObjects.console.isAutocompleteVisible() + ); + expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true); + + expect(await PageObjects.console.getAutocompleteSuggestion(0)).to.be.eql('test'); + }); + }); + // FLAKY: https://github.com/elastic/kibana/issues/164584 describe.skip('anti-regression watchdogs', () => { beforeEach(async () => { diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index 9efe80741621e..21a183c832606 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -150,6 +150,18 @@ export class ConsolePageObject extends FtrService { return !attribute.includes('display: none;'); } + public async getAutocompleteSuggestion(index: number = 0) { + const children1 = await this.find + .allByCssSelector('.ace_autocomplete .ace_line :nth-child(1)') + .catch(() => null); + const children2 = await this.find + .allByCssSelector('.ace_autocomplete .ace_line :nth-child(2)') + .catch(() => null); + if (!children1 || !children2) return null; + + return (await children1[index].getVisibleText()) + (await children2[index].getVisibleText()); + } + public async enterRequest(request: string = '\nGET _search') { const textArea = await this.getEditorTextArea(); await textArea.pressKeys(request); @@ -206,24 +218,24 @@ export class ConsolePageObject extends FtrService { await textArea.pressKeys(Key.ESCAPE); } - public async pressDown() { + public async pressDown(shift: boolean = false) { const textArea = await this.testSubjects.find('console-textarea'); - await textArea.pressKeys(Key.DOWN); + await textArea.pressKeys(shift ? [Key.SHIFT, Key.DOWN] : Key.DOWN); } - public async pressLeft() { + public async pressLeft(shift: boolean = false) { const textArea = await this.testSubjects.find('console-textarea'); - await textArea.pressKeys(Key.LEFT); + await textArea.pressKeys(shift ? [Key.SHIFT, Key.LEFT] : Key.LEFT); } - public async pressRight() { + public async pressRight(shift: boolean = false) { const textArea = await this.testSubjects.find('console-textarea'); - await textArea.pressKeys(Key.RIGHT); + await textArea.pressKeys(shift ? [Key.SHIFT, Key.RIGHT] : Key.RIGHT); } - public async pressUp() { + public async pressUp(shift: boolean = false) { const textArea = await this.testSubjects.find('console-textarea'); - await textArea.pressKeys(Key.UP); + await textArea.pressKeys(shift ? [Key.SHIFT, Key.UP] : Key.UP); } public async clearTextArea() { diff --git a/test/functional/page_objects/home_page.ts b/test/functional/page_objects/home_page.ts index ac942c70b5d90..61eb1f40c49e7 100644 --- a/test/functional/page_objects/home_page.ts +++ b/test/functional/page_objects/home_page.ts @@ -53,7 +53,9 @@ export class HomePageObject extends FtrService { } async isWelcomeInterstitialDisplayed() { - return await this.testSubjects.isDisplayed('homeWelcomeInterstitial'); + // give the interstitial enough time to fade in + await new Promise((resolve) => setTimeout(resolve, 500)); + return await this.testSubjects.isDisplayed('homeWelcomeInterstitial', 2000); } async isGuidedOnboardingLandingDisplayed() { diff --git a/test/functional/services/common/browser.ts b/test/functional/services/common/browser.ts index fd46e5ac1448b..f7957777408c3 100644 --- a/test/functional/services/common/browser.ts +++ b/test/functional/services/common/browser.ts @@ -73,6 +73,11 @@ class BrowserService extends FtrService { return await this.driver.manage().window().getRect(); } + public async getWindowInnerSize(): Promise<{ height: number; width: number }> { + const JS_GET_INNER_WIDTH = 'return { width: window.innerWidth, height: window.innerHeight };'; + return await this.driver.executeScript(JS_GET_INNER_WIDTH); + } + /** * Sets the dimensions of a window. * https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/webdriver_exports_Window.html diff --git a/test/functional/services/common/test_subjects.ts b/test/functional/services/common/test_subjects.ts index e54a1caa08d26..9cbce20b05068 100644 --- a/test/functional/services/common/test_subjects.ts +++ b/test/functional/services/common/test_subjects.ts @@ -285,9 +285,9 @@ export class TestSubjects extends FtrService { return await element.isEnabled(); } - public async isDisplayed(selector: string): Promise { + public async isDisplayed(selector: string, timeout?: number): Promise { this.log.debug(`TestSubjects.isDisplayed(${selector})`); - const element = await this.find(selector); + const element = await this.find(selector, timeout); return await element.isDisplayed(); } diff --git a/test/plugin_functional/test_suites/core_plugins/applications.ts b/test/plugin_functional/test_suites/core_plugins/applications.ts index df4ac37b96464..5af71ba799457 100644 --- a/test/plugin_functional/test_suites/core_plugins/applications.ts +++ b/test/plugin_functional/test_suites/core_plugins/applications.ts @@ -49,11 +49,11 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide const navigateTo = async (path: string) => await browser.navigateTo(`${deployment.getHostPort()}${path}`); - // FLAKY: https://github.com/elastic/kibana/issues/127545 - describe.skip('ui applications', function describeIndexTests() { + describe('ui applications', function describeIndexTests() { before(async () => { await esArchiver.emptyKibanaIndex(); await PageObjects.common.navigateToApp('foo'); + await PageObjects.common.dismissBanner(); }); it('starts on home page', async () => { @@ -126,7 +126,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide expect(await testSubjects.exists('headerGlobalNav')).to.be(false); const wrapperHeight = await getAppWrapperHeight(); - const windowHeight = (await browser.getWindowSize()).height; + const windowHeight = (await browser.getWindowInnerSize()).height; expect(wrapperHeight).to.eql(windowHeight); }); @@ -136,7 +136,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide expect(await testSubjects.exists('headerGlobalNav')).to.be(true); const wrapperHeight = await getAppWrapperHeight(); - const windowHeight = (await browser.getWindowSize()).height; + const windowHeight = (await browser.getWindowInnerSize()).height; expect(wrapperHeight).to.be.below(windowHeight); }); }); diff --git a/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_icons.tsx b/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_icons.tsx index b81b25144fcd0..f2b8247840cac 100644 --- a/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_icons.tsx +++ b/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_icons.tsx @@ -81,9 +81,7 @@ export const LandingLinkIcon: React.FC = React.memo(functi - - {description} - + {description} {children} diff --git a/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_images.tsx b/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_images.tsx index 18c8ef07c10cb..20caecd5a4e2c 100644 --- a/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_images.tsx +++ b/x-pack/packages/security-solution/navigation/src/landing_links/landing_links_images.tsx @@ -89,7 +89,7 @@ export const LandingLinksImages: React.FC = React.memo( {isBeta && } - + {description} diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid/search_box.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid/search_box.tsx index 593ad3e60e82b..9206de2d48f17 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid/search_box.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid/search_box.tsx @@ -54,6 +54,24 @@ export const SearchBox: FunctionComponent = ({ }); }; + const onCategoryButtonClick = () => { + if (selectedSubCategory) { + if (setSelectedSubCategory) setSelectedSubCategory(undefined); + setUrlandReplaceHistory({ + categoryId: selectedCategory, + subCategoryId: '', + }); + } else { + setCategory(''); + if (setSelectedSubCategory) setSelectedSubCategory(undefined); + setUrlandReplaceHistory({ + searchString: '', + categoryId: '', + subCategoryId: '', + }); + } + }; + const selectedCategoryTitle = selectedCategory ? categories.find((category) => category.id === selectedCategory)?.title : undefined; @@ -100,15 +118,7 @@ export const SearchBox: FunctionComponent = ({ {getCategoriesLabel}