diff --git a/package.json b/package.json index 9da0588e6f67a..9b72355c15beb 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ }, "resolutions": { "**/@babel/parser": "7.24.7", + "**/@emotion/sheet": "npm:@elastic/emotion-sheet@1.4.1", "**/@hello-pangea/dnd": "18.0.1", "**/@langchain/core": "0.3.80", "**/@langchain/google-common": "0.2.18", diff --git a/src/core/packages/chrome/browser-components/src/classic/__snapshots__/collapsible_nav.test.tsx.snap b/src/core/packages/chrome/browser-components/src/classic/__snapshots__/collapsible_nav.test.tsx.snap index 7b47b0f7b75f5..0238aeecd74d4 100644 --- a/src/core/packages/chrome/browser-components/src/classic/__snapshots__/collapsible_nav.test.tsx.snap +++ b/src/core/packages/chrome/browser-components/src/classic/__snapshots__/collapsible_nav.test.tsx.snap @@ -883,7 +883,6 @@ exports[`CollapsibleNav renders the default nav 1`] = ` "css-1751mc5-navCss": "@media (max-height: 240px){overflow-y:auto;};label:navCss;", }, "sheet": StyleSheet { - "_alreadyInsertedOrderInsensitiveRule": true, "_insertTag": [Function], "before": null, "container": @@ -892,19 +891,11 @@ exports[`CollapsibleNav renders the default nav 1`] = ` data-s="" > - .css-1751mc5-navCss{} - - , "ctr": 2, "insertionPoint": undefined, - "isSpeedy": false, + "isSpeedy": true, "key": "css", "nonce": undefined, "prepend": undefined, @@ -914,14 +905,6 @@ exports[`CollapsibleNav renders the default nav 1`] = ` data-s="" > - .css-1751mc5-navCss{} - , - , ], }, @@ -1149,7 +1132,6 @@ exports[`CollapsibleNav renders the default nav 2`] = ` "css-1751mc5-navCss": "@media (max-height: 240px){overflow-y:auto;};label:navCss;", }, "sheet": StyleSheet { - "_alreadyInsertedOrderInsensitiveRule": true, "_insertTag": [Function], "before": null, "container": @@ -1158,19 +1140,11 @@ exports[`CollapsibleNav renders the default nav 2`] = ` data-s="" > - .css-1751mc5-navCss{} - - , "ctr": 2, "insertionPoint": undefined, - "isSpeedy": false, + "isSpeedy": true, "key": "css", "nonce": undefined, "prepend": undefined, @@ -1180,14 +1154,6 @@ exports[`CollapsibleNav renders the default nav 2`] = ` data-s="" > - .css-1751mc5-navCss{} - , - , ], }, diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/page_objects/index.ts b/src/platform/packages/shared/kbn-scout/src/playwright/page_objects/index.ts index 91402b71a3d07..4f5c66b6c0f1d 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/page_objects/index.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/page_objects/index.ts @@ -23,6 +23,7 @@ import { createLazyPageObject } from './utils'; import { Inspector } from './inspector'; import { LensApp } from './lens_app'; import { LoginPage } from './login_page'; +import { OverlaysPage } from './overlays'; import type { KibanaUrl } from '../../common/services/kibana_url'; export interface PageObjectsFixtures { @@ -45,6 +46,7 @@ export interface PageObjects { inspector: Inspector; lens: LensApp; login: LoginPage; + overlays: OverlaysPage; } /** @@ -67,6 +69,6 @@ export function createCorePageObjects(fixtures: PageObjectsFixtures): PageObject inspector: createLazyPageObject(Inspector, fixtures.page), lens: createLazyPageObject(LensApp, fixtures.page), login: createLazyPageObject(LoginPage, fixtures.page, fixtures.kbnUrl), - // Add new page objects here + overlays: createLazyPageObject(OverlaysPage, fixtures.page), }; } diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/page_objects/overlays.ts b/src/platform/packages/shared/kbn-scout/src/playwright/page_objects/overlays.ts new file mode 100644 index 0000000000000..cbac75555c71b --- /dev/null +++ b/src/platform/packages/shared/kbn-scout/src/playwright/page_objects/overlays.ts @@ -0,0 +1,43 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import type { ScoutPage } from '..'; +import { expect } from '..'; + +export class OverlaysPage { + constructor(private readonly page: ScoutPage) {} + + public get docViewerFlyout() { + return this.page.testSubj.locator('docViewerFlyout'); + } + + public get newsfeedButton() { + return this.page.testSubj.locator('newsfeed'); + } + + public get newsfeedFlyout() { + return this.page.testSubj.locator('NewsfeedFlyout'); + } + + public get newsfeedFlyoutCloseButton() { + return this.page.testSubj + .locator('NewsfeedFlyout') + .locator('[data-test-subj="euiFlyoutCloseButton"]'); + } + + public async openNewsfeedFlyout() { + await this.newsfeedButton.click(); + await expect(this.newsfeedFlyout).toBeVisible(); + } + + public async closeNewsfeedFlyout() { + await this.newsfeedFlyoutCloseButton.click(); + await expect(this.newsfeedFlyout).toBeHidden(); + } +} diff --git a/src/platform/plugins/shared/chart_expressions/expression_legacy_metric/public/components/__snapshots__/with_auto_scale.test.tsx.snap b/src/platform/plugins/shared/chart_expressions/expression_legacy_metric/public/components/__snapshots__/with_auto_scale.test.tsx.snap index 1cbc4213d6bb3..6358981c830a9 100644 --- a/src/platform/plugins/shared/chart_expressions/expression_legacy_metric/public/components/__snapshots__/with_auto_scale.test.tsx.snap +++ b/src/platform/plugins/shared/chart_expressions/expression_legacy_metric/public/components/__snapshots__/with_auto_scale.test.tsx.snap @@ -16,7 +16,6 @@ exports[`AutoScale withAutoScale renders 1`] = ` "nonce": undefined, "registered": Object {}, "sheet": StyleSheet { - "_alreadyInsertedOrderInsensitiveRule": true, "_insertTag": [Function], "before": null, "container": @@ -25,12 +24,11 @@ exports[`AutoScale withAutoScale renders 1`] = ` data-s="" > - .css-4vd3s2-autoScaleWrapperStyle{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;max-width:100%;max-height:100%;overflow:hidden;line-height:1.5;} , "ctr": 1, "insertionPoint": undefined, - "isSpeedy": false, + "isSpeedy": true, "key": "css", "nonce": undefined, "prepend": undefined, @@ -40,7 +38,6 @@ exports[`AutoScale withAutoScale renders 1`] = ` data-s="" > - .css-4vd3s2-autoScaleWrapperStyle{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;max-width:100%;max-height:100%;overflow:hidden;line-height:1.5;} , ], }, diff --git a/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/constants.ts b/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/constants.ts new file mode 100644 index 0000000000000..a8952d007f03c --- /dev/null +++ b/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/constants.ts @@ -0,0 +1,16 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export const LOGSTASH = { + DEFAULT_START_TIME: 'Sep 19, 2015 @ 06:31:44.000', + DEFAULT_END_TIME: 'Sep 23, 2015 @ 18:31:44.000', + DATA_VIEW_NAME: 'logstash-*', + KBN_ARCHIVE: + 'src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/kbn_archives/logstash_data_view.json', +}; diff --git a/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/index.ts b/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/index.ts new file mode 100644 index 0000000000000..48ca368ab9884 --- /dev/null +++ b/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/index.ts @@ -0,0 +1,11 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export { LOGSTASH } from './constants'; +export { setupFlyoutStability, teardownFlyoutStability } from './setup'; diff --git a/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/kbn_archives/logstash_data_view.json b/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/kbn_archives/logstash_data_view.json new file mode 100644 index 0000000000000..5bf476490dc1f --- /dev/null +++ b/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/kbn_archives/logstash_data_view.json @@ -0,0 +1,15 @@ +{ + "attributes": { + "name": "logstash-*", + "timeFieldName": "@timestamp", + "title": "logstash-*" + }, + "coreMigrationVersion": "8.8.0", + "created_at": "2025-01-01T00:00:00.000Z", + "id": "logstash-data-view", + "managed": false, + "references": [], + "type": "index-pattern", + "typeMigrationVersion": "7.11.0", + "updated_at": "2025-01-01T00:00:00.000Z" +} diff --git a/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/setup.ts b/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/setup.ts new file mode 100644 index 0000000000000..2b24d296ab8a1 --- /dev/null +++ b/src/platform/plugins/shared/discover/test/scout/ui/fixtures/flyout_stability/setup.ts @@ -0,0 +1,27 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import type { ScoutParallelWorkerFixtures } from '@kbn/scout'; +import { LOGSTASH } from './constants'; + +export async function setupFlyoutStability(scoutSpace: ScoutParallelWorkerFixtures['scoutSpace']) { + await scoutSpace.savedObjects.load(LOGSTASH.KBN_ARCHIVE); + await scoutSpace.uiSettings.setDefaultIndex(LOGSTASH.DATA_VIEW_NAME); + await scoutSpace.uiSettings.setDefaultTime({ + from: LOGSTASH.DEFAULT_START_TIME, + to: LOGSTASH.DEFAULT_END_TIME, + }); +} + +export async function teardownFlyoutStability( + scoutSpace: ScoutParallelWorkerFixtures['scoutSpace'] +) { + await scoutSpace.uiSettings.unset('defaultIndex', 'timepicker:timeDefaults'); + await scoutSpace.savedObjects.cleanStandardList(); +} diff --git a/src/platform/plugins/shared/discover/test/scout/ui/parallel_tests/flyout_stability/flyout_emotion_cache.spec.ts b/src/platform/plugins/shared/discover/test/scout/ui/parallel_tests/flyout_stability/flyout_emotion_cache.spec.ts new file mode 100644 index 0000000000000..535a2e691f60a --- /dev/null +++ b/src/platform/plugins/shared/discover/test/scout/ui/parallel_tests/flyout_stability/flyout_emotion_cache.spec.ts @@ -0,0 +1,69 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { tags, spaceTest } from '@kbn/scout'; +import { expect } from '@kbn/scout/ui'; +import { setupFlyoutStability, teardownFlyoutStability } from '../../fixtures/flyout_stability'; + +spaceTest.describe('Flyout system Emotion cache stability', { tag: tags.stateful.classic }, () => { + spaceTest.beforeAll(async ({ scoutSpace }) => { + await setupFlyoutStability(scoutSpace); + }); + + spaceTest.beforeEach(async ({ browserAuth, pageObjects }) => { + await browserAuth.loginAsViewer(); + await pageObjects.discover.goto(); + }); + + spaceTest.afterAll(async ({ scoutSpace }) => { + await teardownFlyoutStability(scoutSpace); + }); + + spaceTest( + 'opening a flyout after a cascade close does not corrupt the Emotion style cache', + async ({ page, pageObjects }) => { + const consoleErrors: string[] = []; + page.on('console', (msg) => { + if (msg.type() === 'error') { + consoleErrors.push(msg.text()); + } + }); + + await spaceTest.step('open a document flyout', async () => { + await pageObjects.discover.waitUntilSearchingHasFinished(); + await pageObjects.discover.openDocumentDetails({ rowIndex: 0 }); + await expect(pageObjects.overlays.docViewerFlyout).toBeVisible(); + }); + + await spaceTest.step('open a second flyout from a different domain', async () => { + await pageObjects.overlays.openNewsfeedFlyout(); + }); + + await spaceTest.step('close the second flyout, triggering a cascade close', async () => { + await pageObjects.overlays.closeNewsfeedFlyout(); + await expect(pageObjects.overlays.docViewerFlyout).toBeHidden(); + }); + + await spaceTest.step('open a new flyout after the cascade close', async () => { + await pageObjects.discover.openDocumentDetails({ rowIndex: 0 }); + await expect(pageObjects.overlays.docViewerFlyout).toBeVisible(); + }); + + await spaceTest.step( + 'verify no insertBefore errors from stale Emotion cache refs', + async () => { + await expect(page.testSubj.locator('discoverDocumentsTable')).toBeVisible(); + + const hasInsertBeforeError = consoleErrors.some((msg) => msg.includes('insertBefore')); + expect(hasInsertBeforeError).toBe(false); + } + ); + } + ); +}); diff --git a/src/platform/plugins/shared/discover/test/scout/ui/parallel_tests/global.setup.ts b/src/platform/plugins/shared/discover/test/scout/ui/parallel_tests/global.setup.ts index 1cc7d2a889bef..663ea7828508e 100644 --- a/src/platform/plugins/shared/discover/test/scout/ui/parallel_tests/global.setup.ts +++ b/src/platform/plugins/shared/discover/test/scout/ui/parallel_tests/global.setup.ts @@ -13,7 +13,24 @@ import { TRACES, richTrace, traceCorrelatedLogs } from '../fixtures/traces_exper globalSetupHook( 'Setup Discover tests data', - async ({ esClient, apmSynthtraceEsClient, logsSynthtraceEsClient, apiServices, config, log }) => { + async ({ + esClient, + esArchiver, + apmSynthtraceEsClient, + logsSynthtraceEsClient, + apiServices, + config, + log, + }) => { + // Logstash data for flyout stability tests + log.debug( + '[setup:logstash] loading logstash_functional ES data (only if it does not exist)...' + ); + await esArchiver.loadIfNeeded( + 'src/platform/test/functional/fixtures/es_archiver/logstash_functional' + ); + log.debug('[setup:logstash] logstash_functional ES data ready'); + // Metrics Experience setup log.debug('[setup:metrics] creating metrics test index (only if it does not exist)...'); const created = await createMetricsTestIndexIfNeeded(esClient); diff --git a/x-pack/platform/plugins/shared/maps/public/connected_components/mb_map/scale_control/__snapshots__/scale_control.test.tsx.snap b/x-pack/platform/plugins/shared/maps/public/connected_components/mb_map/scale_control/__snapshots__/scale_control.test.tsx.snap index b33f323015dc2..0bfecb02936cf 100644 --- a/x-pack/platform/plugins/shared/maps/public/connected_components/mb_map/scale_control/__snapshots__/scale_control.test.tsx.snap +++ b/x-pack/platform/plugins/shared/maps/public/connected_components/mb_map/scale_control/__snapshots__/scale_control.test.tsx.snap @@ -34,7 +34,6 @@ exports[`isFullScreen 1`] = ` "nonce": undefined, "registered": Object {}, "sheet": StyleSheet { - "_alreadyInsertedOrderInsensitiveRule": true, "_insertTag": [Function], "before": null, "container": @@ -43,19 +42,11 @@ exports[`isFullScreen 1`] = ` data-s="" > - .css-1hok13p-mapScaleControlStyles-ScaleControl{position:absolute;z-index:1000;left:12px;bottom:12px;pointer-events:none;color:#1D2A3E;border-left:2px solid #1D2A3E99;border-bottom:2px solid #1D2A3E99;text-align:right;background-color:#F6F9FC;padding-left:4px;padding-right:4px;} - - , "ctr": 2, "insertionPoint": undefined, - "isSpeedy": false, + "isSpeedy": true, "key": "css", "nonce": undefined, "prepend": undefined, @@ -65,14 +56,6 @@ exports[`isFullScreen 1`] = ` data-s="" > - .css-1hok13p-mapScaleControlStyles-ScaleControl{position:absolute;z-index:1000;left:12px;bottom:12px;pointer-events:none;color:#1D2A3E;border-left:2px solid #1D2A3E99;border-bottom:2px solid #1D2A3E99;text-align:right;background-color:#F6F9FC;padding-left:4px;padding-right:4px;} - , - , ], }, @@ -136,7 +119,6 @@ exports[`render 1`] = ` "nonce": undefined, "registered": Object {}, "sheet": StyleSheet { - "_alreadyInsertedOrderInsensitiveRule": true, "_insertTag": [Function], "before": null, "container": @@ -145,12 +127,11 @@ exports[`render 1`] = ` data-s="" > - .css-1hok13p-mapScaleControlStyles-ScaleControl{position:absolute;z-index:1000;left:12px;bottom:12px;pointer-events:none;color:#1D2A3E;border-left:2px solid #1D2A3E99;border-bottom:2px solid #1D2A3E99;text-align:right;background-color:#F6F9FC;padding-left:4px;padding-right:4px;} , "ctr": 1, "insertionPoint": undefined, - "isSpeedy": false, + "isSpeedy": true, "key": "css", "nonce": undefined, "prepend": undefined, @@ -160,7 +141,6 @@ exports[`render 1`] = ` data-s="" > - .css-1hok13p-mapScaleControlStyles-ScaleControl{position:absolute;z-index:1000;left:12px;bottom:12px;pointer-events:none;color:#1D2A3E;border-left:2px solid #1D2A3E99;border-bottom:2px solid #1D2A3E99;text-align:right;background-color:#F6F9FC;padding-left:4px;padding-right:4px;} , ], }, diff --git a/yarn.lock b/yarn.lock index 9d07aafc011ec..5758d41bb3b83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2845,10 +2845,10 @@ "@emotion/utils" "^1.2.1" csstype "^3.0.2" -"@emotion/sheet@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" - integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== +"@emotion/sheet@^1.2.2", "@emotion/sheet@npm:@elastic/emotion-sheet@1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@elastic/emotion-sheet/-/emotion-sheet-1.4.1.tgz#ec86896018f34d04c6dff61347e267738d3265c3" + integrity sha512-uzcu/YhEz+AURhe1q/6u9CaVBDtOC6TYWcCa5O5YXOH5ZOTE82xkcm3jEtMX7brCxqSGcP0Cc5kxUUSd04hMMg== "@emotion/styled@11.11.0": version "11.11.0"