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); + } +);