@@ -135,16 +135,11 @@ context('list forecaster workflow', () => {
135135 } ) ;
136136
137137 // Handles the optional "Select your tenant" pop-up
138- cy . get ( 'body' ) . then ( ( $body ) => {
139- // We look for an element containing "Select your tenant" to avoid being
140- // specific about which tag (e.g. h1, h2) is used for the title.
141- if ( $body . find ( ':contains("Select your tenant")' ) . length > 0 ) {
142- const confirmButton = $body . find ( 'button:contains("Confirm")' ) ;
143- if ( confirmButton . length ) {
144- cy . wrap ( confirmButton . first ( ) ) . click ( ) ;
145- }
146- }
147- } ) ;
138+ cy . handleTenantDialog ( ) ;
139+
140+ cy . contains ( 'Loading OpenSearch Dashboards' , { timeout : 120000 } ) . should (
141+ 'not.exist'
142+ ) ;
148143
149144 // The application can sometimes re-render the header after loading or
150145 // dismissing initial pop-ups. To prevent a "detached from the DOM" error,
@@ -163,16 +158,8 @@ context('list forecaster workflow', () => {
163158 cy . contains ( 'Forecasting' ) . click ( ) ;
164159
165160 // Handles the optional "Select your tenant" pop-up
166- cy . get ( 'body' ) . then ( ( $body ) => {
167- // We look for an element containing "Select your tenant" to avoid being
168- // specific about which tag (e.g. h1, h2) is used for the title.
169- if ( $body . find ( ':contains("Select your tenant")' ) . length > 0 ) {
170- const confirmButton = $body . find ( 'button:contains("Confirm")' ) ;
171- if ( confirmButton . length ) {
172- cy . wrap ( confirmButton . first ( ) ) . click ( ) ;
173- }
174- }
175- } ) ;
161+ // tenant dialog can appear at any time, so we need to handle it between each clicks
162+ cy . handleTenantDialog ( ) ;
176163
177164 // Verify we're redirected to the forecasters list page
178165 // match ensures that the url ends with /forecasters
@@ -181,8 +168,10 @@ context('list forecaster workflow', () => {
181168 // ========== Scenario: CREATE FORECASTER ==========
182169 // Verify the title contains the word "Forecasters"
183170 cy . contains ( 'Forecasters (0)' ) . should ( 'exist' ) ;
171+ cy . handleTenantDialog ( ) ;
184172 // we have two create forecaster buttons, click any one of them
185173 cy . getElementByTestId ( 'createForecasterButton' ) . first ( ) . click ( ) ;
174+ cy . handleTenantDialog ( ) ;
186175
187176 // Call the new reusable command to create the forecaster
188177 cy . createForecaster ( {
@@ -433,7 +422,7 @@ context('list forecaster workflow', () => {
433422 buttonCount
434423 ) => {
435424 if ( buttonIndex >= buttonCount ) {
436- throw new Error (
425+ cy . log (
437426 `Could not open the "${ modalTestSubj } " modal after trying all buttons.`
438427 ) ;
439428 }
@@ -473,42 +462,51 @@ context('list forecaster workflow', () => {
473462 . click ( { force : true } ) ;
474463
475464 // Poll for the menu to appear
465+ cy . wait ( 500 ) ;
476466 cy . get ( 'body' ) . then ( ( $body ) => {
477467 const $visibleMenu = $body . find ( '.euiContextMenuPanel:visible' ) ;
478468 if (
479469 $visibleMenu . length > 0 &&
480470 $visibleMenu . text ( ) . includes ( menuItemText )
481471 ) {
482- // Correct menu found, attempt to click the item
483- cy . log ( ` Correct menu is visible. Clicking "${ menuItemText } ".` ) ;
484- cy . get ( '.euiContextMenuPanel:visible' )
485- . contains ( '.euiContextMenuItem' , menuItemText )
486- . click ( { force : true } ) ;
487-
488- // After clicking, wait a moment and check if the modal appeared.
489- cy . wait ( 500 ) ; // Wait for modal to render
490- cy . get ( 'body' ) . then ( ( $bodyAfterClick ) => {
491- if (
492- $bodyAfterClick . find ( `[data-test-subj="${ modalTestSubj } "]` )
493- . length > 0
494- ) {
495- // SUCCESS! Modal is open. End all loops.
496- cy . log ( ` Success! ${ modalTestSubj } is visible.` ) ;
497- return ;
498- } else {
499- // Modal did not appear. Retry the sequence.
500- cy . log (
501- ' Modal did not appear after click. Closing menu and retrying.'
502- ) ;
503- cy . get ( 'body' ) . click ( 'topLeft' , { force : true } ) ;
504- cy . wait ( 500 ) ;
505- attemptClickSequence ( retryCount - 1 ) ;
506- }
507- } ) ;
472+ // The menu was visible. Re-check just before clicking to be safe.
473+ if ( Cypress . $ ( '.euiContextMenuPanel:visible' ) . length > 0 ) {
474+ cy . log ( ` Correct menu is visible. Clicking "${ menuItemText } ".` ) ;
475+ cy . get ( '.euiContextMenuPanel:visible' )
476+ . contains ( '.euiContextMenuItem' , menuItemText )
477+ . click ( { force : true } ) ;
478+
479+ // After clicking, wait a moment and check if the modal appeared.
480+ cy . wait ( 500 ) ; // Wait for modal to render
481+ cy . get ( 'body' ) . then ( ( $bodyAfterClick ) => {
482+ if (
483+ $bodyAfterClick . find ( `[data-test-subj="${ modalTestSubj } "]` )
484+ . length > 0
485+ ) {
486+ // SUCCESS! Modal is open. End all loops.
487+ cy . log ( ` Success! ${ modalTestSubj } is visible.` ) ;
488+ return ;
489+ } else {
490+ // Modal did not appear. Retry the sequence.
491+ cy . log (
492+ ' Modal did not appear after click. Closing menu and retrying.'
493+ ) ;
494+ cy . get ( 'body' ) . click ( 'topLeft' , { force : true } ) ;
495+ cy . wait ( 500 ) ;
496+ attemptClickSequence ( retryCount - 1 ) ;
497+ }
498+ } ) ;
499+ } else {
500+ // The menu disappeared between the initial check and this one.
501+ cy . log ( ' Menu disappeared before click. Retrying.' ) ;
502+ cy . wait ( 500 ) ;
503+ attemptClickSequence ( retryCount - 1 ) ;
504+ }
508505 } else {
509506 // Menu was not visible or was incorrect. Retry.
510507 cy . log ( ' Menu not visible or incorrect. Retrying.' ) ;
511508 if ( $visibleMenu . length > 0 ) {
509+ cy . log ( ` Visible menu text: "${ $visibleMenu . text ( ) } "` ) ;
512510 cy . get ( 'body' ) . click ( 'topLeft' , { force : true } ) ;
513511 }
514512 cy . wait ( 500 ) ;
@@ -518,7 +516,7 @@ context('list forecaster workflow', () => {
518516 } ;
519517
520518 // Start the inner retry loop for the current button. Allow 3 retries.
521- attemptClickSequence ( 3 ) ;
519+ attemptClickSequence ( 6 ) ;
522520 } ;
523521
524522 // Define a helper to retry clicking a confirm button until its modal disappears.
@@ -561,6 +559,34 @@ context('list forecaster workflow', () => {
561559 }
562560 } ) ;
563561
562+ // After attempting with "Cancel forecast", check if the modal appeared.
563+ // If not, try again with "Stop forecasting". "Cancel forecast" is present
564+ // when state is "Initializing". "Stop forecasting" is present when state
565+ // is "Running". We are not sure which state the forecaster is in when the
566+ // real time run is triggered, so we try both.
567+ cy . get ( 'body' ) . then ( ( $body ) => {
568+ if (
569+ $body . find ( '[data-test-subj="stopForecastersModal"]:visible' ) . length ===
570+ 0
571+ ) {
572+ cy . log (
573+ 'Modal not found with "Cancel forecast", trying "Stop forecasting".'
574+ ) ;
575+ cy . get ( 'button[aria-label="Show actions"]' )
576+ . its ( 'length' )
577+ . then ( ( count ) => {
578+ if ( count > 0 ) {
579+ openActionModalWithRetries (
580+ 'Stop forecasting' ,
581+ 'stopForecastersModal' ,
582+ 0 ,
583+ count
584+ ) ;
585+ }
586+ } ) ;
587+ }
588+ } ) ;
589+
564590 // =====================================================================
565591 // Scenario – STOP FORECASTER VIA ROW ACTIONS
566592 // =====================================================================
@@ -652,10 +678,14 @@ context('list forecaster workflow', () => {
652678 // Verify the 'Delete forecaster' confirmation modal appears.
653679 cy . get ( '[data-test-subj="deleteForecastersModal"]' )
654680 . should ( 'be.visible' )
655- . and (
656- 'contain' ,
657- `Are you sure you want to delete "${ TEST_FORECASTER_NAME } "?`
658- ) ;
681+ . and ( ( $element ) => {
682+ const text = $element . text ( ) ;
683+ const includesFirstName = text . includes ( TEST_FORECASTER_NAME ) ;
684+ const includesSecondName = text . includes ( TEST_FORECASTER_NAME_2 ) ;
685+
686+ // Assert that at least one of the names is in the text
687+ expect ( includesFirstName || includesSecondName ) . to . be . true ;
688+ } ) ;
659689
660690 // Type 'delete' in the confirmation field to enable the button.
661691 cy . get ( '[data-test-subj="deleteForecastersModal"]' )
0 commit comments