From 2c8d43f06b951641dee7dbf62d62f654b10c8f06 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Fri, 27 Aug 2021 15:13:32 -0700 Subject: [PATCH] Cypress Testing: Modify default timeout (#1835) - Change default timeout to 20 seconds on 8 more brittle e2e tests --- cypress/integration/all/app/hosts.spec.ts | 265 ++++++++--------- cypress/integration/all/app/labelflow.spec.ts | 94 +++--- cypress/integration/all/app/packflow.spec.ts | 80 +++--- cypress/integration/all/app/queryflow.spec.ts | 198 ++++++------- cypress/integration/basic/admin.spec.ts | 200 ++++++------- cypress/integration/basic/maintainer.spec.ts | 174 ++++++------ cypress/integration/core/admin.spec.ts | 230 +++++++-------- cypress/integration/core/maintainer.spec.ts | 268 +++++++++--------- 8 files changed, 783 insertions(+), 726 deletions(-) diff --git a/cypress/integration/all/app/hosts.spec.ts b/cypress/integration/all/app/hosts.spec.ts index 38b0a8ec7f..dc30544608 100644 --- a/cypress/integration/all/app/hosts.spec.ts +++ b/cypress/integration/all/app/hosts.spec.ts @@ -1,146 +1,155 @@ import * as path from "path"; -describe("Hosts flow", () => { - beforeEach(() => { - cy.setup(); - cy.login(); - cy.addDockerHost(); - }); +describe( + "Hosts flow", + { + defaultCommandTimeout: 20000, + }, + () => { + beforeEach(() => { + cy.setup(); + cy.login(); + cy.addDockerHost(); + }); - afterEach(() => { - cy.stopDockerHost(); - }); + afterEach(() => { + cy.stopDockerHost(); + }); - it( - "Can add new host from manage hosts page", - { - retries: { - runMode: 2, - }, - }, - () => { - cy.visit("/"); - - cy.contains("button", /add new host/i).click(); - - cy.get('a[href*="showSecret"]').click(); - cy.contains("a", /download/i) - .first() - .click(); - - // Assert enroll secret downloaded matches the one displayed - // NOTE: This test often fails when the Cypress downloads folder was not cleared properly - // before each test run (seems to be related to issues with Cypress trashAssetsBeforeRun) - cy.readFile(path.join(Cypress.config("downloadsFolder"), "secret.txt"), { - timeout: 5000, - }).then((contents) => { - cy.get("input[disabled]").should("have.value", contents); - }); - - // Wait until the host becomes available (usually immediate in local - // testing, but may vary by environment). - cy.waitUntil( - () => { - cy.visit("/"); - return Cypress.$('button[title="Online"]').length > 0; + it( + "Can add new host from manage hosts page", + { + retries: { + runMode: 2, }, - { timeout: 30000, interval: 1000 } - ); + }, + () => { + cy.visit("/"); - // Go to host details page - cy.get('button[title="Online"]').click(); - cy.get("span.status").contains("online"); - } - ); + cy.contains("button", /add new host/i).click(); - it("Can delete a host from host details page", () => { - let hostname = ""; + cy.get('a[href*="showSecret"]').click(); + cy.contains("a", /download/i) + .first() + .click(); - cy.visit("/hosts/manage"); - - cy.get("tbody").within(() => { - cy.get(".button--text-link").first().as("hostLink"); - }); - - cy.get("@hostLink") - // Set hostname variable for later assertions - .then((el) => { - console.log(el); - hostname = el.text(); - return el; - }) - .click() - .then(() => { - cy.findByText(/about this host/i).should("exist"); - cy.findByText(hostname).should("exist"); - - // Open delete host modal and cancel - cy.get('img[alt="Delete host icon"]').click(); - cy.get(".modal__modal_container").within(() => { - cy.findByText(/delete host/i).should("exist"); - cy.findByRole("button", { name: /cancel/i }).click(); + // Assert enroll secret downloaded matches the one displayed + // NOTE: This test often fails when the Cypress downloads folder was not cleared properly + // before each test run (seems to be related to issues with Cypress trashAssetsBeforeRun) + cy.readFile( + path.join(Cypress.config("downloadsFolder"), "secret.txt"), + { + timeout: 5000, + } + ).then((contents) => { + cy.get("input[disabled]").should("have.value", contents); }); - cy.findByText(/delete host/i).should("not.exist"); - // Open delete host modal and delete host - cy.get('img[alt="Delete host icon"]').click(); - cy.get(".modal__modal_container") - .within(() => { + // Wait until the host becomes available (usually immediate in local + // testing, but may vary by environment). + cy.waitUntil( + () => { + cy.visit("/"); + return Cypress.$('button[title="Online"]').length > 0; + }, + { timeout: 30000, interval: 1000 } + ); + + // Go to host details page + cy.get('button[title="Online"]').click(); + cy.get("span.status").contains("online"); + } + ); + + it("Can delete a host from host details page", () => { + let hostname = ""; + + cy.visit("/hosts/manage"); + + cy.get("tbody").within(() => { + cy.get(".button--text-link").first().as("hostLink"); + }); + + cy.get("@hostLink") + // Set hostname variable for later assertions + .then((el) => { + console.log(el); + hostname = el.text(); + return el; + }) + .click() + .then(() => { + cy.findByText(/about this host/i).should("exist"); + cy.findByText(hostname).should("exist"); + + // Open delete host modal and cancel + cy.get('img[alt="Delete host icon"]').click(); + cy.get(".modal__modal_container").within(() => { cy.findByText(/delete host/i).should("exist"); - cy.findByRole("button", { name: /delete/i }).click(); - }) - .then(() => { - cy.findByText(/successfully deleted/i).should("exist"); - cy.findByText(/kinda empty in here/i).should("exist"); - cy.findByText(/about this host/i).should("not.exist"); - cy.findByText(hostname).should("not.exist"); + cy.findByRole("button", { name: /cancel/i }).click(); }); - }); - }); + cy.findByText(/delete host/i).should("not.exist"); - it("Can query a host from host details page", () => { - cy.seedQueries(); - - let hostname = ""; - - cy.visit("/hosts/manage"); - - cy.get("tbody").within(() => { - cy.get(".button--text-link").first().as("hostLink"); + // Open delete host modal and delete host + cy.get('img[alt="Delete host icon"]').click(); + cy.get(".modal__modal_container") + .within(() => { + cy.findByText(/delete host/i).should("exist"); + cy.findByRole("button", { name: /delete/i }).click(); + }) + .then(() => { + cy.findByText(/successfully deleted/i).should("exist"); + cy.findByText(/kinda empty in here/i).should("exist"); + cy.findByText(/about this host/i).should("not.exist"); + cy.findByText(hostname).should("not.exist"); + }); + }); }); - cy.get("@hostLink") - // Set hostname variable for later assertions - .then((el) => { - hostname = el.text(); - return el; - }) - .click() - .then(() => { - cy.findByText(/about this host/i).should("exist"); - cy.findByText(hostname).should("exist"); + it("Can query a host from host details page", () => { + cy.seedQueries(); - // Open query host modal and cancel - cy.get('img[alt="Query host icon"]').click(); - cy.get(".modal__modal_container").within(() => { - cy.findByText(/select a query/i).should("exist"); - cy.get(".modal__ex").click(); - }); - cy.findByText(/select a query/i).should("not.exist"); + let hostname = ""; - // Open query host modal and select query - cy.get('img[alt="Query host icon"]').click(); - cy.get(".modal__modal_container") - .within(() => { - cy.findByText(/select a query/i).should("exist"); - cy.findByText(/detect presence/i).click(); - }) - .then(() => { - cy.findByText(/edit & run query/i).should("exist"); - cy.get(".target-select").within(() => { - cy.findByText(hostname).should("exist"); - }); - }); + cy.visit("/hosts/manage"); + + cy.get("tbody").within(() => { + cy.get(".button--text-link").first().as("hostLink"); }); - }); -}); + + cy.get("@hostLink") + // Set hostname variable for later assertions + .then((el) => { + hostname = el.text(); + return el; + }) + .click() + .then(() => { + cy.findByText(/about this host/i).should("exist"); + cy.findByText(hostname).should("exist"); + + // Open query host modal and cancel + cy.get('img[alt="Query host icon"]').click(); + cy.get(".modal__modal_container").within(() => { + cy.findByText(/select a query/i).should("exist"); + cy.get(".modal__ex").click(); + }); + cy.findByText(/select a query/i).should("not.exist"); + + // Open query host modal and select query + cy.get('img[alt="Query host icon"]').click(); + cy.get(".modal__modal_container") + .within(() => { + cy.findByText(/select a query/i).should("exist"); + cy.findByText(/detect presence/i).click(); + }) + .then(() => { + cy.findByText(/edit & run query/i).should("exist"); + cy.get(".target-select").within(() => { + cy.findByText(hostname).should("exist"); + }); + }); + }); + }); + } +); diff --git a/cypress/integration/all/app/labelflow.spec.ts b/cypress/integration/all/app/labelflow.spec.ts index 096dfd8374..8303224def 100644 --- a/cypress/integration/all/app/labelflow.spec.ts +++ b/cypress/integration/all/app/labelflow.spec.ts @@ -1,63 +1,69 @@ -describe("Label flow", () => { - beforeEach(() => { - cy.setup(); - cy.login(); - }); +describe( + "Label flow", + { + defaultCommandTimeout: 20000, + }, + () => { + beforeEach(() => { + cy.setup(); + cy.login(); + }); - it("Create, edit, and delete a label successfully", () => { - cy.visit("/hosts/manage"); + it("Create, edit, and delete a label successfully", () => { + cy.visit("/hosts/manage"); - cy.findByRole("button", { name: /add label/i }).click(); + cy.findByRole("button", { name: /add label/i }).click(); - // Using class selector because third party element doesn't work with Cypress Testing Selector Library - cy.get(".ace_content") - .click() - .type("{selectall}{backspace}SELECT * FROM users;"); + // Using class selector because third party element doesn't work with Cypress Testing Selector Library + cy.get(".ace_content") + .click() + .type("{selectall}{backspace}SELECT * FROM users;"); - cy.findByLabelText(/name/i).click().type("Show all users"); + cy.findByLabelText(/name/i).click().type("Show all users"); - cy.findByLabelText(/description/i) - .click() - .type("Select all users across platforms."); + cy.findByLabelText(/description/i) + .click() + .type("Select all users across platforms."); - // Cannot call cy.select on div disguised as a dropdown - cy.findByText(/select one/i).click(); - cy.findByText(/all platforms/i).click(); + // Cannot call cy.select on div disguised as a dropdown + cy.findByText(/select one/i).click(); + cy.findByText(/all platforms/i).click(); - cy.findByRole("button", { name: /save label/i }).click(); + cy.findByRole("button", { name: /save label/i }).click(); - cy.findByText(/show all users/i).click(); + cy.findByText(/show all users/i).click(); - cy.get(".manage-hosts__label-block button").first().click(); + cy.get(".manage-hosts__label-block button").first().click(); - // Label SQL not editable to test + // Label SQL not editable to test - cy.findByLabelText(/name/i) - .click() - .type("{selectall}{backspace}Show all usernames"); + cy.findByLabelText(/name/i) + .click() + .type("{selectall}{backspace}Show all usernames"); - cy.findByLabelText(/description/i) - .click() - .type("{selectall}{backspace}Select all usernames on Mac."); + cy.findByLabelText(/description/i) + .click() + .type("{selectall}{backspace}Select all usernames on Mac."); - cy.findByText(/select one/i).should("not.exist"); + cy.findByText(/select one/i).should("not.exist"); - cy.findByText(/label platforms are immutable/i).should("exist"); + cy.findByText(/label platforms are immutable/i).should("exist"); - cy.findByRole("button", { name: /update label/i }).click(); + cy.findByRole("button", { name: /update label/i }).click(); - // TODO add test for flash message once issue with router is fixed - // Close success notification - // cy.get(".flash-message__remove").click(); + // TODO add test for flash message once issue with router is fixed + // Close success notification + // cy.get(".flash-message__remove").click(); - cy.get(".manage-hosts__label-block button").last().click(); + cy.get(".manage-hosts__label-block button").last().click(); - // Can't figure out how attach findByRole onto modal button - // Can't use findByText because delete button under modal - cy.get(".manage-hosts__modal-buttons > .button--alert") - .contains("button", /delete/i) - .click(); + // Can't figure out how attach findByRole onto modal button + // Can't use findByText because delete button under modal + cy.get(".manage-hosts__modal-buttons > .button--alert") + .contains("button", /delete/i) + .click(); - cy.findByText(/show all users/i).should("not.exist"); - }); -}); + cy.findByText(/show all users/i).should("not.exist"); + }); + } +); diff --git a/cypress/integration/all/app/packflow.spec.ts b/cypress/integration/all/app/packflow.spec.ts index 0054d9c413..4a89453042 100644 --- a/cypress/integration/all/app/packflow.spec.ts +++ b/cypress/integration/all/app/packflow.spec.ts @@ -1,54 +1,60 @@ -describe("Pack flow", () => { - beforeEach(() => { - cy.setup(); - cy.login(); - }); +describe( + "Pack flow", + { + defaultCommandTimeout: 20000, + }, + () => { + beforeEach(() => { + cy.setup(); + cy.login(); + }); - it("Create, edit, and delete a pack successfully", () => { - cy.visit("/packs/manage"); + it("Create, edit, and delete a pack successfully", () => { + cy.visit("/packs/manage"); - cy.findByRole("button", { name: /create new pack/i }).click(); + cy.findByRole("button", { name: /create new pack/i }).click(); - cy.findByLabelText(/query pack title/i) - .click() - .type("Errors and crashes"); + cy.findByLabelText(/query pack title/i) + .click() + .type("Errors and crashes"); - cy.findByLabelText(/description/i) - .click() - .type("See all user errors and window crashes."); + cy.findByLabelText(/description/i) + .click() + .type("See all user errors and window crashes."); - cy.findByRole("button", { name: /save query pack/i }).click(); + cy.findByRole("button", { name: /save query pack/i }).click(); - cy.visit("/packs/manage"); + cy.visit("/packs/manage"); - cy.findByText(/errors and crashes/i).click(); + cy.findByText(/errors and crashes/i).click(); - cy.findByText(/edit pack/i).click(); + cy.findByText(/edit pack/i).click(); - cy.findByLabelText(/query pack title/i) - .click() - .type("{selectall}{backspace}Server errors"); + cy.findByLabelText(/query pack title/i) + .click() + .type("{selectall}{backspace}Server errors"); - cy.findByLabelText(/description/i) - .click() - .type("{selectall}{backspace}See all server errors."); + cy.findByLabelText(/description/i) + .click() + .type("{selectall}{backspace}See all server errors."); - cy.findByRole("button", { name: /save/i }).click(); + cy.findByRole("button", { name: /save/i }).click(); - cy.visit("/packs/manage"); + cy.visit("/packs/manage"); - cy.get(".fleet-checkbox__input").check({ force: true }); + cy.get(".fleet-checkbox__input").check({ force: true }); - cy.findByRole("button", { name: /delete/i }).click(); + cy.findByRole("button", { name: /delete/i }).click(); - // Can't figure out how attach findByRole onto modal button - // Can't use findByText because delete button under modal - cy.get(".remove-pack-modal__btn-wrap > .button--alert") - .contains("button", /delete/i) - .click(); + // Can't figure out how attach findByRole onto modal button + // Can't use findByText because delete button under modal + cy.get(".remove-pack-modal__btn-wrap > .button--alert") + .contains("button", /delete/i) + .click(); - cy.findByText(/successfully deleted/i).should("be.visible"); + cy.findByText(/successfully deleted/i).should("be.visible"); - cy.findByText(/server errors/i).should("not.exist"); - }); -}); + cy.findByText(/server errors/i).should("not.exist"); + }); + } +); diff --git a/cypress/integration/all/app/queryflow.spec.ts b/cypress/integration/all/app/queryflow.spec.ts index 4fd73841aa..b166cf1919 100644 --- a/cypress/integration/all/app/queryflow.spec.ts +++ b/cypress/integration/all/app/queryflow.spec.ts @@ -1,141 +1,147 @@ -describe("Query flow", () => { - beforeEach(() => { - cy.setup(); - cy.login(); - }); +describe( + "Query flow", + { + defaultCommandTimeout: 20000, + }, + () => { + beforeEach(() => { + cy.setup(); + cy.login(); + }); - it("Create, check, edit, and delete a query successfully and create, edit, and delete a global scheduled query successfully", () => { - cy.visit("/queries/manage"); + it("Create, check, edit, and delete a query successfully and create, edit, and delete a global scheduled query successfully", () => { + cy.visit("/queries/manage"); - cy.findByRole("button", { name: /create new query/i }).click(); + cy.findByRole("button", { name: /create new query/i }).click(); - cy.findByLabelText(/query name/i) - .click() - .type("Query all window crashes"); + cy.findByLabelText(/query name/i) + .click() + .type("Query all window crashes"); - // Using class selector because third party element doesn't work with Cypress Testing Selector Library - cy.get(".ace_scroller") - .click({ force: true }) - .type("{selectall}{backspace}SELECT * FROM windows_crashes;"); + // Using class selector because third party element doesn't work with Cypress Testing Selector Library + cy.get(".ace_scroller") + .click({ force: true }) + .type("{selectall}{backspace}SELECT * FROM windows_crashes;"); - cy.findByLabelText(/description/i) - .click() - .type("See all window crashes"); + cy.findByLabelText(/description/i) + .click() + .type("See all window crashes"); - cy.findByRole("button", { name: /save/i }).click(); + cy.findByRole("button", { name: /save/i }).click(); - cy.findByRole("button", { name: /save as new/i }).click(); + cy.findByRole("button", { name: /save as new/i }).click(); - // Just refreshes to create new query, needs success alert to user that they created a query + // Just refreshes to create new query, needs success alert to user that they created a query - cy.visit("/queries/manage"); + cy.visit("/queries/manage"); - cy.findByText(/query all/i).click(); + cy.findByText(/query all/i).click(); - cy.findByText(/edit & run query/i).should("exist"); + cy.findByText(/edit & run query/i).should("exist"); - cy.get(".ace_scroller") - .click({ force: true }) - .type( - "{selectall}{backspace}SELECT datetime, username FROM windows_crashes;" - ); + cy.get(".ace_scroller") + .click({ force: true }) + .type( + "{selectall}{backspace}SELECT datetime, username FROM windows_crashes;" + ); - cy.findByRole("button", { name: /save/i }).click(); + cy.findByRole("button", { name: /save/i }).click(); - cy.findByRole("button", { name: /save changes/i }).click(); + cy.findByRole("button", { name: /save changes/i }).click(); - cy.findByText(/query updated/i).should("be.visible"); + cy.findByText(/query updated/i).should("be.visible"); - // Test Schedules - cy.visit("/schedule/manage"); + // Test Schedules + cy.visit("/schedule/manage"); - cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting + cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting - cy.findByRole("button", { name: /schedule a query/i }).click(); + cy.findByRole("button", { name: /schedule a query/i }).click(); - cy.findByText(/select query/i).click(); + cy.findByText(/select query/i).click(); - cy.findByText(/query all window crashes/i).click(); + cy.findByText(/query all window crashes/i).click(); - cy.get( - ".schedule-editor-modal__form-field--frequency > .dropdown__select" - ).click(); + cy.get( + ".schedule-editor-modal__form-field--frequency > .dropdown__select" + ).click(); - cy.findByText(/every week/i).click(); + cy.findByText(/every week/i).click(); - cy.findByText(/show advanced options/i).click(); + cy.findByText(/show advanced options/i).click(); - cy.get( - ".schedule-editor-modal__form-field--logging > .dropdown__select" - ).click(); + cy.get( + ".schedule-editor-modal__form-field--logging > .dropdown__select" + ).click(); - cy.findByText(/ignore removals/i).click(); + cy.findByText(/ignore removals/i).click(); - cy.get(".schedule-editor-modal__form-field--shard > .input-field") - .click() - .type("50"); + cy.get(".schedule-editor-modal__form-field--shard > .input-field") + .click() + .type("50"); - cy.get(".schedule-editor-modal__btn-wrap") - .contains("button", /schedule/i) - .click(); + cy.get(".schedule-editor-modal__btn-wrap") + .contains("button", /schedule/i) + .click(); - cy.visit("/schedule/manage"); + cy.visit("/schedule/manage"); - cy.findByText(/query all window crashes/i).should("exist"); + cy.findByText(/query all window crashes/i).should("exist"); - cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting - cy.findByText(/actions/i).click(); - cy.findByText(/edit/i).click(); + cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting + cy.findByText(/actions/i).click(); + cy.findByText(/edit/i).click(); - cy.get( - ".schedule-editor-modal__form-field--frequency > .dropdown__select" - ).click(); + cy.get( + ".schedule-editor-modal__form-field--frequency > .dropdown__select" + ).click(); - cy.findByText(/every 6 hours/i).click(); + cy.findByText(/every 6 hours/i).click(); - cy.findByText(/show advanced options/i).click(); + cy.findByText(/show advanced options/i).click(); - cy.findByText(/ignore removals/i).click(); - cy.findByText(/snapshot/i).click(); + cy.findByText(/ignore removals/i).click(); + cy.findByText(/snapshot/i).click(); - cy.get(".schedule-editor-modal__form-field--shard > .input-field") - .click() - .type("{selectall}{backspace}10"); + cy.get(".schedule-editor-modal__form-field--shard > .input-field") + .click() + .type("{selectall}{backspace}10"); - cy.get(".schedule-editor-modal__btn-wrap") - .contains("button", /schedule/i) - .click(); + cy.get(".schedule-editor-modal__btn-wrap") + .contains("button", /schedule/i) + .click(); - cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting - cy.findByText(/actions/i).click(); - cy.findByText(/remove/i).click(); + cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting + cy.findByText(/actions/i).click(); + cy.findByText(/remove/i).click(); - cy.get(".remove-scheduled-query-modal__btn-wrap") - .contains("button", /remove/i) - .click(); + cy.get(".remove-scheduled-query-modal__btn-wrap") + .contains("button", /remove/i) + .click(); - cy.findByText(/query all window crashes/i).should("not.exist"); - // End Test Schedules + cy.findByText(/query all window crashes/i).should("not.exist"); + // End Test Schedules - cy.visit("/queries/manage"); + cy.visit("/queries/manage"); - cy.findByText(/query all window crashes/i) - .parent() - .parent() - .within(() => { - cy.get(".fleet-checkbox__input").check({ force: true }); - }); + cy.findByText(/query all window crashes/i) + .parent() + .parent() + .within(() => { + cy.get(".fleet-checkbox__input").check({ force: true }); + }); - cy.findByRole("button", { name: /delete/i }).click(); + cy.findByRole("button", { name: /delete/i }).click(); - // Can't figure out how attach findByRole onto modal button - // Can't use findByText because delete button under modal - cy.get(".remove-query-modal") - .contains("button", /delete/i) - .click(); + // Can't figure out how attach findByRole onto modal button + // Can't use findByText because delete button under modal + cy.get(".remove-query-modal") + .contains("button", /delete/i) + .click(); - cy.findByText(/successfully removed query/i).should("be.visible"); + cy.findByText(/successfully removed query/i).should("be.visible"); - cy.findByText(/query all/i).should("not.exist"); - }); -}); + cy.findByText(/query all/i).should("not.exist"); + }); + } +); diff --git a/cypress/integration/basic/admin.spec.ts b/cypress/integration/basic/admin.spec.ts index 7cf497a99d..5dfc4416f0 100644 --- a/cypress/integration/basic/admin.spec.ts +++ b/cypress/integration/basic/admin.spec.ts @@ -1,107 +1,115 @@ -describe("Basic tier - Admin user", () => { - beforeEach(() => { - cy.setup(); - cy.login(); - cy.seedBasic(); - cy.setupSMTP(); - cy.seedQueries(); - cy.addDockerHost("apples"); - cy.logout(); - }); - afterEach(() => { - cy.stopDockerHost(); - }); +describe( + "Basic tier - Admin user", + { + defaultCommandTimeout: 20000, + }, + () => { + beforeEach(() => { + cy.setup(); + cy.login(); + cy.seedBasic(); + cy.setupSMTP(); + cy.seedQueries(); + cy.addDockerHost("apples"); + cy.logout(); + }); + afterEach(() => { + cy.stopDockerHost(); + }); - it( - "Can perform the appropriate basic-tier admin actions", - { - retries: { - runMode: 2, + it( + "Can perform the appropriate basic-tier admin actions", + { + retries: { + runMode: 2, + }, }, - }, - () => { - cy.login("anna@organization.com", "user123#"); - cy.visit("/"); + () => { + cy.login("anna@organization.com", "user123#"); + cy.visit("/"); - // Ensure the hosts page is loaded - cy.contains("All hosts"); + // Ensure the hosts page is loaded + cy.contains("All hosts"); - // On the hosts page, they should… + // On the hosts page, they should… - // See the “Teams” column in the Hosts table - cy.get("thead").contains(/team/i).should("exist"); + // See the “Teams” column in the Hosts table + cy.get("thead").contains(/team/i).should("exist"); - // See and select the “Add new host” button - cy.contains("button", /add new host/i).click(); + // See and select the “Add new host” button + cy.contains("button", /add new host/i).click(); - // See the “Select a team for this new host” in the Add new host modal. This modal appears after the user selects the “Add new host” button - cy.get(".add-host-modal__team-dropdown-wrapper .Select-control").click(); + // See the “Select a team for this new host” in the Add new host modal. This modal appears after the user selects the “Add new host” button + cy.get( + ".add-host-modal__team-dropdown-wrapper .Select-control" + ).click(); - cy.get(".Select-menu-outer").within(() => { - cy.findByText(/no team/i).should("exist"); + cy.get(".Select-menu-outer").within(() => { + cy.findByText(/no team/i).should("exist"); + cy.findByText(/apples/i).should("exist"); + cy.findByText(/oranges/i).should("exist"); + }); + + cy.contains("button", /done/i).click(); + + // On the Host details page, they should… + // See the “Team” information below the hostname + // Be able to transfer Teams + cy.visit("/hosts/1"); + cy.findByText(/team/i).next().contains("Apples"); + cy.contains("button", /transfer/i).click(); + cy.get(".Select-control").click(); + cy.findByText(/create a team/i).should("exist"); + cy.get(".Select-menu").within(() => { + cy.findByText(/no team/i).should("exist"); + cy.findByText(/apples/i).should("exist"); + cy.findByText(/oranges/i).click(); + }); + cy.get(".transfer-action-btn").click(); + cy.findByText(/transferred to oranges/i).should("exist"); + cy.findByText(/team/i).next().contains("Oranges"); + + // On the Queries - new / edit / run page, they should… + // See the “Teams” section in the Select target picker. This picker is summoned when the “Select targets” field is selected. + cy.visit("/queries/new"); + cy.get(".target-select").within(() => { + cy.findByText(/Label name, host name, IP address, etc./i).click(); + cy.findByText(/teams/i).should("exist"); + }); + + // On the Packs pages (manage, new, and edit), they should… + // ^^General admin functionality for packs page is being tested in app/packflow.spec.ts + + // On the Schedule pages (manage, new, and edit), they should… + // ^^General admin functionality for packs page is being tested in app/queryflow.spec.ts + + // On the Settings pages, they should… + // See the “Teams” navigation item and access the Settings - Teams page + cy.visit("/settings/organization"); + cy.get(".react-tabs").within(() => { + cy.findByText(/teams/i).click(); + }); + // Access the Settings - Team details page + cy.findByText(/apples/i).click(); cy.findByText(/apples/i).should("exist"); - cy.findByText(/oranges/i).should("exist"); - }); + cy.findByText(/manage users with global access here/i).should("exist"); - cy.contains("button", /done/i).click(); + // See the “Team” section in the create user modal. This modal is summoned when the “Create user” button is selected + cy.visit("/settings/organization"); + cy.get(".react-tabs").within(() => { + cy.findByText(/users/i).click(); + }); + cy.findByRole("button", { name: /create user/i }).click(); + cy.findByText(/assign teams/i).should("exist"); - // On the Host details page, they should… - // See the “Team” information below the hostname - // Be able to transfer Teams - cy.visit("/hosts/1"); - cy.findByText(/team/i).next().contains("Apples"); - cy.contains("button", /transfer/i).click(); - cy.get(".Select-control").click(); - cy.findByText(/create a team/i).should("exist"); - cy.get(".Select-menu").within(() => { - cy.findByText(/no team/i).should("exist"); - cy.findByText(/apples/i).should("exist"); - cy.findByText(/oranges/i).click(); - }); - cy.get(".transfer-action-btn").click(); - cy.findByText(/transferred to oranges/i).should("exist"); - cy.findByText(/team/i).next().contains("Oranges"); - - // On the Queries - new / edit / run page, they should… - // See the “Teams” section in the Select target picker. This picker is summoned when the “Select targets” field is selected. - cy.visit("/queries/new"); - cy.get(".target-select").within(() => { - cy.findByText(/Label name, host name, IP address, etc./i).click(); - cy.findByText(/teams/i).should("exist"); - }); - - // On the Packs pages (manage, new, and edit), they should… - // ^^General admin functionality for packs page is being tested in app/packflow.spec.ts - - // On the Schedule pages (manage, new, and edit), they should… - // ^^General admin functionality for packs page is being tested in app/queryflow.spec.ts - - // On the Settings pages, they should… - // See the “Teams” navigation item and access the Settings - Teams page - cy.visit("/settings/organization"); - cy.get(".react-tabs").within(() => { - cy.findByText(/teams/i).click(); - }); - // Access the Settings - Team details page - cy.findByText(/apples/i).click(); - cy.findByText(/apples/i).should("exist"); - cy.findByText(/manage users with global access here/i).should("exist"); - - // See the “Team” section in the create user modal. This modal is summoned when the “Create user” button is selected - cy.visit("/settings/organization"); - cy.get(".react-tabs").within(() => { - cy.findByText(/users/i).click(); - }); - cy.findByRole("button", { name: /create user/i }).click(); - cy.findByText(/assign teams/i).should("exist"); - - // On the Profile page, they should… - // See Global in the Team section and Admin in the Role section - cy.visit("/profile"); - cy.findByText(/team/i) - .next() - .contains(/global/i); - cy.findByText("Role").next().contains(/admin/i); - } - ); -}); + // On the Profile page, they should… + // See Global in the Team section and Admin in the Role section + cy.visit("/profile"); + cy.findByText(/team/i) + .next() + .contains(/global/i); + cy.findByText("Role").next().contains(/admin/i); + } + ); + } +); diff --git a/cypress/integration/basic/maintainer.spec.ts b/cypress/integration/basic/maintainer.spec.ts index 46af404e6d..6621211cef 100644 --- a/cypress/integration/basic/maintainer.spec.ts +++ b/cypress/integration/basic/maintainer.spec.ts @@ -1,91 +1,99 @@ -describe("Basic tier - Maintainer user", () => { - beforeEach(() => { - cy.setup(); - cy.login(); - cy.seedBasic(); - cy.seedQueries(); - cy.addDockerHost(); - cy.logout(); - }); - - afterEach(() => { - cy.stopDockerHost(); - }); - - it("Can perform the appropriate basic global maintainer actions", () => { - cy.login("mary@organization.com", "user123#"); - cy.visit("/"); - - // Ensure page is loaded - cy.contains("All hosts"); - - // Host manage page: Teams column, select a team - cy.visit("/hosts/manage"); - - cy.get("thead").within(() => { - cy.findByText(/team/i).should("exist"); +describe( + "Basic tier - Maintainer user", + { + defaultCommandTimeout: 20000, + }, + () => { + beforeEach(() => { + cy.setup(); + cy.login(); + cy.seedBasic(); + cy.seedQueries(); + cy.addDockerHost(); + cy.logout(); }); - cy.contains("button", /add new host/i).click(); - // TODO: Check Team Apples is in Select a team dropdown - cy.contains("button", /done/i).click(); - - // Host details page: Can see team UI - cy.get("tbody").within(() => { - // Test host text varies - cy.findByRole("button").click(); - }); - cy.get(".title").within(() => { - cy.findByText("Team").should("exist"); - }); - cy.contains("button", /transfer/i).click(); - cy.get(".Select-control").click(); - cy.findByText(/create a team/i).should("not.exist"); - cy.get(".Select-menu").within(() => { - cy.findByText(/no team/i).should("exist"); - cy.findByText(/apples/i).should("exist"); - cy.findByText(/oranges/i).click(); - }); - cy.get(".transfer-action-btn").click(); - cy.findByText(/transferred to oranges/i).should("exist"); - cy.findByText(/team/i).next().contains("Oranges"); - cy.contains("button", /delete/i).should("exist"); - cy.contains("button", /query/i).click(); - cy.contains("button", /create custom query/i).should("exist"); - - // Query pages: Can see teams UI for create, edit, and run query - cy.visit("/queries/manage"); - - cy.findByRole("button", { name: /create new query/i }).click(); - - cy.get(".target-select").within(() => { - cy.findByText(/Label name, host name, IP address, etc./i).click(); - cy.findByText(/teams/i).should("exist"); + afterEach(() => { + cy.stopDockerHost(); }); - cy.visit("/queries/manage"); + it("Can perform the appropriate basic global maintainer actions", () => { + cy.login("mary@organization.com", "user123#"); + cy.visit("/"); - cy.findByText(/detect presence/i).click(); + // Ensure page is loaded + cy.contains("All hosts"); - cy.findByText(/edit & run query/i).should("exist"); + // Host manage page: Teams column, select a team + cy.visit("/hosts/manage"); - cy.get(".target-select").within(() => { - cy.findByText(/Label name, host name, IP address, etc./i).click(); - cy.findByText(/teams/i).should("exist"); + cy.wait(10000); // eslint-disable-line cypress/no-unnecessary-waiting + + cy.get("thead").within(() => { + cy.findByText(/team/i).should("exist"); + }); + + cy.contains("button", /add new host/i).click(); + // TODO: Check Team Apples is in Select a team dropdown + cy.contains("button", /done/i).click(); + + // Host details page: Can see team UI + cy.get("tbody").within(() => { + // Test host text varies + cy.findByRole("button").click(); + }); + cy.get(".title").within(() => { + cy.findByText("Team").should("exist"); + }); + cy.contains("button", /transfer/i).click(); + cy.get(".Select-control").click(); + cy.findByText(/create a team/i).should("not.exist"); + cy.get(".Select-menu").within(() => { + cy.findByText(/no team/i).should("exist"); + cy.findByText(/apples/i).should("exist"); + cy.findByText(/oranges/i).click(); + }); + cy.get(".transfer-action-btn").click(); + cy.findByText(/transferred to oranges/i).should("exist"); + cy.findByText(/team/i).next().contains("Oranges"); + cy.contains("button", /delete/i).should("exist"); + cy.contains("button", /query/i).click(); + cy.contains("button", /create custom query/i).should("exist"); + + // Query pages: Can see teams UI for create, edit, and run query + cy.visit("/queries/manage"); + + cy.findByRole("button", { name: /create new query/i }).click(); + + cy.get(".target-select").within(() => { + cy.findByText(/Label name, host name, IP address, etc./i).click(); + cy.findByText(/teams/i).should("exist"); + }); + + cy.visit("/queries/manage"); + + cy.findByText(/detect presence/i).click(); + + cy.findByText(/edit & run query/i).should("exist"); + + cy.get(".target-select").within(() => { + cy.findByText(/Label name, host name, IP address, etc./i).click(); + cy.findByText(/teams/i).should("exist"); + }); + + // On the Packs pages (manage, new, and edit), they should… + // On the Schedule pages (manage, new, and edit), they should… + // ^^General maintainer functionality for packs page is being tested in core/maintainer.spec.ts + + // On the Profile page, they should… + // See Global in the Team section and Maintainer in the Role section + cy.visit("/profile"); + cy.findByText(/team/i) + .next() + .contains(/global/i); + cy.findByText("Role") + .next() + .contains(/maintainer/i); }); - - // On the Packs pages (manage, new, and edit), they should… - // On the Schedule pages (manage, new, and edit), they should… - // ^^General maintainer functionality for packs page is being tested in core/maintainer.spec.ts - - // On the Profile page, they should… - // See Global in the Team section and Maintainer in the Role section - cy.visit("/profile"); - cy.findByText(/team/i) - .next() - .contains(/global/i); - cy.findByText("Role") - .next() - .contains(/maintainer/i); - }); -}); + } +); diff --git a/cypress/integration/core/admin.spec.ts b/cypress/integration/core/admin.spec.ts index 480e3c3c5a..36eaf1b487 100644 --- a/cypress/integration/core/admin.spec.ts +++ b/cypress/integration/core/admin.spec.ts @@ -1,126 +1,132 @@ -describe("Core tier - Admin user", () => { - beforeEach(() => { - cy.setup(); - cy.login(); - cy.setupSMTP(); - cy.seedCore(); - cy.seedQueries(); - cy.addDockerHost(); - cy.logout(); - }); - afterEach(() => { - cy.stopDockerHost(); - }); - - it("Can perform the appropriate core-tier admin actions", () => { - cy.login("anna@organization.com", "user123#"); - cy.visit("/"); - - // Ensure page is loaded - cy.contains("All hosts"); - - // On the hosts page, they should… - - // Not see "team" anywhere on the page - cy.contains(/team/i).should("not.exist"); - - // See all navigation items - cy.get("nav").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("exist"); - cy.findByText(/settings/i).should("exist"); +describe( + "Core tier - Admin user", + { + defaultCommandTimeout: 20000, + }, + () => { + beforeEach(() => { + cy.setup(); + cy.login(); + cy.setupSMTP(); + cy.seedCore(); + cy.seedQueries(); + cy.addDockerHost(); + cy.logout(); + }); + afterEach(() => { + cy.stopDockerHost(); }); - // See and select "add new host" - cy.findByRole("button", { name: /new host/i }).click(); - cy.contains(/team/i).should("not.exist"); - cy.findByRole("button", { name: /done/i }).click(); + it("Can perform the appropriate core-tier admin actions", () => { + cy.login("anna@organization.com", "user123#"); + cy.visit("/"); - // See the “Show enroll secret” button. A modal appears after the user selects the button - cy.contains("button", /show enroll secret/i).click(); - cy.contains("button", /done/i).click(); + // Ensure page is loaded + cy.contains("All hosts"); - // See and select "add label" - cy.findByRole("button", { name: /add label/i }).click(); - cy.findByRole("button", { name: /cancel/i }).click(); + // On the hosts page, they should… - // On the Host details page, they should… - cy.visit("/hosts/1"); + // Not see "team" anywhere on the page + cy.contains(/team/i).should("not.exist"); - // Not see "team" information or transfer button - cy.findByText(/team/i).should("not.exist"); - cy.contains("button", /transfer/i).should("not.exist"); + // See all navigation items + cy.get("nav").within(() => { + cy.findByText(/hosts/i).should("exist"); + cy.findByText(/queries/i).should("exist"); + cy.findByText(/schedule/i).should("exist"); + cy.findByText(/settings/i).should("exist"); + }); - // See and select the “Delete” button - cy.findByRole("button", { name: /delete/i }).click(); - cy.findByText(/delete host/i).should("exist"); - cy.findByRole("button", { name: /cancel/i }).click(); + // See and select "add new host" + cy.findByRole("button", { name: /new host/i }).click(); + cy.contains(/team/i).should("not.exist"); + cy.findByRole("button", { name: /done/i }).click(); - // See and select the “Query” button - cy.findByRole("button", { name: /query/i }).click(); - cy.findByRole("button", { name: /create custom query/i }).should("exist"); - cy.get(".modal__ex").within(() => { - cy.findByRole("button").click(); - }); + // See the “Show enroll secret” button. A modal appears after the user selects the button + cy.contains("button", /show enroll secret/i).click(); + cy.contains("button", /done/i).click(); - // On the queries manage page, they should… - cy.contains("a", "Queries").click(); - // See the "observer can run column" - cy.contains(/observer can run/i); - // See and select the "create new query" button - cy.findByRole("button", { name: /new query/i }).click(); + // See and select "add label" + cy.findByRole("button", { name: /add label/i }).click(); + cy.findByRole("button", { name: /cancel/i }).click(); - // On the Queries - new/edit/run page, they should… - // Edit the “Query name,” “SQL,” “Description,” “Observers can run,” and “Select targets” input fields. - cy.findByLabelText(/query name/i) - .click() - .type("Cypress test query"); - // ACE editor requires special handling to get typing to work sometimes - cy.get(".ace_text-input") - .first() - .click({ force: true }) - .type("{selectall}{backspace}SELECT * FROM cypress;", { force: true }); - cy.findByLabelText(/description/i) - .click() - .type("Cypress test of create new query flow."); - cy.findByLabelText(/observers can run/i).click({ force: true }); + // On the Host details page, they should… + cy.visit("/hosts/1"); - // See and select the “Save changes,” “Save as new,” and “Run” buttons. - cy.findByRole("button", { name: /save/i }).click(); - cy.findByRole("button", { name: /new/i }).click(); - cy.findByRole("button", { name: /run/i }).should("exist"); + // Not see "team" information or transfer button + cy.findByText(/team/i).should("not.exist"); + cy.contains("button", /transfer/i).should("not.exist"); - // NOT see the “Teams” section in the Select target picker. This picker is summoned when the “Select targets” field is selected. - cy.get(".target-select").within(() => { - cy.findByText(/Label name, host name, IP address, etc./i).click(); + // See and select the “Delete” button + cy.findByRole("button", { name: /delete/i }).click(); + cy.findByText(/delete host/i).should("exist"); + cy.findByRole("button", { name: /cancel/i }).click(); + + // See and select the “Query” button + cy.findByRole("button", { name: /query/i }).click(); + cy.findByRole("button", { name: /create custom query/i }).should("exist"); + cy.get(".modal__ex").within(() => { + cy.findByRole("button").click(); + }); + + // On the queries manage page, they should… + cy.contains("a", "Queries").click(); + // See the "observer can run column" + cy.contains(/observer can run/i); + // See and select the "create new query" button + cy.findByRole("button", { name: /new query/i }).click(); + + // On the Queries - new/edit/run page, they should… + // Edit the “Query name,” “SQL,” “Description,” “Observers can run,” and “Select targets” input fields. + cy.findByLabelText(/query name/i) + .click() + .type("Cypress test query"); + // ACE editor requires special handling to get typing to work sometimes + cy.get(".ace_text-input") + .first() + .click({ force: true }) + .type("{selectall}{backspace}SELECT * FROM cypress;", { force: true }); + cy.findByLabelText(/description/i) + .click() + .type("Cypress test of create new query flow."); + cy.findByLabelText(/observers can run/i).click({ force: true }); + + // See and select the “Save changes,” “Save as new,” and “Run” buttons. + cy.findByRole("button", { name: /save/i }).click(); + cy.findByRole("button", { name: /new/i }).click(); + cy.findByRole("button", { name: /run/i }).should("exist"); + + // NOT see the “Teams” section in the Select target picker. This picker is summoned when the “Select targets” field is selected. + cy.get(".target-select").within(() => { + cy.findByText(/Label name, host name, IP address, etc./i).click(); + cy.findByText(/teams/i).should("not.exist"); + }); + + cy.contains("a", /back to queries/i).click({ force: true }); + cy.findByText(/cypress test query/i).click({ force: true }); + cy.findByText(/edit & run query/i).should("exist"); + + // On the Packs pages (manage, new, and edit), they should… + // ^^General admin functionality for packs page is being tested in app/packflow.spec.ts + + // On the Settings pages, they should… + // See everything except for the “Teams” pages + cy.visit("/settings/organization"); cy.findByText(/teams/i).should("not.exist"); + cy.get(".react-tabs").within(() => { + cy.findByText(/organization settings/i).should("exist"); + cy.findByText(/users/i).click(); + }); + cy.findByRole("button", { name: /create user/i }).click(); + cy.findByText(/team/i).should("not.exist"); + cy.visit("/settings/teams"); + cy.findByText(/you do not have permissions/i).should("exist"); + + // On the Profile page, they should… + // See Admin in Role section, and no Team section + cy.visit("/profile"); + cy.findByText(/teams/i).should("not.exist"); + cy.findByText("Role").next().contains(/admin/i); }); - - cy.contains("a", /back to queries/i).click({ force: true }); - cy.findByText(/cypress test query/i).click({ force: true }); - cy.findByText(/edit & run query/i).should("exist"); - - // On the Packs pages (manage, new, and edit), they should… - // ^^General admin functionality for packs page is being tested in app/packflow.spec.ts - - // On the Settings pages, they should… - // See everything except for the “Teams” pages - cy.visit("/settings/organization"); - cy.findByText(/teams/i).should("not.exist"); - cy.get(".react-tabs").within(() => { - cy.findByText(/organization settings/i).should("exist"); - cy.findByText(/users/i).click(); - }); - cy.findByRole("button", { name: /create user/i }).click(); - cy.findByText(/team/i).should("not.exist"); - cy.visit("/settings/teams"); - cy.findByText(/you do not have permissions/i).should("exist"); - - // On the Profile page, they should… - // See Admin in Role section, and no Team section - cy.visit("/profile"); - cy.findByText(/teams/i).should("not.exist"); - cy.findByText("Role").next().contains(/admin/i); - }); -}); + } +); diff --git a/cypress/integration/core/maintainer.spec.ts b/cypress/integration/core/maintainer.spec.ts index bd779a8ee8..0d4571c010 100644 --- a/cypress/integration/core/maintainer.spec.ts +++ b/cypress/integration/core/maintainer.spec.ts @@ -1,138 +1,146 @@ -describe("Core tier - Maintainer user", () => { - beforeEach(() => { - cy.setup(); - cy.login(); - cy.seedCore(); - cy.seedQueries(); - cy.addDockerHost(); - cy.logout(); - }); - - afterEach(() => { - cy.stopDockerHost(); - }); - - it("Can perform the appropriate core global maintainer actions", () => { - cy.login("mary@organization.com", "user123#"); - cy.visit("/"); - - // Ensure page is loaded - cy.contains("All hosts"); - - // Settings restrictions - cy.findByText(/settings/i).should("not.exist"); - cy.visit("/settings/organization"); - cy.findByText(/you do not have permissions/i).should("exist"); - - // Host manage page: No team UI, can add host and label - cy.visit("/hosts/manage"); - cy.findByText(/teams/i).should("not.exist"); - cy.contains("button", /add new host/i).click(); - cy.findByText("select a team").should("not.exist"); - cy.contains("button", /done/i).click(); - - // See the “Show enroll secret” button. A modal appears after the user selects the button - cy.contains("button", /show enroll secret/i).click(); - cy.contains("button", /done/i).click(); - - cy.contains("button", /add label/i).click(); - cy.contains("button", /cancel/i).click(); - - // Host details page: No team UI, can delete and create new query - cy.get("tbody").within(() => { - // Test host text varies - cy.findByRole("button").click(); - }); - cy.get(".title").within(() => { - cy.findByText(/team/i).should("not.exist"); - }); - cy.contains("button", /transfer/i).should("not.exist"); - - cy.contains("button", /delete/i).click(); - cy.contains("button", /cancel/i).click(); - - cy.contains("button", /query/i).click(); - cy.contains("button", /create custom query/i).click(); - - // Queries pages: Can create, edit, and run query - cy.visit("/queries/manage"); - cy.get("thead").within(() => { - cy.findByText(/observer can run/i).should("exist"); +describe( + "Core tier - Maintainer user", + { + defaultCommandTimeout: 20000, + }, + () => { + beforeEach(() => { + cy.setup(); + cy.login(); + cy.seedCore(); + cy.seedQueries(); + cy.addDockerHost(); + cy.logout(); }); - cy.findByRole("button", { name: /create new query/i }).click(); + afterEach(() => { + cy.stopDockerHost(); + }); - cy.findByLabelText(/query name/i) - .click() - .type("Query all window crashes"); + it("Can perform the appropriate core global maintainer actions", () => { + cy.login("mary@organization.com", "user123#"); + cy.visit("/"); - cy.get(".ace_scroller") - .click({ force: true }) - .type("{selectall}{backspace}SELECT * FROM windows_crashes;"); + // Ensure page is loaded + cy.contains("All hosts"); - cy.findByLabelText(/description/i) - .click() - .type("See all window crashes"); + // Settings restrictions + cy.findByText(/settings/i).should("not.exist"); + cy.visit("/settings/organization"); + cy.findByText(/you do not have permissions/i).should("exist"); - cy.findByRole("button", { name: /save/i }).click(); - - cy.findByRole("button", { name: /save as new/i }).click(); - - cy.findByLabelText(/observers can run/i).click({ force: true }); - - cy.get(".target-select").within(() => { - cy.findByText(/Label name, host name, IP address, etc./i).click(); + // Host manage page: No team UI, can add host and label + cy.visit("/hosts/manage"); cy.findByText(/teams/i).should("not.exist"); + cy.contains("button", /add new host/i).click(); + cy.findByText("select a team").should("not.exist"); + cy.contains("button", /done/i).click(); + + // See the “Show enroll secret” button. A modal appears after the user selects the button + cy.contains("button", /show enroll secret/i).click(); + cy.contains("button", /done/i).click(); + + cy.contains("button", /add label/i).click(); + cy.contains("button", /cancel/i).click(); + + // Host details page: No team UI, can delete and create new query + cy.get("tbody").within(() => { + // Test host text varies + cy.findByRole("button").click(); + }); + cy.get(".title").within(() => { + cy.findByText(/team/i).should("not.exist"); + }); + cy.contains("button", /transfer/i).should("not.exist"); + + cy.contains("button", /delete/i) + .should("exist") + .click(); + cy.contains("button", /cancel/i).click(); + + cy.contains("button", /query/i).click(); + cy.contains("button", /create custom query/i).click(); + + // Queries pages: Can create, edit, and run query + cy.visit("/queries/manage"); + cy.get("thead").within(() => { + cy.findByText(/observer can run/i).should("exist"); + }); + + cy.findByRole("button", { name: /create new query/i }).click(); + + cy.findByLabelText(/query name/i) + .click() + .type("Query all window crashes"); + + cy.get(".ace_scroller") + .click({ force: true }) + .type("{selectall}{backspace}SELECT * FROM windows_crashes;"); + + cy.findByLabelText(/description/i) + .click() + .type("See all window crashes"); + + cy.findByRole("button", { name: /save/i }).click(); + + cy.findByRole("button", { name: /save as new/i }).click(); + + cy.findByLabelText(/observers can run/i).click({ force: true }); + + cy.get(".target-select").within(() => { + cy.findByText(/Label name, host name, IP address, etc./i).click(); + cy.findByText(/teams/i).should("not.exist"); + }); + + cy.findByRole("button", { name: /run/i }).should("exist"); + + cy.visit("/queries/manage"); + + cy.findByText(/query all/i).click(); + + cy.findByText(/edit & run query/i).should("exist"); + + // Packs pages: Can create, edit, delete a pack + cy.visit("/packs/manage"); + + cy.findByRole("button", { name: /create new pack/i }).click(); + + cy.findByLabelText(/query pack title/i) + .click() + .type("Errors and crashes"); + + cy.findByLabelText(/description/i) + .click() + .type("See all user errors and window crashes."); + + cy.findByRole("button", { name: /save query pack/i }).click(); + + cy.visit("/packs/manage"); + + cy.get(".fleet-checkbox__input").check({ force: true }); + + cy.findByRole("button", { name: /delete/i }).click(); + + // Can't figure out how attach findByRole onto modal button + // Can't use findByText because delete button under modal + cy.get(".remove-pack-modal__btn-wrap > .button--alert") + .contains("button", /delete/i) + .click(); + + cy.findByText(/successfully deleted/i).should("be.visible"); + + cy.findByText(/server errors/i).should("not.exist"); + + // Schedule page: Can create, edit, remove a schedule + // TODO: Copy flow from queryflow.spec.ts here to ensure maintainers have access + + // On the Profile page, they should… + // See Maintainer in Role section, and no Team section + cy.visit("/profile"); + cy.findByText(/teams/i).should("not.exist"); + cy.findByText("Role") + .next() + .contains(/maintainer/i); }); - - cy.findByRole("button", { name: /run/i }).should("exist"); - - cy.visit("/queries/manage"); - - cy.findByText(/query all/i).click(); - - cy.findByText(/edit & run query/i).should("exist"); - - // Packs pages: Can create, edit, delete a pack - cy.visit("/packs/manage"); - - cy.findByRole("button", { name: /create new pack/i }).click(); - - cy.findByLabelText(/query pack title/i) - .click() - .type("Errors and crashes"); - - cy.findByLabelText(/description/i) - .click() - .type("See all user errors and window crashes."); - - cy.findByRole("button", { name: /save query pack/i }).click(); - - cy.visit("/packs/manage"); - - cy.get(".fleet-checkbox__input").check({ force: true }); - - cy.findByRole("button", { name: /delete/i }).click(); - - // Can't figure out how attach findByRole onto modal button - // Can't use findByText because delete button under modal - cy.get(".remove-pack-modal__btn-wrap > .button--alert") - .contains("button", /delete/i) - .click(); - - cy.findByText(/successfully deleted/i).should("be.visible"); - - cy.findByText(/server errors/i).should("not.exist"); - - // Schedule page: Can create, edit, remove a schedule - // TODO: Copy flow from queryflow.spec.ts here to ensure maintainers have access - - // On the Profile page, they should… - // See Maintainer in Role section, and no Team section - cy.visit("/profile"); - cy.findByText(/teams/i).should("not.exist"); - cy.findByText("Role") - .next() - .contains(/maintainer/i); - }); -}); + } +);