diff --git a/cypress/integration/1_detectors.spec.js b/cypress/integration/1_detectors.spec.js
index b40ed8db4..74dd7119b 100644
--- a/cypress/integration/1_detectors.spec.js
+++ b/cypress/integration/1_detectors.spec.js
@@ -37,7 +37,6 @@ describe('Detectors', () => {
before(() => {
cy.cleanUpTests();
-
// Create test index
cy.createIndex(indexName, sample_index_settings);
@@ -56,7 +55,7 @@ describe('Detectors', () => {
it('...can be created', () => {
// Locate Create detector button click to start
- cy.contains('Create detector').click({ force: true });
+ cy.get('.euiButton').filter(':contains("Create detector")').click({ force: true });
// Check to ensure process started
cy.waitForPageLoad('create-detector', {
@@ -64,29 +63,41 @@ describe('Detectors', () => {
});
// Enter a name for the detector in the appropriate input
- cy.get(`input[placeholder="Enter a name for the detector."]`).type('test detector{enter}');
+ cy.get(`input[placeholder="Enter a name for the detector."]`).focus().realType('test detector');
// Select our pre-seeded data source (check indexName)
- cy.get(`[data-test-subj="define-detector-select-data-source"]`).type(`${indexName}{enter}`);
+ cy.get(`[data-test-subj="define-detector-select-data-source"]`)
+ .find('input')
+ .focus()
+ .realType(indexName);
+
+ cy.intercept({
+ pathname: '/_plugins/_security_analytics/rules/_search',
+ query: {
+ prePackaged: 'true',
+ },
+ }).as('getSigmaRules');
// Select threat detector type (Windows logs)
cy.get(`input[id="windows"]`).click({ force: true });
- // Open Detection rules accordion
- cy.get('[data-test-subj="detection-rules-btn"]').click({ timeout: 5000 });
+ cy.wait('@getSigmaRules').then(() => {
+ // Open Detection rules accordion
+ cy.get('[data-test-subj="detection-rules-btn"]').click({ force: true, timeout: 5000 });
- // find search, type USB
- cy.triggerSearchField('Search...', 'USB Device Plugged');
+ // find search, type USB
+ cy.get(`input[placeholder="Search..."]`).ospSearch('USB Device Plugged');
- // Disable all rules
- cy.contains('tr', 'USB Device Plugged', { timeout: 20000 });
- cy.get('th').within(() => {
- cy.get('button').first().click({ force: true });
- });
+ // Disable all rules
+ cy.contains('tr', 'USB Device Plugged', { timeout: 1000 });
+ cy.get('table th').within(() => {
+ cy.get('button').first().click({ force: true });
+ });
- // enable single rule
- cy.contains('tr', 'USB Device Plugged').within(() => {
- cy.get('button').eq(1).click({ force: true });
+ // Enable single rule
+ cy.contains('table tr', 'USB Device Plugged').within(() => {
+ cy.get('button').eq(1).click({ force: true });
+ });
});
// Click Next button to continue
@@ -119,10 +130,16 @@ describe('Detectors', () => {
cy.contains('Set up alerts');
// Type name of new trigger
- cy.get(`input[placeholder="Enter a name for the alert condition."]`).type('test_trigger');
+ cy.get(`input[placeholder="Enter a name for the alert condition."]`)
+ .focus()
+ .realType('test_trigger');
// Type in (or select) tags for the alert condition
- cy.get(`[data-test-subj="alert-tags-combo-box"]`).type('attack.defense_evasion{enter}');
+ cy.get(`[data-test-subj="alert-tags-combo-box"]`)
+ .find('input')
+ .focus()
+ .realType('attack.defense_evasion')
+ .realPress('Enter');
// Select applicable severity levels
cy.get(`[data-test-subj="security-levels-combo-box"]`).click({ force: true });
@@ -191,18 +208,26 @@ describe('Detectors', () => {
});
// Change detector name
- cy.get(`[data-test-subj="define-detector-detector-name"]`).type('_edited');
+ cy.get(`input[placeholder="Enter a name for the detector."]`)
+ .realClick()
+ .ospClear()
+ .realType('test detector edited');
// Change detector description
- cy.get(`[data-test-subj="define-detector-detector-description"]`).type('Edited description');
+ cy.get(`[data-test-subj="define-detector-detector-description"]`)
+ .focus()
+ .realType('Edited description');
// Change input source
- cy.get(`[data-test-subj="define-detector-select-data-source"]`).type(
- '{backspace}.opensearch-notifications-config{enter}'
- );
+ cy.get(`[data-test-subj="define-detector-select-data-source"]`)
+ .find('input')
+ .ospClear()
+ .focus()
+ .realType('.opensearch-notifications-config')
+ .realPress('Enter');
// Change detector scheduling
- cy.get(`[data-test-subj="detector-schedule-number-select"]`).type('{selectall}10');
+ cy.get(`[data-test-subj="detector-schedule-number-select"]`).ospClear().focus().realType('10');
cy.get(`[data-test-subj="detector-schedule-unit-select"]`).select('Hours');
// Save changes to detector details
@@ -214,7 +239,7 @@ describe('Detectors', () => {
});
// Verify edits are applied
- cy.contains('test detector_edited');
+ cy.contains('test detector edited');
cy.contains('Every 10 hours');
cy.contains('Edited description');
cy.contains('.opensearch-notifications-config');
@@ -239,16 +264,15 @@ describe('Detectors', () => {
cy.get(`[data-test-subj="edit-detector-rules"]`).click({ force: true });
// Confirm arrival on "Edit detector rules" page
- cy.url().should(
- 'include',
- 'http://localhost:5601/app/opensearch_security_analytics_dashboards#/edit-detector-rules'
- );
+ cy.waitForPageLoad('edit-detector-rules', {
+ contains: 'Edit detector rules',
+ });
// Search for specific rule
- cy.triggerSearchField('Search...', 'USB Device');
+ cy.get(`input[placeholder="Search..."]`).ospSearch('USB Device');
// Toggle single search result to unchecked
- cy.contains('tr', 'USB Device Plugged').within(() => {
+ cy.contains('table tr', 'USB Device Plugged').within(() => {
// Of note, timeout can sometimes work instead of wait here, but is very unreliable from case to case.
cy.wait(1000);
cy.get('button').eq(1).click();
@@ -269,10 +293,10 @@ describe('Detectors', () => {
});
// Search for specific rule
- cy.triggerSearchField('Search...', 'USB');
+ cy.get(`input[placeholder="Search..."]`).ospSearch('USB');
// Toggle single search result to checked
- cy.contains('tr', 'USB Device Plugged').within(() => {
+ cy.contains('table tr', 'USB Device Plugged').within(() => {
cy.wait(2000);
cy.get('button').eq(1).click({ force: true });
});
@@ -289,7 +313,7 @@ describe('Detectors', () => {
it('...can be deleted', () => {
// Click on detector to be removed
- cy.contains('test detector_edited').click({ force: true });
+ cy.contains('test detector edited').click({ force: true });
// Confirm page
cy.waitForPageLoad('detector-details', {
@@ -297,8 +321,8 @@ describe('Detectors', () => {
});
// Click "Actions" button, the click "Delete"
- cy.contains('Actions').click({ force: true });
- cy.contains('Delete').click({ force: true });
+ cy.get('button').contains('Actions').click({ force: true });
+ cy.get('button').contains('Delete').click({ force: true });
// Confirm detector is deleted
cy.contains('There are no existing detectors');
diff --git a/cypress/integration/2_rules.spec.js b/cypress/integration/2_rules.spec.js
index eff0cff07..70fe548ba 100644
--- a/cypress/integration/2_rules.spec.js
+++ b/cypress/integration/2_rules.spec.js
@@ -121,7 +121,7 @@ describe('Rules', () => {
cy.wait('@getRules');
// Search for the rule
- cy.triggerSearchField('Search rules', SAMPLE_RULE.name);
+ cy.get(`input[placeholder="Search rules"]`).ospSearch(SAMPLE_RULE.name);
// Click the rule link to open the details flyout
cy.get(`[data-test-subj="rule_link_${SAMPLE_RULE.name}"]`).click({ force: true });
@@ -204,7 +204,7 @@ describe('Rules', () => {
url: '/rules',
}).as('deleteRule');
- cy.triggerSearchField('Search rules', SAMPLE_RULE.name);
+ cy.get(`input[placeholder="Search rules"]`).ospSearch(SAMPLE_RULE.name);
// Click the rule link to open the details flyout
cy.get(`[data-test-subj="rule_link_${SAMPLE_RULE.name}"]`).click({ force: true });
@@ -227,7 +227,7 @@ describe('Rules', () => {
cy.wait('@deleteRule');
// Search for sample_detector, presumably deleted
- cy.triggerSearchField('Search rules', SAMPLE_RULE.name);
+ cy.get(`input[placeholder="Search rules"]`).ospSearch(SAMPLE_RULE.name);
// Click the rule link to open the details flyout
cy.get('tbody').contains(SAMPLE_RULE.name).should('not.exist');
});
diff --git a/cypress/integration/4_findings.spec.js b/cypress/integration/4_findings.spec.js
index cd8025433..0629e111f 100644
--- a/cypress/integration/4_findings.spec.js
+++ b/cypress/integration/4_findings.spec.js
@@ -56,7 +56,7 @@ describe('Findings', () => {
it('displays finding details flyout when user clicks on View details icon', () => {
// filter table to show only sample_detector findings
- cy.triggerSearchField('Search findings', 'sample_detector');
+ cy.get(`input[placeholder="Search findings"]`).ospSearch('sample_detector');
// Click View details icon
cy.getTableFirstRow('[data-test-subj="view-details-icon"]').then(($el) => {
@@ -73,7 +73,7 @@ describe('Findings', () => {
it('displays finding details flyout when user clicks on Finding ID', () => {
// filter table to show only sample_detector findings
- cy.triggerSearchField('Search findings', 'sample_detector');
+ cy.get(`input[placeholder="Search findings"]`).ospSearch('sample_detector');
// Click findingId to trigger Finding details flyout
cy.getTableFirstRow('[data-test-subj="finding-details-flyout-button"]').then(($el) => {
@@ -90,7 +90,7 @@ describe('Findings', () => {
it('allows user to view details about rules that were triggered', () => {
// filter table to show only sample_detector findings
- cy.triggerSearchField('Search findings', 'sample_detector');
+ cy.get(`input[placeholder="Search findings"]`).ospSearch('sample_detector');
// open Finding details flyout via finding id link. cy.wait essential, timeout insufficient.
cy.get(`[data-test-subj="view-details-icon"]`).eq(0).click({ force: true });
@@ -116,7 +116,7 @@ describe('Findings', () => {
it('opens rule details flyout when rule name inside accordion drop down is clicked', () => {
// filter table to show only sample_detector findings
- cy.triggerSearchField('Search findings', 'sample_detector');
+ cy.get(`input[placeholder="Search findings"]`).ospSearch('sample_detector');
// open Finding details flyout via finding id link. cy.wait essential, timeout insufficient.
cy.getTableFirstRow('[data-test-subj="view-details-icon"]').then(($el) => {
@@ -142,7 +142,7 @@ describe('Findings', () => {
});
// filter table to show only sample_detector findings
- cy.triggerSearchField('Search threat detectors', 'sample_detector');
+ cy.get(`input[placeholder="Search threat detectors"]`).ospSearch('sample_detector');
// intercept detectors and rules requests
cy.intercept('detectors/_search').as('getDetector');
@@ -166,7 +166,7 @@ describe('Findings', () => {
cy.get('[data-test-subj="editButton"]').contains('Delete').click({ force: true });
// Search for sample_detector, presumably deleted
- cy.triggerSearchField('Search threat detectors', 'sample_detector');
+ cy.get(`input[placeholder="Search threat detectors"]`).ospSearch('sample_detector');
// Confirm sample_detector no longer exists
cy.contains('There are no existing detectors.');
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index 7ab68f3da..a318227df 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -3,7 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
-const { NODE_API, OPENSEARCH_DASHBOARDS, OPENSEARCH_DASHBOARDS_URL } = require('./constants');
+const { OPENSEARCH_DASHBOARDS_URL } = require('./constants');
+require('./detectors');
+require('./rules');
+require('./indexes');
+require('./typings');
+
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
@@ -94,183 +99,14 @@ Cypress.Commands.add('getTableFirstRow', (selector) => {
return cy.get('tbody > tr:first').find(selector);
});
-Cypress.Commands.add('triggerSearchField', (placeholder, text) => {
- cy.get(`[placeholder="${placeholder}"]`).type(`{selectall}${text}`).realPress('Enter');
-});
-
-Cypress.Commands.add('waitForPageLoad', (url, { timeout = 10000, contains = null }) => {
- const fullUrl = `${OPENSEARCH_DASHBOARDS_URL}/${url}`;
+Cypress.Commands.add('waitForPageLoad', (pathname, { timeout = 60000, contains = null }) => {
+ const fullUrl = `${OPENSEARCH_DASHBOARDS_URL}/${pathname}`;
Cypress.log({
message: `Wait for url: ${fullUrl} to be loaded.`,
});
cy.url({ timeout: timeout })
.should('include', fullUrl)
.then(() => {
- contains && cy.contains(contains);
- });
-});
-
-Cypress.Commands.add('deleteAllIndices', () => {
- cy.request({
- method: 'DELETE',
- url: `${Cypress.env('opensearch')}/index*,sample*,opensearch_dashboards*,test*,cypress*`,
- failOnStatusCode: false,
- });
-});
-
-Cypress.Commands.add('deleteAllDetectors', () => {
- cy.request({
- method: 'DELETE',
- url: `${Cypress.env('opensearch')}/.opensearch-sap-detectors-config`,
- failOnStatusCode: false,
- });
-});
-
-Cypress.Commands.add('createDetector', (detectorJSON) => {
- cy.request('POST', `${Cypress.env('opensearch')}${NODE_API.DETECTORS_BASE}`, detectorJSON);
-});
-
-Cypress.Commands.add('updateDetector', (detectorId, detectorJSON) => {
- cy.request(
- 'PUT',
- `${Cypress.env('opensearch')}/${NODE_API.DETECTORS_BASE}/${detectorId}`,
- detectorJSON
- );
-});
-
-Cypress.Commands.add('deleteDetector', (detectorName) => {
- const body = {
- from: 0,
- size: 5000,
- query: {
- nested: {
- path: 'detector',
- query: {
- bool: {
- must: [{ match: { 'detector.name': detectorName } }],
- },
- },
- },
- },
- };
- cy.request({
- method: 'POST',
- url: `${Cypress.env('opensearch')}${NODE_API.DETECTORS_BASE}/_search`,
- failOnStatusCode: false,
- body,
- }).then((response) => {
- if (response.status === 200) {
- for (let hit of response.body.hits.hits) {
- cy.request('DELETE', `${Cypress.env('opensearch')}${NODE_API.DETECTORS_BASE}/${hit._id}`);
- }
- }
- });
-});
-
-Cypress.Commands.add('deleteIndex', (indexName, options = {}) => {
- cy.request({
- method: 'DELETE',
- url: `${Cypress.env('opensearch')}/${indexName}`,
- failOnStatusCode: false,
- ...options,
- });
-});
-
-Cypress.Commands.add(
- 'createAliasMappings',
- (indexName, ruleTopic, aliasMappingsBody, partial = true) => {
- const body = {
- index_name: indexName,
- rule_topic: ruleTopic,
- partial: partial,
- alias_mappings: aliasMappingsBody,
- };
- cy.request({
- method: 'POST',
- url: `${Cypress.env('opensearch')}${NODE_API.MAPPINGS_BASE}`,
- body: body,
+ contains && cy.contains(contains).should('be.visible');
});
- }
-);
-
-Cypress.Commands.add('createRule', (ruleJSON) => {
- return cy.request({
- method: 'POST',
- url: `${OPENSEARCH_DASHBOARDS}${NODE_API.RULES_BASE}?category=${ruleJSON.category}`,
- body: JSON.stringify(ruleJSON),
- });
-});
-
-Cypress.Commands.add('updateRule', (ruleId, ruleJSON) => {
- cy.request('PUT', `${Cypress.env('opensearch')}/${NODE_API.RULES_BASE}/${ruleId}`, ruleJSON);
-});
-
-Cypress.Commands.add('createIndex', (index, settings = {}) => {
- cy.request('PUT', `${Cypress.env('opensearch')}/${index}`, settings);
-});
-
-Cypress.Commands.add('ingestDocument', (indexId, documentJSON) => {
- cy.request('POST', `${Cypress.env('opensearch')}/${indexId}/_doc`, documentJSON);
-});
-
-Cypress.Commands.add('deleteRule', (ruleName) => {
- const body = {
- from: 0,
- size: 5000,
- query: {
- nested: {
- path: 'rule',
- query: {
- bool: {
- must: [{ match: { 'rule.title': 'Cypress test rule' } }],
- },
- },
- },
- },
- };
- cy.request({
- method: 'POST',
- url: `${Cypress.env('opensearch')}${NODE_API.RULES_BASE}/_search?pre_packaged=false`,
- failOnStatusCode: false,
- body,
- }).then((response) => {
- if (response.status === 200) {
- for (let hit of response.body.hits.hits) {
- if (hit._source.title === ruleName)
- cy.request(
- 'DELETE',
- `${Cypress.env('opensearch')}${NODE_API.RULES_BASE}/${hit._id}?forced=true`
- );
- }
- }
- });
-});
-
-Cypress.Commands.add('deleteAllCustomRules', () => {
- cy.request({
- method: 'DELETE',
- url: `${Cypress.env('opensearch')}/.opensearch-sap-custom-rules-config`,
- failOnStatusCode: false,
- body: { query: { match_all: {} } },
- });
-});
-
-Cypress.Commands.add('createIndex', (index, settings = {}) => {
- cy.request('PUT', `${Cypress.env('opensearch')}/${index}`, settings);
-});
-
-Cypress.Commands.add('createIndexTemplate', (name, template) => {
- cy.request(
- 'PUT',
- `${Cypress.env('opensearch')}${NODE_API.INDEX_TEMPLATE_BASE}/${name}`,
- template
- );
-});
-
-Cypress.Commands.add('insertDocumentToIndex', (indexName, documentId, documentBody) => {
- cy.request({
- method: 'POST',
- url: `${Cypress.env('opensearch')}/${indexName}/_doc/${documentId}`,
- body: documentBody,
- });
});
diff --git a/cypress/support/detectors.js b/cypress/support/detectors.js
new file mode 100644
index 000000000..b0ec6c60f
--- /dev/null
+++ b/cypress/support/detectors.js
@@ -0,0 +1,72 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+const { NODE_API } = require('./constants');
+
+Cypress.Commands.add('createDetector', (detectorJSON) => {
+ cy.request('POST', `${Cypress.env('opensearch')}${NODE_API.DETECTORS_BASE}`, detectorJSON);
+});
+
+Cypress.Commands.add(
+ 'createAliasMappings',
+ (indexName, ruleTopic, aliasMappingsBody, partial = true) => {
+ const body = {
+ index_name: indexName,
+ rule_topic: ruleTopic,
+ partial: partial,
+ alias_mappings: aliasMappingsBody,
+ };
+ cy.request({
+ method: 'POST',
+ url: `${Cypress.env('opensearch')}${NODE_API.MAPPINGS_BASE}`,
+ body: body,
+ });
+ }
+);
+
+Cypress.Commands.add('updateDetector', (detectorId, detectorJSON) => {
+ cy.request(
+ 'PUT',
+ `${Cypress.env('opensearch')}/${NODE_API.DETECTORS_BASE}/${detectorId}`,
+ detectorJSON
+ );
+});
+
+Cypress.Commands.add('deleteDetector', (detectorName) => {
+ const body = {
+ from: 0,
+ size: 5000,
+ query: {
+ nested: {
+ path: 'detector',
+ query: {
+ bool: {
+ must: [{ match: { 'detector.name': detectorName } }],
+ },
+ },
+ },
+ },
+ };
+ cy.request({
+ method: 'POST',
+ url: `${Cypress.env('opensearch')}${NODE_API.DETECTORS_BASE}/_search`,
+ failOnStatusCode: false,
+ body,
+ }).then((response) => {
+ if (response.status === 200) {
+ for (let hit of response.body.hits.hits) {
+ cy.request('DELETE', `${Cypress.env('opensearch')}${NODE_API.DETECTORS_BASE}/${hit._id}`);
+ }
+ }
+ });
+});
+
+Cypress.Commands.add('deleteAllDetectors', () => {
+ cy.request({
+ method: 'DELETE',
+ url: `${Cypress.env('opensearch')}/.opensearch-sap-detectors-config`,
+ failOnStatusCode: false,
+ });
+});
diff --git a/cypress/support/index.d.ts b/cypress/support/index.d.ts
index 2af6cf0b6..104581c1e 100644
--- a/cypress/support/index.d.ts
+++ b/cypress/support/index.d.ts
@@ -3,53 +3,87 @@
* SPDX-License-Identifier: Apache-2.0
*/
+// eslint-disable-next-line
///
declare namespace Cypress {
interface Chainable {
/**
- * Wait for page to be loaded
- * @param {string} url
- * @param {number} timeout
+ * Removes custom indices, detectors and rules
* @example
- * cy.waitForPageLoad('detectors')
- * cy.waitForPageLoad('detectors', 20000)
+ * cy.cleanUpTests()
*/
- waitForPageLoad(url: string, timeout?: number): Chainable;
+ cleanUpTests(): Chainable;
/**
- * Deletes all indices in cluster
+ * Returns table first row
+ * Finds elements deeper in a row with selector
+ * @param {string} selector
* @example
- * cy.deleteAllIndices()
+ * cy.getTableFirstRow()
+ * cy.getTableFirstRow('td')
*/
- deleteAllIndices(): Chainable;
+ getTableFirstRow(selector: string): Chainable;
/**
- * Removes custom rules, detectors and indices
+ * Waits for page to be loaded
+ * @param {string} pathname
+ * @param {any} opts
* @example
- * cy.cleanUpTests()
+ * cy.waitForPageLoad('detectors')
+ * cy.waitForPageLoad('detectors', {
+ * timeout: 20000,
+ * contains: 'text to verify'
+ * })
*/
- cleanUpTests(): Chainable;
+ waitForPageLoad(pathname: string, opts?: any): Chainable;
/**
* Returns table first row
* Can find elements deeper in a row with selector
- * @param {string} selector
+ * @param {string} text
* @example
- * cy.getTableFirstRow()
- * cy.getTableFirstRow('td')
+ * cy.get('selector').ospSearch('Txt to write into input')
*/
- getTableFirstRow(selector: string): Chainable;
+ ospSearch(text: string): Chainable;
+
+ /**
+ * Clears input text
+ * @example
+ * cy.get('selector').ospClear()
+ */
+ ospClear(): Chainable;
/**
* Returns table first row
* Can find elements deeper in a row with selector
- * @param {string} placeholder
* @param {string} text
* @example
- * cy.triggerSearchField('Search rules', 'USB Detection Rule')
+ * cy.get('selector').ospType('Txt to write into input')
*/
- triggerSearchField(placeholder: string, text: string): Chainable;
+ ospType(text: string): Chainable;
+
+ /**
+ * Creates index with policy
+ * @example
+ * cy.createIndex("some_index", "some_policy")
+ */
+ createIndex(index: string, settings?: object): Chainable;
+
+ /**
+ * Creates an index template.
+ * @example
+ * cy.createIndexTemplate("some_index_template", { "index_patterns": "abc", "properties": { ... } })
+ */
+ createIndexTemplate(name: string, template: object): Chainable;
+
+ /**
+ /**
+ * Deletes all indices in cluster
+ * @example
+ * cy.deleteAllIndices()
+ */
+ deleteAllIndices(): Chainable;
/**
* Deletes all custom rules in cluster
@@ -98,20 +132,6 @@ declare namespace Cypress {
*/
updateDetector(detectorId: string, detectorJSON: object): Chainable;
- /**
- * Creates index with policy
- * @example
- * cy.createIndex("some_index", "some_policy")
- */
- createIndex(index: string, settings?: object): Chainable;
-
- /**
- * Creates an index template.
- * @example
- * cy.createIndexTemplate("some_index_template", { "index_patterns": "abc", "properties": { ... } })
- */
- createIndexTemplate(name: string, template: object): Chainable;
-
/**
* Deletes detector by its name
* @example
diff --git a/cypress/support/indexes.js b/cypress/support/indexes.js
new file mode 100644
index 000000000..1ffc22116
--- /dev/null
+++ b/cypress/support/indexes.js
@@ -0,0 +1,47 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+const { NODE_API } = require('./constants');
+
+Cypress.Commands.add('createIndex', (index, settings = {}) => {
+ cy.request('PUT', `${Cypress.env('opensearch')}/${index}`, settings);
+});
+
+Cypress.Commands.add('createIndexTemplate', (name, template) => {
+ cy.request(
+ 'PUT',
+ `${Cypress.env('opensearch')}${NODE_API.INDEX_TEMPLATE_BASE}/${name}`,
+ template
+ );
+});
+
+Cypress.Commands.add('ingestDocument', (indexId, documentJSON) => {
+ cy.request('POST', `${Cypress.env('opensearch')}/${indexId}/_doc`, documentJSON);
+});
+
+Cypress.Commands.add('insertDocumentToIndex', (indexName, documentId, documentBody) => {
+ cy.request({
+ method: 'POST',
+ url: `${Cypress.env('opensearch')}/${indexName}/_doc/${documentId}`,
+ body: documentBody,
+ });
+});
+
+Cypress.Commands.add('deleteIndex', (indexName, options = {}) => {
+ cy.request({
+ method: 'DELETE',
+ url: `${Cypress.env('opensearch')}/${indexName}`,
+ failOnStatusCode: false,
+ ...options,
+ });
+});
+
+Cypress.Commands.add('deleteAllIndices', () => {
+ cy.request({
+ method: 'DELETE',
+ url: `${Cypress.env('opensearch')}/index*,sample*,opensearch_dashboards*,test*,cypress*`,
+ failOnStatusCode: false,
+ });
+});
diff --git a/cypress/support/rules.js b/cypress/support/rules.js
new file mode 100644
index 000000000..46f01b3b7
--- /dev/null
+++ b/cypress/support/rules.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+const { OPENSEARCH_DASHBOARDS, NODE_API } = require('./constants');
+
+Cypress.Commands.add('createRule', (ruleJSON) => {
+ return cy.request({
+ method: 'POST',
+ url: `${OPENSEARCH_DASHBOARDS}${NODE_API.RULES_BASE}?category=${ruleJSON.category}`,
+ body: JSON.stringify(ruleJSON),
+ });
+});
+
+Cypress.Commands.add('updateRule', (ruleId, ruleJSON) => {
+ cy.request('PUT', `${Cypress.env('opensearch')}/${NODE_API.RULES_BASE}/${ruleId}`, ruleJSON);
+});
+
+Cypress.Commands.add('deleteRule', (ruleName) => {
+ const body = {
+ from: 0,
+ size: 5000,
+ query: {
+ nested: {
+ path: 'rule',
+ query: {
+ bool: {
+ must: [{ match: { 'rule.title': 'Cypress test rule' } }],
+ },
+ },
+ },
+ },
+ };
+ cy.request({
+ method: 'POST',
+ url: `${Cypress.env('opensearch')}${NODE_API.RULES_BASE}/_search?pre_packaged=false`,
+ failOnStatusCode: false,
+ body,
+ }).then((response) => {
+ if (response.status === 200) {
+ for (let hit of response.body.hits.hits) {
+ if (hit._source.title === ruleName)
+ cy.request(
+ 'DELETE',
+ `${Cypress.env('opensearch')}${NODE_API.RULES_BASE}/${hit._id}?forced=true`
+ );
+ }
+ }
+ });
+});
+
+Cypress.Commands.add('deleteAllCustomRules', () => {
+ cy.request({
+ method: 'DELETE',
+ url: `${Cypress.env('opensearch')}/.opensearch-sap-custom-rules-config`,
+ failOnStatusCode: false,
+ body: { query: { match_all: {} } },
+ });
+});
diff --git a/cypress/support/typings.js b/cypress/support/typings.js
new file mode 100644
index 000000000..4345d7e0b
--- /dev/null
+++ b/cypress/support/typings.js
@@ -0,0 +1,39 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+Cypress.Commands.add(
+ 'ospSearch',
+ {
+ prevSubject: true,
+ },
+ (subject, text) => {
+ return cy.get(subject).ospType(text).realPress('Enter');
+ }
+);
+
+Cypress.Commands.add(
+ 'ospClear',
+ {
+ prevSubject: true,
+ },
+ (subject) => {
+ return cy
+ .get(subject)
+ .wait(100)
+ .type('{selectall}{backspace}')
+ .clear({ force: true })
+ .invoke('val', '');
+ }
+);
+
+Cypress.Commands.add(
+ 'ospType',
+ {
+ prevSubject: true,
+ },
+ (subject, text) => {
+ return cy.get(subject).wait(10).focus().realType(text);
+ }
+);