From 7614734709665ae1acbcc904fe3df320cac29ae3 Mon Sep 17 00:00:00 2001
From: ruby <ruichao.hu@daocloud.io>
Date: Tue, 19 Nov 2024 01:14:32 +0800
Subject: [PATCH] [Console]: incorrect position of console tour #198389
 (#198636)

---
 src/plugins/console/common/constants/index.ts |  2 +-
 .../console/common/constants/plugin.ts        |  2 ++
 .../components/console_tour_step.tsx          | 25 ++++++++++++++++--
 .../embeddable/console_resize_button.tsx      | 17 ++++++++++++
 .../apps/console/_onboarding_tour.ts          | 26 ++++++++++++++++---
 test/functional/page_objects/console_page.ts  |  6 ++++-
 6 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/src/plugins/console/common/constants/index.ts b/src/plugins/console/common/constants/index.ts
index a00bcebcf38cc..b4d6a594241ce 100644
--- a/src/plugins/console/common/constants/index.ts
+++ b/src/plugins/console/common/constants/index.ts
@@ -7,7 +7,7 @@
  * License v3.0 only", or the "Server Side Public License, v 1".
  */
 
-export { MAJOR_VERSION } from './plugin';
+export { MAJOR_VERSION, WELCOME_TOUR_DELAY } from './plugin';
 export { API_BASE_PATH, KIBANA_API_PREFIX } from './api';
 export { DEFAULT_VARIABLES } from './variables';
 export {
diff --git a/src/plugins/console/common/constants/plugin.ts b/src/plugins/console/common/constants/plugin.ts
index 27ddb7d5dff1d..bb87e300c138d 100644
--- a/src/plugins/console/common/constants/plugin.ts
+++ b/src/plugins/console/common/constants/plugin.ts
@@ -8,3 +8,5 @@
  */
 
 export const MAJOR_VERSION = '8.0.0';
+
+export const WELCOME_TOUR_DELAY = 250;
diff --git a/src/plugins/console/public/application/components/console_tour_step.tsx b/src/plugins/console/public/application/components/console_tour_step.tsx
index 578d590bfff4a..97e999b0090aa 100644
--- a/src/plugins/console/public/application/components/console_tour_step.tsx
+++ b/src/plugins/console/public/application/components/console_tour_step.tsx
@@ -7,8 +7,9 @@
  * License v3.0 only", or the "Server Side Public License, v 1".
  */
 
-import React, { ReactNode, ReactElement } from 'react';
+import React, { ReactNode, ReactElement, useState, useEffect } from 'react';
 import { EuiTourStep, PopoverAnchorPosition } from '@elastic/eui';
+import { WELCOME_TOUR_DELAY } from '../../../common/constants';
 
 export interface ConsoleTourStepProps {
   step: number;
@@ -44,11 +45,31 @@ export const ConsoleTourStep = ({ tourStepProps, children }: Props) => {
     css,
   } = tourStepProps;
 
+  const [popoverVisible, setPopoverVisible] = useState(false);
+
+  useEffect(() => {
+    let timeoutId: any;
+
+    if (isStepOpen) {
+      timeoutId = setTimeout(() => {
+        setPopoverVisible(true);
+      }, WELCOME_TOUR_DELAY);
+    } else {
+      setPopoverVisible(false);
+    }
+
+    return () => {
+      if (timeoutId) {
+        clearTimeout(timeoutId);
+      }
+    };
+  }, [isStepOpen]);
+
   return (
     <EuiTourStep
       step={step}
       stepsTotal={stepsTotal}
-      isStepOpen={isStepOpen}
+      isStepOpen={popoverVisible}
       title={title}
       content={content}
       onFinish={onFinish}
diff --git a/src/plugins/console/public/application/containers/embeddable/console_resize_button.tsx b/src/plugins/console/public/application/containers/embeddable/console_resize_button.tsx
index 9a9f4222ef91b..6dcebcb15a56d 100644
--- a/src/plugins/console/public/application/containers/embeddable/console_resize_button.tsx
+++ b/src/plugins/console/public/application/containers/embeddable/console_resize_button.tsx
@@ -8,7 +8,9 @@
  */
 
 import React, { useCallback, useEffect, useState, useRef } from 'react';
+import { debounce } from 'lodash';
 import { EuiResizableButton, useEuiTheme, keys, EuiThemeComputed } from '@elastic/eui';
+import { WELCOME_TOUR_DELAY } from '../../../../common/constants';
 
 const CONSOLE_MIN_HEIGHT = 200;
 
@@ -61,6 +63,21 @@ export const EmbeddedConsoleResizeButton = ({
   const initialConsoleHeight = useRef(consoleHeight);
   const initialMouseY = useRef(0);
 
+  // When the height changes, simulate a window resize to prompt
+  // the current onboarding tour step to adjust its layouts
+  useEffect(() => {
+    const debouncedResize = debounce(() => {
+      window.dispatchEvent(new Event('resize'));
+    }, WELCOME_TOUR_DELAY);
+
+    debouncedResize();
+
+    // Cleanup the debounce instance on unmount or dependency change
+    return () => {
+      debouncedResize.cancel();
+    };
+  }, [consoleHeight]);
+
   useEffect(() => {
     function handleResize() {
       const newMaxConsoleHeight = getCurrentConsoleMaxSize(euiTheme);
diff --git a/test/functional/apps/console/_onboarding_tour.ts b/test/functional/apps/console/_onboarding_tour.ts
index 330498cb7b5ec..1fc47a70d14b0 100644
--- a/test/functional/apps/console/_onboarding_tour.ts
+++ b/test/functional/apps/console/_onboarding_tour.ts
@@ -10,6 +10,9 @@
 import expect from '@kbn/expect';
 import { FtrProviderContext } from '../../ftr_provider_context';
 
+// The euiTour shows with a small delay, so with 1s we should be safe
+const DELAY_FOR = 1000;
+
 export default function ({ getService, getPageObjects }: FtrProviderContext) {
   const log = getService('log');
   const browser = getService('browser');
@@ -40,22 +43,30 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
       expect(await isTourStepOpen('filesTourStep')).to.be(false);
     };
 
+    const waitUntilFinishedLoading = async () => {
+      await PageObjects.header.waitUntilLoadingHasFinished();
+      await PageObjects.common.sleep(DELAY_FOR);
+    };
+
     it('displays all five steps in the tour', async () => {
+      const andWaitFor = DELAY_FOR;
+      await waitUntilFinishedLoading();
+
       log.debug('on Shell tour step');
       expect(await isTourStepOpen('shellTourStep')).to.be(true);
-      await PageObjects.console.clickNextTourStep();
+      await PageObjects.console.clickNextTourStep(andWaitFor);
 
       log.debug('on Editor tour step');
       expect(await isTourStepOpen('editorTourStep')).to.be(true);
-      await PageObjects.console.clickNextTourStep();
+      await PageObjects.console.clickNextTourStep(andWaitFor);
 
       log.debug('on History tour step');
       expect(await isTourStepOpen('historyTourStep')).to.be(true);
-      await PageObjects.console.clickNextTourStep();
+      await PageObjects.console.clickNextTourStep(andWaitFor);
 
       log.debug('on Config tour step');
       expect(await isTourStepOpen('configTourStep')).to.be(true);
-      await PageObjects.console.clickNextTourStep();
+      await PageObjects.console.clickNextTourStep(andWaitFor);
 
       log.debug('on Files tour step');
       expect(await isTourStepOpen('filesTourStep')).to.be(true);
@@ -73,10 +84,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
       // Tour should reset after clearing local storage
       await browser.clearLocalStorage();
       await browser.refresh();
+
+      await waitUntilFinishedLoading();
       expect(await isTourStepOpen('shellTourStep')).to.be(true);
     });
 
     it('skipping the tour hides the tour steps', async () => {
+      await waitUntilFinishedLoading();
+
       expect(await isTourStepOpen('shellTourStep')).to.be(true);
       expect(await testSubjects.exists('consoleSkipTourButton')).to.be(true);
       await PageObjects.console.clickSkipTour();
@@ -90,6 +105,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
     });
 
     it('allows re-running the tour', async () => {
+      await waitUntilFinishedLoading();
+
       await PageObjects.console.skipTourIfExists();
 
       // Verify that tour is hiddern
@@ -100,6 +117,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
       await PageObjects.console.clickRerunTour();
 
       // Verify that first tour step is visible
+      await waitUntilFinishedLoading();
       expect(await isTourStepOpen('shellTourStep')).to.be(true);
     });
   });
diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts
index 87308d24fd8c4..a80f3426e256e 100644
--- a/test/functional/page_objects/console_page.ts
+++ b/test/functional/page_objects/console_page.ts
@@ -276,8 +276,12 @@ export class ConsolePageObject extends FtrService {
     await this.testSubjects.click('consoleSkipTourButton');
   }
 
-  public async clickNextTourStep() {
+  public async clickNextTourStep(andWaitFor: number = 0) {
     await this.testSubjects.click('consoleNextTourStepButton');
+
+    if (andWaitFor) {
+      await this.common.sleep(andWaitFor);
+    }
   }
 
   public async clickCompleteTour() {