From 4ecc7db6d6e0c03352539c7a004e1a990bbd704f Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Fri, 18 Aug 2023 11:06:12 -0600 Subject: [PATCH] Complete removal of Cypress (#13389) Remove the last of the dependencies and configuration around Cypress since we no longer use it for testing. --- .eslintrc.js | 8 - .github/workflows/test.yml | 2 - .gitignore | 5 - .prettierignore | 5 - cypress/README.md | 42 - cypress/cypress-free.json | 13 - cypress/cypress-premium.json | 13 - cypress/fixtures/example.json | 5 - .../integration/all/app/activateuser.spec.ts | 114 --- cypress/integration/all/app/dashboard.spec.ts | 59 -- .../integration/all/app/fleetdesktop.spec.ts | 88 --- cypress/integration/all/app/hosts.spec.ts | 261 ------- cypress/integration/all/app/labelflow.spec.ts | 89 --- .../integration/all/app/manageUsers.spec.ts | 132 ---- cypress/integration/all/app/packflow.spec.ts | 92 --- .../integration/all/app/policiesflow.spec.ts | 736 ------------------ cypress/integration/all/app/queryflow.spec.ts | 98 --- .../integration/all/app/resetsessions.spec.ts | 58 -- .../integration/all/app/settingsflow.spec.ts | 540 ------------- cypress/integration/all/app/software.spec.ts | 422 ---------- .../integration/all/sessions/sessions.spec.ts | 38 - cypress/integration/all/sessions/sso.spec.ts | 64 -- cypress/integration/all/setup/setup.spec.ts | 64 -- cypress/integration/free/README.md | 23 - cypress/integration/free/admin.spec.ts | 226 ------ cypress/integration/free/maintainer.spec.ts | 191 ----- cypress/integration/free/observer.spec.ts | 180 ----- cypress/integration/pages/dashboardPage.ts | 116 --- cypress/integration/pages/hostDetailsPage.ts | 46 -- cypress/integration/pages/manageHostsPage.ts | 57 -- cypress/integration/pages/managePacksPage.ts | 62 -- .../integration/pages/managePoliciesPage.ts | 115 --- .../integration/pages/manageQueriesPage.ts | 163 ---- .../integration/pages/manageSchedulePage.ts | 124 --- .../integration/pages/manageSoftwarePage.ts | 16 - cypress/integration/pages/teamsDropdown.ts | 10 - cypress/integration/pages/userProfilePage.ts | 21 - cypress/integration/premium/README.md | 23 - cypress/integration/premium/admin.spec.ts | 596 -------------- .../integration/premium/fleetdesktop.spec.ts | 33 - .../integration/premium/maintainer.spec.ts | 127 --- cypress/integration/premium/observer.spec.ts | 173 ---- cypress/integration/premium/sso.spec.ts | 55 -- .../integration/premium/team_admin.spec.ts | 213 ----- .../premium/team_maintainer_observer.spec.ts | 220 ------ cypress/integration/premium/teamflow.spec.ts | 147 ---- cypress/pages/appSettingsPage.ts | 12 - cypress/pages/teamSettingsPage.ts | 12 - cypress/plugins/index.js | 21 - cypress/support/commands.ts | 489 ------------ cypress/support/constants.ts | 245 ------ cypress/support/index.d.ts | 140 ---- cypress/support/index.js | 17 - cypress/tsconfig.json | 13 - package.json | 15 +- yarn.lock | 595 +------------- 56 files changed, 25 insertions(+), 7419 deletions(-) delete mode 100644 cypress/README.md delete mode 100644 cypress/cypress-free.json delete mode 100644 cypress/cypress-premium.json delete mode 100644 cypress/fixtures/example.json delete mode 100644 cypress/integration/all/app/activateuser.spec.ts delete mode 100644 cypress/integration/all/app/dashboard.spec.ts delete mode 100644 cypress/integration/all/app/fleetdesktop.spec.ts delete mode 100644 cypress/integration/all/app/hosts.spec.ts delete mode 100644 cypress/integration/all/app/labelflow.spec.ts delete mode 100644 cypress/integration/all/app/manageUsers.spec.ts delete mode 100644 cypress/integration/all/app/packflow.spec.ts delete mode 100644 cypress/integration/all/app/policiesflow.spec.ts delete mode 100644 cypress/integration/all/app/queryflow.spec.ts delete mode 100644 cypress/integration/all/app/resetsessions.spec.ts delete mode 100644 cypress/integration/all/app/settingsflow.spec.ts delete mode 100644 cypress/integration/all/app/software.spec.ts delete mode 100644 cypress/integration/all/sessions/sessions.spec.ts delete mode 100644 cypress/integration/all/sessions/sso.spec.ts delete mode 100644 cypress/integration/all/setup/setup.spec.ts delete mode 100644 cypress/integration/free/README.md delete mode 100644 cypress/integration/free/admin.spec.ts delete mode 100644 cypress/integration/free/maintainer.spec.ts delete mode 100644 cypress/integration/free/observer.spec.ts delete mode 100644 cypress/integration/pages/dashboardPage.ts delete mode 100644 cypress/integration/pages/hostDetailsPage.ts delete mode 100644 cypress/integration/pages/manageHostsPage.ts delete mode 100644 cypress/integration/pages/managePacksPage.ts delete mode 100644 cypress/integration/pages/managePoliciesPage.ts delete mode 100644 cypress/integration/pages/manageQueriesPage.ts delete mode 100644 cypress/integration/pages/manageSchedulePage.ts delete mode 100644 cypress/integration/pages/manageSoftwarePage.ts delete mode 100644 cypress/integration/pages/teamsDropdown.ts delete mode 100644 cypress/integration/pages/userProfilePage.ts delete mode 100644 cypress/integration/premium/README.md delete mode 100644 cypress/integration/premium/admin.spec.ts delete mode 100644 cypress/integration/premium/fleetdesktop.spec.ts delete mode 100644 cypress/integration/premium/maintainer.spec.ts delete mode 100644 cypress/integration/premium/observer.spec.ts delete mode 100644 cypress/integration/premium/sso.spec.ts delete mode 100644 cypress/integration/premium/team_admin.spec.ts delete mode 100644 cypress/integration/premium/team_maintainer_observer.spec.ts delete mode 100644 cypress/integration/premium/teamflow.spec.ts delete mode 100644 cypress/pages/appSettingsPage.ts delete mode 100644 cypress/pages/teamSettingsPage.ts delete mode 100644 cypress/plugins/index.js delete mode 100644 cypress/support/commands.ts delete mode 100644 cypress/support/constants.ts delete mode 100644 cypress/support/index.d.ts delete mode 100644 cypress/support/index.js delete mode 100644 cypress/tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index bc42a93c1..d570a3b9a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,7 +5,6 @@ module.exports = { "plugin:jest/recommended", "plugin:react-hooks/recommended", "plugin:@typescript-eslint/recommended", - "plugin:cypress/recommended", "plugin:prettier/recommended", "plugin:storybook/recommended", ], @@ -83,13 +82,6 @@ module.exports = { "jsx-a11y/anchor-has-content": "off", }, overrides: [ - { - files: ["cypress/**/*.ts"], - // Set to turn off jest linting error on cypress library - rules: { - "jest/valid-expect": "off", - }, - }, ], settings: { "import/resolver": { diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 85c46e3a9..144085dbe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -44,7 +44,6 @@ jobs: with: path: | **/node_modules - ~/.cache/Cypress key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-modules- @@ -78,7 +77,6 @@ jobs: with: path: | **/node_modules - ~/.cache/Cypress key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-modules- diff --git a/.gitignore b/.gitignore index de01834ea..34a07c0d3 100644 --- a/.gitignore +++ b/.gitignore @@ -41,11 +41,6 @@ helm-temp #editors .idea -# Cypress e2e testing -cypress/screenshots -cypress/videos -cypress/downloads - # Fleet local development DB backups backup.sql.gz diff --git a/.prettierignore b/.prettierignore index bd3ee8cac..9bc2a3577 100644 --- a/.prettierignore +++ b/.prettierignore @@ -28,11 +28,6 @@ tmp/ .vscode .idea -# Cypress e2e testing -cypress/screenshots -cypress/videos -cypress/downloads - # fleetdm.com website (uses its own formatting conventions) website/ diff --git a/cypress/README.md b/cypress/README.md deleted file mode 100644 index 04387d1de..000000000 --- a/cypress/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Cypress testing - -Cypress tests are designed solely for end-to-end testing. If this is your first time developing or running end-to-end tests, [Fleet testing documentation](../docs/Contributing/Testing-and-local-development.md) includes git instructions for test preparation and running tests. - -## Fleet Cypress directories - -### Integration directory - -Cypress tests the integration of [entire features](integration/all/app) of the app. - -With the roll out of teams, Cypress tests the user interface of each role of a user on the Premium Tier ([Fleet Premium Documentation](integration/premium/README.md)) and Free Tier ([Fleet Free Documentation](integration/free/README.md)). - -### Support directory - -[Commands](support/commands.ts) that are shared across tests are located in the support directory. - -## Opening Cypress locally - -To open simply run: - -`yarn cypress:open` - -This will open up cypress locally and -allow you to view the current test suite, as well as start writing new tests. - -## Building best practices - -As much as possible, build from a user's perspective. Use `.within` cypress command as needed to scope a command within a specific element (e.g. table, nav). - -As much as possible, assert that the code is only selecting 1 item or that the final assertion is the appropriate count. - -### Prioritization of selecting elements - -1. By **element tag** using elements (e.g. buttons), we can target text within. Confirm what the user is seeing with target text. If this is not specific enough, add on Role. -2. By **role** using default or explicitly assigned roles of elements. If this is not specific enough, add on element class. -3. By **element class** is least preferred as it does not follow a user's perspective. Occasionally this may be the only option. If that is the case, prioritize using the class name that specifies what the element is doing. - -## Resources - -- [Fleet testing documentation](../docs/Contributing/Testing-and-local-development.md) -- [Cypress documentation](https://docs.cypress.io/api/table-of-contents) -- [React testing-library query documentation](https://testing-library.com/docs/queries/about/) diff --git a/cypress/cypress-free.json b/cypress/cypress-free.json deleted file mode 100644 index d6f778384..000000000 --- a/cypress/cypress-free.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "baseUrl": "https://localhost:8642", - "fixturesFolder": false, - "experimentalSessionSupport": true, - "testFiles": "{all,free}/**/*.spec.ts", - "retries": { - "runMode": 2, - "openMode": 0 - }, - "video": false, - "videoUploadOnPasses": false, - "defaultCommandTimeout": 8000 -} diff --git a/cypress/cypress-premium.json b/cypress/cypress-premium.json deleted file mode 100644 index 7219e3d6f..000000000 --- a/cypress/cypress-premium.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "baseUrl": "https://localhost:8642", - "fixturesFolder": false, - "experimentalSessionSupport": true, - "testFiles": "{all,premium}/**/*.spec.ts", - "retries": { - "runMode": 2, - "openMode": 0 - }, - "video": false, - "videoUploadOnPasses": false, - "defaultCommandTimeout": 8000 -} diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json deleted file mode 100644 index 02e425437..000000000 --- a/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/cypress/integration/all/app/activateuser.spec.ts b/cypress/integration/all/app/activateuser.spec.ts deleted file mode 100644 index de30a8966..000000000 --- a/cypress/integration/all/app/activateuser.spec.ts +++ /dev/null @@ -1,114 +0,0 @@ -import CONSTANTS from "../../../support/constants"; - -const { - GOOD_PASSWORD, - BAD_PASSWORD_LENGTH, - BAD_PASSWORD_NO_NUMBER, - BAD_PASSWORD_NO_SYMBOL, -} = CONSTANTS; - -describe("Activate user flow", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.setupSMTP(); - cy.viewport(1600, 900); - }); - after(() => { - cy.logout(); - }); - - describe("Users settings page", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.viewport(1600, 900); - cy.visit("/settings/organization"); - cy.getAttached(".component__tabs-wrapper").within(() => { - cy.findByRole("tab", { name: /^users$/i }).click(); - }); - }); - it("invites and activates a user", () => { - cy.getAttached(".user-management").within(() => { - cy.contains("button", /create user/i).click(); - }); - cy.getAttached(".create-user-modal").within(() => { - cy.findByLabelText(/name/i).click().type("Ash Ketchum"); - cy.findByLabelText(/email/i).click().type("ash@example.com"); - cy.getAttached(".create-user-form__new-user-radios").within(() => { - cy.findByRole("radio", { name: "Invite user" }).parent().click(); - }); - cy.findByRole("button", { name: /^create$/i }).click(); - }); - // Ensures the email has been delivered - cy.wait(3000); // eslint-disable-line cypress/no-unnecessary-waiting - cy.logout(); - // Retrieves user invite in email - const inviteLink = { url: "" }; - const regex = /\/login\/invites\/[a-zA-Z0-9=?%&@._-]*/gm; - cy.getEmails().then((response) => { - expect(response.body.items[0].To[0]).to.have.property("Domain"); - expect(response.body.items[0].To[0].Mailbox).to.equal("ash"); - expect(response.body.items[0].To[0].Domain).to.equal("example.com"); - expect(response.body.items[0].From.Mailbox).to.equal("fleet"); - expect(response.body.items[0].From.Domain).to.equal("example.com"); - const match = response.body.items[0].Content.Body.match(regex); - inviteLink.url = match[0]; - }); - // Activates user - cy.visit(inviteLink); - cy.getAttached(".confirm-invite-page").within(() => { - cy.findByLabelText(/full name/i) - .clear() - .type("Ash Ketchum"); - cy.findByLabelText(/^password$/i) - .click() - .type(BAD_PASSWORD_LENGTH); - cy.findByLabelText(/confirm password/i) - .click() - .type(BAD_PASSWORD_LENGTH); - cy.findByRole("button", { name: /submit/i }).click(); - }); - cy.findByText(/password does not meet required criteria/i).should( - "exist" - ); - cy.getAttached("#password").clear().type(BAD_PASSWORD_NO_NUMBER); - cy.getAttached("#password_confirmation") - .clear() - .type(BAD_PASSWORD_NO_NUMBER); - cy.findByRole("button", { name: /submit/i }).click(); - cy.findByText(/password does not meet required criteria/i).should( - "exist" - ); - cy.getAttached("#password").clear().type(BAD_PASSWORD_NO_SYMBOL); - cy.getAttached("#password_confirmation") - .clear() - .type(BAD_PASSWORD_NO_SYMBOL); - cy.findByRole("button", { name: /submit/i }).click(); - cy.findByText(/password does not meet required criteria/i).should( - "exist" - ); - cy.getAttached("#password").clear().type(GOOD_PASSWORD); - cy.getAttached("#password_confirmation").clear().type(GOOD_PASSWORD); - cy.findByRole("button", { name: /submit/i }).click(); - - cy.getAttached(".login-form").within(() => { - cy.findByLabelText(/email/i).clear().type("ash@example.com"); - cy.findByLabelText(/^password$/i) - .click() - .type(GOOD_PASSWORD); - cy.findByRole("button", { name: /login/i }).click(); - }); - Cypress.session.clearAllSavedSessions(); // Switch back to admin user - }); - it("shows new user in admin settings", () => { - cy.getAttached("tbody>tr>td") - .contains("Ash Ketchum") - .parent() - .parent() - .within(() => { - cy.findByText(/active/i).should("exist"); - }); - }); - }); -}); diff --git a/cypress/integration/all/app/dashboard.spec.ts b/cypress/integration/all/app/dashboard.spec.ts deleted file mode 100644 index a2477eeae..000000000 --- a/cypress/integration/all/app/dashboard.spec.ts +++ /dev/null @@ -1,59 +0,0 @@ -import dashboardPage from "../../pages/dashboardPage"; - -describe("Dashboard", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.viewport(1200, 660); - }); - - after(() => { - cy.logout(); - }); - - describe("Operating systems card", () => { - beforeEach(() => { - cy.loginWithCySession(); - dashboardPage.visitsDashboardPage(); - }); - - it("displays operating systems card if macOS platform is selected", () => { - dashboardPage.switchesPlatform("macOS"); - }); - - it("displays operating systems card if Windows platform is selected", () => { - dashboardPage.switchesPlatform("Windows"); - }); - - it("displays operating systems card if Linux platform is selected", () => { - dashboardPage.switchesPlatform("Linux"); - }); - }); - describe("Hosts filter by dashboard host summary", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.visit("/dashboard"); - }); - it("filters macOS hosts", () => { - cy.findByText(/macos hosts/i).click(); - cy.findByRole("status", { - name: /hosts filtered by macos/i, - }).should("exist"); - }); - it("filters Windows hosts", () => { - cy.findByText(/windows hosts/i).click(); - cy.findByRole("status", { - name: /hosts filtered by windows/i, - }).should("exist"); - }); - - it("filters linux hosts", () => { - cy.findByText(/macos hosts/i).click(); - cy.findByRole("status", { - name: /hosts filtered by macos/i, - }).should("exist"); - }); - // filters missing hosts and low disk space hosts on premium only, premium/admin.spec.ts - }); -}); diff --git a/cypress/integration/all/app/fleetdesktop.spec.ts b/cypress/integration/all/app/fleetdesktop.spec.ts deleted file mode 100644 index f0e5f5066..000000000 --- a/cypress/integration/all/app/fleetdesktop.spec.ts +++ /dev/null @@ -1,88 +0,0 @@ -const fakeDeviceToken = "phAK3d3vIC37OK3n"; - -describe("Fleet Desktop", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.addDockerHost(); - cy.setDesktopToken(1, fakeDeviceToken); - cy.viewport(1200, 660); - }); - after(() => { - cy.stopDockerHost(); - }); - describe("Fleet Desktop device user page", () => { - beforeEach(() => { - Cypress.session.clearAllSavedSessions(); - cy.visit(`/device/${fakeDeviceToken}`); - }); - it("renders the device user information and info modal", () => { - cy.findByText(/my device/i).should("exist"); - cy.getAttached(".status--online").should("exist"); - cy.getAttached(".info-flex").within(() => { - cy.findByText(/ubuntu 20/i) - .prev() - .contains(/operating system/i); - }); - cy.getAttached(".info-grid").within(() => { - cy.findByText(/private ip address/i) - .next() - .findByText(/---/i) - .should("not.exist"); - }); - cy.getAttached(".device-user__action-button-container").within(() => { - cy.getAttached('img[alt="Host info icon"]').click(); - }); - cy.getAttached(".device-user-info__modal").within(() => { - cy.findByRole("button", { name: /ok/i }).click(); - }); - }); - it("renders and searches the host's software", () => { - cy.getAttached(".react-tabs__tab-list").within(() => { - cy.findByText(/software/i).click(); - }); - let initialCount = 0; - cy.getAttached(".section--software").within(() => { - cy.getAttached(".table-container__results-count") - .invoke("text") - .then((text) => { - const fullText = text; - const pattern = /[0-9]+/g; - const newCount = fullText.match(pattern); - initialCount = parseInt(newCount[0], 10); - expect(initialCount).to.be.at.least(1); - }); - cy.findByPlaceholderText(/search software/i).type("lib"); - // Ensures search completes - cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting - cy.getAttached(".table-container__results-count") - .invoke("text") - .then((text) => { - const fullText = text; - const pattern = /[0-9]+/g; - const newCount = fullText.match(pattern); - const searchCount = parseInt(newCount[0], 10); - expect(searchCount).to.be.lessThan(initialCount); - }); - }); - }); - it( - "refetches host vitals", - { - retries: { - runMode: 2, - }, - defaultCommandTimeout: 15000, - }, - () => { - cy.getAttached(".display-name-container").within(() => { - cy.contains("button", /refetch/i).click(); - cy.findByText(/fetching/i).should("exist"); - cy.contains("button", /refetch/i).should("exist"); - cy.findByText(/less than a minute/i).should("exist"); - }); - } - ); - }); -}); diff --git a/cypress/integration/all/app/hosts.spec.ts b/cypress/integration/all/app/hosts.spec.ts deleted file mode 100644 index 9011b8fba..000000000 --- a/cypress/integration/all/app/hosts.spec.ts +++ /dev/null @@ -1,261 +0,0 @@ -import * as path from "path"; -import { format } from "date-fns"; -import manageHostsPage from "../../pages/manageHostsPage"; -import hostDetailsPage from "../../pages/hostDetailsPage"; - -let hostname = ""; - -describe("Hosts flow", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.addDockerHost(); - cy.clearDownloads(); - cy.seedQueries(); - cy.seedSchedule(); - cy.seedPolicies(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - describe("Manage hosts page", () => { - beforeEach(() => { - cy.loginWithCySession(); - manageHostsPage.visitsManageHostsPage(); - }); - it("adds a new host and downloads installation files", () => { - // Download add hosts files - cy.getAttached(".manage-hosts").within(() => { - cy.contains("button", /add hosts/i).click(); - }); - cy.getAttached(".react-tabs").within(() => { - cy.findByText(/advanced/i) - .first() - .should("exist") - .click(); - }); - cy.getAttached(".reveal-button").click(); - cy.getAttached('a[href*="#downloadEnrollSecret"]').click(); - cy.getAttached('a[href*="#downloadCertificate"]').last().click(); - cy.getAttached('a[href*="#downloadFlagfile"]').click(); - - // 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) - if (Cypress.platform !== "win32") { - // windows has issues with downloads location - - // Feature pushed back from 4.13 release - // const formattedTime = format(new Date(), "yyyy-MM-dd"); - // const filename = `Hosts ${formattedTime}.csv`; - // cy.readFile(path.join(Cypress.config("downloadsFolder"), filename), { - // timeout: 5000, - // }); - cy.readFile( - path.join(Cypress.config("downloadsFolder"), "secret.txt"), - { - timeout: 5000, - } - ); - cy.readFile( - path.join(Cypress.config("downloadsFolder"), "flagfile.txt"), - { - timeout: 5000, - } - ); - cy.readFile(path.join(Cypress.config("downloadsFolder"), "fleet.pem"), { - timeout: 5000, - }); - } - }); - it(`exports hosts to CSV`, () => { - cy.getAttached(".manage-hosts").within(() => { - cy.getAttached(".manage-hosts__export-btn").click(); - }); - if (Cypress.platform !== "win32") { - // windows has issues with downloads location - const formattedTime = format(new Date(), "yyyy-MM-dd"); - const filename = `Hosts ${formattedTime}.csv`; - cy.readFile(path.join(Cypress.config("downloadsFolder"), filename), { - timeout: 5000, - }); - } - }); - it(`hides and shows "Used by" column`, () => { - cy.getAttached("thead").within(() => - cy.findByText(/used by/i).should("not.exist") - ); - cy.getAttached(".table-container").within(() => { - cy.contains("button", /edit columns/i).click(); - }); - cy.getAttached(".edit-columns-modal").within(() => { - cy.findByLabelText(/used by/i).check({ force: true }); - cy.contains("button", /save/i).click(); - }); - cy.getAttached("thead").within(() => - cy.findByText(/used by/i).should("exist") - ); - }); - }); - describe("Manage policies page", () => { - beforeEach(() => { - cy.loginWithCySession(); - manageHostsPage.visitsManageHostsPage(); - }); - it( - "runs policy on an existing host", - { - retries: { - runMode: 2, - }, - defaultCommandTimeout: 10000, - }, - () => { - cy.getAttached("tbody").within(() => { - cy.get(".button--text-link").first().as("hostLink"); - }); - cy.getAttached("@hostLink") - // Set hostname variable for later assertions - .then((el) => { - hostname = el.text(); - return el; - }) - .click(); - // Go to host details page - cy.location("pathname").should("match", /hosts\/[0-9]/i); - cy.getAttached(".status--online").should("exist"); - // Run policy on host - cy.contains("a", "Policies").click(); - cy.getAttached("tbody").within(() => { - cy.get(".button--text-link").first().as("policyLink"); - }); - cy.getAttached("@policyLink") - // Set policyname variable for later assertions - .then((el) => { - console.log(el); - return el; - }); - cy.findByText(/filevault/i) - .should("exist") - .click(); - cy.getAttached(".policy-form__run").should("exist").click(); - cy.findByText(/all hosts/i) - .should("exist") - .click() - .then(() => { - cy.findByText(/run/i).click(); - }); - cy.getAttached(".data-table").within(() => { - cy.findByText(hostname).should("exist"); - }); - } - ); - }); - describe("Host details page", () => { - beforeEach(() => { - cy.loginWithCySession(); - manageHostsPage.visitsManageHostsPage(); - cy.getAttached("tbody").within(() => { - cy.getAttached(".button--text-link").first().click(); - }); - }); - it("renders and searches the host's users", () => { - cy.getAttached(".section--users").within(() => { - cy.getAttached("tbody>tr").should("have.length.greaterThan", 0); - cy.findByPlaceholderText(/search/i).type("Ash"); - cy.getAttached("tbody>tr").should("have.length", 0); - cy.getAttached(".empty-table__container").within(() => { - cy.findByText(/no users match/i).should("exist"); - }); - }); - }); - it("renders and searches the host's software", () => { - cy.getAttached(".react-tabs__tab-list").within(() => { - cy.findByText(/software/i).click(); - }); - let initialCount = 0; - cy.getAttached(".section--software").within(() => { - cy.getAttached(".table-container__results-count") - .invoke("text") - .then((text) => { - const fullText = text; - const pattern = /[0-9]+/g; - const newCount = fullText.match(pattern); - initialCount = parseInt(newCount[0], 10); - expect(initialCount).to.be.at.least(1); - }); - cy.findByPlaceholderText(/search software/i).type("lib"); - // Ensures search completes - cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting - cy.getAttached(".table-container__results-count") - .invoke("text") - .then((text) => { - const fullText = text; - const pattern = /[0-9]+/g; - const newCount = fullText.match(pattern); - const searchCount = parseInt(newCount[0], 10); - expect(searchCount).to.be.lessThan(initialCount); - }); - }); - }); - it("host's software table links to filter hosts by software", () => { - cy.getAttached(".react-tabs__tab-list").within(() => { - cy.findByText(/software/i).click(); - }); - cy.getAttached(".software-link").first().click({ force: true }); - cy.findByText(/adduser 3.118ubuntu2/i).should("exist"); // first seeded software item - cy.getAttached(".data-table").within(() => { - cy.findByText(hostname).should("exist"); - }); - }); - it("host's software table links to software details", () => { - cy.getAttached(".react-tabs__tab-list").within(() => { - cy.findByText(/software/i).click(); - }); - cy.contains(/adduser/i).click(); - cy.findByText(/adduser, 3.118ubuntu2/i).should("exist"); - }); - it("renders host's schedule", () => { - cy.getAttached(".react-tabs__tab-list").within(() => { - cy.findByText(/schedule/i).click(); - }); - cy.getAttached(".data-table").within(() => { - cy.getAttached(".query_name__header").should("exist"); - }); - }); - it("renders host's policies and links to filter hosts by policy status", () => { - cy.getAttached(".react-tabs__tab-list").within(() => { - cy.findByText(/policies/i).click(); - }); - cy.getAttached(".section--policies").within(() => { - cy.findByText(/failing 1 policy/i).should("exist"); - cy.getAttached(".policy-link").first().click({ force: true }); - }); - cy.findAllByText(/Is Filevault enabled on macOS devices/i).should( - "exist" - ); - cy.getAttached(".data-table").within(() => { - cy.findByText(hostname).should("exist"); - }); - }); - it( - "refetches host vitals", - { - retries: { - runMode: 2, - }, - defaultCommandTimeout: 15000, - }, - () => { - cy.getAttached(".display-name-container").within(() => { - cy.contains("button", /refetch/i).click(); - cy.findByText(/fetching/i).should("exist"); - cy.contains("button", /refetch/i).should("exist"); - cy.findByText(/less than a minute/i).should("exist"); - }); - } - ); - }); -}); diff --git a/cypress/integration/all/app/labelflow.spec.ts b/cypress/integration/all/app/labelflow.spec.ts deleted file mode 100644 index 024672216..000000000 --- a/cypress/integration/all/app/labelflow.spec.ts +++ /dev/null @@ -1,89 +0,0 @@ -import manageHostsPage from "../../pages/manageHostsPage"; - -describe("Labels flow", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.addDockerHost(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - - describe("Manage hosts page", () => { - beforeEach(() => { - cy.loginWithCySession(); - manageHostsPage.visitsManageHostsPage(); - }); - it("creates a custom label", () => { - cy.getAttached(".label-filter-select__control").click(); - cy.findByRole("button", { name: /add label/i }).click(); - cy.getAttached(".label-form__text-editor-wrapper .ace_content").type( - "{selectall}{backspace}SELECT * FROM users;" - ); - cy.findByLabelText(/name/i).click().type("Show all MAC users"); - cy.findByLabelText(/description/i) - .click() - .type("Select all MAC users."); - cy.getAttached(".label-form__form-field--platform > .Select").click(); - cy.getAttached(".Select-menu-outer").within(() => { - cy.findByText(/macOS/i).click(); - }); - cy.findByRole("button", { name: /save label/i }).click(); - cy.findByText(/label created/i).should("exist"); - }); - it("edits a custom label", () => { - cy.getAttached(".label-filter-select__control").click(); - cy.findByText(/Show all MAC users/i).click(); - cy.findByRole("button", { name: /edit label/i }).click(); - // SQL and Platform are immutable fields - cy.findByLabelText(/name/i).clear().type("Show all mac usernames"); - cy.findByLabelText(/description/i) - .clear() - .type("Select all usernames on Mac."); - cy.findByText(/select one/i).should("not.exist"); - cy.findByRole("button", { name: /update label/i }).click(); - cy.findByText(/label updated/i).should("exist"); - }); - it("deletes a custom label", () => { - cy.getAttached(".label-filter-select__control").click(); - cy.findByText(/Show all mac usernames/i).click(); - cy.findByRole("button", { name: /delete label/i }).click(); - cy.getAttached(".delete-label-modal") - .contains("button", /delete/i) - .click(); - cy.getAttached(".label-filter-select__control").within(() => { - cy.findByText(/show all mac usernames/i).should("not.exist"); - }); - }); - it("creates labels with special characters", () => { - cy.getAttached(".label-filter-select__control").click(); - cy.findByRole("button", { name: /add label/i }).click(); - cy.getAttached(".label-form__text-editor-wrapper .ace_content").type( - "{selectall}{backspace}SELECT * FROM users;" - ); - cy.findByLabelText(/name/i) - .click() - .type("** Special label (Mac / Users)"); - cy.findByLabelText(/description/i) - .click() - .type("Select all MAC users using special characters."); - cy.getAttached(".label-form__form-field--platform > .Select").click(); - cy.getAttached(".Select-menu-outer").within(() => { - cy.findByText(/macOS/i).click(); - }); - cy.findByRole("button", { name: /save label/i }).click(); - cy.findByText(/label created/i).should("exist"); - }); - it("searches labels with special characters", () => { - cy.getAttached(".label-filter-select__control").click(); - cy.findByPlaceholderText(/filter labels by name.../i).type( - "{selectall}{backspace}**" - ); - cy.findByText(/Special label/i).should("exist"); - }); - }); -}); diff --git a/cypress/integration/all/app/manageUsers.spec.ts b/cypress/integration/all/app/manageUsers.spec.ts deleted file mode 100644 index 0a063cba4..000000000 --- a/cypress/integration/all/app/manageUsers.spec.ts +++ /dev/null @@ -1,132 +0,0 @@ -import CONSTANTS from "../,,/../../../support/constants"; - -const { - GOOD_PASSWORD, - BAD_PASSWORD_LENGTH, - BAD_PASSWORD_NO_NUMBER, - BAD_PASSWORD_NO_SYMBOL, -} = CONSTANTS; - -describe("Manage users flow", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.viewport(1200, 660); - cy.setupSMTP(); - }); - after(() => { - cy.logout(); - }); - describe("User management page", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.visit("/settings/users"); - }); - it("searches for an existing user", () => { - cy.findByText("admin@example.com").should("exist"); - cy.findByText("maintainer@example.com").should("exist"); - cy.findByText("observer@example.com").should("exist"); - cy.findByText("sso_user@example.com").should("exist"); - - cy.findByPlaceholderText("Search").type("admin"); - - cy.getAttached("tbody>tr").should("have.length", 1); - cy.findByText("admin@example.com").should("exist"); - cy.findByText("maintainer@example.com").should("not.exist"); - cy.findByText("observer@example.com").should("not.exist"); - cy.findByText("sso_user@example.com").should("not.exist"); - }); - it("creates a new user", () => { - cy.contains("button:enabled", /create user/i).click(); - cy.findByPlaceholderText("Full name").type("New Name"); - cy.findByPlaceholderText("Email").type("new-user@example.com"); - cy.getAttached( - ".create-user-form__form-field--global-role > .Select" - ).click(); - cy.getAttached(".create-user-form__form-field--global-role").within( - () => { - cy.findByText(/maintainer/i).click(); - } - ); - cy.findByPlaceholderText("Password").clear().type(BAD_PASSWORD_LENGTH); - cy.getAttached(".modal-cta-wrap") - .contains("button", /create/i) - .click(); - cy.findByText(/password must meet the criteria below/i).should("exist"); - cy.findByLabelText(/password must meet the criteria below/i) - .clear() - .type(BAD_PASSWORD_NO_NUMBER); - cy.getAttached(".modal-cta-wrap") - .contains("button", /create/i) - .click(); - cy.findByText(/password must meet the criteria below/i).should("exist"); - cy.findByLabelText(/password must meet the criteria below/i) - .clear() - .type(BAD_PASSWORD_NO_NUMBER); - cy.getAttached(".modal-cta-wrap") - .contains("button", /create/i) - .click(); - cy.findByText(/password must meet the criteria below/i).should("exist"); - cy.findByLabelText(/password must meet the criteria below/i) - .clear() - .type(GOOD_PASSWORD); - cy.getAttached(".modal-cta-wrap") - .contains("button", /create/i) - .click(); - cy.findByText(/new name/i).should("exist"); - }); - it("edits an existing user", () => { - cy.getAttached("tbody>tr") - .should("have.length", 5) - .eq(1) - .within(() => { - cy.findByText(/action/i).click(); - cy.findByText(/edit/i).click(); - }); - cy.findByPlaceholderText("Full name").clear().type("New Admin"); - cy.findByPlaceholderText("Email").clear().type("new-admin@example.com"); - cy.getAttached( - ".create-user-form__form-field--global-role > .Select" - ).click(); - cy.getAttached(".create-user-form__form-field--global-role").within( - () => { - cy.findByText(/admin/i).click(); - } - ); - cy.findByLabelText("Password").clear().type(BAD_PASSWORD_LENGTH); - cy.getAttached(".modal-cta-wrap").contains("button", /save/i).click(); - cy.findByText(/password must meet the criteria below/i).should("exist"); - cy.findByLabelText(/password must meet the criteria below/i) - .clear() - .type(BAD_PASSWORD_NO_NUMBER); - cy.getAttached(".modal-cta-wrap").contains("button", /save/i).click(); - cy.findByText(/password must meet the criteria below/i).should("exist"); - cy.findByLabelText(/password must meet the criteria below/i) - .clear() - .type(BAD_PASSWORD_NO_SYMBOL); - cy.getAttached(".modal-cta-wrap").contains("button", /save/i).click(); - cy.findByText(/password must meet the criteria below/i).should("exist"); - cy.findByLabelText(/password must meet the criteria below/i) - .clear() - .type(GOOD_PASSWORD); - cy.getAttached(".modal-cta-wrap").contains("button", /save/i).click(); - cy.findByText(/successfully edited/i).should("exist"); - }); - it("deletes an existing user", () => { - cy.getAttached("tbody>tr") - .eq(1) - .within(() => { - cy.findByText(/new admin/i).should("exist"); - cy.findByText(/action/i).click(); - cy.findByText(/delete/i).click(); - }); - cy.getAttached(".modal-cta-wrap") - .contains("button", /delete/i) - .click(); - cy.findByText(/successfully deleted/i).should("exist"); - cy.getAttached("tbody>tr").should("have.length", 4); - cy.findByText(/new-user/i).should("not.exist"); - }); - }); -}); diff --git a/cypress/integration/all/app/packflow.spec.ts b/cypress/integration/all/app/packflow.spec.ts deleted file mode 100644 index b81be8272..000000000 --- a/cypress/integration/all/app/packflow.spec.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* NOTE: Product decision to remove packs from UI - -import managePacksPage from "../../pages/managePacksPage"; - -describe("Pack flow (empty)", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - - describe("Manage packs page", () => { - beforeEach(() => { - cy.loginWithCySession(); - managePacksPage.visitsManagePacksPage(); - }); - it("creates a new pack", () => { - managePacksPage.allowsCreatePack(); - managePacksPage.verifiesCreatedPack(); - }); - }); -}); -describe("Pack flow (seeded)", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.seedQueries(); - cy.seedPacks(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - - describe("Pack details page", () => { - beforeEach(() => { - cy.loginWithCySession(); - managePacksPage.visitsManagePacksPage(); - cy.getAttached(".name__cell > .button--text-link").first().click(); - }); - it("adds a query to an existing pack", () => { - cy.findByRole("button", { name: /add query/i }).click(); - cy.findByText(/select query/i).click(); - cy.findByText(/get authorized/i).click(); - cy.getAttached( - ".pack-query-editor-modal__form-field--frequency > .input-field" - ) - .click() - .type("3600"); - cy.getAttached( - ".pack-query-editor-modal__form-field--osquer-vers > .Select" - ).click(); - cy.findByText(/4.7/i).click(); - cy.getAttached( - ".pack-query-editor-modal__form-field--shard > .input-field" - ) - .click() - .type("50"); - cy.getAttached(".pack-query-editor-modal .modal-cta-wrap") - .contains("button", /add query/i) - .click(); - cy.findByText(/get authorized/i).should("exist"); - }); - it("removes a query from an existing pack", () => { - cy.getAttached(".fleet-checkbox__input").check({ force: true }); - cy.findByRole("button", { name: /remove/i }).click(); - cy.getAttached(".remove-pack-query-modal .modal-cta-wrap") - .contains("button", /remove/i) - .click(); - }); - it("edits an existing pack", () => { - managePacksPage.allowsEditPack(); - managePacksPage.verifiesEditedPack(); - }); - }); - describe("Manage packs page", () => { - beforeEach(() => { - cy.loginWithCySession(); - managePacksPage.visitsManagePacksPage(); - }); - it("deletes an existing pack", () => { - managePacksPage.allowsDeletePack(); - managePacksPage.verifiesDeletedPack(); - }); - }); -}); -*/ diff --git a/cypress/integration/all/app/policiesflow.spec.ts b/cypress/integration/all/app/policiesflow.spec.ts deleted file mode 100644 index ec8713d0f..000000000 --- a/cypress/integration/all/app/policiesflow.spec.ts +++ /dev/null @@ -1,736 +0,0 @@ -import CONSTANTS from "../../../support/constants"; -import managePoliciesPage from "../../pages/managePoliciesPage"; - -const { - CONFIG_INTEGRATIONS_AUTOMATIONS, - CONFIG_INTEGRATIONS_AUTOMATIONS_DISABLED, -} = CONSTANTS; - -const enableJiraPoliciesIntegration = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira1@example.com", - api_token: "jira123", - project_key: "PROJECT 1", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.atlassian.com", - username: "jira2@example.com", - api_token: "jira123", - project_key: "PROJECT 2", - enable_failing_policies: true, - enable_software_vulnerabilities: false, - }, - ], - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.zendesk.com", - email: "zendesk2@example.com", - api_token: "zendesk123", - group_id: 87654321, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - }, - webhook_settings: { - host_status_webhook: { - enable_host_status_webhook: false, - destination_url: "", - host_percentage: 0, - days_count: 0, - }, - failing_policies_webhook: { - enable_failing_policies_webhook: false, - destination_url: "https://www.foo.com/bar", - policy_ids: [5, 10], - host_batch_size: 0, - }, - vulnerabilities_webhook: { - destination_url: "https://www.foo.com/bar", - enable_vulnerabilities_webhook: false, - }, - }, -}; - -const enableZendeskPoliciesIntegration = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira1@example.com", - api_token: "jira123", - project_key: "PROJECT 1", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.atlassian.com", - username: "jira2@example.com", - api_token: "jira123", - project_key: "PROJECT 2", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.zendesk.com", - email: "zendesk2@example.com", - api_token: "zendesk123", - group_id: 87654321, - enable_failing_policies: true, - enable_software_vulnerabilities: false, - }, - ], - }, - webhook_settings: { - host_status_webhook: { - enable_host_status_webhook: false, - destination_url: "", - host_percentage: 0, - days_count: 0, - }, - failing_policies_webhook: { - enable_failing_policies_webhook: false, - destination_url: "https://www.foo.com/bar", - policy_ids: [5, 10], - host_batch_size: 0, - }, - vulnerabilities_webhook: { - destination_url: "https://www.foo.com/bar", - enable_vulnerabilities_webhook: false, - }, - }, -}; - -describe("Policies flow (empty)", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - - describe("Manage policies page", () => { - beforeEach(() => { - cy.loginWithCySession(); - managePoliciesPage.visitManagePoliciesPage(); - }); - it("creates a custom policy", () => { - cy.getAttached(".empty-table__cta-buttons").within(() => { - cy.findByText(/add a policy/i).click(); - }); - cy.findByText(/create your own policy/i).click(); - cy.getAttached(".policy-page__form .ace_scroller") - .click({ force: true }) - .type( - "{selectall}SELECT 1 FROM users WHERE username = 'backup' LIMIT 1;" - ); - cy.findByRole("button", { name: /save/i }).click(); - cy.getAttached(".policy-form__policy-save-modal-name") - .click() - .type("Does the device have a user named 'backup'?"); - cy.getAttached(".policy-form__policy-save-modal-description") - .click() - .type("Returns yes or no for having a user named 'backup'"); - cy.getAttached(".policy-form__policy-save-modal-resolution") - .click() - .type("Create a user named 'backup'"); - cy.findByRole("button", { name: /save policy/i }).click(); - cy.findByText(/policy created/i).should("exist"); - }); - - it("creates a default policy", () => { - managePoliciesPage.allowsAddDefaultPolicy(); - managePoliciesPage.verifiesAddedDefaultPolicy(); - }); - }); - - describe("Platform compatibility", () => { - beforeEach(() => { - cy.loginWithCySession(); - managePoliciesPage.visitManagePoliciesPage(); - }); - const platforms = ["macOS", "Windows", "Linux"]; - - const testCompatibility = ( - el: JQuery, - i: number, - expected: boolean[] - ) => { - const check = expected[i] - ? "compatible-platform" - : "incompatible-platform"; - const compatibility = expected[i] ? "compatible" : "incompatible"; - assert( - el.children("div").attr("class").includes(check), - `expected policy to be ${platforms[i]} ${compatibility}` - ); - }; - - const testSelections = ( - el: JQuery, - i: number, - expected: boolean[] - ) => { - assert( - el.prop("checked") === expected[i], - `expected ${platforms[i]} to be ${ - expected[i] ? "selected " : "not selected" - }` - ); - }; - - it("checks sql statement for platform compatibility", () => { - cy.getAttached(".manage-policies-page__header-wrap").within(() => { - cy.findByText(/add a policy/i).click(); - }); - cy.getAttached(".add-policy-modal").within(() => { - cy.findByRole("button", { name: /create your own policy/i }).click(); - }); - - cy.getAttached(".platform").each((el, i) => { - testCompatibility(el, i, [true, true, true]); - }); - - // Query with unknown table name displays error message - cy.getAttached(".policy-page__form .ace_scroller") - .first() - .click({ force: true }) - .type("{selectall}SELECT 1 FROM foo WHERE start_time > 1;"); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(700); // wait for text input debounce - cy.getAttached(".platform-compatibility").within(() => { - cy.findByText( - "No platforms (check your query for invalid tables or tables that are supported on different platforms)" - ).should("exist"); - }); - - // Query with syntax error displays error message - cy.getAttached(".policy-page__form .ace_scroller") - .first() - .click({ force: true }) - .type("{selectall}SELEC 1 FRO osquery_info WHER start_time > 1;"); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(700); // wait for text input debounce - cy.getAttached(".platform-compatibility").within(() => { - cy.findByText( - "No platforms (check your query for a possible syntax error)" - ).should("exist"); - }); - - // Query with no tables treated as compatible with all platforms - cy.getAttached(".policy-page__form .ace_scroller") - .first() - .click({ force: true }) - .type("{selectall}SELECT * WHERE 1 = 1;"); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(700); // wait for text input debounce - cy.getAttached(".platform").each((el, i) => { - testCompatibility(el, i, [true, true, true]); - }); - - // Tables defined in common table expression not factored into compatibility check - cy.getAttached(".policy-page__form .ace_scroller") - .first() - .click({ force: true }) - .type("{selectall} ") - .type( - `WITH target_jars AS ( SELECT DISTINCT path FROM ( WITH split(word, str) AS( SELECT '', cmdline || ' ' FROM processes UNION ALL SELECT substr(str, 0, instr(str, ' ')), substr(str, instr(str, ' ') + 1) FROM split WHERE str != '') SELECT word AS path FROM split WHERE word LIKE '%.jar' UNION ALL SELECT path FROM process_open_files WHERE path LIKE '%.jar' ) ) SELECT path, matches FROM yara WHERE path IN (SELECT path FROM target_jars) AND count > 0 AND sigrule IN ( 'rule log4jJndiLookup { strings: $jndilookup = "JndiLookup" condition: $jndilookup }', 'rule log4jJavaClass { strings: $javaclass = "org/apache/logging/log4j" condition: $javaclass }' );`, - { parseSpecialCharSequences: false } - ); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(1000); // wait for text input debounce - cy.getAttached(".platform").each((el, i) => { - testCompatibility(el, i, [true, false, true]); - }); - - // Query with only macOS tables treated as compatible only with macOS - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.getAttached(" .policy-page__form .ace_scroller") - .first() - .click({ force: true }) - .type("{selectall} ") - .wait(300) // wait for ace to clear text before proceeding - .type( - "{selectall}SELECT 1 FROM gatekeeper WHERE assessments_enabled = 1;" - ); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(700); // wait for text input debounce - cy.getAttached(".platform").each((el, i) => { - testCompatibility(el, i, [true, false, false]); - }); - - // Query with macadmins extension table is not treated as incompatible - cy.getAttached(".policy-page__form .ace_scroller") - .first() - .click({ force: true }) - .type("{selectall}SELECT 1 FROM mdm WHERE enrolled='true';"); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(700); // wait for text input debounce - cy.getAttached(".platform").each((el, i) => { - testCompatibility(el, i, [true, false, false]); - }); - }); - - it("preselects platforms to check based on platform compatiblity when saving new policy", () => { - cy.getAttached(".manage-policies-page__header-wrap").within(() => { - cy.findByText(/add a policy/i).click(); - }); - cy.getAttached(".add-policy-modal").within(() => { - cy.findByText("Automatic login disabled (macOS)").click(); - }); - - cy.getAttached(".platform-compatibility").within(() => { - cy.getAttached(".platform").each((el, i) => { - testCompatibility(el, i, [true, false, false]); - }); - }); - cy.findByRole("button", { name: /save/i }).click(); - cy.getAttached(".modal__content").within(() => { - cy.getAttached(".platform-selector").within(() => { - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [true, false, false]); - }); - }); - }); - }); - - it("disables modal save button if no platforms are selected", () => { - cy.getAttached(".manage-policies-page__header-wrap").within(() => { - cy.findByText(/add a policy/i).click(); - }); - cy.getAttached(".add-policy-modal").within(() => { - cy.findByText("Automatic login disabled (macOS)").click(); - }); - cy.findByRole("button", { name: /save/i }).click(); - - cy.getAttached(".modal__content").within(() => { - cy.getAttached(".platform-selector").within(() => { - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [true, false, false]); - }); - cy.getAttached(".fleet-checkbox__label").first().click(); // deselect macOS - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [false, false, false]); - }); - }); - - cy.getAttached(".modal-cta-wrap").within(() => { - cy.findByRole("button", { name: /save policy/i }).should( - "be.disabled" - ); - }); - }); - }); - - it("allows user to overide preselected platforms when saving new policy", () => { - cy.getAttached(".manage-policies-page__header-wrap").within(() => { - cy.findByText(/add a policy/i).click(); - }); - cy.getAttached(".add-policy-modal").within(() => { - cy.findByText("Automatic login disabled (macOS)").click(); - }); - - cy.getAttached(".platform-compatibility").within(() => { - cy.getAttached(".platform").each((el, i) => { - testCompatibility(el, i, [true, false, false]); - }); - }); - cy.findByRole("button", { name: /save/i }).click(); - cy.getAttached(".modal__content").within(() => { - cy.getAttached(".platform-selector").within(() => { - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [true, false, false]); - }); - cy.getAttached(".fleet-checkbox__label").first().click(); // deselect macOS - cy.getAttached(".fleet-checkbox__label").last().click(); // select Linux - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [false, false, true]); - }); - }); - }); - cy.findByRole("button", { name: /save policy/i }).click(); - cy.findByText(/policy created/i).should("exist"); - - // confirm that new policy was saved with user-selected platforms - managePoliciesPage.visitManagePoliciesPage(); - cy.getAttached("tbody").within(() => { - cy.getAttached(".name__cell .button--text-link") - .contains("Automatic login disabled (macOS)") - .click(); - }); - cy.getAttached(".platform-selector").within(() => { - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [false, false, true]); - }); - }); - }); - - it("allows user to edit existing policy platform selections", () => { - // add a default policy for this test - cy.getAttached(".manage-policies-page__header-wrap").within(() => { - cy.findByText(/add a policy/i).click(); - }); - cy.getAttached(".add-policy-modal").within(() => { - cy.findByText("Antivirus healthy (macOS)").click(); - }); - cy.findByRole("button", { name: /save/i }).click(); - cy.findByRole("button", { name: /save policy/i }).click(); - cy.findByText(/policy created/i).should("exist"); - - // edit platform selections for policy - managePoliciesPage.visitManagePoliciesPage(); - cy.getAttached("tbody").within(() => { - cy.getAttached(".name__cell .button--text-link") - .contains("Antivirus healthy (macOS)") - .click(); - }); - cy.getAttached(".platform-selector").within(() => { - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [true, false, false]); - }); - cy.getAttached(".fleet-checkbox__label").first().click(); // deselect macOS - }); - - // confirm save/run buttons are disabled when no platforms are selected - cy.findByRole("button", { name: /^Save$/ }).should("be.disabled"); - cy.findByRole("button", { name: /^Run$/ }).should("be.disabled"); - cy.getAttached(".platform-selector").within(() => { - cy.getAttached(".fleet-checkbox__label").last().click(); // select Linux - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [false, false, true]); - }); - }); - - // save policy with new selection - cy.findByRole("button", { name: /^Save$/ }).click(); - cy.findByText(/policy updated/i).should("exist"); - - // confirm that policy was saved with new selection - managePoliciesPage.visitManagePoliciesPage(); - cy.getAttached("tbody").within(() => { - cy.getAttached(".name__cell .button--text-link") - .contains("Antivirus healthy (macOS)") - .click(); - }); - cy.getAttached(".platform-selector").within(() => { - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [false, false, true]); - }); - }); - }); - }); -}); - -describe("Policies flow (seeded)", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.seedPolicies(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - - describe("Manage policies page", () => { - beforeEach(() => { - cy.loginWithCySession(); - managePoliciesPage.visitManagePoliciesPage(); - }); - it("links to manage host page filtered by policy", () => { - // Move internal clock forward 2 hours so that policies report host results - cy.clock(Date.now() + 1000 * 60 * 120); - cy.getAttached(".failing_host_count__cell") - .first() - .within(() => { - cy.getAttached(".button--text-link").click(); - }); - // confirm policy functionality on manage host page - cy.getAttached(".manage-hosts__labels-active-filter-wrap").within(() => { - cy.findByText(/filevault enabled/i).should("exist"); - cy.findByText(/no/i).should("exist").click(); - cy.findByText(/yes/i).should("exist"); - cy.get('img[alt="Remove filter"]').click(); - cy.findByText(/filevault enabled'/i).should("not.exist"); - }); - }); - it("edits an existing policy", () => { - cy.getAttached("tbody").within(() => { - cy.getAttached(".name__cell .button--text-link").first().click(); - }); - cy.getAttached(".policy-page__form .ace_scroller") - .click({ force: true }) - .type( - "{selectall}SELECT 1 FROM gatekeeper WHERE assessments_enabled = 1;" - ); - cy.getAttached(".fleet-checkbox__label").first().click(); - cy.findByRole("button", { name: /save/i }).click(); - cy.findByText(/policy updated/i).should("exist"); - cy.visit("policies/1"); - cy.getAttached(".fleet-checkbox__input").first().should("not.be.checked"); - }); - - it("deletes an existing policy", () => { - managePoliciesPage.allowsDeletePolicy(); - managePoliciesPage.verifiesDeletedPolicy(); - }); - it("creates a failing policies webhook", () => { - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { name: /manage automations/i }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - // Ensure clicking on slider after modal animation - cy.wait(300); // eslint-disable-line cypress/no-unnecessary-waiting - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-checkbox__input").check({ force: true }); - }); - cy.getAttached("#webhook-url").click().type("http://www.foo.com/bar"); - cy.findByRole("button", { name: /^Save$/ }).click(); - // Ensure update - cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting - // Confirm failing policies webhook was added successfully - cy.findByText(/updated policy automations/i).should("exist"); - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { name: /manage automations/i }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-checkbox__input").should("be.checked"); - }); - // reset slider for subsequent tests - cy.getAttached(".manage-automations-modal").within(() => { - // Ensure clicking on slider after modal animation - cy.wait(300); // eslint-disable-line cypress/no-unnecessary-waiting - cy.getAttached(".fleet-slider").click(); - }); - cy.findByRole("button", { name: /^Save$/ }).click(); - // Confirm failing policies webhook was updated successfully - cy.findByText(/updated policy automations/i).should("exist"); - }); - it("empty automation state prompts to create an integration", () => { - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { name: /manage automations/i }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-checkbox__input").check({ force: true }); - }); - cy.getAttached("#ticket-radio-btn").next().click(); - - cy.findByText(/you have no integrations/i).should("exist"); - cy.getAttached(".manage-automations-modal__add-integration-link").click(); - // should be redirected to integrations settings page - cy.getAttached(".table-container").within(() => { - cy.findByText(/set up integration/i).should("exist"); - }); - }); - }); - describe("Manage policies page (mock integrations)", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.viewport(1600, 900); - cy.intercept( - "GET", - "/api/latest/fleet/config", - CONFIG_INTEGRATIONS_AUTOMATIONS - ).as("getIntegrations"); - managePoliciesPage.visitManagePoliciesPage(); - cy.wait("@getIntegrations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - }); - it("creates jira integration failing policies automation", () => { - cy.getAttached(".manage-policies-page__header-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-slider").click(); - cy.getAttached("#ticket-radio-btn").next().click(); - cy.findByText(/project 1/i).click(); - cy.findByText(/project 2/i).click(); - }); - cy.intercept( - "PATCH", - "/api/latest/fleet/config", - enableJiraPoliciesIntegration - ).as("enableJiraPoliciesIntegration"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - enableJiraPoliciesIntegration - ).as("enabledJiraPoliciesIntegration"); - cy.findByRole("button", { name: /^Save$/ }).click(); - cy.wait("@enableJiraPoliciesIntegration").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - // Confirm jira integration was added successfully - cy.findByText(/updated policy automations/i).should("exist"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - enableJiraPoliciesIntegration - ).as("getIntegrations"); - managePoliciesPage.visitManagePoliciesPage(); - cy.wait("@getIntegrations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider--active").should("exist"); - cy.findByText(/project 2/i).should("exist"); - }); - }); - it("creates zendesk integration failing policies automation", () => { - cy.getAttached(".manage-policies-page__header-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-slider").click(); - cy.getAttached("#ticket-radio-btn").next().click(); - cy.findByText(/project 1/i).click(); - cy.findByText(/87654321/i).click(); - }); - cy.intercept( - "PATCH", - "/api/latest/fleet/config", - enableZendeskPoliciesIntegration - ).as("enableZendeskPoliciesIntegration"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - enableZendeskPoliciesIntegration - ).as("enabledZendeskPoliciesIntegration"); - cy.findByRole("button", { name: /^Save$/ }).click(); - cy.wait("@enableZendeskPoliciesIntegration").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - // Confirm zendesk integration was added successfully - cy.findByText(/updated policy automations/i).should("exist"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - enableZendeskPoliciesIntegration - ).as("getIntegrations"); - managePoliciesPage.visitManagePoliciesPage(); - cy.wait("@getIntegrations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider--active").should("exist"); - cy.findByText(/87654321/i).should("exist"); - }); - }); - it("disables failing policies automation", () => { - cy.getAttached(".manage-policies-page__header-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - }); - cy.intercept( - "PATCH", - "/api/latest/fleet/config", - CONFIG_INTEGRATIONS_AUTOMATIONS_DISABLED - ).as("disablePoliciesAutomations"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - CONFIG_INTEGRATIONS_AUTOMATIONS_DISABLED - ).as("disabledAutomations"); - cy.findByRole("button", { name: /^Save$/ }).click(); - cy.wait("@disablePoliciesAutomations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - cy.wait("@disabledAutomations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - // Confirm integration was disabled successfully - cy.findByText(/updated policy automations/i).should("exist"); - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.findByText(/policy automations disabled/i).should("exist"); - }); - }); - }); - describe("Platform compatibility", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.visit("/policies/manage"); - }); - const platforms = ["macOS", "Windows", "Linux"]; - - const testSelections = ( - el: JQuery, - i: number, - expected: boolean[] - ) => { - assert( - el.prop("checked") === expected[i], - `expected ${platforms[i]} to be ${ - expected[i] ? "selected " : "not selected" - }` - ); - }; - it('preselects all platforms if API response contains `platform: ""`', () => { - cy.getAttached("tbody").within(() => { - cy.getAttached(".name__cell .button--text-link") - .contains("Is Ubuntu, version 16.4.0 or later, installed?") - .click(); - }); - cy.getAttached(".platform-selector").within(() => { - cy.getAttached(".fleet-checkbox__input").each((el, i) => { - testSelections(el, i, [true, true, true]); - }); - }); - }); - }); -}); diff --git a/cypress/integration/all/app/queryflow.spec.ts b/cypress/integration/all/app/queryflow.spec.ts deleted file mode 100644 index 06eb83aa2..000000000 --- a/cypress/integration/all/app/queryflow.spec.ts +++ /dev/null @@ -1,98 +0,0 @@ -import manageQueriesPage from "../../pages/manageQueriesPage"; -import manageSchedulePage from "../../pages/manageSchedulePage"; - -describe("Query flow (empty)", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - describe("Manage queries page", () => { - beforeEach(() => { - cy.loginWithCySession(); - manageQueriesPage.visitManageQueriesPage(); - }); - it("creates a new query", () => { - manageQueriesPage.allowsCreateNewQuery(); - manageQueriesPage.verifiesCreatedNewQuery(); - }); - }); -}); - -describe("Query flow (seeded)", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.seedQueries(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - describe("Manage queries page", () => { - beforeEach(() => { - cy.loginWithCySession(); - manageQueriesPage.visitManageQueriesPage(); - }); - it("runs a live query and allows exporting results", () => { - cy.addDockerHost(); - manageQueriesPage.allowsRunQuery(); - manageQueriesPage.verifiesRanQuery(); - manageQueriesPage.allowsViewRanQuery(); - manageQueriesPage.allowsExportQueryResults(); - cy.stopDockerHost(); - }); - it("edits an existing query", () => { - manageQueriesPage.allowsEditExistingQuery(); - manageQueriesPage.verifiesEditedExistingQuery(); - }); - it("saves an existing query as new query", () => { - manageQueriesPage.allowsSaveAsNewQuery(); - manageQueriesPage.verifiesSavedAsNewQuery(); - }); - it("deletes an existing query", () => { - manageQueriesPage.allowsDeleteExistingQuery(); - manageQueriesPage.verifiesDeletedExistingQuery(); - }); - }); - describe("Manage schedules page", () => { - beforeEach(() => { - cy.loginWithCySession(); - manageSchedulePage.visitManageSchedulePage(); - }); - it("creates a new scheduled query", () => { - manageSchedulePage.allowsAddSchedule(); - manageSchedulePage.verifiesAddedSchedule(); - }); - - it("shows sql of a scheduled query successfully", () => { - cy.getAttached("tbody>tr") - .should("have.length", 1) - .within(() => { - cy.findByText(/action/i).click(); - cy.findByText(/show query/i).click(); - }); - cy.getAttached(".show-query-modal").within(() => { - cy.getAttached(".ace_content").within(() => { - cy.contains(/select/i).should("exist"); - cy.contains(/cypress/i).should("exist"); - }); - }); - }); - - it("edit a scheduled query successfully", () => { - manageSchedulePage.allowsEditSchedule(); - manageSchedulePage.verifiesEditedSchedule(); - }); - - it("remove a scheduled query successfully", () => { - manageSchedulePage.allowsRemoveSchedule(); - manageSchedulePage.verifiesRemovedSchedule(); - }); - }); -}); diff --git a/cypress/integration/all/app/resetsessions.spec.ts b/cypress/integration/all/app/resetsessions.spec.ts deleted file mode 100644 index 3c753728a..000000000 --- a/cypress/integration/all/app/resetsessions.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -describe("Reset sessions", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.setupSMTP(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - - describe("User settings page", () => { - beforeEach(() => { - cy.loginWithCySession(); - }); - it("resets a user's session generating a new api token", () => { - cy.visit("/profile"); - cy.getAttached(".user-side-panel").within(() => { - cy.findByRole("button", { name: /get api token/i }).click(); - }); - cy.getAttached(".secret-field__secret-input").within(() => { - cy.getAttached(".secret-field__show-secret").click(); - cy.getAttached("input").invoke("val").as("token1"); - }); - cy.visit("/settings/users"); - cy.getAttached("div.Select-placeholder").eq(0).click(); - cy.contains(/reset sessions/i).click(); - - cy.get(".modal__modal_container").within(() => { - cy.findByText(/reset sessions/i).should("exist"); - cy.findByRole("button", { name: /confirm/i }).click(); - }); - cy.findByText(/reset sessions/i).should("not.exist"); - // user should be logged out so log in for new API token - cy.getAttached(".login-form__container").within(() => { - cy.findByRole("button", { name: /login/i }).should("exist"); - }); - cy.login(); - cy.visit("/profile"); - cy.getAttached(".user-side-panel").within(() => { - cy.findByRole("button", { name: /get api token/i }).click(); - }); - cy.getAttached(".modal__content").within(() => { - cy.getAttached(".secret-field__show-secret").click(); - }); - cy.getAttached(".secret-field__secret-input").within(() => { - cy.get("input").invoke("val").as("token2"); - }); - // new token should not equal old token - cy.get("@token1").then((val1) => { - cy.get("@token2").then((val2) => { - expect(val1).to.not.eq(val2); - }); - }); - }); - }); -}); diff --git a/cypress/integration/all/app/settingsflow.spec.ts b/cypress/integration/all/app/settingsflow.spec.ts deleted file mode 100644 index e5c84da37..000000000 --- a/cypress/integration/all/app/settingsflow.spec.ts +++ /dev/null @@ -1,540 +0,0 @@ -import CONSTANTS from "../../../support/constants"; - -const { CONFIG_INTEGRATIONS_AUTOMATIONS } = CONSTANTS; - -const addJiraIntegration = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira@example.com", - api_token: "jira123", - project_key: "PROJECT", - enable_software_vulnerabilities: false, - }, - ], - }, -}; - -const deleteJiraIntegration = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira1@example.com", - api_token: "jira123", - project_key: "PROJECT 1", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.zendesk.com", - email: "zendesk2@example.com", - api_token: "zendesk123", - group_id: 87654321, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - }, -}; - -const addZendeskIntegration = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - }, -}; - -const deleteZendeskIntegration = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira1@example.com", - api_token: "jira123", - project_key: "PROJECT 1", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.atlassian.com", - username: "jira2@example.com", - api_token: "jira123", - project_key: "PROJECT 2", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - }, -}; - -describe("App settings flow", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - - describe("Organization settings page", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.visit("/settings/organization"); - }); - it("edits organization info", () => { - cy.getAttached(".app-config-form").within(() => { - cy.findByLabelText(/organization name/i) - .clear() - .type("TJ's Run"); - cy.findByLabelText(/organization avatar url/i) - .click() - .type("http://tjsrun.com/img/logo.png"); - }); - - cy.findByRole("button", { name: /save/i }) - .invoke("attr", "disabled", false) - .click(); - - cy.findByText(/updated settings/i).should("exist"); - - // confirm edits - cy.visit("/settings/organization"); - - cy.getAttached(".app-config-form").within(() => { - cy.findByLabelText(/organization name/i).should( - "have.value", - "TJ's Run" - ); - }); - - cy.findByLabelText(/organization avatar url/i).should( - "have.value", - "http://tjsrun.com/img/logo.png" - ); - }); - - it("edits fleet web address", () => { - cy.findByText(/fleet web address/i).click(); - - cy.findByLabelText(/fleet app url/i) - .clear() - .type("https://localhost:5000"); - - cy.findByRole("button", { name: /save/i }) - .invoke("attr", "disabled", false) - .click(); - - cy.findByText(/updated settings/i).should("exist"); - - // confirm edits - cy.visit("/settings/organization"); - cy.findByText(/fleet web address/i).click(); - cy.findByLabelText(/fleet app url/i).should( - "have.value", - "https://localhost:5000" - ); - }); - - it("edits single sign-on settings", () => { - cy.findByText(/single sign-on options/i).click(); - cy.findByLabelText(/enable single sign-on/i).check({ force: true }); - - cy.findByLabelText(/identity provider name/i) - .click({ force: true }) - .type("Rachel"); - - cy.findByLabelText(/entity id/i) - .click({ force: true }) - .type("my entity id"); - - cy.findByLabelText(/idp image url/i) - .click() - .type("https://http.cat/100"); - - // specifically targeting this one to avoid conflict - // with cypress seeing multiple "metadata url" - one - // in a tooltip, the other as the actual label - cy.getAttached("[for='metadataUrl']") - .click() - .type("http://github.com/fleetdm/fleet"); - - cy.findByLabelText(/allow sso login initiated/i).check({ force: true }); - - cy.findByRole("button", { name: /save/i }) - .invoke("attr", "disabled", false) - .click(); - - cy.findByText(/updated settings/i).should("exist"); - - // confirm edits - cy.visit("/settings/organization"); - cy.findByText(/single sign-on options/i).click(); - cy.findByLabelText(/identity provider name/i).should( - "have.value", - "Rachel" - ); - - cy.findByLabelText(/entity id/i).should("have.value", "my entity id"); - - cy.findByLabelText(/idp image url/i).should( - "have.value", - "https://http.cat/100" - ); - - cy.getAttached("#metadataUrl").should( - "have.value", - "http://github.com/fleetdm/fleet" - ); - }); - - it("edits smtp settings", () => { - cy.findByText(/smtp options/i).click(); - cy.findByLabelText(/enable smtp/i).check({ force: true }); - - cy.findByLabelText(/sender address/i) - .click({ force: true }) - .type("rachel@example.com"); - - // specifically targeting this one to avoid conflict - // with cypress seeing multiple "metadata" - one - // in a tooltip, the other as the actual label - cy.findByLabelText(/SMTP server/) - .click({ force: true }) - .type("localhost"); - - cy.getAttached("#smtpPort").clear().type("1025"); - - cy.findByLabelText(/use ssl\/tls/i).check({ force: true }); - - cy.findByLabelText(/smtp username/i) - .click() - .type("rachelsusername"); - - cy.findByLabelText(/smtp password/i) - .click() - .type("rachelspassword"); - - cy.findByRole("button", { name: /save/i }) - .invoke("attr", "disabled", false) - .click(); - - cy.findByText(/updated settings/i).should("exist"); - - // confirm edits - cy.visit("/settings/organization"); - cy.findByText(/smtp options/i).click(); - cy.findByLabelText(/sender address/i).should( - "have.value", - "rachel@example.com" - ); - - cy.getAttached("#smtpServer").should("have.value", "localhost"); - - cy.getAttached("#smtpPort").should("have.value", "1025"); - - cy.findByLabelText(/smtp username/i).should( - "have.value", - "rachelsusername" - ); - cy.findByText(/single sign-on options/i).click(); - - cy.getAttached("#metadataUrl").should( - "have.value", - "http://github.com/fleetdm/fleet" - ); - }); - - it("edits host status webhook", () => { - cy.findByText(/host status webhook/i).click(); - cy.findByLabelText(/enable host status webhook/i).check({ - force: true, - }); - - cy.findByLabelText(/destination url/i) - .click() - .type("http://server.com/example"); - - cy.getAttached( - ".app-config-form__host-percentage .Select-control" - ).click(); - cy.getAttached(".Select-menu-outer").contains(/5%/i).click(); - - cy.getAttached(".app-config-form__days-count .Select-control").click(); - cy.getAttached(".Select-menu-outer") - .contains(/7 days/i) - .click(); - - cy.findByRole("button", { name: /save/i }) - .invoke("attr", "disabled", false) - .click(); - - cy.findByText(/updated settings/i).should("exist"); - - // confirm edits - cy.visit("/settings/organization"); - cy.findByText(/host status webhook/i).click(); - - cy.findByLabelText(/destination url/i).should( - "have.value", - "http://server.com/example" - ); - - cy.findByText(/5%/i).should("exist"); - - cy.findByText(/7 days/i).should("exist"); - cy.findByText(/1 day/i).should("not.exist"); - cy.findByText(/select one/i).should("not.exist"); - }); - - it("edits usage statistics", () => { - cy.findByText(/usage statistics/i).click(); - cy.findByLabelText(/enable usage statistics/i).check({ - force: true, - }); - - cy.findByRole("button", { name: /save/i }) - .invoke("attr", "disabled", false) - .click(); - - cy.findByText(/updated settings/i).should("exist"); - - // confirm edits - cy.visit("/settings/organization"); - cy.findByText(/usage statistics/i).click(); - cy.findByLabelText(/enable usage statistics/i).should("be.checked"); - }); - - it("edits advanced options", () => { - cy.findByText(/advanced options/i).click(); - - cy.findByLabelText(/domain/i) - .click() - .type("http://www.fleetdm.com"); - - cy.findByLabelText(/verify ssl certs/i).check({ force: true }); - cy.findByLabelText(/enable starttls/i).check({ force: true }); - cy.getAttached("[for='enableHostExpiry']").within(() => { - cy.getAttached("[type='checkbox']").check({ force: true }); - }); - - // specifically targeting this one to avoid conflict - // with cypress seeing multiple "host expiry" - one - // in the checkbox above, the other as this label - cy.getAttached("[name='hostExpiryWindow']").clear().type("5"); - - cy.findByLabelText(/disable live queries/i).check({ force: true }); - - cy.findByRole("button", { name: /save/i }) - .invoke("attr", "disabled", false) - .click(); - - cy.findByText(/updated settings/i).should("exist"); - - // confirm edits - cy.visit("/settings/organization"); - cy.findByText(/advanced options/i).click(); - - cy.findByLabelText(/verify ssl certs/i).should("be.checked"); - cy.findByLabelText(/enable starttls/i).should("be.checked"); - cy.findByLabelText(/host expiry window/i).should("have.value", "5"); - - // confirm smtp configured - cy.getEmails().then((response) => { - expect(response.body.items[0].To[0]).to.have.property("Domain"); - expect(response.body.items[0].To[0].Mailbox).to.equal("admin"); - expect(response.body.items[0].To[0].Domain).to.equal("example.com"); - expect(response.body.items[0].From.Mailbox).to.equal("rachel"); - expect(response.body.items[0].From.Domain).to.equal("example.com"); - expect(response.body.items[0].Content.Headers.Subject[0]).to.equal( - "Hello from Fleet" - ); - }); - }); - }); - - describe("Integrations settings page (empty)", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.visit("/settings/integrations"); - }); - it("adds a new jira integration", () => { - cy.getAttached(".no-integrations__add-button").click(); - cy.getAttached("#url").click().type("https://fleetdm.atlassian.com"); - cy.getAttached("#username").click().type("jira@example.com"); - cy.getAttached("#apiToken").click().type("jira123"); - cy.getAttached("#projectKey").click().type("PROJECT"); - cy.intercept("PATCH", "/api/latest/fleet/config", addJiraIntegration).as( - "addIntegration" - ); - cy.intercept("GET", "/api/latest/fleet/config", addJiraIntegration).as( - "addedIntegration" - ); - cy.findByRole("button", { name: /save/i }).click(); - cy.wait("@addIntegration").then((configStub) => { - cy.log(JSON.stringify(configStub)); - console.log(JSON.stringify(configStub)); - }); - cy.wait("@addedIntegration").then((configStub) => { - cy.log(JSON.stringify(configStub)); - console.log(JSON.stringify(configStub)); - }); - cy.findByText(/successfully added/i).should("exist"); - cy.getAttached(".table-container").within(() => { - cy.findByText(/fleetdm.atlassian.com - PROJECT/i).should("exist"); - }); - }); - it("adds a new zendesk integration", () => { - cy.getAttached(".no-integrations__add-button").click(); - cy.getAttached(".add-integration-modal__form-field--platform").within( - () => { - cy.findByText(/jira/i).click(); - cy.findByText(/zendesk/i).click(); - } - ); - cy.getAttached("#url").click().type("https://fleetdm.zendesk.com"); - cy.getAttached("#email").click().type("zendesk1@example.com"); - cy.getAttached("#apiToken").click().type("zendesk123"); - cy.getAttached("#groupId").click().type("12345678"); - cy.intercept( - "PATCH", - "/api/latest/fleet/config", - addZendeskIntegration - ).as("addIntegration"); - cy.intercept("GET", "/api/latest/fleet/config", addZendeskIntegration).as( - "addedIntegration" - ); - cy.findByRole("button", { name: /save/i }).click(); - cy.wait("@addIntegration").then((configStub) => { - cy.log(JSON.stringify(configStub)); - console.log(JSON.stringify(configStub)); - }); - cy.wait("@addedIntegration").then((configStub) => { - cy.log(JSON.stringify(configStub)); - console.log(JSON.stringify(configStub)); - }); - cy.findByText(/successfully added/i).should("exist"); - cy.getAttached(".table-container").within(() => { - cy.findByText(/fleetdm.zendesk.com - 12345678/i).should("exist"); - }); - }); - }); - - describe("Integrations settings page (seeded)", () => { - beforeEach(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.viewport(1200, 660); - cy.intercept( - "GET", - "/api/latest/fleet/config", - CONFIG_INTEGRATIONS_AUTOMATIONS - ).as("getIntegrations"); - cy.visit("/settings/integrations"); - cy.wait("@getIntegrations").then((configStub) => { - cy.log(JSON.stringify(configStub)); - console.log(JSON.stringify(configStub)); - }); - }); - it("deletes jira integration", () => { - cy.getAttached("tbody>tr") - .eq(1) - .within(() => { - cy.findByText(/project 2/i).should("exist"); - cy.findByText(/action/i).click(); - cy.findByText(/delete/i).click(); - }); - cy.intercept( - "PATCH", - "/api/latest/fleet/config", - deleteJiraIntegration - ).as("deleteIntegration"); - cy.intercept("GET", "/api/latest/fleet/config", deleteJiraIntegration).as( - "deletedIntegration" - ); - cy.getAttached(".delete-integration-modal .modal-cta-wrap") - .contains("button", /delete/i) - .click(); - cy.wait("@deleteIntegration").then((configStub) => { - cy.log(JSON.stringify(configStub)); - console.log(JSON.stringify(configStub)); - }); - cy.wait("@deletedIntegration").then((configStub) => { - cy.log(JSON.stringify(configStub)); - console.log(JSON.stringify(configStub)); - }); - cy.findByText(/successfully deleted/i).should("exist"); - cy.getAttached("tbody>tr").should("have.length", 3); - cy.findByText(/project 2/i).should("not.exist"); - }); - it("deletes zendesk integration", () => { - cy.getAttached("tbody>tr") - .eq(3) - .within(() => { - cy.findByText(/87654321/i).should("exist"); - cy.findByText(/action/i).click(); - cy.findByText(/delete/i).click(); - }); - cy.intercept( - "PATCH", - "/api/latest/fleet/config", - deleteZendeskIntegration - ).as("deleteIntegration"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - deleteZendeskIntegration - ).as("deletedIntegration"); - cy.getAttached(".delete-integration-modal .modal-cta-wrap") - .contains("button", /delete/i) - .click(); - cy.wait("@deleteIntegration").then((configStub) => { - cy.log(JSON.stringify(configStub)); - console.log(JSON.stringify(configStub)); - }); - cy.wait("@deletedIntegration").then((configStub) => { - cy.log(JSON.stringify(configStub)); - console.log(JSON.stringify(configStub)); - }); - cy.findByText(/successfully deleted/i).should("exist"); - cy.getAttached("tbody>tr").should("have.length", 3); - cy.findByText(/87654321/i).should("not.exist"); - }); - }); -}); diff --git a/cypress/integration/all/app/software.spec.ts b/cypress/integration/all/app/software.spec.ts deleted file mode 100644 index 458364306..000000000 --- a/cypress/integration/all/app/software.spec.ts +++ /dev/null @@ -1,422 +0,0 @@ -import CONSTANTS from "../../../support/constants"; -import manageSoftwarePage from "../../pages/manageSoftwarePage"; - -const { - CONFIG_INTEGRATIONS_AUTOMATIONS, - CONFIG_INTEGRATIONS_AUTOMATIONS_DISABLED, -} = CONSTANTS; - -const enableWebhook = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira1@example.com", - api_token: "jira123", - project_key: "PROJECT 1", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.atlassian.com", - username: "jira2@example.com", - api_token: "jira123", - project_key: "PROJECT 2", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.zendesk.com", - email: "zendesk2@example.com", - api_token: "zendesk123", - group_id: 87654321, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - }, - webhook_settings: { - host_status_webhook: { - enable_host_status_webhook: false, - destination_url: "", - host_percentage: 0, - days_count: 0, - }, - failing_policies_webhook: { - enable_failing_policies_webhook: false, - destination_url: "https://www.foo.com/bar", - policy_ids: [5, 10], - host_batch_size: 0, - }, - vulnerabilities_webhook: { - destination_url: "http://www.foo.com/bar", - enable_vulnerabilities_webhook: true, - }, - }, -}; - -const enableJiraSoftwareIntegration = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira1@example.com", - api_token: "jira123", - project_key: "PROJECT 1", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.atlassian.com", - username: "jira2@example.com", - api_token: "jira123", - project_key: "PROJECT 2", - enable_failing_policies: false, - enable_software_vulnerabilities: true, - }, - ], - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.zendesk.com", - email: "zendesk2@example.com", - api_token: "zendesk123", - group_id: 87654321, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - }, - webhook_settings: { - host_status_webhook: { - enable_host_status_webhook: false, - destination_url: "", - host_percentage: 0, - days_count: 0, - }, - failing_policies_webhook: { - enable_failing_policies_webhook: false, - destination_url: "https://www.foo.com/bar", - policy_ids: [5, 10], - host_batch_size: 0, - }, - vulnerabilities_webhook: { - destination_url: "http://www.foo.com/bar", - enable_vulnerabilities_webhook: false, - }, - }, -}; - -const enableZendeskSoftwareIntegration = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira1@example.com", - api_token: "jira123", - project_key: "PROJECT 1", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.atlassian.com", - username: "jira2@example.com", - api_token: "jira123", - project_key: "PROJECT 2", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.zendesk.com", - email: "zendesk2@example.com", - api_token: "zendesk123", - group_id: 87654321, - enable_failing_policies: false, - enable_software_vulnerabilities: true, - }, - ], - }, - webhook_settings: { - host_status_webhook: { - enable_host_status_webhook: false, - destination_url: "", - host_percentage: 0, - days_count: 0, - }, - failing_policies_webhook: { - enable_failing_policies_webhook: false, - destination_url: "https://www.foo.com/bar", - policy_ids: [5, 10], - host_batch_size: 0, - }, - vulnerabilities_webhook: { - destination_url: "http://www.foo.com/bar", - enable_vulnerabilities_webhook: false, - }, - }, -}; - -describe("Software", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setupWithSoftware(); - cy.loginWithCySession(); - cy.viewport(1600, 900); - }); - after(() => { - cy.logout(); - }); - - // describe("Manage software page", () => { - // beforeEach(() => { - // cy.loginWithCySession(); - // cy.viewport(1600, 900); - // manageSoftwarePage.visitManageSoftwarePage(); - // }); - // it("renders and searches the host's software, links to filter hosts by software", () => { - // // cy.getAttached(".manage-software-page__count").within(() => { - // // cy.findByText(/902 software items/i).should("exist"); - // // }); - // cy.findByPlaceholderText(/search software/i).type("lib"); - // // Ensures search completes - // cy.wait(3000); // eslint-disable-line cypress/no-unnecessary-waiting - // cy.getAttached(".table-container__results-count") - // .invoke("text") - // .then((text) => { - // const fullText = text; - // const pattern = /[0-9]+/g; - // const newCount = fullText.match(pattern); - // const searchCount = parseInt(newCount[0], 10); - // expect(searchCount).to.be.equal(444); - // }); - // cy.getAttached(".software-link").first().click({ force: true }); - // cy.getAttached(".manage-hosts__software-filter-block").within(() => { - // cy.getAttached(".manage-hosts__software-filter-name-card").should( - // "exist" - // ); - // }); - // cy.getAttached(".table-container__results-count") - // .invoke("text") - // .then((text) => { - // const fullText = text; - // const pattern = /[0-9]+/g; - // const newCount = fullText.match(pattern); - // const searchCount = parseInt(newCount[0], 10); - // expect(searchCount).to.be.equal(2); - // }); - // }); - // }); - describe("Manage software page (mock integrations)", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.viewport(1600, 900); - cy.intercept( - "GET", - "/api/latest/fleet/config", - CONFIG_INTEGRATIONS_AUTOMATIONS - ).as("getIntegrations"); - manageSoftwarePage.visitManageSoftwarePage(); - cy.wait("@getIntegrations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - }); - it("creates webhook software vulnerability automation", () => { - cy.getAttached(".manage-software-page__header-wrap").within(() => { - cy.findByRole("button", { name: /manage automations/i }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-slider").click(); - cy.getAttached("#webhook-radio-btn").next().click(); - }); - cy.getAttached("#webhook-url").click().type("http://www.foo.com/bar"); - cy.intercept("PATCH", "/api/latest/fleet/config", enableWebhook).as( - "createWebhook" - ); - cy.intercept("GET", "/api/latest/fleet/config", enableWebhook).as( - "createdWebhook" - ); - cy.findByRole("button", { name: /^Save$/ }).click(); - cy.wait("@createWebhook").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - cy.wait("@createdWebhook").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - // Confirm manage automations webhook was added successfully - cy.findByText(/updated vulnerability automations/i).should("exist"); - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider--active").should("exist"); - cy.getAttached("#webhook-url").should("exist"); - }); - }); - it("creates jira integration software vulnerability automation", () => { - cy.getAttached(".manage-software-page__header-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-slider").click(); - cy.getAttached("#ticket-radio-btn").next().click(); - cy.findByText(/project 1/i).click(); - cy.findByText(/project 2/i).click(); - }); - cy.intercept( - "PATCH", - "/api/latest/fleet/config", - enableJiraSoftwareIntegration - ).as("enableJiraSoftwareIntegration"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - enableJiraSoftwareIntegration - ).as("enabledJiraSoftwareIntegration"); - cy.findByRole("button", { name: /^Save$/ }).click(); - cy.wait("@enableJiraSoftwareIntegration").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - // Confirm jira integration was added successfully - cy.findByText(/updated vulnerability automations/i).should("exist"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - enableJiraSoftwareIntegration - ).as("getIntegrations"); - manageSoftwarePage.visitManageSoftwarePage(); - cy.wait("@getIntegrations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider--active").should("exist"); - cy.findByText(/project 2/i).should("exist"); - }); - }); - it("creates zendesk integration software vulnerability automation", () => { - cy.getAttached(".manage-software-page__header-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-slider").click(); - cy.getAttached("#ticket-radio-btn").next().click(); - cy.findByText(/project 1/i).click(); - cy.findByText(/87654321/i).click(); - }); - cy.intercept( - "PATCH", - "/api/latest/fleet/config", - enableZendeskSoftwareIntegration - ).as("enableZendeskSoftwareIntegration"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - enableZendeskSoftwareIntegration - ).as("enabledZendeskIntegration"); - cy.findByRole("button", { name: /^Save$/ }).click(); - cy.wait("@enableZendeskSoftwareIntegration").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - // Confirm zendesk integration was added successfully - cy.findByText(/updated vulnerability automations/i).should("exist"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - enableZendeskSoftwareIntegration - ).as("getIntegrations"); - manageSoftwarePage.visitManageSoftwarePage(); - cy.wait("@getIntegrations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider--active").should("exist"); - cy.findByText(/87654321/i).should("exist"); - }); - }); - it("disables software vulnerability automation", () => { - cy.getAttached(".manage-software-page__header-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - }); - cy.intercept( - "PATCH", - "/api/latest/fleet/config", - CONFIG_INTEGRATIONS_AUTOMATIONS_DISABLED - ).as("disableSoftwareAutomations"); - cy.intercept( - "GET", - "/api/latest/fleet/config", - CONFIG_INTEGRATIONS_AUTOMATIONS_DISABLED - ).as("disabledAutomations"); - cy.findByRole("button", { name: /^Save$/ }).click(); - cy.wait("@disableSoftwareAutomations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - cy.wait("@disabledAutomations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - // Confirm integration was disabled successfully - cy.findByText(/updated vulnerability automations/i).should("exist"); - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.findByText(/vulnerability automations disabled/i).should("exist"); - }); - }); - }); -}); diff --git a/cypress/integration/all/sessions/sessions.spec.ts b/cypress/integration/all/sessions/sessions.spec.ts deleted file mode 100644 index bf733df2c..000000000 --- a/cypress/integration/all/sessions/sessions.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import CONSTANTS from "../../../support/constants"; -import manageHostsPage from "../../pages/manageHostsPage"; - -const { GOOD_PASSWORD } = CONSTANTS; - -describe("Sessions", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - }); - it("logs in and out successfully", () => { - cy.visit("/"); - cy.getAttached(".login-form__forgot-link").should("exist"); - // Log in - cy.getAttached("input").first().type("admin@example.com"); - cy.getAttached("input").last().type(GOOD_PASSWORD); - cy.getAttached("button").click(); - // Verify dashboard - cy.url().should("include", "/dashboard"); - cy.contains("Host"); - // Log out - cy.getAttached(".user-menu button").first().click(); - cy.contains("button", "Sign out").click(); - cy.url().should("match", /\/login$/); - }); - it("fails login with invalid password", () => { - cy.visit("/"); - cy.getAttached("input").first().type("admin@example.com"); - cy.getAttached("input").last().type("bad_password"); - cy.getAttached(".button").click(); - cy.url().should("match", /\/login$/); - cy.contains("Authentication failed"); - }); - it("fails to access authenticated resource", () => { - manageHostsPage.visitsManageHostsPage(); - cy.url().should("match", /\/login$/); - }); -}); diff --git a/cypress/integration/all/sessions/sso.spec.ts b/cypress/integration/all/sessions/sso.spec.ts deleted file mode 100644 index a65cfb5da..000000000 --- a/cypress/integration/all/sessions/sso.spec.ts +++ /dev/null @@ -1,64 +0,0 @@ -import CONSTANTS from "../../../support/constants"; - -const { GOOD_PASSWORD } = CONSTANTS; - -const enable_sso_idp_login = true; - -describe("SSO Sessions", () => { - beforeEach(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - }); - it("non-SSO user can login with username/password", () => { - cy.login(); - cy.setupSSO({ enable_sso_idp_login }); - cy.logout(); - cy.visit("/"); - cy.getAttached(".login-form__forgot-link").should("exist"); - // Log in - cy.getAttached("input").first().type("admin@example.com"); - cy.getAttached("input").last().type(GOOD_PASSWORD); - cy.contains("button", "Login").click(); - // Verify dashboard - cy.url().should("include", "/dashboard"); - cy.contains("Hosts"); - // Log out - cy.getAttached(".user-menu button").first().click(); - cy.contains("button", "Sign out").click(); - cy.url().should("match", /\/login$/); - }); - it("can login via SSO", () => { - cy.login(); - cy.setupSSO({ enable_sso_idp_login }); - cy.logout(); - cy.visit("/"); - // Log in - cy.contains("button", "Sign on with SimpleSAML"); - cy.loginSSO(); - cy.contains("Hosts"); - }); - it("can't login if doesn't have an account", () => { - cy.login(); - cy.setupSSO({ enable_sso_idp_login }); - cy.logout(); - cy.visit("/"); - // Log in - cy.contains("button", "Sign on with SimpleSAML"); - cy.loginSSO({ username: "sso_user2" }); - cy.visit("/login?status=account_invalid"); - }); - it("fails when IdP login disabled", () => { - cy.login(); - cy.setupSSO(); - cy.logout(); - cy.visit("/"); - cy.contains("button", "Sign on with SimpleSAML"); - cy.loginSSO(); - // Log in should fail - cy.contains("Password"); - }); - it("displays an error message when status is set", () => { - cy.visit("/login?status=account_disabled"); - cy.getAttached(".flash-message"); - }); -}); diff --git a/cypress/integration/all/setup/setup.spec.ts b/cypress/integration/all/setup/setup.spec.ts deleted file mode 100644 index 924fdedf8..000000000 --- a/cypress/integration/all/setup/setup.spec.ts +++ /dev/null @@ -1,64 +0,0 @@ -import CONSTANTS from "../../../support/constants"; - -const { GOOD_PASSWORD } = CONSTANTS; - -const fillOutForm = () => { - // Page 1 - cy.findByLabelText(/full name/i).type("Test name"); - - cy.findByLabelText(/email/i).type("test@example.com"); - - cy.findByLabelText(/^password/i) - .first() - .type(GOOD_PASSWORD); - - cy.findByLabelText(/confirm password/i) - .last() - .type(GOOD_PASSWORD); - - cy.contains("button:enabled", /next/i).click(); - - // Page 2 - cy.findByLabelText(/organization name/i).type("Fleet Test"); - - cy.contains("button:enabled", /next/i).click(); - - // Page 3 - cy.contains("button:enabled", /next/i).click(); - - // Page 4 - cy.contains("button:enabled", /confirm/i).click(); -}; - -describe("Setup", () => { - // Different than normal beforeEach because we don't run the fleetctl setup. - beforeEach(() => { - const SHELL = Cypress.platform === "win32" ? "cmd" : "bash"; - cy.exec("make e2e-reset-db", { - timeout: 20000, - env: { SHELL }, - }); - }); - - it("Completes setup", () => { - cy.visit("/"); - cy.url().should("match", /\/setup$/); - cy.contains(/setup/i); - - fillOutForm(); - - cy.url().should("match", /\/hosts\/manage$/i); - cy.contains(/add your devices/i); - }); - - it("shows messaging when there is an error during setup", () => { - cy.visit("/"); - cy.intercept("POST", "/api/v1/setup", { forceNetworkError: true }); - - fillOutForm(); - - cy.findByText( - "We were unable to configure Fleet. If your Fleet server is behind a proxy, please ensure the server can be reached." - ).should("exist"); - }); -}); diff --git a/cypress/integration/free/README.md b/cypress/integration/free/README.md deleted file mode 100644 index 2dd85c40a..000000000 --- a/cypress/integration/free/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Free tier tests - -These tests should only run when the server is in `free` tier. - -To enable the tests: - -```sh -export CYPRESS_FLEET_TIER=free -``` - -Before running the appropriate `yarn cypress (open|run)` command. - -## Filtering - -Any test suite in this directory should use the following pattern for filtering: - -**FIXME**: There must be a better way to do this for all tests in the directory rather than having to add the check in each file? - -```js -if (Cypress.env("FLEET_TIER") === "free") { - // test suite here -} -``` diff --git a/cypress/integration/free/admin.spec.ts b/cypress/integration/free/admin.spec.ts deleted file mode 100644 index e7acc5083..000000000 --- a/cypress/integration/free/admin.spec.ts +++ /dev/null @@ -1,226 +0,0 @@ -import CONSTANTS from "../../support/constants"; -import dashboardPage from "../pages/dashboardPage"; -import hostDetailsPage from "../pages/hostDetailsPage"; -import managePoliciesPage from "../pages/managePoliciesPage"; -import manageHostsPage from "../pages/manageHostsPage"; -import manageQueriesPage from "../pages/manageQueriesPage"; -import manageSoftwarePage from "../pages/manageSoftwarePage"; -import userProfilePage from "../pages/userProfilePage"; - -const { GOOD_PASSWORD } = CONSTANTS; - -describe( - "Free tier - Admin user", - { - defaultCommandTimeout: 20000, - }, - () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.setupSMTP(); - cy.seedFree(); - cy.seedQueries(); - cy.seedPolicies(); - cy.addDockerHost(); - }); - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - describe("Navigation", () => { - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - dashboardPage.visitsDashboardPage(); - }); - it("displays intended admin top navigation", () => { - cy.getAttached(".site-nav-container").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/software/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("exist"); - cy.findByText(/policies/i).should("exist"); - cy.getAttached(".user-menu").click(); - cy.findByText(/settings/i).click(); - }); - cy.getAttached(".react-tabs__tab--selected").within(() => { - cy.findByText(/organization/i).should("exist"); - }); - cy.getAttached(".site-nav-container").within(() => { - cy.getAttached(".user-menu").click(); - cy.findByText(/manage users/i).click(); - }); - cy.getAttached(".react-tabs__tab--selected").within(() => { - cy.findByText(/users/i).should("exist"); - }); - }); - }); - describe("Dashboard", () => { - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - dashboardPage.visitsDashboardPage(); - }); - it("displays cards for all platforms and does not filter host platform", () => { - dashboardPage.displaysCards("All"); - dashboardPage.verifiesFilteredHostByPlatform("none"); - }); - it("displays cards for windows only and filters hosts by Windows platform", () => { - dashboardPage.switchesPlatform("Windows"); - dashboardPage.displaysCards("Windows"); - dashboardPage.verifiesFilteredHostByPlatform("Windows"); - }); - it("displays cards for linux only and filters hosts by Linux platform", () => { - dashboardPage.switchesPlatform("Linux"); - dashboardPage.displaysCards("Linux"); - dashboardPage.verifiesFilteredHostByPlatform("Linux"); - }); - it("displays cards for macOS only and filters hosts by macOS platform", () => { - dashboardPage.switchesPlatform("macOS"); - dashboardPage.displaysCards("macOS"); - dashboardPage.verifiesFilteredHostByPlatform("macOS"); - }); - }); - describe("Manage hosts page", () => { - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - manageHostsPage.visitsManageHostsPage(); - }); - it("verifies teams is disabled on Manage hosts page", () => { - manageHostsPage.verifiesTeamsIsDisabled(); - }); - it("allows admin to see and click CTA buttons", () => { - manageHostsPage.allowsAddLabelForm(); - manageHostsPage.allowsAddHosts(); - manageHostsPage.allowsManageAndAddSecrets(); - }); - }); - describe("Host details page", () => { - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - hostDetailsPage.visitsHostDetailsPage(1); - }); - it("verifies teams is disabled on Host Details page", () => { - hostDetailsPage.verifiesTeamsisDisabled(); - hostDetailsPage.hidesButton("Transfer"); - }); - }); - describe("Manage software page", () => { - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - manageSoftwarePage.visitManageSoftwarePage(); - }); - it("allows admin to click 'Manage automations' button", () => { - manageSoftwarePage.allowsManageAutomations(); - }); - }); - describe("Query pages", () => { - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - manageQueriesPage.visitManageQueriesPage(); - }); - it("allows admin add a new query", () => { - manageQueriesPage.allowsCreateNewQuery(); - manageQueriesPage.verifiesCreatedNewQuery(); - }); - it("allows admin to edit a query", () => { - manageQueriesPage.allowsEditExistingQuery(); - manageQueriesPage.verifiesEditedExistingQuery(); - }); - it("allows admin to run a query", () => { - manageQueriesPage.allowsRunQuery(); - manageQueriesPage.verifiesRanQuery(); - }); - }); - describe("Manage policies page", () => { - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - managePoliciesPage.visitManagePoliciesPage(); - }); - it("allows admin to click 'Manage automations' button", () => { - managePoliciesPage.allowsAutomatePolicy(); - managePoliciesPage.verifiesAutomatedPolicy(); - }); - it("allows admin to add a new policy", () => { - managePoliciesPage.allowsAddDefaultPolicy(); - managePoliciesPage.verifiesAddedDefaultPolicy(); - }); - it("allows admin to delete a policy", () => { - managePoliciesPage.allowsDeletePolicy(); - }); - it("allows admin to select a policy and see CTAs to run and save", () => { - managePoliciesPage.allowsSelectRunSavePolicy(); - }); - }); - describe("Admin settings page", () => { - // cypress tends to fail on uncaught exceptions. since we have - // our own error handling, it's suggested to use this block to - // suppress so the tests will keep running - Cypress.on("uncaught:exception", () => { - return false; - }); - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - cy.visit("/settings/users"); - }); - it("hides access to Fleet Desktop settings", () => { - cy.visit("settings/organization"); - cy.findByRole("navigation", { name: "settings" }).within(() => { - cy.findByText(/organization info/i).should("exist"); - cy.findByText(/fleet desktop/i).should("not.exist"); - }); - cy.visit("settings/organization/fleet-desktop"); - cy.findAllByText(/access denied/i).should("exist"); - }); - it("hides access team settings", () => { - cy.findByText(/teams/i).should("not.exist"); - }); - it("allows admin to access integrations and users settings", () => { - cy.getAttached(".react-tabs").within(() => { - cy.findByText(/organization settings/i).should("exist"); - cy.findByText(/integrations/i).click(); - }); - cy.getAttached(".react-tabs").within(() => { - cy.findByText(/users/i).click(); - }); - }); - it("displays the 'Create user' button", () => { - cy.findByRole("button", { name: /create user/i }).click({ - force: true, - }); - }); - it("hides assigning a user to a team", () => { - cy.findByText(/team/i).should("not.exist"); - }); - it("allows admin to edit existing user password", () => { - cy.visit("/settings/users"); - cy.getAttached("tbody").within(() => { - cy.findByText(/mary@organization.com/i) - .parent() - .next() - .within(() => cy.getAttached(".Select-placeholder").click()); - }); - cy.getAttached(".Select-menu").within(() => { - cy.findByText(/edit/i).click(); - }); - cy.getAttached(".create-user-form").within(() => { - cy.findByLabelText(/email/i).should("exist"); - cy.findByLabelText(/password/i).should("exist"); - }); - }); - it("verifies admin is not authorized to reach the Team Settings page", () => { - cy.visit("/settings/teams"); - cy.findByText(/you do not have permissions/i).should("exist"); - }); - }); - describe("User profile page", () => { - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - userProfilePage.visitUserProfilePage(); - }); - it("verifies admin role and team", () => { - userProfilePage.showRole("Admin"); - }); - }); - } -); diff --git a/cypress/integration/free/maintainer.spec.ts b/cypress/integration/free/maintainer.spec.ts deleted file mode 100644 index c2e25f8ff..000000000 --- a/cypress/integration/free/maintainer.spec.ts +++ /dev/null @@ -1,191 +0,0 @@ -import CONSTANTS from "../../support/constants"; -import dashboardPage from "../pages/dashboardPage"; -import hostDetailsPage from "../pages/hostDetailsPage"; -import manageHostsPage from "../pages/manageHostsPage"; -import manageQueriesPage from "../pages/manageQueriesPage"; -import managePacksPage from "../pages/managePacksPage"; -import managePoliciesPage from "../pages/managePoliciesPage"; -import manageSoftwarePage from "../pages/manageSoftwarePage"; -import userProfilePage from "../pages/userProfilePage"; - -const { GOOD_PASSWORD } = CONSTANTS; - -describe( - "Free tier - Maintainer user", - { - defaultCommandTimeout: 20000, - }, - () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.setupSMTP(); - cy.seedFree(); - cy.seedQueries(); - cy.seedPolicies(); - cy.addDockerHost(); - }); - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - - describe("Navigation", () => { - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - dashboardPage.visitsDashboardPage(); - }); - it("displays intended global maintainer top navigation", () => { - cy.getAttached(".site-nav-container").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/software/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("exist"); - cy.findByText(/policies/i).should("exist"); - cy.getAttached(".user-menu").click(); - cy.findByText(/settings/i).should("not.exist"); - cy.findByText(/manage users/i).should("not.exist"); - }); - }); - }); - describe("Dashboard", () => { - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - dashboardPage.visitsDashboardPage(); - }); - it("displays cards for all platforms and does not filter host platform", () => { - dashboardPage.displaysCards("All"); - dashboardPage.verifiesFilteredHostByPlatform("none"); - }); - it("displays cards for windows only and filters hosts by Windows platform", () => { - dashboardPage.switchesPlatform("Windows"); - dashboardPage.displaysCards("Windows"); - dashboardPage.verifiesFilteredHostByPlatform("Windows"); - }); - it("displays cards for linux only and filters hosts by Linux platform", () => { - dashboardPage.switchesPlatform("Linux"); - dashboardPage.displaysCards("Linux"); - dashboardPage.verifiesFilteredHostByPlatform("Linux"); - }); - it("displays cards for macOS only and filters hosts by macOS platform", () => { - dashboardPage.switchesPlatform("macOS"); - dashboardPage.displaysCards("macOS"); - dashboardPage.verifiesFilteredHostByPlatform("macOS"); - }); - }); - describe("Manage hosts page", () => { - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - manageHostsPage.visitsManageHostsPage(); - }); - it("verifies teams is disabled", () => { - manageHostsPage.verifiesTeamsIsDisabled(); - }); - it("allows maintainer to see and click 'Add label', 'Add hosts', and 'Manage enroll secrets' buttons", () => { - manageHostsPage.allowsAddHosts(); - manageHostsPage.allowsManageAndAddSecrets(); - }); - }); - describe("Host details page", () => { - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - hostDetailsPage.visitsHostDetailsPage(1); - }); - it("verifies teams is disabled", () => { - hostDetailsPage.verifiesTeamsisDisabled(); - hostDetailsPage.hidesButton("Transfer"); - }); - it("allows maintainer to create an operating system policy", () => { - hostDetailsPage.allowsCreateOsPolicy(); - }); - }); - describe("Manage software page", () => { - beforeEach(() => manageSoftwarePage.visitManageSoftwarePage()); - it("hides 'Manage automations' button from global maintainer", () => { - manageSoftwarePage.hidesButton("Manage automations"); - }); - }); - describe("Query pages", () => { - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - manageQueriesPage.visitManageQueriesPage(); - }); - it("allows maintainer to add a new query", () => { - manageQueriesPage.allowsCreateNewQuery(); - manageQueriesPage.verifiesCreatedNewQuery(); - }); - it("allows maintainer to edit a query", () => { - manageQueriesPage.allowsEditExistingQuery(); - manageQueriesPage.verifiesEditedExistingQuery(); - }); - it("allows maintainer to run a query", () => { - manageQueriesPage.allowsRunQuery(); - manageQueriesPage.verifiesRanQuery(); - }); - }); - describe("Manage policies page", () => { - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - managePoliciesPage.visitManagePoliciesPage(); - }); - it("hides manage automations from maintainer", () => { - managePoliciesPage.hidesButton("Manage automations"); - }); - it("allows maintainer to add a policy", () => { - managePoliciesPage.allowsAddDefaultPolicy(); - managePoliciesPage.verifiesAddedDefaultPolicy(); - }); - it("allows maintainer to delete a policy", () => { - managePoliciesPage.allowsDeletePolicy(); - }); - it("allows maintainer to select a policy and see CTAs to run and save", () => { - managePoliciesPage.allowsRunSavePolicy(); - }); - }); - /* NOTE: Product decision to remove packs from UI - describe("Manage packs page", () => { - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - managePacksPage.visitsManagePacksPage(); - }); - it("allows maintainer to create a pack", () => { - managePacksPage.allowsCreatePack(); - managePacksPage.verifiesCreatedPack(); - }); - it("allows maintainer to delete a pack", () => { - managePacksPage.allowsDeletePack(); - managePacksPage.verifiesDeletedPack(); - }); - }); - */ - describe("User profile page", () => { - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - userProfilePage.visitUserProfilePage(); - }); - it("verifies maintainer role and teams is disabled", () => { - userProfilePage.showRole("Maintainer"); - }); - }); - - // nav restrictions are at the end because we expect to see a - // 403 error overlay which will hide the nav and make the test fail - describe("Nav restrictions", () => { - // cypress tends to fail on uncaught exceptions. since we have - // our own error handling, it's suggested to use this block to - // suppress so the tests will keep running - Cypress.on("uncaught:exception", () => { - return false; - }); - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - }); - it("verifies maintainer does not have access to settings", () => { - cy.findByText(/settings/i).should("not.exist"); - cy.visit("/settings/organization"); - cy.findByText(/you do not have permissions/i).should("exist"); - }); - }); - } -); diff --git a/cypress/integration/free/observer.spec.ts b/cypress/integration/free/observer.spec.ts deleted file mode 100644 index 734159396..000000000 --- a/cypress/integration/free/observer.spec.ts +++ /dev/null @@ -1,180 +0,0 @@ -import CONSTANTS from "../../support/constants"; -import dashboardPage from "../pages/dashboardPage"; -import hostDetailsPage from "../pages/hostDetailsPage"; -import manageHostsPage from "../pages/manageHostsPage"; -import managePacksPage from "../pages/managePacksPage"; -import managePoliciesPage from "../pages/managePoliciesPage"; -import manageQueriesPage from "../pages/manageQueriesPage"; -import manageSchedulePage from "../pages/manageSchedulePage"; -import manageSoftwarePage from "../pages/manageSoftwarePage"; -import userProfilePage from "../pages/userProfilePage"; - -const { GOOD_PASSWORD } = CONSTANTS; - -describe("Free tier - Observer user", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.setupSMTP(); - cy.seedFree(); - cy.seedQueries(); - cy.seedPolicies(); - cy.addDockerHost(); - }); - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - - describe("Navigation", () => { - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - dashboardPage.visitsDashboardPage(); - }); - it("displays intended global observer top navigation", () => { - cy.getAttached(".site-nav-container").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/software/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("not.exist"); - cy.findByText(/policies/i).should("exist"); - cy.getAttached(".user-menu").click(); - cy.findByText(/settings/i).should("not.exist"); - cy.findByText(/manage users/i).should("not.exist"); - }); - }); - }); - describe("Dashboard", () => { - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - dashboardPage.visitsDashboardPage(); - }); - it("displays cards for all platforms and does not filter host platform", () => { - dashboardPage.displaysCards("All"); - dashboardPage.verifiesFilteredHostByPlatform("none"); - }); - it("displays cards for windows only and filters hosts by Windows platform", () => { - dashboardPage.switchesPlatform("Windows"); - dashboardPage.displaysCards("Windows"); - dashboardPage.verifiesFilteredHostByPlatform("Windows"); - }); - it("displays cards for linux only and filters hosts by Linux platform", () => { - dashboardPage.switchesPlatform("Linux"); - dashboardPage.displaysCards("Linux"); - dashboardPage.verifiesFilteredHostByPlatform("Linux"); - }); - it("displays cards for macOS only and filters hosts by macOS platform", () => { - dashboardPage.switchesPlatform("macOS"); - dashboardPage.displaysCards("macOS"); - dashboardPage.verifiesFilteredHostByPlatform("macOS"); - }); - }); - describe("Manage hosts page", () => { - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - manageHostsPage.visitsManageHostsPage(); - }); - it("verifies teams is disabled", () => { - manageHostsPage.verifiesTeamsIsDisabled(); - }); - it("hides 'Add hosts', 'Add label', and 'Manage enroll secrets' buttons", () => { - manageHostsPage.hidesButton("Add label"); - manageHostsPage.hidesButton("Add hosts"); - manageHostsPage.hidesButton("Manage enroll secret"); - }); - }); - describe("Host details page", () => { - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - hostDetailsPage.visitsHostDetailsPage(1); - }); - it("verifies teams is disabled on Host Details page", () => { - hostDetailsPage.verifiesTeamsisDisabled(); - }); - it("hides all cta buttons", () => { - hostDetailsPage.hidesButton("Transfer"); - hostDetailsPage.hidesButton("Query"); - hostDetailsPage.hidesButton("Delete"); - hostDetailsPage.hidesCreateOSPolicy(); - }); - }); - describe("Manage software page", () => { - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - manageSoftwarePage.visitManageSoftwarePage(); - }); - it("hides manage automations button", () => { - manageSoftwarePage.hidesButton("Manage automations"); - }); - }); - describe("Query page", () => { - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - manageQueriesPage.visitManageQueriesPage(); - }); - it("hides 'Create a query' button", () => { - manageQueriesPage.hidesButton("Create new query"); - }); - it("verifies observer can select a query and only run it", () => { - cy.getAttached(".data-table__table").within(() => { - cy.findByRole("button", { name: /detect presence/i }).click(); - }); - cy.findByText(/packs/i).should("not.exist"); - cy.findByLabelText(/query name/i).should("not.exist"); - cy.findByLabelText(/sql/i).should("not.exist"); - cy.findByLabelText(/description/i).should("not.exist"); - cy.findByLabelText(/observer can run/i).should("not.exist"); - cy.findByText(/show sql/i).click(); - cy.findByRole("button", { name: /run query/i }).should("exist"); - }); - }); - describe("Manage policies page", () => { - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - managePoliciesPage.visitManagePoliciesPage(); - }); - it("hides manage automations button", () => { - managePoliciesPage.hidesButton("Manage automations"); - }); - it("hides 'Add a policy' button", () => { - managePoliciesPage.hidesButton("Add a policy"); - }); - it("hides 'Run', 'Edit', and 'Delete' a policy", () => { - managePoliciesPage.allowsViewPolicyOnly(); - }); - }); - describe("User profile page", () => { - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - userProfilePage.visitUserProfilePage(); - }); - it("verifies user role and teams is disabled", () => { - userProfilePage.showRole("Observer"); - }); - }); - - // nav restrictions are at the end because we expect to see a - // 403 error overlay which will hide the nav and make the test fail - describe("Nav restrictions", () => { - // cypress tends to fail on uncaught exceptions. since we have - // our own error handling, it's suggested to use this block to - // suppress so the tests will keep running - Cypress.on("uncaught:exception", () => { - return false; - }); - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - }); - it("should restrict navigation according to role-based access controls", () => { - cy.findByText(/settings/i).should("not.exist"); - cy.findByText(/schedule/i).should("not.exist"); - cy.visit("/settings/organization"); - cy.findByText(/you do not have permissions/i).should("exist"); - managePacksPage.visitsManagePacksPage(); - cy.findByText(/you do not have permissions/i).should("exist"); - manageSchedulePage.visitManageSchedulePage(); - cy.findByText(/you do not have permissions/i).should("exist"); - }); - }); -}); diff --git a/cypress/integration/pages/dashboardPage.ts b/cypress/integration/pages/dashboardPage.ts deleted file mode 100644 index d73cc12a4..000000000 --- a/cypress/integration/pages/dashboardPage.ts +++ /dev/null @@ -1,116 +0,0 @@ -const dashboardPage = { - visitsDashboardPage: () => { - cy.visit("/dashboard"); - }, - - switchesPlatform: (platform = "") => { - cy.getAttached(".dashboard-page__platform_dropdown").click(); - cy.getAttached(".Select-menu-outer").within(() => { - cy.findAllByText(platform).click(); - }); - }, - - displaysCards: (platform = "", tier = "free") => { - switch (platform) { - case "macOS": - cy.getAttached(".dashboard-page__wrapper").within(() => { - cy.findByText(/platform/i).should("exist"); - cy.getAttached(".hosts-summary").should("exist"); - cy.getAttached(".operating-systems").should("exist"); - // "get" because we expect it not to exist - cy.get(".home-software").should("not.exist"); - cy.get(".activity-feed").should("not.exist"); - if (tier === "premium") { - cy.getAttached(".hosts-missing").should("exist"); - cy.getAttached(".hosts-low-space").should("exist"); - } else { - cy.get(".hosts-missing").should("not.exist"); - cy.get(".hosts-low-space").should("not.exist"); - } - }); - break; - case "Windows": - cy.getAttached(".dashboard-page__wrapper").within(() => { - cy.findByText(/platform/i).should("exist"); - cy.getAttached(".hosts-summary").should("exist"); - cy.getAttached(".operating-systems").should("exist"); - // "get" because we expect it not to exist - cy.get(".home-software").should("not.exist"); - cy.get(".activity-feed").should("not.exist"); - if (tier === "premium") { - cy.getAttached(".hosts-missing").should("exist"); - cy.getAttached(".hosts-low-space").should("exist"); - } else { - cy.get(".hosts-missing").should("not.exist"); - cy.get(".hosts-low-space").should("not.exist"); - } - }); - break; - case "Linux": - cy.getAttached(".dashboard-page__wrapper").within(() => { - cy.findByText(/platform/i).should("exist"); - cy.getAttached(".hosts-summary").should("exist"); - // "get" because we expect it not to exist - cy.get(".home-software").should("not.exist"); - cy.get(".activity-feed").should("not.exist"); - if (tier === "premium") { - cy.getAttached(".hosts-missing").should("exist"); - cy.getAttached(".hosts-low-space").should("exist"); - } else { - cy.get(".hosts-missing").should("not.exist"); - cy.get(".hosts-low-space").should("not.exist"); - } - }); - break; - case "All": - cy.getAttached(".dashboard-page__wrapper").within(() => { - cy.findByText(/platform/i).should("exist"); - cy.getAttached(".hosts-summary").should("exist"); - cy.getAttached(".activity-feed").should("exist"); - // hidden if no software - cy.get(".home-software").should("not.exist"); - if (tier === "premium") { - cy.getAttached(".hosts-missing").should("exist"); - cy.getAttached(".hosts-low-space").should("exist"); - } else { - cy.get(".hosts-missing").should("not.exist"); - cy.get(".hosts-low-space").should("not.exist"); - } - }); - break; - default: - // no activity feed on team dashboard - cy.getAttached(".dashboard-page__wrapper").within(() => { - cy.findByText(/platform/i).should("exist"); - cy.getAttached(".hosts-summary").should("exist"); - // hidden if no software - cy.get(".home-software").should("not.exist"); - cy.get(".activity-feed").should("not.exist"); - if (tier === "premium") { - cy.getAttached(".hosts-missing").should("exist"); - cy.getAttached(".hosts-low-space").should("exist"); - } else { - cy.get(".hosts-missing").should("not.exist"); - cy.get(".hosts-low-space").should("not.exist"); - } - }); - break; - } - }, - - verifiesFilteredHostByPlatform: (platform: string) => { - if (platform === "none") { - cy.findByText(/view all hosts/i).click(); - cy.findByRole("status", { name: /hosts filtered by/i }).should( - "not.exist" - ); - } else { - cy.findByText(/view all hosts/i).click(); - cy.findByRole("status", { - name: `hosts filtered by ${platform}`, - }).should("exist"); - } - }, -}; - -export default dashboardPage; diff --git a/cypress/integration/pages/hostDetailsPage.ts b/cypress/integration/pages/hostDetailsPage.ts deleted file mode 100644 index 5b240f4c6..000000000 --- a/cypress/integration/pages/hostDetailsPage.ts +++ /dev/null @@ -1,46 +0,0 @@ -const hostDetailsPage = { - visitsHostDetailsPage: (hostId: number) => { - cy.visit(`/hosts/${hostId}`); - }, - - verifiesTeamsisDisabled: () => { - cy.findByText(/team/i).should("not.exist"); - }, - - verifiesTeam: (teamName: string) => { - cy.getAttached(".info-flex").within(() => { - // Team is shown for host - cy.findByText(teamName).should("exist"); - }); - }, - - hidesButton: (text: string) => { - cy.contains("button", text).should("not.exist"); - }, - - allowsCreateOsPolicy: () => { - cy.getAttached(".info-flex").within(() => { - cy.findByText(/ubuntu/i).should("exist"); - cy.getAttached(".host-summary__os-policy-button").click(); - }); - cy.getAttached(".modal__content") - .findByRole("button", { name: /create new policy/i }) - .should("be.enabled"); - }, - - hidesCreateOSPolicy: () => { - cy.getAttached(".info-flex").within(() => { - cy.findByText("Operating system") - .next() - .findByText(/ubuntu/i) - .should("exist"); - - cy.findByText("Operating system") - .next() - .findByRole("button") - .should("not.exist"); - }); - }, -}; - -export default hostDetailsPage; diff --git a/cypress/integration/pages/manageHostsPage.ts b/cypress/integration/pages/manageHostsPage.ts deleted file mode 100644 index 5732d06e2..000000000 --- a/cypress/integration/pages/manageHostsPage.ts +++ /dev/null @@ -1,57 +0,0 @@ -const manageHostsPage = { - visitsManageHostsPage: () => { - cy.visit("/hosts/manage"); - }, - - allowsManageAndAddSecrets: () => { - cy.getAttached(".button-wrap") - .contains("button", /manage enroll secret/i) - .click(); - cy.wait(500); // eslint-disable-line cypress/no-unnecessary-waiting - cy.contains("button", /add secret/i).click(); - cy.wait(500); // eslint-disable-line cypress/no-unnecessary-waiting - cy.contains("button", /save/i).click(); - cy.findByText(/successfully added/i); - }, - - allowsAddHosts: () => { - cy.getAttached(".button-wrap") - .contains("button", /add hosts/i) - .click(); - cy.getAttached(".modal__content").contains("button", /done/i).click(); - }, - - allowsAddLabelForm: () => { - cy.getAttached(".label-filter-select__control").click(); - cy.findByRole("button", { name: /add label/i }).click(); - cy.findByText(/new label/i).should("exist"); - cy.getAttached(".label-form__button-wrap") - .contains("button", /cancel/i) - .click(); - }, - - hidesButton: (text: string) => { - if (text === "Add label") { - cy.getAttached(".label-filter-select__control").click(); - cy.contains("button", /add label/i).should("not.exist"); - } else { - cy.contains("button", text).should("not.exist"); - } - }, - - includesTeamColumn: () => { - cy.getAttached("thead").within(() => { - cy.findByText(/team/i).should("exist"); - }); - }, - - includesTeamDropdown: (teamName = "All teams") => { - cy.getAttached(".Select-value-label").contains(teamName); - }, - - verifiesTeamsIsDisabled: () => { - cy.findByText(/teams/i).should("not.exist"); - }, -}; - -export default manageHostsPage; diff --git a/cypress/integration/pages/managePacksPage.ts b/cypress/integration/pages/managePacksPage.ts deleted file mode 100644 index 7d7a0611a..000000000 --- a/cypress/integration/pages/managePacksPage.ts +++ /dev/null @@ -1,62 +0,0 @@ -const managePacksPage = { - visitsManagePacksPage: () => { - cy.visit("/packs/manage"); - }, - - hidesButton: (text: string) => { - cy.contains("button", text).should("not.exist"); - }, - - allowsCreatePack: () => { - cy.getAttached(".empty-table__container"); - cy.findByRole("button", { name: /create new pack/i }).click(); - cy.findByLabelText(/name/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 }).should("be.enabled"); - }, - - verifiesCreatedPack: () => { - cy.findByRole("button", { name: /save query pack/i }).click(); - }, - - allowsEditPack: () => { - cy.findByLabelText(/name/i).clear().type("Server errors"); - cy.findByLabelText(/description/i) - .clear() - .type("See all server errors."); - cy.findByRole("button", { name: /save/i }).should("be.enabled"); - }, - - verifiesEditedPack: () => { - cy.findByRole("button", { name: /save/i }).click(); - }, - - allowsDeletePack: () => { - cy.getAttached("tbody").within(() => { - cy.getAttached("tr") - .first() - .within(() => { - cy.getAttached(".fleet-checkbox__input").check({ force: true }); - }); - }); - cy.findByRole("button", { name: /delete/i }).click(); - cy.getAttached(".remove-pack-modal .modal-cta-wrap > .button--alert") - .contains("button", /delete/i) - .should("be.enabled"); - }, - - verifiesDeletedPack: () => { - cy.getAttached(".remove-pack-modal .modal-cta-wrap > .button--alert") - .contains("button", /delete/i) - .click({ force: true }); - cy.findByText(/successfully deleted/i).should("be.visible"); - managePacksPage.visitsManagePacksPage(); - cy.getAttached(".table-container").within(() => { - cy.findByText(/windows starter pack/i).should("not.exist"); - }); - }, -}; - -export default managePacksPage; diff --git a/cypress/integration/pages/managePoliciesPage.ts b/cypress/integration/pages/managePoliciesPage.ts deleted file mode 100644 index 4171d6e40..000000000 --- a/cypress/integration/pages/managePoliciesPage.ts +++ /dev/null @@ -1,115 +0,0 @@ -const managePoliciesPage = { - visitManagePoliciesPage: () => { - cy.visit("/policies/manage"); - }, - - hidesButton: (text: string) => { - cy.contains("button", text).should("not.exist"); - }, - - allowsAddDefaultPolicy: () => { - cy.findByRole("button", { name: /add a policy/i }).click(); - // Add a default policy - cy.findByText(/gatekeeper enabled/i).click(); - cy.getAttached(".policy-form__button-wrap").within(() => { - cy.findByRole("button", { name: /run/i }).should("exist"); - cy.findByRole("button", { name: /save/i }).click(); - }); - }, - - verifiesAddedDefaultPolicy: () => { - cy.getAttached(".modal-cta-wrap").within(() => { - cy.findByRole("button", { name: /save policy/i }).click(); - }); - cy.findByText(/policy created/i).should("exist"); - cy.findByText(/gatekeeper enabled/i).should("exist"); - }, - - allowsAutomatePolicy: () => { - cy.getAttached(".button-wrap") - .findByRole("button", { name: /manage automations/i }) - .click(); - - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-checkbox__input").check({ force: true }); - cy.getAttached("#webhook-url").clear().type("https://example.com/admin"); - }); - }, - - verifiesAutomatedPolicy: () => { - cy.getAttached(".manage-automations-modal").within(() => { - cy.findByRole("button", { name: /save/i }).click(); - }); - cy.findByText(/successfully updated policy automations/i).should("exist"); - }, - - allowsDeletePolicy: () => { - cy.getAttached("tbody").within(() => { - cy.getAttached("tr") - .first() - .within(() => { - cy.getAttached(".fleet-checkbox__input").check({ - force: true, - }); - }); - }); - cy.findByRole("button", { name: /delete/i }).click(); - cy.getAttached(".delete-policy-modal").within(() => { - cy.findByRole("button", { name: /delete/i }).should("be.enabled"); - }); - }, - - verifiesDeletedPolicy: () => { - cy.getAttached(".delete-policy-modal").within(() => { - cy.findByRole("button", { name: /delete/i }).click(); - }); - cy.findByText(/deleted policy/i).should("exist"); - cy.findByText(/backup/i).should("not.exist"); - }, - - allowsSelectRunSavePolicy: (name = "gatekeeper") => { - cy.getAttached(".data-table__table").within(() => { - cy.findByRole("button", { name: RegExp(name, "i") }).click(); - }); - cy.getAttached(".policy-form__button-wrap").within(() => { - cy.findByRole("button", { name: /run/i }).should("exist"); - cy.findByRole("button", { name: /save/i }).should("exist"); - }); - }, - - allowsViewPolicyOnly: () => { - cy.getAttached("tbody").within(() => { - cy.getAttached("tr") - .first() - .within(() => { - cy.contains(".fleet-checkbox__input").should("not.exist"); - cy.findByRole("button", { name: /filevault/i }).click(); - }); - }); - cy.getAttached(".policy-form__wrapper").within(() => { - cy.findByRole("button", { name: /run/i }).should("not.exist"); - cy.findByRole("button", { name: /save/i }).should("not.exist"); - }); - }, - - allowsRunSavePolicy: () => { - cy.getAttached(".data-table__table").within(() => { - cy.getAttached("tbody").within(() => { - cy.getAttached("tr") - .first() - .within(() => { - cy.findByRole("button", { - name: /gatekeeper/i, - }).click(); - }); - }); - }); - cy.getAttached(".policy-form__button-wrap").within(() => { - cy.findByRole("button", { name: /run/i }).should("exist"); - cy.findByRole("button", { name: /save/i }).should("exist"); - }); - }, -}; - -export default managePoliciesPage; diff --git a/cypress/integration/pages/manageQueriesPage.ts b/cypress/integration/pages/manageQueriesPage.ts deleted file mode 100644 index a5ff7854a..000000000 --- a/cypress/integration/pages/manageQueriesPage.ts +++ /dev/null @@ -1,163 +0,0 @@ -import * as path from "path"; -import { format } from "date-fns"; - -const manageQueriesPage = { - visitManageQueriesPage: () => { - cy.visit("/queries/manage"); - }, - - hidesButton: (text: string) => { - cy.contains("button", text).should("not.exist"); - }, - - allowsCreateNewQuery: () => { - cy.getAttached(".button--brand"); // ensures cta button loads - cy.findByRole("button", { name: /new query/i }).click(); - cy.getAttached(".query-page__form .ace_scroller") - .click({ force: true }) - .type("{selectall}SELECT * FROM windows_crashes;"); - cy.findByRole("button", { name: /save/i }).click(); - cy.getAttached(".modal__background").within(() => { - cy.getAttached(".modal__modal_container").within(() => { - cy.getAttached(".modal__content").within(() => { - cy.getAttached("form").within(() => { - cy.findByLabelText(/name/i).click().type("Cypress test query"); - cy.findByLabelText(/description/i) - .click() - .type("Cypress test of create new query flow."); - cy.findByLabelText(/observers can run/i).click({ force: true }); - }); - }); - }); - }); - }, - - verifiesCreatedNewQuery: () => { - cy.getAttached(".modal__background").within(() => { - cy.getAttached(".modal__modal_container").within(() => { - cy.getAttached(".modal__content").within(() => { - cy.getAttached("form").within(() => { - cy.findByRole("button", { name: /save query/i }).click(); - }); - }); - }); - }); - cy.findByText(/query created/i).should("exist"); - cy.getAttached(".query-form__query-name").within(() => { - cy.findByText(/cypress test query/i).should("exist"); - }); - }, - - allowsEditExistingQuery: () => { - cy.getAttached(".name__cell .button--text-link") - .first() - .click({ force: true }); - cy.getAttached(".query-page__form .ace_text-input") - .click({ force: true }) - .clear({ force: true }) - .type("SELECT 1 FROM cypress;", { - force: true, - }); - }, - - verifiesEditedExistingQuery: () => { - cy.findByRole("button", { name: "Save" }).click(); // we have 'save as new' also - cy.findByText(/query updated/i).should("be.visible"); - }, - - allowsSaveAsNewQuery: () => { - cy.getAttached(".name__cell .button--text-link") - .eq(1) - .within(() => { - cy.findByText(/get authorized/i).click(); - }); - cy.findByRole("button", { name: /run query/i }).should("exist"); - cy.getAttached(".query-page__form .ace_scroller") - .click() - .type("{selectall}SELECT datetime, username FROM windows_crashes;"); - cy.findByRole("button", { name: /save as new/i }).should("be.enabled"); - }, - - verifiesSavedAsNewQuery: () => { - cy.findByRole("button", { name: /save as new/i }).click(); - cy.findByText(/successfully added query/i).should("be.visible"); - cy.findByText(/copy of/i).should("be.visible"); - }, - - allowsDeleteExistingQuery: () => { - cy.findByText(/detect presence of authorized ssh keys/i) - .parent() - .parent() - .parent() - .within(() => { - cy.getAttached(".fleet-checkbox__input").check({ - force: true, - }); - }); - cy.findByRole("button", { name: /delete/i }).click(); - cy.getAttached(".delete-query-modal .modal-cta-wrap").within(() => { - cy.findByRole("button", { name: /delete/i }).should("exist"); - }); - }, - - verifiesDeletedExistingQuery: () => { - cy.getAttached(".delete-query-modal .modal-cta-wrap").within(() => { - cy.findByRole("button", { name: /delete/i }).click(); - }); - cy.findByText(/successfully deleted query/i).should("be.visible"); - cy.findByText(/detect presence of authorized ssh keys/i).should( - "not.exist" - ); - }, - - // TODO: Allows delete of self authored query only (Team Admin, team maintainer) - - allowsSelectTeamTargets: () => { - cy.getAttached("tbody").within(() => { - cy.findAllByText(/detect presence/i).click(); - }); - - cy.getAttached(".query-form__button-wrap").within(() => { - cy.findByRole("button", { name: /run/i }).click(); - }); - cy.contains("h3", /teams/i).should("exist"); - cy.contains(".selector-name", /apples/i).should("exist"); - }, - - allowsRunQuery: () => { - cy.getAttached(".name__cell .button--text-link").first().click(); - cy.findByRole("button", { name: /run query/i }).click(); - cy.findByText(/select targets/i).should("exist"); - cy.findByText(/all hosts/i).click(); - cy.findByText(/host targeted/i).should("exist"); // target count - }, - - verifiesRanQuery: () => { - cy.findByRole("button", { name: /run/i }).click(); - cy.findByText(/querying selected host/i).should("exist"); // target count - }, - - allowsViewRanQuery: () => { - // Ensures live query runs - cy.wait(10000); // eslint-disable-line cypress/no-unnecessary-waiting - cy.getAttached(".table-container").within(() => { - cy.findByRole("button", { name: /show query/i }).click(); - }); - cy.getAttached(".show-query-modal").within(() => { - cy.findByRole("button", { name: /done/i }).click(); - }); - }, - - allowsExportQueryResults: () => { - cy.getAttached(".table-container").within(() => { - cy.findByRole("button", { name: /export results/i }).click(); - const formattedTime = format(new Date(), "MM-dd-yy hh-mm-ss"); - const filename = `Query Results (${formattedTime}).csv`; - cy.readFile(path.join(Cypress.config("downloadsFolder"), filename), { - timeout: 5000, - }); - }); - }, -}; - -export default manageQueriesPage; diff --git a/cypress/integration/pages/manageSchedulePage.ts b/cypress/integration/pages/manageSchedulePage.ts deleted file mode 100644 index a9a8c8a35..000000000 --- a/cypress/integration/pages/manageSchedulePage.ts +++ /dev/null @@ -1,124 +0,0 @@ -const manageSchedulePage = { - visitManageSchedulePage: () => { - cy.visit("/schedule/manage"); - }, - - hidesButton: (text: string) => { - if (text === "Advanced") { - cy.getAttached(".empty-table__cta-buttons").within(() => { - cy.contains("button", text).should("not.exist"); - }); - } else cy.contains("button", text).should("not.exist"); - }, - - changesTeam: (team1: string, team2: string) => { - cy.getAttached(".manage-schedule-page__header").within(() => { - cy.contains(team1).click({ force: true }); - cy.contains(team2).click({ force: true }); - }); - }, - - confirmsTeam: (team: string) => { - cy.getAttached(".manage-schedule-page__header-wrap").within(() => { - cy.findByText(team).should("exist"); - }); - }, - - allowsAddSchedule: () => { - cy.getAttached(".empty-table__cta-buttons").within(() => { - cy.findByRole("button", { name: /schedule a query/i }).click({ - force: true, - }); - }); - cy.getAttached(".schedule-editor-modal__form").within(() => { - cy.findByText(/select query/i).click(); - cy.findByText(/get local/i).click(); - cy.findByText(/every day/i).click(); - cy.findByText(/every 6 hours/i).click(); - cy.findByText(/show advanced options/i).click(); - cy.findByText(/snapshot/i).click(); - cy.findByText(/ignore removals/i).click(); - cy.getAttached(".schedule-editor-modal__form-field--platform").within( - () => { - cy.findByText(/select/i).click(); - cy.findByText(/linux/i).click(); - } - ); - cy.getAttached(".schedule-editor-modal__form-field--osquer-vers").within( - () => { - cy.findByText(/all/i).click(); - cy.findByText(/4.6.0/i).click(); - } - ); - cy.getAttached(".schedule-editor-modal__form-field--shard").within(() => { - cy.getAttached(".input-field").click().type("50"); - }); - cy.getAttached(".modal-cta-wrap").within(() => { - cy.findByRole("button", { name: /schedule/i }).should("be.enabled"); - }); - }); - }, - - verifiesAddedSchedule: () => { - cy.getAttached(".modal-cta-wrap").within(() => { - cy.findByRole("button", { name: /schedule/i }).click(); - }); - cy.findByText(/successfully added/i).should("be.visible"); - cy.getAttached("tbody>tr").should("have.length", 1); - }, - - allowsEditSchedule: () => { - cy.getAttached(".manage-schedule-page"); - cy.getAttached("tbody>tr") - .should("have.length", 1) - .within(() => { - cy.findByText(/action/i).click(); - cy.findByText(/edit/i).click(); - }); - cy.getAttached(".schedule-editor-modal__form").within(() => { - cy.findByText(/every 6 hours/i).click(); - cy.findByText(/every day/i).click(); - - cy.getAttached(".modal-cta-wrap").within(() => { - cy.findByRole("button", { name: /schedule/i }).should("be.enabled"); - }); - }); - }, - - verifiesEditedSchedule: () => { - cy.getAttached(".modal-cta-wrap").within(() => { - cy.findByRole("button", { name: /schedule/i }).click(); - }); - cy.findByText(/successfully updated/i).should("be.visible"); - }, - - allowsRemoveSchedule: () => { - cy.getAttached(".manage-schedule-page"); - cy.getAttached("tbody>tr") - .should("have.length", 1) - .within(() => { - cy.getAttached(".Select-placeholder").within(() => { - cy.findByText(/action/i).click(); - }); - cy.getAttached(".Select-menu").within(() => { - cy.findByText(/remove/i).click(); - }); - }); - cy.getAttached(".remove-scheduled-query-modal .modal-cta-wrap").within( - () => { - cy.findByRole("button", { name: /remove/i }).should("be.enabled"); - } - ); - }, - - verifiesRemovedSchedule: () => { - cy.getAttached(".remove-scheduled-query-modal .modal-cta-wrap").within( - () => { - cy.findByRole("button", { name: /remove/i }).click(); - } - ); - cy.findByText(/successfully removed/i).should("be.visible"); - }, -}; - -export default manageSchedulePage; diff --git a/cypress/integration/pages/manageSoftwarePage.ts b/cypress/integration/pages/manageSoftwarePage.ts deleted file mode 100644 index cf9c1d100..000000000 --- a/cypress/integration/pages/manageSoftwarePage.ts +++ /dev/null @@ -1,16 +0,0 @@ -const manageSoftwarePage = { - visitManageSoftwarePage: () => { - cy.visit("/software/manage"); - }, - - hidesButton: (text: string) => { - cy.contains("button", text).should("not.exist"); - }, - - allowsManageAutomations: () => { - cy.findByRole("button", { name: /manage automations/i }).click(); - cy.findByRole("button", { name: /cancel/i }).click(); - }, -}; - -export default manageSoftwarePage; diff --git a/cypress/integration/pages/teamsDropdown.ts b/cypress/integration/pages/teamsDropdown.ts deleted file mode 100644 index 985930adf..000000000 --- a/cypress/integration/pages/teamsDropdown.ts +++ /dev/null @@ -1,10 +0,0 @@ -const teamsDropdown = { - switchTeams: (team1: string, team2: string) => { - cy.getAttached(".component__team-dropdown").within(() => { - cy.findByText(team1).click({ force: true }); - }); - cy.getAttached(".Select-menu").contains(team2).click({ force: true }); - }, -}; - -export default teamsDropdown; diff --git a/cypress/integration/pages/userProfilePage.ts b/cypress/integration/pages/userProfilePage.ts deleted file mode 100644 index b5d805fd2..000000000 --- a/cypress/integration/pages/userProfilePage.ts +++ /dev/null @@ -1,21 +0,0 @@ -const userProfilePage = { - visitUserProfilePage: () => { - cy.visit("/profile"); - }, - - showRole: (role: string, team?: string) => { - cy.getAttached(".user-side-panel").within(() => { - if (team) { - cy.getAttached(".user-side-panel__header") - .contains(/team/i) - .next() - .contains(team); - } else { - cy.findByText(/teams/i).should("not.exist"); - } - cy.findByText("Role").next().contains(role); - }); - }, -}; - -export default userProfilePage; diff --git a/cypress/integration/premium/README.md b/cypress/integration/premium/README.md deleted file mode 100644 index ad3846176..000000000 --- a/cypress/integration/premium/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Premium tier tests - -These tests should only run when the server is in `premium` tier. - -To enable the tests: - -```sh -export CYPRESS_FLEET_TIER=premium -``` - -Before running the appropriate `yarn cypress (open|run)` command. - -## Filtering - -Any test suite in this directory should use the following pattern for filtering: - -**FIXME**: There must be a better way to do this for all tests in the directory rather than having to add the check in each file? - -```js -if (Cypress.env("FLEET_TIER") === "premium") { - // test suite here -} -``` diff --git a/cypress/integration/premium/admin.spec.ts b/cypress/integration/premium/admin.spec.ts deleted file mode 100644 index 20a927188..000000000 --- a/cypress/integration/premium/admin.spec.ts +++ /dev/null @@ -1,596 +0,0 @@ -import CONSTANTS from "../../support/constants"; -import hostDetailsPage from "../pages/hostDetailsPage"; -import managePoliciesPage from "../pages/managePoliciesPage"; -import manageHostsPage from "../pages/manageHostsPage"; -import manageQueriesPage from "../pages/manageQueriesPage"; -import manageSoftwarePage from "../pages/manageSoftwarePage"; -import teamsDropdown from "../pages/teamsDropdown"; -import userProfilePage from "../pages/userProfilePage"; -import dashboardPage from "../pages/dashboardPage"; - -const { GOOD_PASSWORD, CONFIG_INTEGRATIONS_AUTOMATIONS } = CONSTANTS; - -const patchTeamJiraPoliciesIntegration = { - integrations: { - jira: [ - { - enable_failing_policies: false, - project_key: "PROJECT 1", - url: "https://fleetdm.atlassian.com", - }, - { - enable_failing_policies: true, - project_key: "PROJECT 2", - url: "https://fleetdm.atlassian.com", - }, - ], - zendesk: [ - { - enable_failing_policies: false, - group_id: 12345678, - url: "https://fleetdm.zendesk.com", - }, - { - enable_failing_policies: false, - group_id: 87654321, - url: "https://fleetdm.zendesk.com", - }, - ], - }, - webhook_settings: { - failing_policies_webhook: { - destination_url: "https://example.com/global_admin", - enable_failing_policies_webhook: false, - policy_ids: [1, 3, 2], - }, - }, -}; - -const getTeamJiraPoliciesIntegration = { - team: { - id: 1, - created_at: "2022-07-01T19:31:46Z", - name: "Apples", - description: "", - agent_options: { - config: { - options: { - pack_delimiter: "/", - logger_tls_period: 10, - distributed_plugin: "tls", - disable_distributed: false, - logger_tls_endpoint: "/api/osquery/log", - distributed_interval: 10, - distributed_tls_max_attempts: 3, - }, - decorators: { - load: [ - "SELECT uuid AS host_uuid FROM system_info;", - "SELECT hostname AS hostname FROM system_info;", - ], - }, - }, - overrides: {}, - }, - webhook_settings: { - failing_policies_webhook: { - enable_failing_policies_webhook: false, - destination_url: "https://example.com/global_admin", - policy_ids: [1, 3, 2], - host_batch_size: 0, - }, - }, - integrations: { - jira: [ - { - enable_failing_policies: false, - project_key: "PROJECT 1", - url: "https://fleetdm.atlassian.com", - }, - { - enable_failing_policies: true, - project_key: "PROJECT 2", - url: "https://fleetdm.atlassian.com", - }, - ], - zendesk: [ - { - enable_failing_policies: false, - group_id: 12345678, - url: "https://fleetdm.zendesk.com", - }, - { - enable_failing_policies: false, - group_id: 87654321, - url: "https://fleetdm.zendesk.com", - }, - ], - }, - user_count: 0, - users: [ - { - created_at: "0001-01-01T00:00:00Z", - updated_at: "0001-01-01T00:00:00Z", - id: 8, - name: "Marco", - email: "marco@organization.com", - force_password_reset: false, - gravatar_url: "", - sso_enabled: false, - global_role: null, - api_only: false, - teams: null, - role: "observer", - }, - { - created_at: "0001-01-01T00:00:00Z", - updated_at: "0001-01-01T00:00:00Z", - id: 9, - name: "Anita T. Admin", - email: "anita@organization.com", - force_password_reset: false, - gravatar_url: "", - sso_enabled: false, - global_role: null, - api_only: false, - teams: null, - role: "admin", - }, - { - created_at: "0001-01-01T00:00:00Z", - updated_at: "0001-01-01T00:00:00Z", - id: 10, - name: "Toni", - email: "toni@organization.com", - force_password_reset: false, - gravatar_url: "", - sso_enabled: false, - global_role: null, - api_only: false, - teams: null, - role: "observer", - }, - ], - host_count: 0, - secrets: [ - { - secret: "OgkyoX/SGsuvLXPaNHUVIJoYSx1PTV+S", - created_at: "2022-07-01T19:31:46Z", - team_id: 1, - }, - ], - }, -}; - -const patchTeamZendeskPoliciesIntegration = { - integrations: { - jira: [ - { - enable_failing_policies: false, - project_key: "PROJECT 1", - url: "https://fleetdm.atlassian.com", - }, - { - enable_failing_policies: false, - project_key: "PROJECT 2", - url: "https://fleetdm.atlassian.com", - }, - ], - zendesk: [ - { - enable_failing_policies: false, - group_id: 12345678, - url: "https://fleetdm.zendesk.com", - }, - { - enable_failing_policies: true, - group_id: 87654321, - url: "https://fleetdm.zendesk.com", - }, - ], - }, - webhook_settings: { - failing_policies_webhook: { - destination_url: "https://example.com/global_admin", - enable_failing_policies_webhook: false, - policy_ids: [1, 3, 2], - }, - }, -}; - -const getTeamZendeskPoliciesIntegration = { - team: { - id: 1, - created_at: "2022-07-01T19:31:46Z", - name: "Apples", - description: "", - agent_options: { - config: { - options: { - pack_delimiter: "/", - logger_tls_period: 10, - distributed_plugin: "tls", - disable_distributed: false, - logger_tls_endpoint: "/api/osquery/log", - distributed_interval: 10, - distributed_tls_max_attempts: 3, - }, - decorators: { - load: [ - "SELECT uuid AS host_uuid FROM system_info;", - "SELECT hostname AS hostname FROM system_info;", - ], - }, - }, - overrides: {}, - }, - webhook_settings: { - failing_policies_webhook: { - enable_failing_policies_webhook: false, - destination_url: "https://example.com/global_admin", - policy_ids: [1, 3, 2], - host_batch_size: 0, - }, - }, - integrations: { - jira: [ - { - enable_failing_policies: false, - project_key: "PROJECT 1", - url: "https://fleetdm.atlassian.com", - }, - { - enable_failing_policies: false, - project_key: "PROJECT 2", - url: "https://fleetdm.atlassian.com", - }, - ], - zendesk: [ - { - enable_failing_policies: false, - group_id: 12345678, - url: "https://fleetdm.zendesk.com", - }, - { - enable_failing_policies: true, - group_id: 87654321, - url: "https://fleetdm.zendesk.com", - }, - ], - }, - user_count: 0, - users: [ - { - created_at: "0001-01-01T00:00:00Z", - updated_at: "0001-01-01T00:00:00Z", - id: 8, - name: "Marco", - email: "marco@organization.com", - force_password_reset: false, - gravatar_url: "", - sso_enabled: false, - global_role: null, - api_only: false, - teams: null, - role: "observer", - }, - { - created_at: "0001-01-01T00:00:00Z", - updated_at: "0001-01-01T00:00:00Z", - id: 9, - name: "Anita T. Admin", - email: "anita@organization.com", - force_password_reset: false, - gravatar_url: "", - sso_enabled: false, - global_role: null, - api_only: false, - teams: null, - role: "admin", - }, - { - created_at: "0001-01-01T00:00:00Z", - updated_at: "0001-01-01T00:00:00Z", - id: 10, - name: "Toni", - email: "toni@organization.com", - force_password_reset: false, - gravatar_url: "", - sso_enabled: false, - global_role: null, - api_only: false, - teams: null, - role: "observer", - }, - ], - host_count: 0, - secrets: [ - { - secret: "OgkyoX/SGsuvLXPaNHUVIJoYSx1PTV+S", - created_at: "2022-07-01T19:31:46Z", - team_id: 1, - }, - ], - }, -}; - -describe("Premium tier - Global Admin user", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.seedPremium(); - cy.seedQueries(); - cy.seedPolicies("apples"); - cy.addDockerHost("apples"); // host not transferred - cy.addDockerHost("oranges"); // host transferred between teams by global admin - }); - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - - beforeEach(() => { - cy.loginWithCySession("anna@organization.com", GOOD_PASSWORD); - }); - describe("Navigation and dashboard", () => { - beforeEach(() => dashboardPage.visitsDashboardPage()); - it("displays intended global admin top navigation", () => { - cy.getAttached(".site-nav-container").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/software/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("exist"); - cy.findByText(/policies/i).should("exist"); - cy.getAttached(".user-menu").click(); - cy.findByText(/settings/i).click(); - }); - cy.getAttached(".react-tabs__tab--selected").within(() => { - cy.findByText(/organization/i).should("exist"); - }); - cy.getAttached(".site-nav-container").within(() => { - cy.getAttached(".user-menu").click(); - cy.findByText(/manage users/i).click(); - }); - cy.getAttached(".react-tabs__tab--selected").within(() => { - cy.findByText(/users/i).should("exist"); - }); - }); - // Premium dashboard feature - it("filters missing hosts", () => { - cy.findByText(/missing hosts/i).click(); - cy.getAttached(".manage-hosts__filter-dropdowns").within(() => { - cy.findByText(/missing hosts/i).should("exist"); - }); - }); - // Premium dashboard feature - it("filters low disk space hosts", () => { - cy.findByText(/low disk space hosts/i).click(); - cy.findByRole("status", { - name: /hosts filtered by low disk space/i, - }).should("exist"); - }); - }); - // Global Admin dashboard tested in integration/free/admin.spec.ts - // Team Admin dashboard tested below in integration/premium/admin.spec.ts - describe("Manage hosts page", () => { - beforeEach(() => manageHostsPage.visitsManageHostsPage()); - it("verifies teams is enabled on Manage host page", () => { - manageHostsPage.includesTeamColumn(); - }); - it("allows global admin to see and click all CTA buttons", () => { - manageHostsPage.allowsAddHosts(); - manageHostsPage.allowsAddLabelForm(); - manageHostsPage.allowsManageAndAddSecrets(); - }); - }); - describe("Host details page", () => { - beforeEach(() => hostDetailsPage.visitsHostDetailsPage(1)); - it("allows global admin to create an operating system policy", () => { - hostDetailsPage.allowsCreateOsPolicy(); - }); - }); - describe("Manage software page", () => { - beforeEach(() => { - manageSoftwarePage.visitManageSoftwarePage(); - }); - // it(`displays "Probability of exploit" column`, () => { - // cy.getAttached("thead").within(() => { - // cy.findByText(/vulnerabilities/i).should("not.exist"); - // cy.findByText(/probability of exploit/i).should("exist"); - // }); - // }); - it("allows admin to click 'Manage automations' button", () => { - manageSoftwarePage.allowsManageAutomations(); - }); - it("hides manage automations button since all teams not selected", () => { - cy.getAttached(".manage-software-page__header-wrap").within(() => { - teamsDropdown.switchTeams("All teams", "Apples"); - manageSoftwarePage.hidesButton("Manage automations"); - }); - }); - }); - describe("Query pages", () => { - beforeEach(() => manageQueriesPage.visitManageQueriesPage()); - it("allows global admin to select teams targets for query", () => { - manageQueriesPage.allowsSelectTeamTargets(); - }); - // TODO: Allowed to delete self-authored query only - }); - // Global Admin schedule tested in integration/free/admin.spec.ts - // Team Admin team schedule tested below in integration/premium/admin.spec.ts - describe("Manage policies page", () => { - beforeEach(() => managePoliciesPage.visitManagePoliciesPage()); - it("allows global admin to add a new policy", () => { - managePoliciesPage.allowsAddDefaultPolicy(); - managePoliciesPage.verifiesAddedDefaultPolicy(); - }); - it("allows global admin to automate a global policy", () => { - managePoliciesPage.allowsAutomatePolicy(); - managePoliciesPage.verifiesAutomatedPolicy(); - }); - it("allows global admin to automate a team policy webhook", () => { - managePoliciesPage.visitManagePoliciesPage(); - teamsDropdown.switchTeams("All teams", "Apples"); - managePoliciesPage.allowsAutomatePolicy(); - managePoliciesPage.verifiesAutomatedPolicy(); - }); - - it("allows global admin to delete a team policy", () => { - cy.visit("/policies/manage"); - teamsDropdown.switchTeams("All teams", "Apples"); - managePoliciesPage.allowsDeletePolicy(); - }); - it("allows global admin to edit a team policy", () => { - managePoliciesPage.visitManagePoliciesPage(); - teamsDropdown.switchTeams("All teams", "Apples"); - managePoliciesPage.allowsSelectRunSavePolicy("filevault"); - }); - }); - describe("Manage policies page (mock integrations)", () => { - beforeEach(() => { - cy.intercept( - "GET", - "/api/latest/fleet/config", - CONFIG_INTEGRATIONS_AUTOMATIONS - ).as("getIntegrations"); - managePoliciesPage.visitManagePoliciesPage(); - cy.wait("@getIntegrations").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - }); - it("allows global admin to delete team policy", () => { - teamsDropdown.switchTeams("All teams", "Apples"); - managePoliciesPage.allowsDeletePolicy(); - }); - it("allows global admin to automate a team policy jira integration", () => { - managePoliciesPage.visitManagePoliciesPage; - teamsDropdown.switchTeams("All teams", "Apples"); - cy.getAttached(".button-wrap") - .findByRole("button", { name: /manage automations/i }) - .click(); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-checkbox__input").check({ force: true }); - cy.getAttached("#ticket-radio-btn").next().click(); - cy.findByText(/select integration/i).click(); - cy.findByText(/project 2/i).click(); - cy.intercept( - "PATCH", - "/api/latest/fleet/teams/1", - patchTeamJiraPoliciesIntegration - ).as("enableJiraPoliciesIntegration"); - cy.intercept( - "GET", - "/api/latest/fleet/teams/1", - getTeamJiraPoliciesIntegration - ).as("enabledJiraPoliciesIntegration"); - cy.findByText(/save/i).click(); - }); - cy.findByText(/successfully updated policy automations/i).should("exist"); - }); - - it("allows global admin to automate a team policy zendesk integration", () => { - managePoliciesPage.visitManagePoliciesPage(); - teamsDropdown.switchTeams("All teams", "Apples"); - cy.getAttached(".button-wrap") - .findByRole("button", { name: /manage automations/i }) - .click(); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-slider").click(); - cy.getAttached(".fleet-checkbox__input").check({ force: true }); - cy.getAttached("#ticket-radio-btn").next().click(); - cy.findByText(/select integration/i).click(); - cy.findByText(/87654321/i).click(); - cy.intercept( - "PATCH", - "/api/latest/fleet/teams/1", - patchTeamZendeskPoliciesIntegration - ).as("enableZendeskPoliciesIntegration"); - cy.intercept( - "GET", - "/api/latest/fleet/teams/1", - getTeamZendeskPoliciesIntegration - ).as("enabledZendeskPoliciesIntegration"); - cy.findByText(/save/i).click(); - cy.wait("@enableZendeskPoliciesIntegration").then((configStub) => { - console.log(JSON.stringify(configStub)); - }); - }); - cy.findByText(/successfully updated policy automations/i).should("exist"); - }); - }); - describe("Admin settings page", () => { - beforeEach(() => cy.visit("/settings/organization")); - it("allows global admin to access team settings", () => { - cy.getAttached(".react-tabs").within(() => { - cy.findByText(/teams/i).click(); - }); - // Access the Settings - Team details page - cy.getAttached("tbody").within(() => { - cy.getAttached(".name__cell .button--text-link") - .eq(0) - .within(() => { - cy.findByText(/apples/i).click(); - }); - }); - cy.findByText(/apples/i).should("exist"); - cy.findByText(/manage users with global access here/i).should("exist"); - }); - it("displays the 'Team' section in the create user modal", () => { - cy.getAttached(".react-tabs").within(() => { - cy.findByText(/users/i).click(); - }); - cy.findByRole("button", { name: /create user/i }).click({ force: true }); - cy.findByText(/assign teams/i).should("exist"); - }); - it("allows global admin to edit existing user password", () => { - cy.visit("/settings/users"); - cy.getAttached("tbody").within(() => { - cy.contains("Oliver") // case-sensitive - .parent() - .next() - .next() - .next() - .next() - .next() - .within(() => cy.getAttached(".Select-placeholder").click()); - }); - cy.getAttached(".Select-menu").within(() => { - cy.findByText(/edit/i).click(); - }); - cy.getAttached(".create-user-form").within(() => { - cy.findByLabelText(/email/i).should("exist"); - cy.findByLabelText(/password/i).should("exist"); - }); - }); - it("allows access to Fleet Desktop settings", () => { - cy.visit("settings/organization"); - cy.findByRole("navigation", { name: "settings" }).within(() => { - cy.findByText(/organization info/i).should("exist"); - cy.findByText(/fleet desktop/i) - .should("exist") - .click(); - }); - cy.getAttached("[id=transparency_url") - .should("have.value", "https://fleetdm.com/transparency") - .clear() - .type("http://example.com/transparency"); - cy.findByRole("button", { name: /save/i }).click(); - cy.findByText(/successfully updated/i).should("exist"); - cy.visit("settings/organization/fleet-desktop"); - cy.getAttached("[id=transparency_url").should( - "have.value", - "http://example.com/transparency" - ); - }); - }); - describe("User profile page", () => { - it("verifies admin user role and global access", () => { - userProfilePage.visitUserProfilePage(); - userProfilePage.showRole("Admin", "Global"); - }); - }); -}); diff --git a/cypress/integration/premium/fleetdesktop.spec.ts b/cypress/integration/premium/fleetdesktop.spec.ts deleted file mode 100644 index 0e1695d90..000000000 --- a/cypress/integration/premium/fleetdesktop.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -const fakeDeviceToken = "phAK3d3vIC37OK3n"; - -describe("Fleet Desktop", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.addDockerHost(); - cy.setDesktopToken(1, fakeDeviceToken); - cy.viewport(1200, 660); - cy.seedPolicies(); - }); - after(() => { - cy.stopDockerHost(); - }); - describe("Fleet Desktop device user page", () => { - beforeEach(() => { - Cypress.session.clearAllSavedSessions(); - cy.visit(`/device/${fakeDeviceToken}`); - }); - it("renders policies and provides instructions for self-remediation", () => { - cy.getAttached(".react-tabs__tab-list").within(() => { - cy.findByText(/policies/i).click(); - }); - cy.getAttached(".section--policies").within(() => { - cy.findByText(/is filevault enabled/i).click(); - }); - cy.getAttached(".policy-details-modal").within(() => { - cy.findByText(/click turn on filevault/i).should("exist"); - }); - }); - }); -}); diff --git a/cypress/integration/premium/maintainer.spec.ts b/cypress/integration/premium/maintainer.spec.ts deleted file mode 100644 index 76f8b82a7..000000000 --- a/cypress/integration/premium/maintainer.spec.ts +++ /dev/null @@ -1,127 +0,0 @@ -import CONSTANTS from "../../support/constants"; -import hostDetailsPage from "../pages/hostDetailsPage"; -import managePoliciesPage from "../pages/managePoliciesPage"; -import manageHostsPage from "../pages/manageHostsPage"; -import manageQueriesPage from "../pages/manageQueriesPage"; -import manageSoftwarePage from "../pages/manageSoftwarePage"; -import teamsDropdown from "../pages/teamsDropdown"; -import userProfilePage from "../pages/userProfilePage"; -import dashboardPage from "../pages/dashboardPage"; - -const { GOOD_PASSWORD } = CONSTANTS; - -describe("Premium tier - Maintainer user", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.seedPremium(); - cy.seedQueries(); - cy.seedPolicies("apples"); - cy.addDockerHost("apples"); - }); - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - - describe("Global maintainer", () => { - beforeEach(() => { - cy.loginWithCySession("mary@organization.com", GOOD_PASSWORD); - }); - describe("Navigation", () => { - beforeEach(() => cy.visit("/dashboard")); - it("displays intended global maintainer top navigation", () => { - cy.getAttached(".site-nav-container").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/software/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("exist"); - cy.findByText(/policies/i).should("exist"); - cy.getAttached(".user-menu").click(); - cy.findByText(/settings/i).should("not.exist"); - cy.findByText(/manage users/i).should("not.exist"); - }); - }); - }); - describe("Dashboard", () => { - beforeEach(() => dashboardPage.visitsDashboardPage()); - it("displays cards for all platforms and does not filter host platform", () => { - dashboardPage.displaysCards("All", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("none"); - }); - it("displays cards for windows only and filters hosts by Windows platform", () => { - dashboardPage.switchesPlatform("Windows"); - dashboardPage.displaysCards("Windows", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("Windows"); - }); - it("displays cards for linux only and filters hosts by Linux platform", () => { - dashboardPage.switchesPlatform("Linux"); - dashboardPage.displaysCards("Linux", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("Linux"); - }); - it("displays cards for macOS only and filters hosts by macOS platform", () => { - dashboardPage.switchesPlatform("macOS"); - dashboardPage.displaysCards("macOS", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("macOS"); - }); - }); - describe("Manage hosts page", () => { - beforeEach(() => manageHostsPage.visitsManageHostsPage()); - it("renders team elements", () => { - manageHostsPage.includesTeamDropdown(); - manageHostsPage.includesTeamColumn(); - }); - it("renders 'Add hosts', 'Add label', and 'Manage enroll secrets' buttons", () => { - manageHostsPage.allowsAddLabelForm(); - manageHostsPage.allowsAddHosts(); - manageHostsPage.allowsManageAndAddSecrets(); - }); - }); - describe("Host details page", () => { - beforeEach(() => { - hostDetailsPage.visitsHostDetailsPage(1); - }); - it("allows global maintainer to create an operating system policy", () => { - hostDetailsPage.allowsCreateOsPolicy(); - }); - }); - describe("Manage software page", () => { - beforeEach(() => manageSoftwarePage.visitManageSoftwarePage()); - it("hides 'Manage automations' button from global maintainer", () => { - manageSoftwarePage.hidesButton("Manage automations"); - }); - }); - describe("Query pages", () => { - beforeEach(() => manageQueriesPage.visitManageQueriesPage()); - it("allows global maintainer to select teams targets for query", () => { - manageQueriesPage.allowsSelectTeamTargets(); - }); - // TODO: Allowed to delete self-authored query only - }); - describe("Manage policies page", () => { - beforeEach(() => managePoliciesPage.visitManagePoliciesPage()); - it("hides manage automations button", () => { - managePoliciesPage.hidesButton("Manage automations"); - }); - it("allows global maintainer to add a new policy", () => { - managePoliciesPage.allowsAddDefaultPolicy(); - managePoliciesPage.verifiesAddedDefaultPolicy(); - }); - it("allows global maintainer to delete a team policy", () => { - teamsDropdown.switchTeams("All teams", "Apples"); - managePoliciesPage.allowsDeletePolicy(); - }); - it("allows global maintainer to edit a team policy", () => { - teamsDropdown.switchTeams("All teams", "Apples"); - managePoliciesPage.allowsSelectRunSavePolicy("filevault"); - }); - }); - describe("User profile page", () => { - it("verifies user role and global access", () => { - userProfilePage.visitUserProfilePage(); - userProfilePage.showRole("Maintainer", "Global"); - }); - }); - }); -}); diff --git a/cypress/integration/premium/observer.spec.ts b/cypress/integration/premium/observer.spec.ts deleted file mode 100644 index c255501be..000000000 --- a/cypress/integration/premium/observer.spec.ts +++ /dev/null @@ -1,173 +0,0 @@ -import CONSTANTS from "../../support/constants"; -import dashboardPage from "../pages/dashboardPage"; -import hostDetailsPage from "../pages/hostDetailsPage"; -import manageHostsPage from "../pages/manageHostsPage"; -import managePacksPage from "../pages/managePacksPage"; -import managePoliciesPage from "../pages/managePoliciesPage"; -import manageQueriesPage from "../pages/manageQueriesPage"; -import manageSchedulePage from "../pages/manageSchedulePage"; -import manageSoftwarePage from "../pages/manageSoftwarePage"; -import teamsDropdown from "../pages/teamsDropdown"; -import userProfilePage from "../pages/userProfilePage"; - -const { GOOD_PASSWORD } = CONSTANTS; - -describe("Premium tier - Observer user", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.seedPremium(); - cy.seedQueries(); - cy.seedPolicies("apples"); - cy.addDockerHost("apples"); - }); - - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - - describe("Global observer", () => { - beforeEach(() => { - cy.loginWithCySession("oliver@organization.com", GOOD_PASSWORD); - }); - describe("Navigation", () => { - beforeEach(() => cy.visit("/dashboard")); - it("displays intended global observer top navigation", () => { - cy.getAttached(".site-nav-container").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/software/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("not.exist"); - cy.findByText(/policies/i).should("exist"); - cy.getAttached(".user-menu").click(); - cy.findByText(/settings/i).should("not.exist"); - cy.findByText(/manage users/i).should("not.exist"); - }); - }); - }); - describe("Dashboard", () => { - beforeEach(() => dashboardPage.visitsDashboardPage()); - it("displays cards for all platforms and does not filter host platform", () => { - dashboardPage.displaysCards("All", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("none"); - }); - it("displays cards for windows only and filters hosts by Windows platform", () => { - dashboardPage.switchesPlatform("Windows"); - dashboardPage.displaysCards("Windows", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("Windows"); - }); - it("displays cards for linux only and filters hosts by Linux platform", () => { - dashboardPage.switchesPlatform("Linux"); - dashboardPage.displaysCards("Linux", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("Linux"); - }); - it("displays cards for macOS only and filters hosts by macOS platform", () => { - dashboardPage.switchesPlatform("macOS"); - dashboardPage.displaysCards("macOS", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("macOS"); - }); - }); - describe("Manage hosts page", () => { - beforeEach(() => manageHostsPage.visitsManageHostsPage()); - it("renders team elements", () => { - manageHostsPage.includesTeamDropdown(); - manageHostsPage.includesTeamColumn(); - }); - it("hides 'Add hosts', 'Add label', and 'Manage enroll secrets' buttons", () => { - manageHostsPage.hidesButton("Add label"); - manageHostsPage.hidesButton("Add hosts"); - manageHostsPage.hidesButton("Manage enroll secret"); - }); - }); - describe("Host details page", () => { - beforeEach(() => hostDetailsPage.visitsHostDetailsPage(1)); - it("should render elements according to role-based access controls", () => { - hostDetailsPage.verifiesTeam("Apples"); - hostDetailsPage.hidesCreateOSPolicy(); - }); - }); - describe("Manage software page", () => { - beforeEach(() => manageSoftwarePage.visitManageSoftwarePage()); - it("hides manage automations button", () => { - manageSoftwarePage.hidesButton("Manage automations"); - }); - }); - describe("Query pages", () => { - beforeEach(() => manageQueriesPage.visitManageQueriesPage()); - it("allows global observer to select teams targets for query", () => { - manageQueriesPage.allowsSelectTeamTargets(); - }); - }); - describe("Policies pages", () => { - beforeEach(() => managePoliciesPage.visitManagePoliciesPage()); - it("should render elements according to role-based access controls", () => { - // No global policies seeded, placeholder displayed - cy.findByText(/ask yes or no questions/i).should("exist"); - cy.findByText(/all your hosts/i).should("exist"); - - managePoliciesPage.hidesButton("Manage automations"); - managePoliciesPage.hidesButton("Add a policy"); - - teamsDropdown.switchTeams("All teams", "Apples"); - managePoliciesPage.hidesButton("Manage automations"); - managePoliciesPage.hidesButton("Add a policy"); - - managePoliciesPage.allowsViewPolicyOnly(); - }); - }); - }); - - describe("Team observer", () => { - beforeEach(() => { - cy.loginWithCySession("toni@organization.com", GOOD_PASSWORD); - }); - describe("Nav restrictions", () => { - it("should restrict navigation according to role-based access controls", () => { - // cypress tends to fail on uncaught exceptions. since we have - // our own error handling, it's suggested to use this block to - // suppress so the tests will keep running - Cypress.on("uncaught:exception", () => { - return false; - }); - cy.findByText(/settings/i).should("not.exist"); - cy.findByText(/schedule/i).should("not.exist"); - cy.visit("/settings/organization"); - cy.findByText(/you do not have permissions/i).should("exist"); - managePacksPage.visitsManagePacksPage(); - cy.findByText(/you do not have permissions/i).should("exist"); - manageSchedulePage.visitManageSchedulePage(); - cy.findByText(/you do not have permissions/i).should("exist"); - }); - }); - describe("Manage hosts page", () => { - it("should render elements according to role-based access controls", () => { - manageHostsPage.visitsManageHostsPage(); - manageHostsPage.includesTeamColumn(); - manageHostsPage.hidesButton("Add hosts"); - manageHostsPage.hidesButton("Manage enroll secret"); - manageHostsPage.hidesButton("Add label"); - }); - }); - describe("Manage policies page", () => { - it("hides 'Add a policy'", () => { - managePoliciesPage.visitManagePoliciesPage(); - managePoliciesPage.hidesButton("Add a policy"); - cy.findByText(/all teams/i).should("not.exist"); - }); - }); - describe("Policy detail page", () => { - it("allows viewing policies only", () => { - managePoliciesPage.visitManagePoliciesPage(); - managePoliciesPage.allowsViewPolicyOnly(); - }); - }); - describe("User profile page", () => { - it("verifies observer role and team", () => { - userProfilePage.visitUserProfilePage(); - userProfilePage.showRole("Observer", "Apples"); - }); - }); - }); -}); diff --git a/cypress/integration/premium/sso.spec.ts b/cypress/integration/premium/sso.spec.ts deleted file mode 100644 index 59bcc0c8a..000000000 --- a/cypress/integration/premium/sso.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -describe("SSO Sessions", () => { - describe("JIT user provisioning", () => { - before(() => { - cy.setup(); - }); - - beforeEach(() => { - Cypress.session.clearAllSavedSessions(); - }); - - it("non-existent users can't login if JIT is not enabled", () => { - cy.login(); - cy.setupSSO({ - enable_sso_idp_login: true, - enable_jit_provisioning: false, - }); - cy.logout(); - cy.visit("/"); - // Log in - cy.contains("button", "Sign on with SimpleSAML"); - cy.loginSSO({ username: "sso_user2" }); - cy.url().should("include", "/login?status=account_invalid"); - cy.getAttached(".flash-message"); - }); - - it("non-existent users are provisioned if JIT is enabled", () => { - cy.login(); - cy.setupSSO({ - enable_sso_idp_login: true, - enable_jit_provisioning: true, - }); - cy.logout(); - cy.visit("/"); - // Log in - cy.contains("button", "Sign on with SimpleSAML"); - cy.loginSSO({ username: "sso_user2" }); - cy.contains("Hosts"); - cy.contains("was added to Fleet by SSO"); - }); - - it("existing users can log-in normally with JIT enabled", () => { - cy.login(); - cy.setupSSO({ - enable_sso_idp_login: true, - enable_jit_provisioning: true, - }); - cy.logout(); - cy.visit("/"); - // Log in - cy.contains("button", "Sign on with SimpleSAML"); - cy.loginSSO({ username: "sso_user" }); - cy.contains("Hosts"); - }); - }); -}); diff --git a/cypress/integration/premium/team_admin.spec.ts b/cypress/integration/premium/team_admin.spec.ts deleted file mode 100644 index e4861e146..000000000 --- a/cypress/integration/premium/team_admin.spec.ts +++ /dev/null @@ -1,213 +0,0 @@ -import CONSTANTS from "../../support/constants"; -import dashboardPage from "../pages/dashboardPage"; -import hostDetailsPage from "../pages/hostDetailsPage"; -import manageHostsPage from "../pages/manageHostsPage"; -import managePoliciesPage from "../pages/managePoliciesPage"; -import manageQueriesPage from "../pages/manageQueriesPage"; -import manageSchedulePage from "../pages/manageSchedulePage"; -import manageSoftwarePage from "../pages/manageSoftwarePage"; -import userProfilePage from "../pages/userProfilePage"; - -const { GOOD_PASSWORD } = CONSTANTS; - -describe("Premium tier - Team Admin user", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.seedPremium(); - cy.seedQueries(); - cy.seedPolicies("apples"); - cy.addDockerHost("apples"); // host not transferred - cy.addDockerHost("oranges"); // host transferred between teams by global admin - }); - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - - beforeEach(() => { - cy.loginWithCySession("anita@organization.com", GOOD_PASSWORD); - }); - describe("Navigation", () => { - beforeEach(() => cy.visit("/dashboard")); - it("displays intended team admin top navigation", () => { - cy.getAttached(".site-nav-container").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/software/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("exist"); - cy.findByText(/policies/i).should("exist"); - cy.getAttached(".user-menu").click(); - cy.findByText(/manage users/i).should("not.exist"); - cy.findByText(/settings/i).click(); - }); - cy.getAttached(".react-tabs__tab--selected").within(() => { - cy.findByText(/members/i).should("exist"); - }); - cy.getAttached(".react-tabs__tab-list").within(() => { - cy.findByText(/agent options/i).should("exist"); - }); - }); - }); - describe("Dashboard", () => { - beforeEach(() => cy.visit("/dashboard")); - it("displays cards for team only, no activity card, and does not filter host platform", () => { - dashboardPage.displaysCards("team", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("none"); - }); - it("displays cards for windows only and filters hosts by Windows platform", () => { - dashboardPage.switchesPlatform("Windows"); - dashboardPage.displaysCards("Windows", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("Windows"); - }); - it("displays cards for linux only and filters hosts by Linux platform", () => { - dashboardPage.switchesPlatform("Linux"); - dashboardPage.displaysCards("Linux", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("Linux"); - }); - it("displays cards for macOS only and filters hosts by macOS platform", () => { - dashboardPage.switchesPlatform("macOS"); - dashboardPage.displaysCards("macOS", "premium"); - dashboardPage.verifiesFilteredHostByPlatform("macOS"); - }); - }); - describe("Manage hosts page", () => { - beforeEach(() => { - manageHostsPage.visitsManageHostsPage(); - }); - it("should render elements according to role-based access controls", () => { - manageHostsPage.includesTeamColumn(); - manageHostsPage.allowsAddHosts(); - manageHostsPage.allowsManageAndAddSecrets(); - }); - }); - describe("Host details page", () => { - beforeEach(() => hostDetailsPage.visitsHostDetailsPage(1)); - it("allows team admin to create an operating system policy", () => { - hostDetailsPage.allowsCreateOsPolicy(); - }); - }); - describe("Manage software page", () => { - beforeEach(() => manageSoftwarePage.visitManageSoftwarePage()); - it("hides manage automations button", () => { - manageSoftwarePage.hidesButton("Manage automations"); - }); - }); - describe("Query pages", () => { - beforeEach(() => manageQueriesPage.visitManageQueriesPage()); - it("allows team admin to select teams targets for query", () => { - manageQueriesPage.allowsSelectTeamTargets(); - }); - it("disables team admin from deleting or editing a query not authored by them", () => { - cy.getAttached("tbody").within(() => { - cy.getAttached("tr") - .first() - .within(() => { - cy.getAttached(".fleet-checkbox__input").should("be.disabled"); - }); - cy.findAllByText(/detect presence/i).click(); - }); - cy.findByRole("button", { name: "Save" }).should("be.disabled"); - }); - }); - describe("Manage schedules page", () => { - beforeEach(() => { - manageSchedulePage.visitManageSchedulePage(); - }); - it("hides advanced button when team admin", () => { - manageSchedulePage.confirmsTeam("Apples"); - manageSchedulePage.hidesButton("Advanced"); - }); - it("creates a new team scheduled query", () => { - manageSchedulePage.allowsAddSchedule(); - manageSchedulePage.verifiesAddedSchedule(); - }); - it("edit a team's scheduled query successfully", () => { - manageSchedulePage.allowsEditSchedule(); - manageSchedulePage.verifiesEditedSchedule(); - }); - it("remove a team's scheduled query successfully", () => { - manageSchedulePage.allowsRemoveSchedule(); - manageSchedulePage.verifiesRemovedSchedule(); - }); - }); - describe("Manage policies page", () => { - beforeEach(() => managePoliciesPage.visitManagePoliciesPage()); - it("allows team admin to add a new policy", () => { - managePoliciesPage.allowsAddDefaultPolicy(); - managePoliciesPage.verifiesAddedDefaultPolicy(); - }); - it("allows team admin to edit a team policy", () => { - managePoliciesPage.visitManagePoliciesPage(); - managePoliciesPage.allowsSelectRunSavePolicy(); - }); - it("allows team admin to automate a team policy", () => { - managePoliciesPage.allowsAutomatePolicy(); - managePoliciesPage.verifiesAutomatedPolicy(); - }); - it("allows team admin to delete a team policy", () => { - managePoliciesPage.allowsDeletePolicy(); - }); - }); - describe("Team admin settings page", () => { - beforeEach(() => cy.visit("/settings/teams/1/members")); - it("allows team admin to access team settings", () => { - // Access the Settings - Team details page - cy.findByText(/apples/i).should("exist"); - }); - it("displays the team admin controls", () => { - cy.findByRole("button", { name: /create user/i }).click({ force: true }); - cy.findByRole("button", { name: /cancel/i }).click(); - cy.findByRole("button", { name: /add hosts/i }).click(); - cy.findByRole("button", { name: /done/i }).click(); - cy.findByRole("button", { name: /manage enroll secrets/i }).click(); - cy.findByRole("button", { name: /done/i }).click(); - }); - it("allows team admin to edit a team member", () => { - cy.getAttached("tbody").within(() => { - cy.getAttached("tr"); - cy.contains("Toni") // case-sensitive - .parent() - .next() - .within(() => { - cy.findByText(/observer/i).should("exist"); - }) - .next() - .next() - .within(() => { - cy.findByText(/action/i).click(); - cy.findByText(/edit/i).click(); - }); - }); - cy.getAttached(".select-role-form__role-dropdown").within(() => { - cy.findByText(/observer/i).click(); - cy.findByText(/maintainer/i).click(); - }); - cy.findByRole("button", { name: /save/i }).click(); - cy.getAttached("tbody").within(() => { - cy.getAttached("tr"); - cy.contains("Toni") // case-sensitive - .parent() - .next() - .within(() => { - cy.findByText(/maintainer/i).should("exist"); - }); - }); - }); - it("allows team admin to edit team name", () => { - cy.findByRole("button", { name: /edit team/i }).click(); - cy.findByLabelText(/team name/i) - .clear() - .type("Mystic"); - cy.findByRole("button", { name: /save/i }).click(); - cy.findByText(/updated team name/i).should("exist"); - }); - }); - describe("User profile page", () => { - it("should render elements according to role-based access controls", () => { - userProfilePage.visitUserProfilePage(); - userProfilePage.showRole("Admin", "Mystic"); - }); - }); -}); diff --git a/cypress/integration/premium/team_maintainer_observer.spec.ts b/cypress/integration/premium/team_maintainer_observer.spec.ts deleted file mode 100644 index 5a3ece98a..000000000 --- a/cypress/integration/premium/team_maintainer_observer.spec.ts +++ /dev/null @@ -1,220 +0,0 @@ -import CONSTANTS from "../../support/constants"; -import dashboardPage from "../pages/dashboardPage"; -import manageHostsPage from "../pages/manageHostsPage"; -import managePacksPage from "../pages/managePacksPage"; -import managePoliciesPage from "../pages/managePoliciesPage"; -import manageSchedulePage from "../pages/manageSchedulePage"; -import manageSoftwarePage from "../pages/manageSoftwarePage"; -import teamsDropdown from "../pages/teamsDropdown"; -import userProfilePage from "../pages/userProfilePage"; - -const { GOOD_PASSWORD } = CONSTANTS; - -describe("Premium tier - Team observer/maintainer user", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.seedPremium(); - cy.seedQueries(); - cy.seedPolicies("apples"); - cy.addDockerHost("apples"); - cy.addDockerHost("oranges"); - }); - after(() => { - cy.logout(); - cy.stopDockerHost(); - }); - describe("Team maintainer and team observer", () => { - beforeEach(() => { - cy.loginWithCySession("marco@organization.com", GOOD_PASSWORD); - }); - describe("Navigation", () => { - beforeEach(() => cy.visit("/dashboard")); - it("displays intended team maintainer and team observer top navigation", () => { - cy.getAttached(".site-nav-container").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/software/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("exist"); - cy.findByText(/policies/i).should("exist"); - cy.getAttached(".user-menu").click(); - cy.findByText(/settings/i).should("not.exist"); - cy.findByText(/manage users/i).should("not.exist"); - }); - }); - }); - describe("Dashboard", () => { - beforeEach(() => dashboardPage.visitsDashboardPage()); - it("displays cards for all platforms", () => { - dashboardPage.displaysCards("team", "premium"); - }); - it("displays cards for windows only", () => { - dashboardPage.switchesPlatform("Windows"); - dashboardPage.displaysCards("Windows", "premium"); - }); - it("displays cards for linux only", () => { - dashboardPage.switchesPlatform("Linux"); - dashboardPage.displaysCards("Linux", "premium"); - }); - it("displays cards for macOS only", () => { - dashboardPage.switchesPlatform("macOS"); - dashboardPage.displaysCards("macOS", "premium"); - }); - it("views all hosts for all platforms", () => { - cy.findByText(/view all hosts/i).click(); - cy.findByRole("status", { name: /hosts filtered by/i }).should( - "not.exist" - ); - }); - it("views all hosts for windows only", () => { - cy.getAttached(".dashboard-page__platforms").within(() => { - cy.getAttached(".Select-control").click(); - cy.findByText(/windows/i).click(); - }); - cy.findByText(/view all hosts/i).click(); - cy.findByRole("status", { name: /hosts filtered by Windows/i }).should( - "exist" - ); - }); - it("views all hosts for linux only", () => { - cy.getAttached(".dashboard-page__platforms").within(() => { - cy.getAttached(".Select-control").click(); - cy.findByText(/linux/i).click(); - }); - cy.findByText(/view all hosts/i).click(); - cy.findByRole("status", { name: /hosts filtered by Linux/i }).should( - "exist" - ); - }); - it("views all hosts for macOS only", () => { - cy.getAttached(".dashboard-page__platforms").within(() => { - cy.getAttached(".Select-control").click(); - cy.findByText(/macos/i).click(); - }); - cy.findByText(/view all hosts/i).click(); - cy.findByRole("status", { name: /hosts filtered by macOS/i }).should( - "exist" - ); - }); - }); - }); - describe("Team observer", () => { - beforeEach(() => { - cy.loginWithCySession("marco@organization.com", GOOD_PASSWORD); - }); - describe("Manage hosts page", () => { - it("should render elements according to role-based access controls", () => { - manageHostsPage.visitsManageHostsPage(); - - cy.contains(/apples/i).should("exist"); - manageHostsPage.includesTeamColumn(); - - manageHostsPage.hidesButton("Add label"); - manageHostsPage.hidesButton("Add hosts"); - manageHostsPage.hidesButton("Manage enroll secrets"); - }); - }); - describe("Manage policies page", () => { - it("hides 'Manage automation' and 'Add a policy' buttons", () => { - managePoliciesPage.visitManagePoliciesPage(); - cy.contains(/apples/i).should("exist"); - - managePoliciesPage.hidesButton("Manage automations"); - managePoliciesPage.hidesButton("Add a policy"); - }); - }); - describe("Policy detail page", () => { - it("allows view policy only", () => { - managePoliciesPage.visitManagePoliciesPage(); - managePoliciesPage.allowsViewPolicyOnly(); - }); - }); - // nav restrictions are at the end because we expect to see a - // 403 error overlay which will hide the nav and make the test fail - describe("Nav restrictions", () => { - it("should restrict navigation according to role-based access controls", () => { - dashboardPage.visitsDashboardPage(); - cy.findByText(/settings/i).should("not.exist"); - cy.findByText(/schedule/i).should("exist"); - cy.visit("/settings/organization"); - cy.findByText(/you do not have permissions/i).should("exist"); - managePacksPage.visitsManagePacksPage(); - cy.findByText(/you do not have permissions/i).should("exist"); - }); - }); - }); - - describe("Team maintainer", () => { - // cypress tends to fail on uncaught exceptions. since we have - // our own error handling, it's suggested to use this block to - // suppress so the tests will keep running - Cypress.on("uncaught:exception", () => { - return false; - }); - - beforeEach(() => { - cy.loginWithCySession("marco@organization.com", GOOD_PASSWORD); - manageHostsPage.visitsManageHostsPage(); - }); - describe("Manage hosts page", () => { - it("should render elements according to role-based access controls", () => { - manageHostsPage.includesTeamColumn(); - manageHostsPage.hidesButton("Add label"); - - // On maintaining team, see the "add hosts" and "Manage enroll secret" buttons - teamsDropdown.switchTeams("Apples", "Oranges"); - manageHostsPage.includesTeamDropdown("Oranges"); - manageHostsPage.allowsAddHosts(); - manageHostsPage.allowsManageAndAddSecrets(); - }); - }); - describe("Manage software page", () => { - beforeEach(() => manageSoftwarePage.visitManageSoftwarePage()); - it("hides manage automations button", () => { - manageSoftwarePage.hidesButton("Manage automations"); - }); - }); - describe("Manage schedule page", () => { - it("should render elements according to role-based access controls", () => { - manageSchedulePage.visitManageSchedulePage(); - manageSchedulePage.confirmsTeam("Oranges"); - manageSchedulePage.hidesButton("Advanced"); - manageSchedulePage.allowsAddSchedule(); - manageSchedulePage.verifiesAddedSchedule(); - }); - }); - describe("Manage policies page", () => { - it("allows team maintainer to add, edit a policy, but not manage automation", () => { - managePoliciesPage.visitManagePoliciesPage(); - teamsDropdown.switchTeams("Apples", "Oranges"); - - managePoliciesPage.hidesButton("Manage automations"); - managePoliciesPage.allowsAddDefaultPolicy(); - managePoliciesPage.verifiesAddedDefaultPolicy(); - }); - }); - describe("User profile page", () => { - it("verifies user role and team", () => { - userProfilePage.visitUserProfilePage(); - userProfilePage.showRole("Various", "2 teams"); - }); - }); - // nav restrictions are at the end because we expect to see a - // 403 error overlay which will hide the nav and make the test fail - describe("Nav restrictions", () => { - it("should restrict navigation according to role-based access controls", () => { - dashboardPage.visitsDashboardPage(); - - cy.contains("h2", "Hosts").should("exist"); - cy.getAttached("nav").within(() => { - cy.findByText(/hosts/i).should("exist"); - cy.findByText(/queries/i).should("exist"); - cy.findByText(/schedule/i).should("exist"); - cy.findByText(/packs/i).should("not.exist"); - cy.findByText(/settings/i).should("not.exist"); - }); - }); - }); - }); -}); diff --git a/cypress/integration/premium/teamflow.spec.ts b/cypress/integration/premium/teamflow.spec.ts deleted file mode 100644 index b93d49ac4..000000000 --- a/cypress/integration/premium/teamflow.spec.ts +++ /dev/null @@ -1,147 +0,0 @@ -import manageSchedulePage from "../pages/manageSchedulePage"; - -describe("Teams flow (empty)", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - describe("Teams settings page", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.visit("/settings/teams"); - }); - it("creates a new team", () => { - cy.getAttached(".empty-table__cta-buttons").within(() => { - cy.contains("button", /create team/i).click(); - }); - cy.findByLabelText(/team name/i) - .click() - .type("Valor"); - cy.getAttached(".create-team-modal .modal-cta-wrap").within(() => { - // ^$ forces exact match - cy.findByRole("button", { name: /^create$/i }).click(); - }); - cy.findByText(/successfully created valor/i).should("exist"); - }); - }); -}); - -describe("Teams flow (seeded)", () => { - before(() => { - Cypress.session.clearAllSavedSessions(); - cy.setup(); - cy.loginWithCySession(); - cy.seedPremium(); - cy.seedQueries(); - cy.viewport(1200, 660); - }); - after(() => { - cy.logout(); - }); - describe("Teams settings page", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.visit("/settings/teams"); - }); - it("edits name of an existing team", () => { - cy.getAttached(".table-container").within(() => { - cy.contains("Apples"); - cy.getAttached("tbody").within(() => { - cy.getAttached("tr") - .first() - .within(() => { - cy.getAttached(".Select-arrow-zone").click(); - cy.findByText(/edit/i).click({ force: true }); - }); - }); - }); - cy.getAttached(".edit-team-modal").within(() => { - cy.findByLabelText(/team name/i) - .clear() - .type("Bananas"); - cy.findByRole("button", { name: /save/i }).click(); - }); - cy.findByText(/updated team name/i).should("be.visible"); - cy.findByText(/apples/i).should("not.exist"); - }); - it("deletes an existing team", () => { - cy.getAttached(".table-container").within(() => { - cy.contains("Bananas"); - cy.getAttached("tbody").within(() => { - cy.getAttached("tr") - .first() - .within(() => { - cy.getAttached(".Select-arrow-zone").click(); - cy.findByText(/delete/i).click({ force: true }); - }); - }); - }); - cy.getAttached(".delete-team-modal .modal-cta-wrap").within(() => { - cy.findByRole("button", { name: /delete/i }).click(); - }); - cy.findByText(/successfully deleted/i).should("be.visible"); - cy.findByText(/bananas/i).should("not.exist"); - }); - }); - describe("Manage schedules page", () => { - beforeEach(() => { - cy.loginWithCySession(); - manageSchedulePage.visitManageSchedulePage(); - }); - it("adds a query to team schedule", () => { - manageSchedulePage.changesTeam("All teams", "Oranges"); - manageSchedulePage.allowsAddSchedule(); - manageSchedulePage.verifiesAddedSchedule(); - }); - }); - describe("Team details page", () => { - beforeEach(() => { - cy.loginWithCySession(); - cy.visit("/settings/teams"); - cy.getAttached(".table-container").within(() => { - cy.contains("Oranges").click({ force: true }); - }); - }); - it("allows to add new enroll secret to team", () => { - cy.getAttached(".team-details__action-buttons--secondary-buttons") - .contains("button", /manage enroll secret/i) - .click(); - cy.getAttached(".enroll-secret-modal__add-secret") - .contains("button", /add secret/i) - .click(); - cy.getAttached(".secret-editor-modal .modal-cta-wrap") - .contains("button", /save/i) - .click(); - cy.getAttached(".enroll-secret-modal .modal-cta-wrap") - .contains("button", /done/i) - .click(); - }); - it("allows to see and click 'Add hosts'", () => { - cy.getAttached(".team-details__action-buttons--primary") - .contains("button", /add hosts/i) - .click(); - cy.getAttached(".modal__content").contains("button", /done/i).click(); - }); - it("edits agent options of an existing team", () => { - cy.findByText(/agent options/i).click(); - cy.contains(".ace_content", "config:"); - cy.getAttached(".ace_text-input") - .first() - .focus() - .type("{selectall}{backspace}config:\n options:"); - - cy.findByRole("button", { name: /save options/i }).click(); - - cy.contains("span", /successfully updated/i).should("exist"); - cy.visit("/settings/teams/2/options"); - - cy.contains(/config:/i).should("be.visible"); - cy.contains(/options:/i).should("be.visible"); - }); - }); -}); diff --git a/cypress/pages/appSettingsPage.ts b/cypress/pages/appSettingsPage.ts deleted file mode 100644 index 182efa906..000000000 --- a/cypress/pages/appSettingsPage.ts +++ /dev/null @@ -1,12 +0,0 @@ -const AppSettingsPage = { - visitAgentOptions: () => { - cy.visit("/settings/organization/agents"); - }, - - editAgentOptionsForm: (text: string) => { - cy.findByRole("textbox").type(text, { force: true }); - cy.findByRole("button", { name: /save/i }).should("be.enabled").click(); - }, -}; - -export default AppSettingsPage; diff --git a/cypress/pages/teamSettingsPage.ts b/cypress/pages/teamSettingsPage.ts deleted file mode 100644 index 9ce5a36bf..000000000 --- a/cypress/pages/teamSettingsPage.ts +++ /dev/null @@ -1,12 +0,0 @@ -const TeamSettingsPage = { - visitTeamAgentOptions: (id: number) => { - cy.visit(`settings/teams/${id}/options`); - }, - - editAgentOptionsForm: (text: string) => { - cy.findByRole("textbox").type(text, { force: true }); - cy.findByRole("button", { name: /save/i }).click(); - }, -}; - -export default TeamSettingsPage; diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index 9c3928040..000000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,21 +0,0 @@ -// -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -/** - * @type {Cypress.PluginConfig} - */ -module.exports = () => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -}; diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts deleted file mode 100644 index f48dea747..000000000 --- a/cypress/support/commands.ts +++ /dev/null @@ -1,489 +0,0 @@ -import "@testing-library/cypress/add-commands"; -import "cypress-wait-until"; -import CONSTANTS from "./constants"; - -const { GOOD_PASSWORD } = CONSTANTS; - -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) - -const SHELL = Cypress.platform === "win32" ? "cmd" : "bash"; - -Cypress.Commands.add("setup", () => { - cy.exec("make e2e-reset-db e2e-setup", { - timeout: 20000, - env: { SHELL }, - }); -}); - -Cypress.Commands.add("setupWithSoftware", () => { - cy.exec("make e2e-reset-db e2e-setup-with-software", { - timeout: 20000, - env: { SHELL }, - }); -}); - -Cypress.Commands.add("login", (email, password) => { - email ||= "admin@example.com"; - password ||= GOOD_PASSWORD; - cy.request("POST", "/api/latest/fleet/login", { email, password }).then( - (resp) => { - window.localStorage.setItem("FLEET::auth_token", resp.body.token); - } - ); -}); - -Cypress.Commands.add("loginWithCySession", (email, password) => { - email ||= "admin@example.com"; - password ||= GOOD_PASSWORD; - cy.session([email, password], () => { - cy.request("POST", "/api/latest/fleet/login", { email, password }).then( - (resp) => { - window.localStorage.setItem("FLEET::auth_token", resp.body.token); - } - ); - }); -}); - -Cypress.Commands.add("logout", () => { - cy.request({ - url: "/api/latest/fleet/logout", - method: "POST", - body: {}, - auth: { - bearer: window.localStorage.getItem("FLEET::auth_token"), - }, - }).then(() => { - window.localStorage.removeItem("FLEET::auth_token"); - }); -}); - -Cypress.Commands.add("setDesktopToken", (hostId, token) => { - cy.exec(`make e2e-set-desktop-token host_id=${hostId} token=${token}`, { - timeout: 20000, - env: { SHELL }, - }); -}); - -Cypress.Commands.add("seedQueries", () => { - const queries = [ - { - name: "Detect presence of authorized SSH keys", - query: - "SELECT username, authorized_keys. * FROM users CROSS JOIN authorized_keys USING (uid)", - description: - "Presence of authorized SSH keys may be unusual on laptops. Could be completely normal on servers, but may be worth auditing for unusual keys and/or changes.", - observer_can_run: true, - }, - { - name: "Get authorized keys for Domain Joined Accounts", - query: - "SELECT * FROM users CROSS JOIN authorized_keys USING(uid) WHERE username IN (SELECT distinct(username) FROM last);", - description: "List authorized_keys for each user on the system.", - observer_can_run: false, - }, - { - name: "Get local user accounts", - query: - "SELECT uid, gid, username, description,directory, shell FROM users;", - description: - "Local user accounts (including domain accounts that have logged on locally (Windows)).", - observer_can_run: false, - }, - ]; - - queries.forEach((queryForm) => { - const { name, query, description, observer_can_run } = queryForm; - cy.request({ - url: "/api/latest/fleet/queries", - method: "POST", - body: { name, query, description, observer_can_run }, - auth: { - bearer: window.localStorage.getItem("FLEET::auth_token"), - }, - }); - }); -}); - -Cypress.Commands.add("seedSchedule", () => { - const scheduledQueries = [ - { - interval: 86400, - platform: "", - query_id: 1, - removed: false, - shard: null, - snapshot: true, - version: "", - }, - { - interval: 604800, - platform: "linux", - query_id: 2, - removed: true, - shard: 50, - snapshot: false, - version: "4.6.0", - }, - ]; - - scheduledQueries.forEach((scheduleForm) => { - const { - interval, - platform, - query_id, - removed, - shard, - snapshot, - version, - } = scheduleForm; - cy.request({ - url: "/api/latest/fleet/schedule", - method: "POST", - body: { interval, platform, query_id, removed, shard, snapshot, version }, - auth: { - bearer: window.localStorage.getItem("FLEET::auth_token"), - }, - }); - }); -}); - -// @ts-ignore -Cypress.Commands.add("seedPacks", () => { - const packs = [ - { - name: "Mac starter pack", - description: "Run all queries weekly on Mac hosts", - }, - { - name: "Windows starter pack", - description: "Run all queries weekly on Windows hosts", - }, - ]; - - packs.forEach((packForm) => { - const { name, description } = packForm; - cy.request({ - url: "/api/latest/fleet/packs", - method: "POST", - body: { name, description, host_ids: [], label_ids: [], team_ids: [] }, - auth: { - bearer: window.localStorage.getItem("FLEET::auth_token"), - }, - }); - }); -}); - -Cypress.Commands.add("seedPolicies", (team = "") => { - const policies = [ - { - name: "Is Filevault enabled on macOS devices?", - query: - "SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT '' AND filevault_status = 'on' LIMIT 1", - description: - "Checks to make sure that the Filevault feature is enabled on macOS devices.", - resolution: - "Choose Apple menu > System Preferences, then click Security & Privacy. Click the FileVault tab. Click the Lock icon, then enter an administrator name and password. Click Turn On FileVault.", - platform: "darwin,linux", - }, - { - name: "Is Ubuntu, version 20.4.0 installed?", - query: - "SELECT 1 from os_version WHERE name = 'Ubuntu' AND major || '.' || minor || '.' || patch = '20.4.0';", - description: - "Returns yes or no for detecting operating system and version", - resolution: "Update OS if needed", - platform: "darwin,windows,linux", - }, - { - name: "Is Ubuntu, version 16.4.0 or later, installed?", - query: - "SELECT 1 from os_version WHERE name = 'Ubuntu' AND major || '.' || minor || '.' || patch >= '16.4.0';", - description: - "Returns yes or no for detecting operating system and version", - resolution: "Update OS if needed", - platform: "", - }, - ]; - - if (team === "apples") { - policies.forEach((policyForm) => { - cy.request({ - url: "/api/latest/fleet/teams/1/policies", - method: "POST", - body: { ...policyForm }, - auth: { - bearer: window.localStorage.getItem("FLEET::auth_token"), - }, - }); - }); - } else { - policies.forEach((policyForm) => { - cy.request({ - url: "/api/latest/fleet/policies", - method: "POST", - body: { ...policyForm }, - auth: { - bearer: window.localStorage.getItem("FLEET::auth_token"), - }, - }); - }); - } -}); - -Cypress.Commands.add("setupSMTP", () => { - const body = { - smtp_settings: { - authentication_type: "authtype_none", - enable_smtp: true, - port: 1025, - sender_address: "fleet@example.com", - server: "localhost", - }, - }; - - cy.request({ - url: "/api/latest/fleet/config", - method: "PATCH", - body, - auth: { - bearer: window.localStorage.getItem("FLEET::auth_token"), - }, - }); -}); - -Cypress.Commands.add("setupSSO", (options) => { - const body = { - sso_settings: Object.assign( - {}, - { - enable_sso: true, - enable_sso_idp_login: false, - enable_jit_provisioning: false, - entity_id: "https://localhost:8080", - idp_name: "SimpleSAML", - issuer_uri: "http://localhost:8080/simplesaml/saml2/idp/SSOService.php", - metadata_url: "http://localhost:9080/simplesaml/saml2/idp/metadata.php", - }, - options - ), - }; - - cy.request({ - url: "/api/latest/fleet/config", - method: "PATCH", - body, - auth: { - bearer: window.localStorage.getItem("FLEET::auth_token"), - }, - }); -}); - -Cypress.Commands.add( - "loginSSO", - ({ username = "sso_user", password = "user123#" } = {}) => { - // Note these requests set cookies that are required for the SSO flow to - // work properly. This is handled automatically by the browser. - cy.request({ - method: "GET", - url: - "http://localhost:9080/simplesaml/saml2/idp/SSOService.php?spentityid=https://localhost:8080", - followRedirect: false, - }).then((firstResponse) => { - const redirect = firstResponse.headers.location as string; - - cy.request({ - method: "GET", - url: redirect, - followRedirect: false, - }).then((secondResponse) => { - const el = document.createElement("html"); - el.innerHTML = secondResponse.body; - const authState = el - .getElementsByTagName("input") - .namedItem("AuthState").defaultValue; - - cy.request({ - method: "POST", - url: redirect, - body: `username=${username}&password=${password}&AuthState=${authState}`, - form: true, - followRedirect: false, - }).then((finalResponse) => { - el.innerHTML = finalResponse.body; - const saml = el - .getElementsByTagName("input") - .namedItem("SAMLResponse").defaultValue; - - // Load the callback URL with the response from the IdP - cy.visit({ - url: "/api/v1/fleet/sso/callback", - method: "POST", - body: { - SAMLResponse: saml, - }, - }); - }); - }); - }); - } -); - -Cypress.Commands.add("getEmails", () => { - return cy - .request("http://localhost:8025/api/v2/messages") - .then((response) => { - expect(response.status).to.eq(200); - return response; - }); -}); - -Cypress.Commands.add("seedFree", () => { - const authToken = window.localStorage.getItem("FLEET::auth_token"); - cy.exec("bash ./tools/api/fleet/teams/create_free", { - env: { - TOKEN: authToken, - CURL_FLAGS: "-k", - SERVER_URL: Cypress.config().baseUrl, - // clear any value for FLEET_ENV_PATH since we set the environment explicitly just above - FLEET_ENV_PATH: "", - SHELL, - }, - }); -}); - -Cypress.Commands.add("seedPremium", () => { - const authToken = window.localStorage.getItem("FLEET::auth_token"); - cy.exec("bash ./tools/api/fleet/teams/create_premium", { - env: { - TOKEN: authToken, - CURL_FLAGS: "-k", - SERVER_URL: Cypress.config().baseUrl, - // clear any value for FLEET_ENV_PATH since we set the environment explicitly just above - FLEET_ENV_PATH: "", - SHELL, - }, - }); -}); - -Cypress.Commands.add("seedFigma", () => { - const authToken = window.localStorage.getItem("FLEET::auth_token"); - cy.exec("bash ./tools/api/fleet/teams/create_figma", { - env: { - TOKEN: authToken, - CURL_FLAGS: "-k", - SERVER_URL: Cypress.config().baseUrl, - // clear any value for FLEET_ENV_PATH since we set the environment explicitly just above - FLEET_ENV_PATH: "", - SHELL, - }, - }); -}); - -Cypress.Commands.add("addUser", (options = {}) => { - let { password, email, globalRole } = options; - password ||= GOOD_PASSWORD; - email ||= `admin@example.com`; - globalRole ||= "admin"; - - cy.exec( - `./build/fleetctl user create --context e2e --password "${password}" --email "${email}" --global-role "${globalRole}"`, - { - timeout: 5000, - env: { SHELL }, - } - ); -}); - -// Ability to add a docker host to a team using args if ran after seedPremium() -Cypress.Commands.add("addDockerHost", (team = "") => { - const serverPort = new URL(Cypress.config().baseUrl).port; - // Get enroll secret - let enrollSecretUrl = "/api/latest/fleet/spec/enroll_secret"; - if (team === "apples") { - enrollSecretUrl = "/api/latest/fleet/teams/1/secrets"; - } else if (team === "oranges") { - enrollSecretUrl = "/api/latest/fleet/teams/2/secrets"; - } - - cy.request({ - url: enrollSecretUrl, - auth: { - bearer: window.localStorage.getItem("FLEET::auth_token"), - }, - }).then(({ body }) => { - const enrollSecret = - team === "" ? body.spec.secrets[0].secret : body.secrets[0].secret; - - // Start up docker-compose with enroll secret - cy.exec( - "docker-compose -f tools/osquery/docker-compose.yml up -d ubuntu20-osquery", - { - env: { - ENROLL_SECRET: enrollSecret, - FLEET_SERVER: `host.docker.internal:${serverPort}`, - SHELL, - }, - } - ); - }); -}); - -Cypress.Commands.add("stopDockerHost", () => { - // Start up docker-compose with enroll secret - cy.exec("docker-compose -f tools/osquery/docker-compose.yml stop", { - env: { - // Not that ENROLL_SECRET must be specified or docker-compose errors, - // even when just trying to shut down the hosts. - ENROLL_SECRET: "invalid", - SHELL, - }, - }); -}); - -Cypress.Commands.add("clearDownloads", () => { - // windows has issue with downloads location - if (Cypress.platform !== "win32") { - cy.exec(`rm -rf ${Cypress.config("downloadsFolder")}`, { env: { SHELL } }); - } -}); - -Cypress.Commands.add("getAttached", (selector) => { - const uniqueAlias = `element_${selector}`; - - return cy - .waitUntil( - () => - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy - .get(selector) - .as(uniqueAlias) - .wait(1) - .then(($el) => Cypress.dom.isAttached($el)), - { timeout: 10000, interval: 10 } - ) - .get(`@${uniqueAlias}`); -}); diff --git a/cypress/support/constants.ts b/cypress/support/constants.ts deleted file mode 100644 index 958ca0f94..000000000 --- a/cypress/support/constants.ts +++ /dev/null @@ -1,245 +0,0 @@ -const GOOD_PASSWORD = "password123#"; -const BAD_PASSWORD_LENGTH = "password12#"; -const BAD_PASSWORD_NO_NUMBER = "password####"; -const BAD_PASSWORD_NO_SYMBOL = "password1234"; -const CONFIG_INTEGRATIONS_AUTOMATIONS = { - org_info: { - org_name: "Fleet Test", - org_logo_url: "", - }, - server_settings: { - server_url: "https://localhost:8642", - live_query_disabled: false, - enable_analytics: true, - deferred_save_host: false, - }, - smtp_settings: { - enable_smtp: false, - configured: false, - sender_address: "", - server: "", - port: 587, - authentication_type: "authtype_username_password", - user_name: "", - password: "", - enable_ssl_tls: true, - authentication_method: "authmethod_plain", - domain: "", - verify_ssl_certs: true, - enable_start_tls: true, - }, - host_expiry_settings: { - host_expiry_enabled: true, - host_expiry_window: 9, - }, - features: { - enable_host_users: true, - enable_software_inventory: true, - }, - agent_options: { - config: { - options: { - pack_delimiter: "/", - logger_tls_period: 10, - distributed_plugin: "tls", - disable_distributed: false, - logger_tls_endpoint: "/api/osquery/log", - distributed_interval: 10, - distributed_tls_max_attempts: 3, - }, - decorators: { - load: [ - "SELECT uuid AS host_uuid FROM system_info;", - "SELECT hostname AS hostname FROM system_info;", - ], - }, - }, - overrides: {}, - }, - sso_settings: { - entity_id: "", - issuer_uri: "", - idp_image_url: "", - metadata: "", - metadata_url: "", - idp_name: "", - enable_sso: false, - enable_sso_idp_login: false, - enable_jit_provisioning: false, - }, - vulnerability_settings: { - databases_path: "", - }, - webhook_settings: { - host_status_webhook: { - enable_host_status_webhook: false, - destination_url: "", - host_percentage: 0, - days_count: 0, - }, - failing_policies_webhook: { - enable_failing_policies_webhook: false, - destination_url: "https://www.foo.com/bar", - policy_ids: [5, 10], - host_batch_size: 0, - }, - vulnerabilities_webhook: { - enable_vulnerabilities_webhook: false, - destination_url: "", - host_batch_size: 0, - }, - interval: "24h0m0s", - }, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira1@example.com", - api_token: "jira123", - project_key: "PROJECT 1", - enable_failing_policies: true, - enable_software_vulnerabilities: true, - }, - { - url: "https://fleetdm.atlassian.com", - username: "jira2@example.com", - api_token: "jira123", - project_key: "PROJECT 2", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.zendesk.com", - email: "zendesk2@example.com", - api_token: "zendesk123", - group_id: 87654321, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - }, - update_interval: { - osquery_detail: 3600000000000, - osquery_policy: 3600000000000, - }, - vulnerabilities: { - databases_path: "/tmp/vulndbs", - periodicity: 3600000000000, - cpe_database_url: "", - cve_feed_prefix_url: "", - current_instance_checks: "auto", - disable_data_sync: false, - recent_vulnerability_max_age: 2592000000000000, - }, - license: { - tier: "premium", - organization: "development-only", - device_count: 100, - expiration: "2099-06-30T20:00:00-04:00", - note: "for development only", - }, - logging: { - debug: false, - json: false, - result: { - plugin: "filesystem", - config: { - status_log_file: - "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_status", - result_log_file: - "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_result", - enable_log_rotation: false, - enable_log_compression: false, - }, - }, - status: { - plugin: "filesystem", - config: { - status_log_file: - "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_status", - result_log_file: - "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_result", - enable_log_rotation: false, - enable_log_compression: false, - }, - }, - }, -}; -const CONFIG_INTEGRATIONS_AUTOMATIONS_DISABLED = { - ...CONFIG_INTEGRATIONS_AUTOMATIONS, - integrations: { - jira: [ - { - url: "https://fleetdm.atlassian.com", - username: "jira1@example.com", - api_token: "jira123", - project_key: "PROJECT 1", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.atlassian.com", - username: "jira2@example.com", - api_token: "jira123", - project_key: "PROJECT 2", - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - zendesk: [ - { - url: "https://fleetdm.zendesk.com", - email: "zendesk1@example.com", - api_token: "zendesk123", - group_id: 12345678, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - { - url: "https://fleetdm.zendesk.com", - email: "zendesk2@example.com", - api_token: "zendesk123", - group_id: 87654321, - enable_failing_policies: false, - enable_software_vulnerabilities: false, - }, - ], - }, - webhook_settings: { - host_status_webhook: { - enable_host_status_webhook: false, - destination_url: "", - host_percentage: 0, - days_count: 0, - }, - failing_policies_webhook: { - enable_failing_policies_webhook: false, - destination_url: "https://www.foo.com/bar", - policy_ids: [5, 10], - host_batch_size: 0, - }, - vulnerabilities_webhook: { - destination_url: "http://www.foo.com/bar", - enable_vulnerabilities_webhook: false, - }, - }, -}; - -export default { - GOOD_PASSWORD, - BAD_PASSWORD_LENGTH, - BAD_PASSWORD_NO_NUMBER, - BAD_PASSWORD_NO_SYMBOL, - CONFIG_INTEGRATIONS_AUTOMATIONS, - CONFIG_INTEGRATIONS_AUTOMATIONS_DISABLED, -}; diff --git a/cypress/support/index.d.ts b/cypress/support/index.d.ts deleted file mode 100644 index cf4a1578a..000000000 --- a/cypress/support/index.d.ts +++ /dev/null @@ -1,140 +0,0 @@ -// load type definitions that come with Cypress module -// - -declare namespace Cypress { - interface Chainable { - /** - * Custom command to setup the testing environment. - */ - setup(): Chainable; - - /** - * Custom command to setup the testing environment with fixture data for software and vulnerabilities. - */ - setupWithSoftware(): Chainable; - - /** - * Custom command to login the user programmatically using the fleet API. - */ - login(email?: string, password?: string): Chainable; - - /** - * Custom command to login the user programmatically using the fleet API - * but with a Cypress session wrapper. - */ - loginWithCySession(email?: string, password?: string): Chainable; - - /** - * Custom command to log out the current user. - */ - logout(): Chainable; - - /** - * Custom command to set a Fleet Desktop token to a host. - */ - setDesktopToken(hostId?: number, token?: string): Chainable; - - /** - * Custom command to add new queries by default. - */ - seedQueries(): Chainable; - - /** - * Custom command to add new scheduled queries by default. - */ - seedSchedule(): Chainable; - - /** - * Custom command to add new policies by default. - */ - seedPolicies(teamName?: string): Chainable; - - /** - * Custom command to add a new user in Fleet (via fleetctl). - */ - addUser(options?: { - email?: string; - password?: string; - globalRole?: string; - }): Chainable; - - /** - * Custom command to setup the SMTP configuration for this testing environment. - * - * NOTE: login() command is required before this, as it will make authenticated - * requests. - */ - setupSMTP(): Chainable; - - /** - * Custom command to set up SSO auth with the local server. - * - * NOTE: login() command is required before this, as it will make authenticated - * requests. - */ - setupSSO(options?: { - enable_sso_idp_login?: boolean; - enable_jit_provisioning?: boolean; - }): Chainable; - - /** - * Custom command to login a user1@example.com via SSO. - */ - loginSSO(options?: { - username?: string; - password?: string; - }): Chainable; - - /** - * Custom command to get the emails handled by the Mailhog server. - */ - getEmails(): Chainable; - - /** - * Custom command to seed the Free tier teams/users. - * - * NOTE: login() command is required before this, as it will make authenticated - * requests. - */ - seedFree(): Chainable; - - /** - * Custom command to seed the Premium tier teams/users. - * - * NOTE: login() command is required before this, as it will make authenticated - * requests. - */ - seedPremium(): Chainable; - - /** - * Custom command to seed the teams/users as represented in Figma. - * - * NOTE: login() command is required before this, as it will make authenticated - * requests. - */ - seedFigma(): Chainable; - - /** - * Custom command to add Docker osquery host. - * - * NOTE: login() command is required before this, as it will make authenticated - * requests. - */ - addDockerHost(teamName?: string): Chainable; - - /** - * Custom command to stop any running Docker hosts. - */ - stopDockerHost(): Chainable; - - /** - * Custom command to clear downloaded files from test machine. - */ - clearDownloads(): Chainable; - - /** - * Custom command to get any element describe only if it is attached to the DOM. - */ - getAttached(selector: string): Chainable; - } -} diff --git a/cypress/support/index.js b/cypress/support/index.js deleted file mode 100644 index 413b0ecfa..000000000 --- a/cypress/support/index.js +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import "./commands"; diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json deleted file mode 100644 index 542e12310..000000000 --- a/cypress/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "lib": ["es5", "dom"], - "types": [ - "cypress", - "@testing-library/cypress", - "node", - "cypress-wait-until" - ] - }, - "include": ["**/*.ts"] -} diff --git a/package.json b/package.json index f01d52912..4b34206de 100644 --- a/package.json +++ b/package.json @@ -4,16 +4,10 @@ "description": "The premier osquery fleet manager.", "private": true, "scripts": { - "lint": "eslint frontend cypress --ext .js,.jsx,.ts,.tsx", - "prettier:check": "prettier --check frontend/**/*.{jsx,js,tsx,ts} ./cypress/**/*.{js,ts}", + "lint": "eslint frontend --ext .js,.jsx,.ts,.tsx", + "prettier:check": "prettier --check frontend/**/*.{jsx,js,tsx,ts}", "test": "jest --config ./frontend/test/jest.config.ts", "test:ci": "jest --config ./frontend/test/jest.config.ts --ci --coverage", - "e2e-browser": "cypress open", - "e2e-browser:free": "yarn cypress open --config-file cypress/cypress-free.json", - "e2e-browser:premium": "yarn cypress open --config-file cypress/cypress-premium.json", - "e2e-cli": "cypress run", - "e2e-cli:free": "yarn cypress run --config-file cypress/cypress-free.json", - "e2e-cli:premium": "yarn cypress run --config-file cypress/cypress-premium.json", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" }, @@ -90,14 +84,12 @@ "@storybook/addon-mdx-gfm": "7.0.7", "@storybook/react": "7.0.7", "@storybook/react-webpack5": "7.0.7", - "@testing-library/cypress": "8.0.2", "@testing-library/jest-dom": "5.16.2", "@testing-library/react": "12.1.4", "@testing-library/user-event": "14.4.3", "@tsconfig/recommended": "1.0.1", "@types/chrome": "0.0.237", "@types/classnames": "0.0.32", - "@types/cypress": "1.1.3", "@types/expect": "1.20.3", "@types/file-saver": "2.0.5", "@types/js-md5": "0.4.3", @@ -126,14 +118,11 @@ "bourbon": "5.1.0", "classnames": "2.2.5", "css-loader": "6.7.3", - "cypress": "9.5.1", - "cypress-wait-until": "1.7.2", "esbuild-loader": "2.18.0", "eslint": "7.32.0", "eslint-config-airbnb": "15.1.0", "eslint-config-prettier": "8.5.0", "eslint-import-resolver-webpack": "0.10.0", - "eslint-plugin-cypress": "2.12.1", "eslint-plugin-import": "2.25.4", "eslint-plugin-jest": "20.0.3", "eslint-plugin-jsx-a11y": "5.1.1", diff --git a/yarn.lock b/yarn.lock index fa0650744..b8bddbbcb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1441,7 +1441,7 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== @@ -1550,38 +1550,6 @@ dependencies: "@cspotcode/source-map-consumer" "0.8.0" -"@cypress/request@^2.88.10": - version "2.88.10" - resolved "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz" - integrity sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - http-signature "~1.3.6" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^8.3.2" - -"@cypress/xvfb@^1.2.4": - version "1.2.4" - resolved "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz" - integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== - dependencies: - debug "^3.1.0" - lodash.once "^4.1.1" - "@discoveryjs/json-ext@^0.5.0", "@discoveryjs/json-ext@^0.5.3": version "0.5.7" resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" @@ -3149,15 +3117,7 @@ "@types/express" "^4.7.0" file-system-cache "^2.0.0" -"@testing-library/cypress@8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@testing-library/cypress/-/cypress-8.0.2.tgz#b13f0ff2424dec4368b6670dfbfb7e43af8eefc9" - integrity sha512-KVdm7n37sg/A4e3wKMD4zUl0NpzzVhx06V9Tf0hZHZ7nrZ4yFva6Zwg2EFF1VzHkEfN/ahUzRtT1qiW+vuWnJw== - dependencies: - "@babel/runtime" "^7.14.6" - "@testing-library/dom" "^8.1.0" - -"@testing-library/dom@^8.0.0", "@testing-library/dom@^8.1.0": +"@testing-library/dom@^8.0.0": version "8.11.3" resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.11.3.tgz" integrity sha512-9LId28I+lx70wUiZjLvi1DB/WT2zGOxUh46glrSNMaWVx849kKAluezVzZrXJfTKKoQTmEOutLes/bHg4Bj3aA== @@ -3317,13 +3277,6 @@ resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== -"@types/cypress@1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@types/cypress/-/cypress-1.1.3.tgz#0a700c040d53e9e12b5af98e41d4a88c39f39b6a" - integrity sha512-OXe0Gw8LeCflkG1oPgFpyrYWJmEKqYncBsD/J0r17r0ETx/TnIGDNLwXt/pFYSYuYTpzcq1q3g62M9DrfsBL4g== - dependencies: - cypress "*" - "@types/debug@^4.0.0", "@types/debug@^4.1.7": version "4.1.7" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" @@ -3619,7 +3572,7 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.0.tgz#f38c7139247a1d619f6cc6f27b072606af7c289d" integrity sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w== -"@types/node@14.18.12", "@types/node@^14.14.31": +"@types/node@14.18.12": version "14.18.12" resolved "https://registry.npmjs.org/@types/node/-/node-14.18.12.tgz" integrity sha512-q4jlIR71hUpWTnGhXWcakgkZeHa3CCjcQcnuzU8M891BAWA2jHiziiWEPEkdS5pFsz7H9HJiy8BrK7tBRNrY7A== @@ -3775,16 +3728,6 @@ dependencies: "@types/node" "*" -"@types/sinonjs__fake-timers@8.1.1": - version "8.1.1" - resolved "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz" - integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== - -"@types/sizzle@^2.3.2": - version "2.3.3" - resolved "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz" - integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== - "@types/sockjs-client@1.5.1": version "1.5.1" resolved "https://registry.yarnpkg.com/@types/sockjs-client/-/sockjs-client-1.5.1.tgz#7ed2093da89305af370511c4e3beb7e4ef0d7e87" @@ -3846,13 +3789,6 @@ dependencies: "@types/yargs-parser" "*" -"@types/yauzl@^2.9.1": - version "2.9.2" - resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz" - integrity sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA== - dependencies: - "@types/node" "*" - "@typescript-eslint/eslint-plugin@5.58.0": version "5.58.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.58.0.tgz#b1d4b0ad20243269d020ef9bbb036a40b0849829" @@ -4448,7 +4384,7 @@ ansi-colors@^4.1.1: resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: +ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -4520,11 +4456,6 @@ app-root-dir@^1.0.2: resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== -arch@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz" - integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== - are-we-there-yet@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz" @@ -4645,18 +4576,6 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - assert@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" @@ -4721,11 +4640,6 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== -async@^3.2.0: - version "3.2.3" - resolved "https://registry.npmjs.org/async/-/async-3.2.3.tgz" - integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== - async@^3.2.3: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" @@ -4764,16 +4678,6 @@ available-typed-arrays@^1.0.5: resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - axe-core@^4.2.0: version "4.7.0" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" @@ -4994,13 +4898,6 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - better-opn@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" @@ -5032,16 +4929,6 @@ bl@^4.0.3, bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -blob-util@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz" - integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ== - -bluebird@^3.7.2: - version "3.7.2" - resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" @@ -5308,7 +5195,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.5.0, buffer@^5.6.0: +buffer@^5.5.0: version "5.7.1" resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -5417,11 +5304,6 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -cachedir@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz" - integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== - call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" @@ -5504,11 +5386,6 @@ case-sensitive-paths-webpack-plugin@^2.4.0: resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - ccount@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" @@ -5602,11 +5479,6 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -check-more-types@^2.24.0: - version "2.24.0" - resolved "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz" - integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= - chokidar@^3.4.0, chokidar@^3.4.2, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" @@ -5718,23 +5590,6 @@ cli-table3@^0.6.1: optionalDependencies: "@colors/colors" "1.5.0" -cli-table3@~0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz" - integrity sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA== - dependencies: - string-width "^4.2.0" - optionalDependencies: - colors "1.4.0" - -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - cli-width@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" @@ -5834,17 +5689,7 @@ colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -colorette@^2.0.16: - version "2.0.16" - resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== - -colors@1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -5866,11 +5711,6 @@ commander@^4.0.1: resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -commander@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" - integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== - commander@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" @@ -5891,11 +5731,6 @@ common-path-prefix@^3.0.0: resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== -common-tags@^1.8.0: - version "1.8.2" - resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz" - integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -6028,11 +5863,6 @@ core-js@^2.4.0: resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -6247,71 +6077,11 @@ csstype@^3.0.2: resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz" integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== -cypress-wait-until@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/cypress-wait-until/-/cypress-wait-until-1.7.2.tgz#7f534dd5a11c89b65359e7a0210f20d3dfc22107" - integrity sha512-uZ+M8/MqRcpf+FII/UZrU7g1qYZ4aVlHcgyVopnladyoBrpoaMJ4PKZDrdOJ05H5RHbr7s9Tid635X3E+ZLU/Q== - -cypress@*, cypress@9.5.1: - version "9.5.1" - resolved "https://registry.npmjs.org/cypress/-/cypress-9.5.1.tgz" - integrity sha512-H7lUWB3Svr44gz1rNnj941xmdsCljXoJa2cDneAltjI9leKLMQLm30x6jLlpQ730tiVtIbW5HdUmBzPzwzfUQg== - dependencies: - "@cypress/request" "^2.88.10" - "@cypress/xvfb" "^1.2.4" - "@types/node" "^14.14.31" - "@types/sinonjs__fake-timers" "8.1.1" - "@types/sizzle" "^2.3.2" - arch "^2.2.0" - blob-util "^2.0.2" - bluebird "^3.7.2" - buffer "^5.6.0" - cachedir "^2.3.0" - chalk "^4.1.0" - check-more-types "^2.24.0" - cli-cursor "^3.1.0" - cli-table3 "~0.6.1" - commander "^5.1.0" - common-tags "^1.8.0" - dayjs "^1.10.4" - debug "^4.3.2" - enquirer "^2.3.6" - eventemitter2 "^6.4.3" - execa "4.1.0" - executable "^4.1.1" - extract-zip "2.0.1" - figures "^3.2.0" - fs-extra "^9.1.0" - getos "^3.2.1" - is-ci "^3.0.0" - is-installed-globally "~0.4.0" - lazy-ass "^1.6.0" - listr2 "^3.8.3" - lodash "^4.17.21" - log-symbols "^4.0.0" - minimist "^1.2.5" - ospath "^1.2.2" - pretty-bytes "^5.6.0" - proxy-from-env "1.0.0" - request-progress "^3.0.0" - semver "^7.3.2" - supports-color "^8.1.1" - tmp "~0.2.1" - untildify "^4.0.0" - yauzl "^2.10.0" - damerau-levenshtein@^1.0.0: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -6335,11 +6105,6 @@ date-fns@2.28.0: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== -dayjs@^1.10.4: - version "1.11.0" - resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.0.tgz" - integrity sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug== - debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" @@ -6347,14 +6112,14 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.2.7: +debug@^3.2.7: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -6734,14 +6499,6 @@ duplexify@^3.5.0, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" @@ -6859,7 +6616,7 @@ enhanced-resolve@~0.9.0: memory-fs "^0.2.0" tapable "^0.1.8" -enquirer@^2.3.5, enquirer@^2.3.6: +enquirer@^2.3.5: version "2.3.6" resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== @@ -7275,13 +7032,6 @@ eslint-module-utils@^2.7.2: debug "^3.2.7" find-up "^2.1.0" -eslint-plugin-cypress@2.12.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-cypress/-/eslint-plugin-cypress-2.12.1.tgz#9aeee700708ca8c058e00cdafe215199918c2632" - integrity sha512-c2W/uPADl5kospNDihgiLc7n87t5XhUbFDoTl6CfVkmG+kDAb5Ux10V9PoLPu9N+r7znpc+iQlcmAqT1A/89HA== - dependencies: - globals "^11.12.0" - eslint-plugin-import@2.25.4: version "2.25.4" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1" @@ -7507,11 +7257,6 @@ etag@~1.8.1: resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -eventemitter2@^6.4.3: - version "6.4.5" - resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz" - integrity sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw== - events@^3.0.0, events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" @@ -7530,21 +7275,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -execa@4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz" - integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -7560,13 +7290,6 @@ execa@^5.0.0, execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -executable@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz" - integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== - dependencies: - pify "^2.2.0" - exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -7704,7 +7427,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^3.0.0, extend@~3.0.2: +extend@^3.0.0: version "3.0.2" resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -7732,17 +7455,6 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extract-zip@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz" - integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== - dependencies: - debug "^4.1.1" - get-stream "^5.1.0" - yauzl "^2.10.0" - optionalDependencies: - "@types/yauzl" "^2.9.1" - extract-zip@^1.6.6: version "1.7.0" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" @@ -7753,16 +7465,6 @@ extract-zip@^1.6.6: mkdirp "^0.5.4" yauzl "^2.10.0" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -7837,7 +7539,7 @@ fetch-retry@^5.0.2: resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.4.tgz#06e8e4533030bf6faa00ffbb9450cb9264c23c12" integrity sha512-LXcdgpdcVedccGg0AZqg+S8lX/FCdwXD92WNZ5k5qsb0irRhSFsBOpcJt7oevyqT2/C2nEE0zSFNdBEpj3YOSw== -figures@^3.0.0, figures@^3.2.0: +figures@^3.0.0: version "3.2.0" resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== @@ -8020,11 +7722,6 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - fork-ts-checker-webpack-plugin@6.5.0: version "6.5.0" resolved "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.0.tgz" @@ -8080,15 +7777,6 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - forwarded@0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" @@ -8129,7 +7817,7 @@ fs-extra@^11.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0, fs-extra@^9.1.0: +fs-extra@^9.0.0: version "9.1.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -8266,13 +7954,6 @@ get-stdin@^4.0.1: resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= -get-stream@^5.0.0, get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -8291,20 +7972,6 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== -getos@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz" - integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== - dependencies: - async "^3.2.0" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - giget@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/giget/-/giget-1.1.2.tgz#f99a49cb0ff85479c8c3612cdc7ca27f2066e818" @@ -8377,13 +8044,6 @@ glob@~7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -global-dirs@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz" - integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== - dependencies: - ini "2.0.0" - global-modules@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz" @@ -8404,7 +8064,7 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" -globals@^11.1.0, globals@^11.12.0: +globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== @@ -8843,15 +8503,6 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" -http-signature@~1.3.6: - version "1.3.6" - resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz" - integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw== - dependencies: - assert-plus "^1.0.0" - jsprim "^2.0.2" - sshpk "^1.14.1" - https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -8873,11 +8524,6 @@ https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: agent-base "6" debug "4" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== - human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -9012,11 +8658,6 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -ini@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== - ini@^1.3.4: version "1.3.8" resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" @@ -9183,13 +8824,6 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-ci@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz" - integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== - dependencies: - ci-info "^3.2.0" - is-core-module@^2.11.0: version "2.12.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" @@ -9338,14 +8972,6 @@ is-gzip@^1.0.0: resolved "https://registry.yarnpkg.com/is-gzip/-/is-gzip-1.0.0.tgz#6ca8b07b99c77998025900e555ced8ed80879a83" integrity sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ== -is-installed-globally@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz" - integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== - dependencies: - global-dirs "^3.0.0" - is-path-inside "^3.0.2" - is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -9492,11 +9118,6 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9: gopd "^1.0.1" has-tostringtag "^1.0.0" -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" @@ -9589,11 +9210,6 @@ isomorphic-unfetch@^3.1.0: node-fetch "^2.6.1" unfetch "^4.2.0" -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" @@ -10186,11 +9802,6 @@ js-yaml@3.14.1, js-yaml@^3.13.1, js-yaml@^3.7.0: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - jscodeshift@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.14.0.tgz#7542e6715d6d2e8bde0b4e883f0ccea358b46881" @@ -10316,17 +9927,12 @@ json-schema-traverse@^1.0.0: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -10352,16 +9958,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsprim@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz" - integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - jsx-ast-utils@^1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1" @@ -10414,11 +10010,6 @@ klona@^2.0.6: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== -lazy-ass@^1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz" - integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM= - lazy-universal-dotenv@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-4.0.0.tgz#0b220c264e89a042a37181a4928cdd298af73422" @@ -10454,20 +10045,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -listr2@^3.8.3: - version "3.14.0" - resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz" - integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== - dependencies: - cli-truncate "^2.1.0" - colorette "^2.0.16" - log-update "^4.0.0" - p-map "^4.0.0" - rfdc "^1.3.0" - rxjs "^7.5.1" - through "^2.3.8" - wrap-ansi "^7.0.0" - lit-element@^3.3.0: version "3.3.2" resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-3.3.2.tgz#9913bf220b85065f0e5f1bb8878cc44f36b50cfa" @@ -10566,11 +10143,6 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.once@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz" - integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= - lodash.set@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" @@ -10586,7 +10158,7 @@ lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17. resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@^4.0.0, log-symbols@^4.1.0: +log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -10594,16 +10166,6 @@ log-symbols@^4.0.0, log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log-update@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" - integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== - dependencies: - ansi-escapes "^4.3.0" - cli-cursor "^3.1.0" - slice-ansi "^4.0.0" - wrap-ansi "^6.2.0" - lolex@^5.0.0: version "5.1.2" resolved "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz" @@ -11344,7 +10906,7 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.25, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.25, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -11838,7 +11400,7 @@ normalizr@3.6.2: resolved "https://registry.yarnpkg.com/normalizr/-/normalizr-3.6.2.tgz#ac1571207dc3008adb46e3f62311c17f11dcf083" integrity sha512-30qCybsBaCBciotorvuOZTCGEg2AXrJfADMT2Kk/lvpIAcipHdK0zc33nNtwKzyfQAqIJXAcqET6YgflYUgsoQ== -npm-run-path@^4.0.0, npm-run-path@^4.0.1: +npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -12097,11 +11659,6 @@ os-tmpdir@~1.0.2: resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -ospath@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz" - integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs= - outvariant@^1.2.1, outvariant@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.3.0.tgz#c39723b1d2cba729c930b74bf962317a81b9b1c9" @@ -12396,11 +11953,6 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.0, picomatc resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -12571,11 +12123,6 @@ prettier@^2.8.0: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== -pretty-bytes@^5.6.0: - version "5.6.0" - resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" - integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== - pretty-error@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" @@ -12670,11 +12217,6 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -proxy-from-env@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz" - integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4= - proxy-from-env@^1.0.0, proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -12690,7 +12232,7 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== @@ -12787,11 +12329,6 @@ qs@^6.10.0: dependencies: side-channel "^1.0.4" -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - query-string@^3.0.0: version "3.0.3" resolved "https://registry.npmjs.org/query-string/-/query-string-3.0.3.tgz" @@ -13464,13 +13001,6 @@ repeat-string@^1.6.1: resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request-progress@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz" - integrity sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4= - dependencies: - throttleit "^1.0.0" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -13585,11 +13115,6 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" @@ -13631,7 +13156,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^7.5.1, rxjs@^7.5.5: +rxjs@^7.5.5: version "7.5.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== @@ -13676,7 +13201,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -14016,15 +13541,6 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" @@ -14243,21 +13759,6 @@ sqlite-parser@1.0.1: resolved "https://registry.npmjs.org/sqlite-parser/-/sqlite-parser-1.0.1.tgz" integrity sha1-EQGD8mgvBKxsfYrQnEREbvl21ew= -sshpk@^1.14.1: - version "1.17.0" - resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz" @@ -14518,7 +14019,7 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0, supports-color@^8.1.1: +supports-color@^8.0.0: version "8.1.1" resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -14703,11 +14204,6 @@ text-table@^0.2.0: resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -throttleit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz" - integrity sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw= - through2@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -14716,7 +14212,7 @@ through2@^2.0.3: readable-stream "~2.3.6" xtend "~4.0.1" -through@^2.3.6, through@^2.3.8: +through@^2.3.6: version "2.3.8" resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -14758,13 +14254,6 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmp@~0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -14827,14 +14316,6 @@ tough-cookie@^4.0.0, tough-cookie@^4.1.2: universalify "^0.2.0" url-parse "^1.5.3" -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tr46@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" @@ -14985,18 +14466,6 @@ tty-browserify@0.0.0: resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" @@ -15413,7 +14882,7 @@ utils-merge@1.0.1: resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@8.3.2, uuid@^8.3.0, uuid@^8.3.2: +uuid@8.3.2, uuid@^8.3.0: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -15484,15 +14953,6 @@ vary@~1.1.2: resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -verror@1.10.0: - version "1.10.0" - resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - vfile-message@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.2.tgz#a2908f64d9e557315ec9d7ea3a910f658ac05f7d" @@ -15909,15 +15369,6 @@ wordwrap@^1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"