Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add role edit cypress tests #377

1 change: 1 addition & 0 deletions cypress.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"viewportHeight": 900,
"viewportWidth": 1440,
"defaultCommandTimeout": 20000,
"baseUrl": "http://localhost:5601",
"env": {
"opensearch_url": "localhost:9200",
"opensearch_dashboards": "http://localhost:5601",
Expand Down
14 changes: 14 additions & 0 deletions cypress/integration/1_detectors.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ describe('Detectors', () => {
cy.cleanUpTests();
// Create test index
cy.createIndex(indexName, sample_index_settings);
cy.request('POST', '_plugins/_security_analytics/rules/_search?prePackaged=true', {
from: 0,
size: 5000,
query: {
nested: {
path: 'rule',
query: { bool: { must: [{ match: { 'rule.category': 'windows' } }] } },
},
},
});

cy.contains(detectorName).should('not.exist');
});
Expand Down Expand Up @@ -85,6 +95,10 @@ describe('Detectors', () => {
// Open Detection rules accordion
cy.get('[data-test-subj="detection-rules-btn"]').click({ force: true, timeout: 5000 });

cy.contains('table tr', 'Windows', {
timeout: 120000,
});

// find search, type USB
cy.get(`input[placeholder="Search..."]`).ospSearch('USB Device Plugged');

Expand Down
207 changes: 134 additions & 73 deletions cypress/integration/2_rules.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,86 @@ const YAML_RULE_LINES = [
...SAMPLE_RULE.detection.replaceAll(' ', '').replaceAll('{backspace}', '').split('\n'),
];

const checkRulesFlyout = () => {
// Search for the rule
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 });

// Confirm the flyout contains the expected values
cy.get(`[data-test-subj="rule_flyout_${SAMPLE_RULE.name}"]`)
.click({ force: true })
.within(() => {
// Validate name
cy.get('[data-test-subj="rule_flyout_rule_name"]').contains(SAMPLE_RULE.name);

// Validate log type
cy.get('[data-test-subj="rule_flyout_rule_log_type"]').contains(SAMPLE_RULE.logType);

// Validate description
cy.get('[data-test-subj="rule_flyout_rule_description"]').contains(SAMPLE_RULE.description);

// Validate author
cy.get('[data-test-subj="rule_flyout_rule_author"]').contains(SAMPLE_RULE.author);

// Validate source is "custom"
cy.get('[data-test-subj="rule_flyout_rule_source"]').contains('Custom');

// Validate severity
cy.get('[data-test-subj="rule_flyout_rule_severity"]').contains(SAMPLE_RULE.severity);

// Validate tags
SAMPLE_RULE.tags.forEach((tag) =>
cy.get('[data-test-subj="rule_flyout_rule_tags"]').contains(tag)
);

// Validate references
cy.get('[data-test-subj="rule_flyout_rule_references"]').contains(SAMPLE_RULE.references);

// Validate false positives
cy.get('[data-test-subj="rule_flyout_rule_false_positives"]').contains(
SAMPLE_RULE.falsePositive
);

// Validate status
cy.get('[data-test-subj="rule_flyout_rule_status"]').contains(SAMPLE_RULE.status);

// Validate detection
SAMPLE_RULE.detectionLine.forEach((line) =>
cy.get('[data-test-subj="rule_flyout_rule_detection"]').contains(line)
);

cy.get('[data-test-subj="change-editor-type"] label:nth-child(2)').click({
force: true,
});

cy.get('[data-test-subj="rule_flyout_yaml_rule"]')
.get('[class="euiCodeBlock__line"]')
.each((lineElement, lineIndex) => {
if (lineIndex >= YAML_RULE_LINES.length) {
return;
}
let line = lineElement.text().replaceAll('\n', '').trim();
let expectedLine = YAML_RULE_LINES[lineIndex];

// The document ID field is generated when the document is added to the index,
// so this test just checks that the line starts with the ID key.
if (expectedLine.startsWith('id:')) {
expectedLine = 'id:';
expect(line, `Sigma rule line ${lineIndex}`).to.contain(expectedLine);
} else {
expect(line, `Sigma rule line ${lineIndex}`).to.equal(expectedLine);
}
});

// Close the flyout
cy.get('[data-test-subj="close-rule-details-flyout"]').click({
force: true,
});
});
};

describe('Rules', () => {
before(() => cy.cleanUpTests());
beforeEach(() => {
Expand Down Expand Up @@ -120,83 +200,67 @@ describe('Rules', () => {

cy.wait('@getRules');

// Search for the rule
cy.get(`input[placeholder="Search rules"]`).ospSearch(SAMPLE_RULE.name);
checkRulesFlyout();
});

// Click the rule link to open the details flyout
it('...can be edited', () => {
cy.waitForPageLoad('rules', {
contains: 'Rules',
});

cy.get(`input[placeholder="Search rules"]`).ospSearch(SAMPLE_RULE.name);
cy.get(`[data-test-subj="rule_link_${SAMPLE_RULE.name}"]`).click({ force: true });

// Confirm the flyout contains the expected values
cy.get(`[data-test-subj="rule_flyout_${SAMPLE_RULE.name}"]`)
.find('button')
.contains('Action')
.click({ force: true })
.within(() => {
// Validate name
cy.get('[data-test-subj="rule_flyout_rule_name"]').contains(SAMPLE_RULE.name);

// Validate log type
cy.get('[data-test-subj="rule_flyout_rule_log_type"]').contains(SAMPLE_RULE.logType);

// Validate description
cy.get('[data-test-subj="rule_flyout_rule_description"]').contains(SAMPLE_RULE.description);

// Validate author
cy.get('[data-test-subj="rule_flyout_rule_author"]').contains(SAMPLE_RULE.author);
.then(() => {
// Confirm arrival at detectors page
cy.get('.euiPopover__panel').find('button').contains('Edit').click();
});

// Validate source is "custom"
cy.get('[data-test-subj="rule_flyout_rule_source"]').contains('Custom');
const ruleNameSelector = '[data-test-subj="rule_name_field"]';
cy.get(ruleNameSelector).clear();

// Validate severity
cy.get('[data-test-subj="rule_flyout_rule_severity"]').contains(SAMPLE_RULE.severity);
SAMPLE_RULE.name += ' edited';
cy.get(ruleNameSelector).type(SAMPLE_RULE.name);
cy.get(ruleNameSelector).should('have.value', SAMPLE_RULE.name);

// Validate tags
SAMPLE_RULE.tags.forEach((tag) =>
cy.get('[data-test-subj="rule_flyout_rule_tags"]').contains(tag)
);
// Enter the log type
const logSelector = '[data-test-subj="rule_type_dropdown"]';
cy.get(logSelector).within(() => cy.get('.euiFormControlLayoutClearButton').click());
SAMPLE_RULE.logType = 'dns';
YAML_RULE_LINES[2] = `product: ${SAMPLE_RULE.logType}`;
YAML_RULE_LINES[3] = `title: ${SAMPLE_RULE.name}`;
cy.get(logSelector).type(SAMPLE_RULE.logType).type('{enter}');
cy.get(logSelector).contains(SAMPLE_RULE.logType, {
matchCase: false,
});

// Validate references
cy.get('[data-test-subj="rule_flyout_rule_references"]').contains(SAMPLE_RULE.references);
const ruleDescriptionSelector = '[data-test-subj="rule_description_field"]';
SAMPLE_RULE.description += ' edited';
YAML_RULE_LINES[4] = `description: ${SAMPLE_RULE.description}`;
cy.get(ruleDescriptionSelector).clear();
cy.get(ruleDescriptionSelector).type(SAMPLE_RULE.description);
cy.get(ruleDescriptionSelector).should('have.value', SAMPLE_RULE.description);

// Validate false positives
cy.get('[data-test-subj="rule_flyout_rule_false_positives"]').contains(
SAMPLE_RULE.falsePositive
);
cy.intercept({
url: '/rules',
}).as('getRules');

// Validate status
cy.get('[data-test-subj="rule_flyout_rule_status"]').contains(SAMPLE_RULE.status);
// Click "create" button
cy.get('[data-test-subj="submit_rule_form_button"]').click({
force: true,
});

// Validate detection
SAMPLE_RULE.detectionLine.forEach((line) =>
cy.get('[data-test-subj="rule_flyout_rule_detection"]').contains(line)
);
cy.waitForPageLoad('rules', {
contains: 'Rules',
});

cy.get('[data-test-subj="change-editor-type"] label:nth-child(2)').click({
force: true,
});
cy.wait('@getRules');

cy.get('[data-test-subj="rule_flyout_yaml_rule"]')
.get('[class="euiCodeBlock__line"]')
.each((lineElement, lineIndex) => {
if (lineIndex >= YAML_RULE_LINES.length) {
return;
}
let line = lineElement.text().replaceAll('\n', '').trim();
let expectedLine = YAML_RULE_LINES[lineIndex];

// The document ID field is generated when the document is added to the index,
// so this test just checks that the line starts with the ID key.
if (expectedLine.startsWith('id:')) {
expectedLine = 'id:';
expect(line, `Sigma rule line ${lineIndex}`).to.contain(expectedLine);
} else {
expect(line, `Sigma rule line ${lineIndex}`).to.equal(expectedLine);
}
});

// Close the flyout
cy.get('[data-test-subj="close-rule-details-flyout"]').click({
force: true,
});
});
checkRulesFlyout();
});

it('...can be deleted', () => {
Expand All @@ -209,20 +273,17 @@ describe('Rules', () => {
// Click the rule link to open the details flyout
cy.get(`[data-test-subj="rule_link_${SAMPLE_RULE.name}"]`).click({ force: true });

cy.get('.euiButton')
cy.get(`[data-test-subj="rule_flyout_${SAMPLE_RULE.name}"]`)
.find('button')
.contains('Action')
.click({ force: true })
.then(() => {
// Confirm arrival at detectors page
cy.get(
'.euiFlexGroup > :nth-child(3) > .euiButtonEmpty > .euiButtonContent > .euiButtonEmpty__text'
)
.click({
force: true,
})
.then(() => {
cy.get('.euiButton').contains('Delete').click();
});
cy.get('.euiPopover__panel')
.find('button')
.contains('Delete')
.click()
.then(() => cy.get('.euiModalFooter > .euiButton').contains('Delete').click());

cy.wait('@deleteRule');

Expand Down