From 1eb67c69d933a66a2c362a003a08e02b5cdd628f Mon Sep 17 00:00:00 2001 From: Adam Kol <93466081+AdamKol-up9@users.noreply.github.com> Date: Wed, 26 Jan 2022 13:18:25 +0200 Subject: [PATCH] Cypress: big UI test first version is ready (#689) --- .gitignore | 1 + .../integration/configurations/Default.json | 3 +- .../integration/testHelpers/TrafficHelper.js | 9 + .../cypress/integration/tests/UiTest.js | 218 ++++++++++++++++++ acceptanceTests/tap_test.go | 30 +-- 5 files changed, 231 insertions(+), 30 deletions(-) create mode 100644 acceptanceTests/cypress/integration/tests/UiTest.js diff --git a/.gitignore b/.gitignore index 35366c80f..c83baf3b1 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ cypress.env.json */cypress/screenshots */cypress/videos */cypress/support +*/cypress.json diff --git a/acceptanceTests/cypress/integration/configurations/Default.json b/acceptanceTests/cypress/integration/configurations/Default.json index 68621f7ef..d19ccd08f 100644 --- a/acceptanceTests/cypress/integration/configurations/Default.json +++ b/acceptanceTests/cypress/integration/configurations/Default.json @@ -10,7 +10,8 @@ "tests/Redact.js", "tests/NoRedact.js", "tests/Regex.js", - "tests/RegexMasking.js" + "tests/RegexMasking.js", + "tests/UiTest.js" ], "env": { diff --git a/acceptanceTests/cypress/integration/testHelpers/TrafficHelper.js b/acceptanceTests/cypress/integration/testHelpers/TrafficHelper.js index e90ec7e11..02ac41611 100644 --- a/acceptanceTests/cypress/integration/testHelpers/TrafficHelper.js +++ b/acceptanceTests/cypress/integration/testHelpers/TrafficHelper.js @@ -7,3 +7,12 @@ export function isValueExistsInElement(shouldInclude, content, domPathToContaine }); }); } + +export function resizeToHugeMizu() { + cy.viewport(1920, 3500); +} + +export function resizeToNormalMizu() { + cy.viewport(1920, 1080); +} + diff --git a/acceptanceTests/cypress/integration/tests/UiTest.js b/acceptanceTests/cypress/integration/tests/UiTest.js new file mode 100644 index 000000000..92ceb7ec6 --- /dev/null +++ b/acceptanceTests/cypress/integration/tests/UiTest.js @@ -0,0 +1,218 @@ +import {findLineAndCheck, getExpectedDetailsDict} from "../testHelpers/StatusBarHelper"; +import {resizeToHugeMizu, resizeToNormalMizu} from "../testHelpers/TrafficHelper"; +const greenFilterColor = 'rgb(210, 250, 210)'; +const redFilterColor = 'rgb(250, 214, 220)'; +const refreshWaitTimeout = 10000; + +it('opening mizu', function () { + cy.visit(Cypress.env('testUrl')); +}); + +it('top bar check', function () { + const podName1 = 'httpbin', namespace1 = 'mizu-tests'; + const podName2 = 'httpbin2', namespace2 = 'mizu-tests'; + + cy.get('.podsCount').trigger('mouseover'); + findLineAndCheck(getExpectedDetailsDict(podName1, namespace1)); + findLineAndCheck(getExpectedDetailsDict(podName2, namespace2)); + cy.reload(); +}); + +it('filtering guide check', function () { + cy.get('[title="Open Filtering Guide (Cheatsheet)"]').click(); + cy.get('#modal-modal-title').should('be.visible'); + cy.get('[lang="en"]').click(0, 0); + cy.get('#modal-modal-title').should('not.exist'); +}); + +checkIllegalFilter('invalid filter'); + +checkFilter({ + name: 'http', + leftSidePath: '> :nth-child(1) > :nth-child(1)', + leftSideExpectedText: 'HTTP', + rightSidePath: '[title=HTTP]', + rightSideExpectedText: 'Hypertext Transfer Protocol -- HTTP/1.1', + applyByEnter: true +}); + +checkFilter({ + name: 'response.status == 200', + leftSidePath: '[title="Status Code"]', + leftSideExpectedText: '200', + rightSidePath: '> :nth-child(2) [title="Status Code"]', + rightSideExpectedText: '200', + applyByEnter: false +}); + +checkFilter({ + name: 'src.name == ""', + leftSidePath: '[title="Source Name"]', + leftSideExpectedText: '[Unresolved]', + rightSidePath: '> :nth-child(2) [title="Source Name"]', + rightSideExpectedText: '[Unresolved]', + applyByEnter: false +}); + +checkFilter({ + name: 'method == "GET"', + leftSidePath: '> :nth-child(3) > :nth-child(1) > :nth-child(1) > :nth-child(2)', + leftSideExpectedText: 'GET', + rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(1) > :nth-child(1) > :nth-child(2)', + rightSideExpectedText: 'GET', + applyByEnter: true +}); + +checkFilter({ + name: 'summary == "/get"', + leftSidePath: '> :nth-child(3) > :nth-child(1) > :nth-child(2) > :nth-child(2)', + leftSideExpectedText: '/get', + rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(1) > :nth-child(2) > :nth-child(2)', + rightSideExpectedText: '/get', + applyByEnter: false +}); + +checkFilter({ + name: 'dst.name == "httpbin.mizu-tests"', + leftSidePath: '> :nth-child(3) > :nth-child(2) > :nth-child(3) > :nth-child(2)', + leftSideExpectedText: 'httpbin.mizu-tests', + rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(2) > :nth-child(3) > :nth-child(2)', + rightSideExpectedText: 'httpbin.mizu-tests', + applyByEnter: false +}); + +checkFilter({ + name: 'src.ip == "127.0.0.1"', + leftSidePath: '[title="Source IP"]', + leftSideExpectedText: '127.0.0.1', + rightSidePath: '> :nth-child(2) [title="Source IP"]', + rightSideExpectedText: '127.0.0.1', + applyByEnter: false +}); + +checkFilterNoResults('method == "POST"'); + +function checkFilterNoResults(filterName) { + it(`checking the filter: ${filterName}. Expecting no results`, function () { + cy.get('#total-entries').then(number => { + const totalEntries = number.text(); + + // applying the filter + cy.get('.w-tc-editor-text').type(filterName); + cy.get('.w-tc-editor').should('have.attr', 'style').and('include', greenFilterColor); + cy.get('[type="submit"]').click(); + + // waiting for the entries number to load + cy.get('#total-entries', {timeout: refreshWaitTimeout}).should('have.text', totalEntries); + + // the DOM should show 0 entries + cy.get('#entries-length').should('have.text', '0'); + + // going through every potential entry and verifies that it doesn't exist + [...Array(parseInt(totalEntries)).keys()].map(shouldNotExist); + + cy.get('[title="Fetch old records"]').click(); + cy.get('#noMoreDataTop', {timeout: refreshWaitTimeout}).should('be.visible'); + cy.get('#entries-length').should('have.text', '0'); // after loading all entries there should still be 0 entries + + // reloading then waiting for the entries number to load + cy.reload(); + cy.get('#total-entries', {timeout: refreshWaitTimeout}).should('have.text', totalEntries); + }); + }); +} + +function shouldNotExist(entryNum) { + cy.get(`entry-${entryNum}`).should('not.exist'); +} + +function checkIllegalFilter(illegalFilterName) { + it(`should show red search bar with the input: ${illegalFilterName}`, function () { + cy.get('#total-entries').then(number => { + const totalEntries = number.text(); + + cy.get('.w-tc-editor-text').type(illegalFilterName); + cy.get('.w-tc-editor').should('have.attr', 'style').and('include', redFilterColor); + cy.get('[type="submit"]').click(); + + cy.get('[role="alert"]').should('be.visible'); + cy.get('.w-tc-editor-text').clear(); + + // reloading then waiting for the entries number to load + cy.reload(); + cy.get('#total-entries', {timeout: refreshWaitTimeout}).should('have.text', totalEntries); + }); + }); +} +function checkFilter(filterDetails){ + const {name, leftSidePath, rightSidePath, rightSideExpectedText, leftSideExpectedText, applyByEnter} = filterDetails; + const entriesForDeeperCheck = 5; + + it(`checking the filter: ${name}`, function () { + cy.get('#total-entries').then(number => { + const totalEntries = number.text(); + + // checks the hover on the last entry (the only one in DOM at the beginning) + leftOnHoverCheck(totalEntries - 1, leftSidePath, name); + + // applying the filter with alt+enter or with the button + cy.get('.w-tc-editor-text').type(`${name}${applyByEnter ? '{alt+enter}' : ''}`); + cy.get('.w-tc-editor').should('have.attr', 'style').and('include', greenFilterColor); + if (!applyByEnter) + cy.get('[type="submit"]').click(); + + // only one entry in DOM after filtering, checking all four checks on it + leftTextCheck(totalEntries - 1, leftSidePath, leftSideExpectedText); + leftOnHoverCheck(totalEntries - 1, leftSidePath, name); + rightTextCheck(rightSidePath, rightSideExpectedText); + rightOnHoverCheck(rightSidePath, name); + + cy.get('[title="Fetch old records"]').click(); + resizeToHugeMizu(); + + // waiting for the entries number to load + cy.get('#entries-length', {timeout: refreshWaitTimeout}).should('have.text', totalEntries); + + // checking only 'leftTextCheck' on all entries because the rest of the checks require more time + [...Array(parseInt(totalEntries)).keys()].forEach(entryNum => { + leftTextCheck(entryNum, leftSidePath, leftSideExpectedText); + }); + + // making the other 3 checks on the first X entries (longer time for each check) + deeperChcek(leftSidePath, rightSidePath, name, leftSideExpectedText, rightSideExpectedText, entriesForDeeperCheck); + + // reloading then waiting for the entries number to load + resizeToNormalMizu(); + cy.reload(); + cy.get('#total-entries', {timeout: refreshWaitTimeout}).should('have.text', totalEntries); + }); + }); +} + +function deeperChcek(leftSidePath, rightSidePath, filterName, leftSideExpectedText, rightSideExpectedText, entriesNumToCheck) { + [...Array(entriesNumToCheck).keys()].forEach(entryNum => { + leftOnHoverCheck(entryNum, leftSidePath, filterName); + + cy.get(`#list #entry-${entryNum}`).click(); + rightTextCheck(rightSidePath, rightSideExpectedText); + rightOnHoverCheck(rightSidePath, filterName); + }); +} + +function leftTextCheck(entryNum, path, expectedText) { + cy.get(`#list #entry-${entryNum} ${path}`).invoke('text').should('eq', expectedText); +} + +function leftOnHoverCheck(entryNum, path, filterName) { + cy.get(`#list #entry-${entryNum} ${path}`).trigger('mouseover'); + cy.get(`#list #entry-${entryNum} .Queryable-Tooltip`).should('have.text', filterName); +} + +function rightTextCheck(path, expectedText) { + cy.get(`.TrafficPage-Container > :nth-child(2) ${path}`).should('have.text', expectedText); +} + +function rightOnHoverCheck(path, expectedText) { + cy.get(`.TrafficPage-Container > :nth-child(2) ${path}`).trigger('mouseover'); + cy.get(`.TrafficPage-Container > :nth-child(2) .Queryable-Tooltip`).should('have.text', expectedText); +} diff --git a/acceptanceTests/tap_test.go b/acceptanceTests/tap_test.go index fa33c4681..36a9af82c 100644 --- a/acceptanceTests/tap_test.go +++ b/acceptanceTests/tap_test.go @@ -62,35 +62,7 @@ func TestTap(t *testing.T) { } } - entriesCheckFunc := func() error { - timestamp := time.Now().UnixNano() / int64(time.Millisecond) - - entries, err := getDBEntries(timestamp, entriesCount, 1*time.Second) - if err != nil { - return err - } - err = checkEntriesAtLeast(entries, 1) - if err != nil { - return err - } - entry := entries[0] - - entryUrl := fmt.Sprintf("%v/entries/%v", apiServerUrl, entry["id"]) - requestResult, requestErr := executeHttpGetRequest(entryUrl) - if requestErr != nil { - return fmt.Errorf("failed to get entry, err: %v", requestErr) - } - - if requestResult == nil { - return fmt.Errorf("unexpected nil entry result") - } - - return nil - } - if err := retriesExecute(shortRetriesCount, entriesCheckFunc); err != nil { - t.Errorf("%v", err) - return - } + runCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/UiTest.js\" --config-file cypress/integration/configurations/Default.json") }) } }