From 628bc29769aa02232eacb913afd36a32fc185d14 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 22 Sep 2021 18:07:00 -0400 Subject: [PATCH 1/9] Bump chromedriver to 93 (#112847) (#112884) Co-authored-by: Jonathan Budzenski --- package.json | 2 +- yarn.lock | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 7b00ede087e85..0d19121ecc35f 100644 --- a/package.json +++ b/package.json @@ -677,7 +677,7 @@ "callsites": "^3.1.0", "chai": "3.5.0", "chance": "1.0.18", - "chromedriver": "^92.0.1", + "chromedriver": "^93.0.1", "clean-webpack-plugin": "^3.0.0", "cmd-shim": "^2.1.0", "compression-webpack-plugin": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 962b0ffbfd9f6..7d5a4afa8756a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7626,6 +7626,13 @@ axios@^0.21.1: dependencies: follow-redirects "^1.10.0" +axios@^0.21.2: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + axobject-query@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" @@ -9375,13 +9382,13 @@ chrome-trace-event@^1.0.2: dependencies: tslib "^1.9.0" -chromedriver@^92.0.1: - version "92.0.1" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-92.0.1.tgz#3e28b7e0c9fb94d693cf74d51af0c29d57f18dca" - integrity sha512-LptlDVCs1GgyFNVbRoHzzy948JDVzTgGiVPXjNj385qXKQP3hjAVBIgyvb/Hco0xSEW8fjwJfsm1eQRmu6t4pQ== +chromedriver@^93.0.1: + version "93.0.1" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-93.0.1.tgz#3ed1f7baa98a754fc1788c42ac8e4bb1ab27db32" + integrity sha512-KDzbW34CvQLF5aTkm3b5VdlTrvdIt4wEpCzT2p4XJIQWQZEPco5pNce7Lu9UqZQGkhQ4mpZt4Ky6NKVyIS2N8A== dependencies: "@testim/chrome-version" "^1.0.7" - axios "^0.21.1" + axios "^0.21.2" del "^6.0.0" extract-zip "^2.0.1" https-proxy-agent "^5.0.0" @@ -13996,6 +14003,11 @@ follow-redirects@^1.0.0, follow-redirects@^1.10.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== +follow-redirects@^1.14.0: + version "1.14.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.3.tgz#6ada78118d8d24caee595595accdc0ac6abd022e" + integrity sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw== + font-awesome@4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" From 819c670425bcd58e30bd428518e5a069389cc31e Mon Sep 17 00:00:00 2001 From: Kaarina Tungseth Date: Thu, 23 Sep 2021 11:32:33 -0500 Subject: [PATCH 2/9] [DOCS] Adds #112562 known issue to 7.14.2 release notes (#112744) * [DOCS] Adds #112562 known issue to 7.14.2 release notes * Update docs/CHANGELOG.asciidoc Co-authored-by: Jean-Louis Leysens Co-authored-by: Jean-Louis Leysens --- docs/CHANGELOG.asciidoc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index bea30908e0ced..d1324ba0622d5 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -65,6 +65,12 @@ Review important information about the {kib} 7.14.x releases. Review the following information about the 7.14.2 release. +[float] +[[known-issue-v7.14.2]] +=== Known issue + +{kib} is unable to restore *Discover* search sessions with a relative time range. When you restore the *Discover* search session, then run a new search, {kib} displays a `Your search session is still running` message. For more information, refer to {kibana-issue}101430[#101430]. + [float] [[breaking-changes-v7.14.2]] === Breaking changes @@ -817,8 +823,6 @@ Uptime:: [[release-notes-7.13.2]] == {kib} 7.13.2 -coming::[7.13.2] - The 7.13.2 release includes the following bug fixes. [float] From 2add89424bab7199d4e239f9df18b14bd97133a3 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 15 Jul 2021 14:49:20 +0100 Subject: [PATCH 3/9] skip flaky suite (#93188) --- .../apps/ml/data_frame_analytics/feature_importance.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/feature_importance.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/feature_importance.ts index fbd6cc70418d3..91d7b0a9347e2 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/feature_importance.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/feature_importance.ts @@ -183,7 +183,8 @@ export default function ({ getService }: FtrProviderContext) { }); for (const testData of testDataList) { - describe(`${testData.suiteTitle}`, function () { + // FLAKY: https://github.com/elastic/kibana/issues/93188 + describe.skip(`${testData.suiteTitle}`, function () { before(async () => { await ml.navigation.navigateToMl(); await ml.navigation.navigateToDataFrameAnalytics(); From 7194c68da01672ee66f65368567380887ff71980 Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Mon, 27 Sep 2021 13:05:13 -0400 Subject: [PATCH 4/9] [7.14] [Dashboard] Retain Viewmode State in Session (#112302) (#112709) * [Dashboard] Retain Viewmode State in Session (#112302) --- .../hooks/use_dashboard_app_state.ts | 30 ++-- .../lib/dashboard_session_storage.ts | 2 + .../apps/dashboard/dashboard_unsaved_state.ts | 169 +++++++++++------- .../maps/embeddable/tooltip_filter_actions.js | 5 + 4 files changed, 129 insertions(+), 77 deletions(-) diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts index 576f7c06c8dc8..5c963bcee6902 100644 --- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts +++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts @@ -222,27 +222,25 @@ export const useDashboardAppState = ({ .pipe(debounceTime(DashboardConstants.CHANGE_CHECK_DEBOUNCE)) .subscribe((states) => { const [lastSaved, current] = states; - const unsavedChanges = - current.viewMode === ViewMode.EDIT ? diffDashboardState(lastSaved, current) : {}; + const unsavedChanges = diffDashboardState(lastSaved, current); - let savedTimeChanged = false; + const savedTimeChanged = + lastSaved.timeRestore && + !areTimeRangesEqual( + { + from: savedDashboard?.timeFrom, + to: savedDashboard?.timeTo, + }, + timefilter.getTime() + ); /** - * changes to the time filter should only be considered 'unsaved changes' when + * changes to the dashboard should only be considered 'unsaved changes' when * editing the dashboard */ - if (current.viewMode === ViewMode.EDIT) { - savedTimeChanged = - lastSaved.timeRestore && - !areTimeRangesEqual( - { - from: savedDashboard?.timeFrom, - to: savedDashboard?.timeTo, - }, - timefilter.getTime() - ); - } - const hasUnsavedChanges = Object.keys(unsavedChanges).length > 0 || savedTimeChanged; + const hasUnsavedChanges = + current.viewMode === ViewMode.EDIT && + (Object.keys(unsavedChanges).length > 0 || savedTimeChanged); setDashboardAppState((s) => ({ ...s, hasUnsavedChanges })); unsavedChanges.viewMode = current.viewMode; // always push view mode into session store. diff --git a/src/plugins/dashboard/public/application/lib/dashboard_session_storage.ts b/src/plugins/dashboard/public/application/lib/dashboard_session_storage.ts index 7d0e60c0609a8..a696c8bc15b83 100644 --- a/src/plugins/dashboard/public/application/lib/dashboard_session_storage.ts +++ b/src/plugins/dashboard/public/application/lib/dashboard_session_storage.ts @@ -11,6 +11,7 @@ import { Storage } from '../../services/kibana_utils'; import { NotificationsStart } from '../../services/core'; import { panelStorageErrorStrings } from '../../dashboard_strings'; import { DashboardState } from '../../types'; +import { ViewMode } from '../../services/embeddable'; export const DASHBOARD_PANELS_UNSAVED_ID = 'unsavedDashboard'; const DASHBOARD_PANELS_SESSION_KEY = 'dashboardStateManagerPanels'; @@ -69,6 +70,7 @@ export class DashboardSessionStorage { const dashboardsWithUnsavedChanges: string[] = []; Object.keys(dashboardStatesInSpace).map((dashboardId) => { if ( + dashboardStatesInSpace[dashboardId].viewMode === ViewMode.EDIT && Object.keys(dashboardStatesInSpace[dashboardId]).some( (stateKey) => stateKey !== 'viewMode' ) diff --git a/test/functional/apps/dashboard/dashboard_unsaved_state.ts b/test/functional/apps/dashboard/dashboard_unsaved_state.ts index 6b71dd34b76f8..8043c8bf8cc37 100644 --- a/test/functional/apps/dashboard/dashboard_unsaved_state.ts +++ b/test/functional/apps/dashboard/dashboard_unsaved_state.ts @@ -12,6 +12,9 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['dashboard', 'header', 'visualize', 'settings', 'common']); + const browser = getService('browser'); + const queryBar = getService('queryBar'); + const filterBar = getService('filterBar'); const esArchiver = getService('esArchiver'); const testSubjects = getService('testSubjects'); const kibanaServer = getService('kibanaServer'); @@ -19,9 +22,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { let originalPanelCount = 0; let unsavedPanelCount = 0; + const testQuery = 'Test Query'; - // FLAKY: https://github.com/elastic/kibana/issues/91191 - describe.skip('dashboard unsaved panels', () => { + describe('dashboard unsaved state', () => { before(async () => { await esArchiver.load('test/functional/fixtures/es_archiver/dashboard/current/kibana'); await kibanaServer.uiSettings.replace({ @@ -31,79 +34,123 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.dashboard.preserveCrossAppState(); await PageObjects.dashboard.loadSavedDashboard('few panels'); await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.waitForRenderComplete(); originalPanelCount = await PageObjects.dashboard.getPanelCount(); }); - it('does not show unsaved changes badge when there are no unsaved changes', async () => { - await testSubjects.missingOrFail('dashboardUnsavedChangesBadge'); - }); + describe('view mode state', () => { + before(async () => { + await queryBar.setQuery(testQuery); + await filterBar.addFilter('bytes', 'exists'); + await queryBar.submitQuery(); + }); - it('shows the unsaved changes badge after adding panels', async () => { - await PageObjects.dashboard.switchToEditMode(); - // add an area chart by value - await dashboardAddPanel.clickEditorMenuButton(); - await dashboardAddPanel.clickAggBasedVisualizations(); - await PageObjects.visualize.clickAreaChart(); - await PageObjects.visualize.clickNewSearch(); - await PageObjects.visualize.saveVisualizationAndReturn(); + const validateQueryAndFilter = async () => { + const query = await queryBar.getQueryString(); + expect(query).to.eql(testQuery); + const filterCount = await filterBar.getFilterCount(); + expect(filterCount).to.eql(1); + }; + + it('persists after navigating to the listing page and back', async () => { + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.gotoDashboardLandingPage(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.loadSavedDashboard('few panels'); + await PageObjects.dashboard.waitForRenderComplete(); + await validateQueryAndFilter(); + }); - // add a metric by reference - await dashboardAddPanel.addVisualization('Rendering-Test: metric'); + it('persists after navigating to Visualize and back', async () => { + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.visualize.gotoVisualizationLandingPage(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.common.navigateToApp('dashboards'); + await PageObjects.dashboard.loadSavedDashboard('few panels'); + await PageObjects.dashboard.waitForRenderComplete(); + await validateQueryAndFilter(); + }); - await PageObjects.header.waitUntilLoadingHasFinished(); - await testSubjects.existOrFail('dashboardUnsavedChangesBadge'); - }); + it('persists after a hard refresh', async () => { + await browser.refresh(); + const alert = await browser.getAlert(); + await alert?.accept(); + await PageObjects.dashboard.waitForRenderComplete(); + await validateQueryAndFilter(); + }); - it('has correct number of panels', async () => { - unsavedPanelCount = await PageObjects.dashboard.getPanelCount(); - expect(unsavedPanelCount).to.eql(originalPanelCount + 2); + after(async () => { + // discard changes made in view mode + await PageObjects.dashboard.switchToEditMode(); + await PageObjects.dashboard.clickCancelOutOfEditMode(); + }); }); - it('retains unsaved panel count after navigating to listing page and back', async () => { - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.gotoDashboardLandingPage(); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.loadSavedDashboard('few panels'); - await PageObjects.dashboard.switchToEditMode(); - const currentPanelCount = await PageObjects.dashboard.getPanelCount(); - expect(currentPanelCount).to.eql(unsavedPanelCount); - }); + describe('edit mode state', () => { + const addPanels = async () => { + // add an area chart by value + await dashboardAddPanel.clickEditorMenuButton(); + await dashboardAddPanel.clickAggBasedVisualizations(); + await PageObjects.visualize.clickAreaChart(); + await PageObjects.visualize.clickNewSearch(); + await PageObjects.visualize.saveVisualizationAndReturn(); + + // add a metric by reference + await dashboardAddPanel.addVisualization('Rendering-Test: metric'); + }; + + it('does not show unsaved changes badge when there are no unsaved changes', async () => { + await testSubjects.missingOrFail('dashboardUnsavedChangesBadge'); + }); - it('retains unsaved panel count after navigating to another app and back', async () => { - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.visualize.gotoVisualizationLandingPage(); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.common.navigateToApp('dashboards'); - await PageObjects.dashboard.loadSavedDashboard('few panels'); - await PageObjects.dashboard.switchToEditMode(); - const currentPanelCount = await PageObjects.dashboard.getPanelCount(); - expect(currentPanelCount).to.eql(unsavedPanelCount); - }); + it('shows the unsaved changes badge after adding panels', async () => { + await PageObjects.dashboard.switchToEditMode(); + await addPanels(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.existOrFail('dashboardUnsavedChangesBadge'); + }); - it('resets to original panel count upon entering view mode', async () => { - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.clickCancelOutOfEditMode(); - await PageObjects.header.waitUntilLoadingHasFinished(); - const currentPanelCount = await PageObjects.dashboard.getPanelCount(); - expect(currentPanelCount).to.eql(originalPanelCount); - }); + it('has correct number of panels', async () => { + unsavedPanelCount = await PageObjects.dashboard.getPanelCount(); + expect(unsavedPanelCount).to.eql(originalPanelCount + 2); + }); - it('shows unsaved changes badge in view mode if changes have not been discarded', async () => { - await testSubjects.existOrFail('dashboardUnsavedChangesBadge'); - }); + it('retains unsaved panel count after navigating to listing page and back', async () => { + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.gotoDashboardLandingPage(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.loadSavedDashboard('few panels'); + const currentPanelCount = await PageObjects.dashboard.getPanelCount(); + expect(currentPanelCount).to.eql(unsavedPanelCount); + }); - it('retains unsaved panel count after returning to edit mode', async () => { - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.dashboard.switchToEditMode(); - await PageObjects.header.waitUntilLoadingHasFinished(); - const currentPanelCount = await PageObjects.dashboard.getPanelCount(); - expect(currentPanelCount).to.eql(unsavedPanelCount); - }); + it('retains unsaved panel count after navigating to another app and back', async () => { + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.visualize.gotoVisualizationLandingPage(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.common.navigateToApp('dashboards'); + await PageObjects.dashboard.loadSavedDashboard('few panels'); + const currentPanelCount = await PageObjects.dashboard.getPanelCount(); + expect(currentPanelCount).to.eql(unsavedPanelCount); + }); - it('does not show unsaved changes badge after saving', async () => { - await PageObjects.dashboard.saveDashboard('Unsaved State Test'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await testSubjects.missingOrFail('dashboardUnsavedChangesBadge'); + it('resets to original panel count after discarding changes', async () => { + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.clickCancelOutOfEditMode(); + await PageObjects.header.waitUntilLoadingHasFinished(); + const currentPanelCount = await PageObjects.dashboard.getPanelCount(); + expect(currentPanelCount).to.eql(originalPanelCount); + expect(PageObjects.dashboard.getIsInViewMode()).to.eql(true); + }); + + it('does not show unsaved changes badge after saving', async () => { + await PageObjects.dashboard.switchToEditMode(); + await addPanels(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.saveDashboard('Unsaved State Test'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.missingOrFail('dashboardUnsavedChangesBadge'); + }); }); }); } diff --git a/x-pack/test/functional/apps/maps/embeddable/tooltip_filter_actions.js b/x-pack/test/functional/apps/maps/embeddable/tooltip_filter_actions.js index d583e41e5e280..9cba88d1adbcc 100644 --- a/x-pack/test/functional/apps/maps/embeddable/tooltip_filter_actions.js +++ b/x-pack/test/functional/apps/maps/embeddable/tooltip_filter_actions.js @@ -62,6 +62,11 @@ export default function ({ getPageObjects, getService }) { const hasJoinFilter = await filterBar.hasFilter('runtime_shape_name', 'charlie'); expect(hasJoinFilter).to.be(true); }); + + after(async () => { + // Remove all filters so that when loading the dashboard again, the geo shape is still present. Related to #64861 + await filterBar.removeAllFilters(); + }); }); describe('panel actions', () => { From 0a8a334014ed8ca732d373f4cd779e189e8ccc36 Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Mon, 27 Sep 2021 17:10:12 -0400 Subject: [PATCH 5/9] [CI] Balance ci groups (#110711) (#113164) # Conflicts: # test/functional/apps/visualize/index.ts # x-pack/test/functional/config.js --- test/functional/apps/visualize/index.ts | 7 ++++++- .../security_and_spaces/tests/basic/index.ts | 2 +- .../security_and_spaces/tests/trial/index.ts | 2 +- x-pack/test/functional/apps/apm/index.ts | 2 +- x-pack/test/functional/apps/lens/index.ts | 6 +++++- x-pack/test/functional/apps/uptime/index.ts | 2 +- .../test/functional/apps/uptime/synthetics_integration.ts | 2 +- x-pack/test/functional/config.js | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/test/functional/apps/visualize/index.ts b/test/functional/apps/visualize/index.ts index cc5e80bae1b5a..6fdcd2a6659d6 100644 --- a/test/functional/apps/visualize/index.ts +++ b/test/functional/apps/visualize/index.ts @@ -94,13 +94,18 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./_region_map')); }); + describe('visualize ciGroup8', function () { + this.tags('ciGroup8'); + + loadTestFile(require.resolve('./_tsvb_chart')); + }); + describe('visualize ciGroup11', function () { this.tags('ciGroup11'); loadTestFile(require.resolve('./_tag_cloud')); loadTestFile(require.resolve('./_vertical_bar_chart')); loadTestFile(require.resolve('./_vertical_bar_chart_nontimeindex')); - loadTestFile(require.resolve('./_tsvb_chart')); loadTestFile(require.resolve('./_tsvb_time_series')); loadTestFile(require.resolve('./_tsvb_markdown')); loadTestFile(require.resolve('./_tsvb_table')); diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/basic/index.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/basic/index.ts index 90fbb10637434..3fb7d7a29af39 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/basic/index.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/basic/index.ts @@ -12,7 +12,7 @@ import { createSpacesAndUsers, deleteSpacesAndUsers } from '../../../common/lib/ export default ({ loadTestFile, getService }: FtrProviderContext): void => { describe('cases security and spaces enabled: basic', function () { // Fastest ciGroup for the moment. - this.tags('ciGroup5'); + this.tags('ciGroup13'); before(async () => { await createSpacesAndUsers(getService); diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/index.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/index.ts index 26bc6a072450d..cd4b062c065a0 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/index.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/index.ts @@ -12,7 +12,7 @@ import { createSpacesAndUsers, deleteSpacesAndUsers } from '../../../common/lib/ export default ({ loadTestFile, getService }: FtrProviderContext): void => { describe('cases security and spaces enabled: trial', function () { // Fastest ciGroup for the moment. - this.tags('ciGroup5'); + this.tags('ciGroup13'); before(async () => { await createSpacesAndUsers(getService); diff --git a/x-pack/test/functional/apps/apm/index.ts b/x-pack/test/functional/apps/apm/index.ts index e4db5a66aa55f..20c2bc264a74f 100644 --- a/x-pack/test/functional/apps/apm/index.ts +++ b/x-pack/test/functional/apps/apm/index.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('APM specs', function () { - this.tags('ciGroup6'); + this.tags('ciGroup10'); loadTestFile(require.resolve('./feature_controls')); loadTestFile(require.resolve('./correlations')); }); diff --git a/x-pack/test/functional/apps/lens/index.ts b/x-pack/test/functional/apps/lens/index.ts index 99b75bdabe6c4..1b09a4252c3f1 100644 --- a/x-pack/test/functional/apps/lens/index.ts +++ b/x-pack/test/functional/apps/lens/index.ts @@ -25,10 +25,14 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { await esArchiver.unload('x-pack/test/functional/es_archives/lens/basic'); }); + describe('', function () { + this.tags(['ciGroup3', 'skipFirefox']); + loadTestFile(require.resolve('./smokescreen')); + }); + describe('', function () { this.tags(['ciGroup4', 'skipFirefox']); - loadTestFile(require.resolve('./smokescreen')); loadTestFile(require.resolve('./add_to_dashboard')); loadTestFile(require.resolve('./table')); loadTestFile(require.resolve('./runtime_fields')); diff --git a/x-pack/test/functional/apps/uptime/index.ts b/x-pack/test/functional/apps/uptime/index.ts index 501fec5002666..2db29bfca4054 100644 --- a/x-pack/test/functional/apps/uptime/index.ts +++ b/x-pack/test/functional/apps/uptime/index.ts @@ -42,7 +42,7 @@ export default ({ loadTestFile, getService }: FtrProviderContext) => { const uptime = getService('uptime'); describe('Uptime app', function () { - this.tags('ciGroup6'); + this.tags('ciGroup10'); beforeEach('delete settings', async () => { await deleteUptimeSettingsObject(server); diff --git a/x-pack/test/functional/apps/uptime/synthetics_integration.ts b/x-pack/test/functional/apps/uptime/synthetics_integration.ts index 146584d138f22..08617ce2cd44a 100644 --- a/x-pack/test/functional/apps/uptime/synthetics_integration.ts +++ b/x-pack/test/functional/apps/uptime/synthetics_integration.ts @@ -78,7 +78,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); describe('When on the Synthetics Integration Policy Create Page', function () { - this.tags(['ciGroup6']); + this.tags(['ciGroup10']); const basicConfig = { name: monitorName, apmServiceName: 'Sample APM Service', diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index 4f00ef6a18c6d..4a3b657623ddd 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -33,7 +33,6 @@ export default async function ({ readConfigFile }) { resolve(__dirname, './apps/discover'), resolve(__dirname, './apps/security'), resolve(__dirname, './apps/spaces'), - resolve(__dirname, './apps/lens'), resolve(__dirname, './apps/logstash'), resolve(__dirname, './apps/grok_debugger'), resolve(__dirname, './apps/infra'), @@ -60,6 +59,7 @@ export default async function ({ readConfigFile }) { resolve(__dirname, './apps/management'), resolve(__dirname, './apps/reporting'), resolve(__dirname, './apps/observability'), + resolve(__dirname, './apps/lens'), // smokescreen tests cause flakiness in other tests //This upgrade assistant file needs to be run after the rest of the jobs because of //it being destructive. From dfbbca6a25503b383294b10fb42f0d7e8ca4dc41 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 27 Sep 2021 17:25:54 -0400 Subject: [PATCH 6/9] [docs] Update keystore location (#111994) (#113183) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Jonathan Budzenski --- docs/setup/secure-settings.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/setup/secure-settings.asciidoc b/docs/setup/secure-settings.asciidoc index 840a18ac03bab..55b8c39e0ede8 100644 --- a/docs/setup/secure-settings.asciidoc +++ b/docs/setup/secure-settings.asciidoc @@ -18,8 +18,8 @@ To create the `kibana.keystore`, use the `create` command: bin/kibana-keystore create ---------------------------------------------------------------- -The file `kibana.keystore` will be created in the directory defined by the -<> configuration setting. +The file `kibana.keystore` will be created in the `config` directory defined by the +environment variable `KBN_PATH_CONF`. [float] [[list-settings]] From 24b7c67eb86b7cd366c4914308c9b1405b803106 Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Tue, 28 Sep 2021 18:52:58 -0400 Subject: [PATCH 7/9] Compare intervals for unsaved changes on dashboard (#112592) (#113333) --- .../application/hooks/use_dashboard_app_state.ts | 9 +++++++-- .../public/application/lib/filter_utils.ts | 13 +++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts index 5c963bcee6902..cc96be62694ca 100644 --- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts +++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts @@ -36,6 +36,7 @@ import { syncDashboardUrlState, diffDashboardState, areTimeRangesEqual, + areRefreshIntervalsEqual, } from '../lib'; export interface UseDashboardStateProps { @@ -226,13 +227,17 @@ export const useDashboardAppState = ({ const savedTimeChanged = lastSaved.timeRestore && - !areTimeRangesEqual( + (!areTimeRangesEqual( { from: savedDashboard?.timeFrom, to: savedDashboard?.timeTo, }, timefilter.getTime() - ); + ) || + !areRefreshIntervalsEqual( + savedDashboard?.refreshInterval, + timefilter.getRefreshInterval() + )); /** * changes to the dashboard should only be considered 'unsaved changes' when diff --git a/src/plugins/dashboard/public/application/lib/filter_utils.ts b/src/plugins/dashboard/public/application/lib/filter_utils.ts index 51acc4676c543..a31b83ec2df8f 100644 --- a/src/plugins/dashboard/public/application/lib/filter_utils.ts +++ b/src/plugins/dashboard/public/application/lib/filter_utils.ts @@ -10,9 +10,10 @@ import _ from 'lodash'; import moment, { Moment } from 'moment'; import { Optional } from '@kbn/utility-types'; -import { Filter, TimeRange } from '../../services/data'; +import { Filter, TimeRange, RefreshInterval } from '../../services/data'; type TimeRangeCompare = Optional; +type RefreshIntervalCompare = Optional; /** * Converts the time to a utc formatted string. If the time is not valid (e.g. it might be in a relative format like @@ -31,9 +32,13 @@ export const convertTimeToUTCString = (time?: string | Moment): undefined | stri } }; -export const areTimeRangesEqual = (rangeA: TimeRangeCompare, rangeB: TimeRangeCompare): boolean => { - return areTimesEqual(rangeA.from, rangeB.from) && areTimesEqual(rangeA.to, rangeB.to); -}; +export const areTimeRangesEqual = (rangeA: TimeRangeCompare, rangeB: TimeRangeCompare): boolean => + areTimesEqual(rangeA.from, rangeB.from) && areTimesEqual(rangeA.to, rangeB.to); + +export const areRefreshIntervalsEqual = ( + refreshA?: RefreshIntervalCompare, + refreshB?: RefreshIntervalCompare +): boolean => refreshA?.pause === refreshB?.pause && refreshA?.value === refreshB?.value; /** * Compares the two times, making sure they are in both compared in string format. Absolute times From 52113fbdab89e35ecd973872b226af8a037cb795 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 29 Sep 2021 10:04:06 -0400 Subject: [PATCH 8/9] [Discover] Unksip and improve index pattern without time field functional test (#112698) (#113393) Co-authored-by: Matthias Wilhelm --- .../discover/_indexpattern_without_timefield.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/discover/_indexpattern_without_timefield.ts b/test/functional/apps/discover/_indexpattern_without_timefield.ts index ff3ad0daf69db..81fb4f92ab730 100644 --- a/test/functional/apps/discover/_indexpattern_without_timefield.ts +++ b/test/functional/apps/discover/_indexpattern_without_timefield.ts @@ -9,6 +9,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { + const retry = getService('retry'); const browser = getService('browser'); const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); @@ -56,22 +57,33 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should display a timepicker after switching to an index pattern with timefield', async () => { await PageObjects.discover.selectIndexPattern('with-timefield'); + await PageObjects.discover.waitForDocTableLoadingComplete(); if (!(await PageObjects.timePicker.timePickerExists())) { throw new Error('Expected timepicker to exist'); } }); it('should switch between with and without timefield using the browser back button', async () => { await PageObjects.discover.selectIndexPattern('without-timefield'); + await PageObjects.discover.waitForDocTableLoadingComplete(); if (await PageObjects.timePicker.timePickerExists()) { throw new Error('Expected timepicker not to exist'); } await PageObjects.discover.selectIndexPattern('with-timefield'); + await PageObjects.discover.waitForDocTableLoadingComplete(); if (!(await PageObjects.timePicker.timePickerExists())) { throw new Error('Expected timepicker to exist'); } - // Navigating back to discover + // Navigating back await browser.goBack(); + await PageObjects.discover.waitForDocTableLoadingComplete(); + await retry.waitForWithTimeout( + 'index pattern to have been switched back to "without-timefield"', + 5000, + async () => + (await testSubjects.getVisibleText('indexPattern-switch-link')) === 'without-timefield' + ); + if (await PageObjects.timePicker.timePickerExists()) { throw new Error('Expected timepicker not to exist'); } From ffe549cdd8ac9487ab8f836ed452b723ede07786 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 30 Sep 2021 20:37:47 -0400 Subject: [PATCH 9/9] [buildkite] Improve failed test experience (#113483) (#113582) Co-authored-by: Brian Seeders --- .buildkite/pipelines/es_snapshots/verify.yml | 8 - .buildkite/pipelines/hourly.yml | 8 - .../lifecycle/annotate_test_failures.js | 14 ++ .buildkite/scripts/lifecycle/post_command.sh | 5 + packages/kbn-test/BUILD.bazel | 2 + .../report_failures_to_file.ts | 138 ++++++++++++++++++ ...report_failures_to_file_html_template.html | 41 ++++++ .../run_failed_tests_reporter_cli.ts | 3 + 8 files changed, 203 insertions(+), 16 deletions(-) create mode 100644 .buildkite/scripts/lifecycle/annotate_test_failures.js create mode 100644 packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts create mode 100644 packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html diff --git a/.buildkite/pipelines/es_snapshots/verify.yml b/.buildkite/pipelines/es_snapshots/verify.yml index 9af2e938db49d..61212e1fcf0a8 100755 --- a/.buildkite/pipelines/es_snapshots/verify.yml +++ b/.buildkite/pipelines/es_snapshots/verify.yml @@ -91,13 +91,5 @@ steps: - wait: ~ continue_on_failure: true - - plugins: - - junit-annotate#v1.9.0: - artifacts: target/junit/**/*.xml - job-uuid-file-pattern: '-bk__(.*).xml' - - - wait: ~ - continue_on_failure: true - - command: .buildkite/scripts/lifecycle/post_build.sh label: Post-Build diff --git a/.buildkite/pipelines/hourly.yml b/.buildkite/pipelines/hourly.yml index 89541023be8e2..279c8cf96bfe3 100644 --- a/.buildkite/pipelines/hourly.yml +++ b/.buildkite/pipelines/hourly.yml @@ -159,13 +159,5 @@ steps: - wait: ~ continue_on_failure: true - - plugins: - - junit-annotate#v1.9.0: - artifacts: target/junit/**/*.xml - job-uuid-file-pattern: '-bk__(.*).xml' - - - wait: ~ - continue_on_failure: true - - command: .buildkite/scripts/lifecycle/post_build.sh label: Post-Build diff --git a/.buildkite/scripts/lifecycle/annotate_test_failures.js b/.buildkite/scripts/lifecycle/annotate_test_failures.js new file mode 100644 index 0000000000000..caf1e08c2bb4d --- /dev/null +++ b/.buildkite/scripts/lifecycle/annotate_test_failures.js @@ -0,0 +1,14 @@ +const { TestFailures } = require('kibana-buildkite-library'); + +(async () => { + try { + await TestFailures.annotateTestFailures(); + } catch (ex) { + console.error('Annotate test failures error', ex.message); + if (ex.response) { + console.error('HTTP Error Response Status', ex.response.status); + console.error('HTTP Error Response Body', ex.response.data); + } + process.exit(1); + } +})(); diff --git a/.buildkite/scripts/lifecycle/post_command.sh b/.buildkite/scripts/lifecycle/post_command.sh index 23f44a586e978..0f98035f9f828 100755 --- a/.buildkite/scripts/lifecycle/post_command.sh +++ b/.buildkite/scripts/lifecycle/post_command.sh @@ -23,4 +23,9 @@ if [[ "$IS_TEST_EXECUTION_STEP" == "true" ]]; then buildkite-agent artifact upload '.es/**/*.hprof' node scripts/report_failed_tests --build-url="${BUILDKITE_BUILD_URL}#${BUILDKITE_JOB_ID}" 'target/junit/**/*.xml' + + if [[ -d 'target/test_failures' ]]; then + buildkite-agent artifact upload 'target/test_failures/**/*' + node .buildkite/scripts/lifecycle/annotate_test_failures.js + fi fi diff --git a/packages/kbn-test/BUILD.bazel b/packages/kbn-test/BUILD.bazel index c4f3d0d1604e5..a4100abec1ba3 100644 --- a/packages/kbn-test/BUILD.bazel +++ b/packages/kbn-test/BUILD.bazel @@ -50,6 +50,7 @@ RUNTIME_DEPS = [ "@npm//exit-hook", "@npm//form-data", "@npm//globby", + "@npm//he", "@npm//history", "@npm//jest", "@npm//jest-cli", @@ -86,6 +87,7 @@ TYPES_DEPS = [ "@npm//xmlbuilder", "@npm//@types/chance", "@npm//@types/enzyme", + "@npm//@types/he", "@npm//@types/history", "@npm//@types/jest", "@npm//@types/joi", diff --git a/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts b/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts new file mode 100644 index 0000000000000..aca2e6838faec --- /dev/null +++ b/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts @@ -0,0 +1,138 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createHash } from 'crypto'; +import { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'fs'; +import { join, basename, resolve } from 'path'; + +import { ToolingLog } from '@kbn/dev-utils'; +import { REPO_ROOT } from '@kbn/utils'; +import { escape } from 'he'; + +import { TestFailure } from './get_failures'; + +const findScreenshots = (dirPath: string, allScreenshots: string[] = []) => { + const files = readdirSync(dirPath); + + for (const file of files) { + if (statSync(join(dirPath, file)).isDirectory()) { + if (file.match(/node_modules/)) { + continue; + } + + allScreenshots = findScreenshots(join(dirPath, file), allScreenshots); + } else { + const fullPath = join(dirPath, file); + if (fullPath.match(/screenshots\/failure\/.+\.png$/)) { + allScreenshots.push(fullPath); + } + } + } + + return allScreenshots; +}; + +export function reportFailuresToFile(log: ToolingLog, failures: TestFailure[]) { + if (!failures?.length) { + return; + } + + let screenshots: string[]; + try { + screenshots = [ + ...findScreenshots(join(REPO_ROOT, 'test', 'functional')), + ...findScreenshots(join(REPO_ROOT, 'x-pack', 'test', 'functional')), + ]; + } catch (e) { + log.error(e as Error); + screenshots = []; + } + + const screenshotsByName: Record = {}; + for (const screenshot of screenshots) { + const [name] = basename(screenshot).split('.'); + screenshotsByName[name] = screenshot; + } + + // Jest could, in theory, fail 1000s of tests and write 1000s of failures + // So let's just write files for the first 20 + for (const failure of failures.slice(0, 20)) { + const hash = createHash('md5').update(failure.name).digest('hex'); + const filenameBase = `${ + process.env.BUILDKITE_JOB_ID ? process.env.BUILDKITE_JOB_ID + '_' : '' + }${hash}`; + const dir = join('target', 'test_failures'); + + const failureLog = [ + ['Test:', '-----', failure.classname, failure.name, ''], + ['Failure:', '--------', failure.failure], + failure['system-out'] ? ['', 'Standard Out:', '-------------', failure['system-out']] : [], + ] + .flat() + .join('\n'); + + const failureJSON = JSON.stringify( + { + ...failure, + hash, + buildId: process.env.BUJILDKITE_BUILD_ID || '', + jobId: process.env.BUILDKITE_JOB_ID || '', + url: process.env.BUILDKITE_BUILD_URL || '', + jobName: process.env.BUILDKITE_LABEL + ? `${process.env.BUILDKITE_LABEL}${ + process.env.BUILDKITE_PARALLEL_JOB ? ` #${process.env.BUILDKITE_PARALLEL_JOB}` : '' + }` + : '', + }, + null, + 2 + ); + + let screenshot = ''; + const screenshotName = `${failure.name.replace(/([^ a-zA-Z0-9-]+)/g, '_')}`; + if (screenshotsByName[screenshotName]) { + try { + screenshot = readFileSync(screenshotsByName[screenshotName]).toString('base64'); + } catch (e) { + log.error(e as Error); + } + } + + const screenshotHtml = screenshot + ? `` + : ''; + + const failureHTML = readFileSync( + resolve( + REPO_ROOT, + 'packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html' + ) + ) + .toString() + .replace('$TITLE', escape(failure.name)) + .replace( + '$MAIN', + ` + ${failure.classname + .split('.') + .map((part) => `
${escape(part.replace('ยท', '.'))}
`) + .join('')} +
+

${escape(failure.name)}

+
${escape(failure.failure)}
+ ${screenshotHtml} +
${escape(failure['system-out'] || '')}
+ ` + ); + + mkdirSync(dir, { recursive: true }); + writeFileSync(join(dir, `${filenameBase}.log`), failureLog, 'utf8'); + writeFileSync(join(dir, `${filenameBase}.html`), failureHTML, 'utf8'); + writeFileSync(join(dir, `${filenameBase}.json`), failureJSON, 'utf8'); + } +} diff --git a/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html b/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html new file mode 100644 index 0000000000000..485a2c2d4eb3f --- /dev/null +++ b/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html @@ -0,0 +1,41 @@ + + + + + + + + $TITLE + + +
+
$MAIN
+
+ + + diff --git a/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts b/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts index 0129614fe658d..6c88b7408b628 100644 --- a/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts +++ b/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts @@ -21,6 +21,7 @@ import { readTestReport } from './test_report'; import { addMessagesToReport } from './add_messages_to_report'; import { getReportMessageIter } from './report_metadata'; import { reportFailuresToEs } from './report_failures_to_es'; +import { reportFailuresToFile } from './report_failures_to_file'; const DEFAULT_PATTERNS = [Path.resolve(REPO_ROOT, 'target/junit/**/*.xml')]; @@ -98,6 +99,8 @@ export function runFailedTestsReporterCli() { const messages = Array.from(getReportMessageIter(report)); const failures = await getFailures(report); + reportFailuresToFile(log, failures); + if (indexInEs) { await reportFailuresToEs(log, failures); }