Repository: opensearch-project/security-analytics-dashboards-plugin
Pull request #1280: Fix integ tests
Author: login: vikhy-aws
Created: 2025-04-15T07:41:54Z | Merged: 2025-04-16T19:59:47Z

### Description
Change the browser used to run cypress tests to `firefox`. With the current cypress version, the chrome and electron browsers installed have a memory management issue and the browser crashes frequently when running the tests. So, change the browser to `firefox`. Also, fix the failing integ tests.

### Issues Resolved
[[AUTOCUT] Integration Test Failed for securityAnalyticsDashboards-3.0.0](https://github.com/opensearch-project/security-analytics-dashboards-plugin/issues/1273)

### Check List
- [x] Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check [here](https://github.com/opensearch-project/OpenSearch/blob/main/CONTRIBUTING.md#developer-certificate-of-origin).


Diff:
diff --git a/.cypress/integration/1_detectors.spec.js b/.cypress/integration/1_detectors.spec.js
index 42a9355bc..7ffc70b20 100644
--- a/.cypress/integration/1_detectors.spec.js
+++ b/.cypress/integration/1_detectors.spec.js
@@ -103,15 +103,18 @@ const validateAutomaticFieldMappingsPanel = (mappings) =>
   });
 
 const validatePendingFieldMappingsPanel = (mappings) => {
-  cy.get('.editFieldMappings').within(() => {
-    // Pending field mappings
-    cy.getElementByText('.euiText', 'Pending field mappings')
-      .parents('.euiPanel')
-      .within(() => {
-        cy.getElementByTestSubject('pending-mapped-fields-table')
-          .find('.euiBasicTable')
-          .validateTable(mappings);
-      });
+  cy.get('.editFieldMappings').each(($element) => {
+    cy.wrap($element).within(() => {
+      // Pending field mappings
+      cy.getElementByText('.euiText', 'Pending field mappings')
+        .parents('.euiPanel')
+        .first()
+        .within(() => {
+          cy.getElementByTestSubject('pending-mapped-fields-table')
+            .find('.euiBasicTable')
+            .validateTable(mappings);
+        });
+    });
   });
 };
 
@@ -312,7 +315,7 @@ describe('Detectors', () => {
         .blur()
         .parentsUntil('.euiFormRow__fieldWrapper')
         .siblings()
-        .contains('Select an input source.');
+        .contains('Select an input source for the detector.');
 
       getDataSourceField().selectComboboxItem(cypressIndexDns);
       getDataSourceField()
diff --git a/.cypress/integration/2_rules.spec.js b/.cypress/integration/2_rules.spec.js
index fae4c028a..f4f3ac762 100644
--- a/.cypress/integration/2_rules.spec.js
+++ b/.cypress/integration/2_rules.spec.js
@@ -288,7 +288,8 @@ describe('Rules', () => {
 
     it('...should validate log type field', () => {
       getLogTypeField().should('be.empty');
-      getLogTypeField().focus().blur();
+      cy.get('[data-test-subj="comboBoxInput"]').first().click();
+      cy.get('[data-test-subj="comboBoxInput"]').eq(1).click();
       getLogTypeField().containsError('Log type is required');
 
       getLogTypeField().selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType));
@@ -296,8 +297,8 @@ describe('Rules', () => {
     });
 
     it('...should validate rule level field', () => {
-      getRuleLevelField().should('be.empty');
-      getRuleLevelField().focus().blur();
+      cy.get('[data-test-subj="comboBoxInput"]').eq(1).click();
+      cy.get('[data-test-subj="comboBoxInput"]').first().click();
       getRuleLevelField().containsError('Rule level is required');
 
       getRuleLevelField().selectComboboxItem(SAMPLE_RULE.severity);
@@ -309,7 +310,8 @@ describe('Rules', () => {
       getRuleStatusField().focus().blur().shouldNotHaveError();
 
       getRuleStatusField().clearCombobox();
-      getRuleStatusField().focus().blur();
+      cy.get('[data-test-subj="comboBoxInput"]').eq(2).click();
+      cy.get('[data-test-subj="comboBoxInput"]').first().click();
       getRuleStatusField().containsError('Rule status is required');
     });
 
diff --git a/.cypress/support/helpers.js b/.cypress/support/helpers.js
index b3dbb1ff6..1d7ee4530 100644
--- a/.cypress/support/helpers.js
+++ b/.cypress/support/helpers.js
@@ -226,16 +226,15 @@ Cypress.Commands.add(
         const length = data.length;
         length && cy.get($tr).should('have.length', length);
 
-        cy.get($tr).within(($tr) => {
-          data.map((rowData) => {
-            rowData.forEach((tdData) => {
-              if (typeof tdData === 'string') {
-                tdData && cy.get($tr).find('td').contains(`${tdData}`);
-              } else {
-                // if rule is an object then use path
-                tdData && cy.get($tr).find('td').contains(`${tdData.path}`);
+        data.forEach((rowData) => {
+          rowData.forEach((tdData) => {
+            if (typeof tdData === 'string') {
+              if (tdData) {
+                cy.get($tr).contains(tdData).should('exist').and('be.visible');
               }
-            });
+            } else if (tdData && tdData.path) {
+              cy.get($tr).contains(tdData.path).should('exist').and('be.visible');
+            }
           });
         });
       });
diff --git a/.cypress/support/typings.js b/.cypress/support/typings.js
index 594be5a6a..3eaef488a 100644
--- a/.cypress/support/typings.js
+++ b/.cypress/support/typings.js
@@ -9,7 +9,7 @@ Cypress.Commands.add(
     prevSubject: true,
   },
   (subject, text) => {
-    return cy.get(subject).clear().ospType(text).realPress('Enter');
+    return cy.get(subject).clear().ospType(text).type('{enter}');
   }
 );
 
@@ -34,7 +34,7 @@ Cypress.Commands.add(
     prevSubject: true,
   },
   (subject, text) => {
-    return cy.get(subject).wait(10).focus().realType(text);
+    return cy.get(subject).wait(10).focus().type(text);
   }
 );
 
diff --git a/.github/workflows/cypress-workflow.yml b/.github/workflows/cypress-workflow.yml
index c80f84190..4ef2cce71 100644
--- a/.github/workflows/cypress-workflow.yml
+++ b/.github/workflows/cypress-workflow.yml
@@ -2,10 +2,10 @@ name: Cypress integration tests workflow
 on:
   pull_request:
     branches:
-      - "*"
+      - '*'
   push:
     branches:
-      - "*"
+      - '*'
 env:
   OPENSEARCH_DASHBOARDS_VERSION: 'main'
   OPENSEARCH_VERSION: '3.0.0-beta1-SNAPSHOT'
@@ -132,10 +132,10 @@ jobs:
         uses: cypress-io/github-action@v5
         with:
           working-directory: OpenSearch-Dashboards/plugins/security-analytics-dashboards-plugin
-          command: yarn run cypress run
+          command: yarn run cypress run --browser firefox
           wait-on: 'http://localhost:5601'
           wait-on-timeout: 300
-          browser: chrome
+          browser: firefox
         env:
           CYPRESS_CACHE_FOLDER: ${{ matrix.cypress_cache_folder }}
 


Reviews:
user: login: AWSHurneyt
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-16T00:06:02Z
user: login: amsiglan
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-16T00:10:03Z
user: login: amsiglan
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-16T00:10:47Z
user: login: vikhy-aws
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-16T00:20:11Z
user: login: amsiglan
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-16T00:23:41Z

Review comments:
diff_hunk: @@ -288,16 +288,17 @@ describe('Rules', () => {
 
     it('...should validate log type field', () => {
       getLogTypeField().should('be.empty');
-      getLogTypeField().focus().blur();
+      cy.get('[data-test-subj="comboBoxInput"]').first().click();
path: .cypress/integration/2_rules.spec.js
user: login: amsiglan
body: Should we instead fix the method `getLogTypeField`?
created_at: 2025-04-16T00:10:03Z
author_association: COLLABORATOR
diff_hunk: @@ -288,16 +288,17 @@ describe('Rules', () => {
 
     it('...should validate log type field', () => {
       getLogTypeField().should('be.empty');
-      getLogTypeField().focus().blur();
+      cy.get('[data-test-subj="comboBoxInput"]').first().click();
path: .cypress/integration/2_rules.spec.js
user: login: vikhy-aws
body: `getLogTypeField` works as expected. The problem is with `blur()`, it does not work as expected with firefox browser and is flaky sometimes and does not dismiss the dropdown. Using the current approach, we click the intended dropdown to expand it, then click on the other dropdown to close the current dropdown which ensures the condition that we need to select some input on that dropdown.

However, I have a suspicion that because `focus()` and `blur()` are chained together, that may be causing it to be flaky. Need to test this out and it would need to be updated at multiple places. So, was thinking of doing that in a different PR if it works out.
created_at: 2025-04-16T00:20:10Z
author_association: COLLABORATOR
diff_hunk: @@ -288,16 +288,17 @@ describe('Rules', () => {
 
     it('...should validate log type field', () => {
       getLogTypeField().should('be.empty');
-      getLogTypeField().focus().blur();
+      cy.get('[data-test-subj="comboBoxInput"]').first().click();
path: .cypress/integration/2_rules.spec.js
user: login: amsiglan
body: maybe calling blur immediately after focus causes issue, but okay for now. Will wait for the follow up
created_at: 2025-04-16T00:23:41Z
author_association: COLLABORATOR

PR comments:
user: login: vikhy-aws
created_at: 2025-04-15T21:47:43Z
body: `security-analytics plugin` is not starting properly in windows. Will investigate that separately. This PR fixes the integration tests.
author_association: COLLABORATOR
user: login: vikhy-aws
created_at: 2025-04-15T21:55:21Z
body: Cypress version **13.6.0** has memory management issue on chromium based browsers due to which the tests keep on crashing. So, changed the browser to **firefox** which does not experience such issues.
author_association: COLLABORATOR