Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Update unit tests & e2e integration tests #817

Merged
merged 5 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
const baseConfig = require('../webpack.common')

const baseConfig = require("../webpack.common");

module.exports = {
stories: ['../src/**/story.tsx'],
stories: ["../src/**/story.tsx"],
webpackFinal: config => {
return {
...config,
Expand All @@ -13,14 +12,14 @@ module.exports = {
{
test: /\.js$/,
exclude: /node_modules/,
loader: require.resolve('babel-loader'),
loader: require.resolve("babel-loader"),
},
]
],
},
resolve: {
...config.resolve,
...baseConfig.resolve
...baseConfig.resolve,
},
}
}
}
};
},
};
19 changes: 9 additions & 10 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from 'react'
import { addDecorator } from '@storybook/react'
import styled, { createGlobalStyle } from 'styled-components'
import React from "react";
import { addDecorator } from "@storybook/react";
import styled, { createGlobalStyle } from "styled-components";

import { ThemePalette, ThemeProps } from '@src/components/Theme'
import Fonts from '@src/components/ui/Fonts'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import { ThemePalette, ThemeProps } from "@src/components/Theme";
import Fonts from "@src/components/ui/Fonts";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

const Wrapper = styled.div`
display: inline-block;
background: ${ThemePalette.grayscale[7]};
padding: 32px;
`
`;

const GlobalStyle = createGlobalStyle`
${Fonts}
Expand All @@ -22,7 +22,7 @@ const GlobalStyle = createGlobalStyle`
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
`
`;

addDecorator(storyFn => (
<Router>
Expand All @@ -33,5 +33,4 @@ addDecorator(storyFn => (
</Wrapper>
</Switch>
</Router>
)
)
));
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
"port": 9222,
"urlFilter": "http://localhost:3001/*",
"webRoot": "${workspaceFolder}"
},
}
]
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ![Coriolis Web](/src/components/ui/Logo/images/coriolis-small-black.svg)

Web GUI for [coriolis](https://github.com/cloudbase/coriolis)
Web GUI for [coriolis](https://github.com/cloudbase/coriolis)

[![Build and Test](https://github.com/cloudbase/coriolis-web/actions/workflows/build.yml/badge.svg)](https://github.com/cloudbase/coriolis-web/actions/workflows/build.yml) [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)

Expand Down
45 changes: 20 additions & 25 deletions cypress/e2e/dashboard/dashboard.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ describe("Dashboard", () => {
};

it("renders empty dashboard", () => {
cy.intercept(routeSelectors.REPLICAS, {
body: { replicas: [] },
}).as("replicas");
cy.intercept(routeSelectors.MIGRATIONS, {
body: { migrations: [] },
}).as("migrations");
cy.intercept(routeSelectors.TRANSFERS, {
body: { transfers: [] },
}).as("transfers");
cy.intercept(routeSelectors.DEPLOYMENTS, {
body: { deployments: [] },
}).as("deployments");
cy.intercept(routeSelectors.ENDPOINTS, {
body: { endpoints: [] },
}).as("endpoints");

cy.visit("/");
waitForAll();
cy.wait(["@replicas", "@migrations", "@endpoints"]);
cy.wait(["@transfers", "@deployments", "@endpoints"]);

cy.get("*[class^='DashboardActivity__Message']").should(
"contain.text",
Expand All @@ -58,43 +58,42 @@ describe("Dashboard", () => {

cy.get("*[class^='DashboardLicence__ChartHeaderCurrent']").should(
"contain.text",
`${applianceStatus.appliance_licence_status.current_performed_replicas} Fulfilled Replica ${applianceStatus.appliance_licence_status.current_performed_migrations} Fulfilled Migrations`
`${applianceStatus.appliance_licence_status.current_performed_replicas} Used Replica ${applianceStatus.appliance_licence_status.current_performed_migrations} Used Migrations`
);
});

cy.get("button").should("contain.text", "New Replica / Migration");
cy.get("button").should("contain.text", "New Transfer");
cy.get("button").should("contain.text", "New Endpoint");
});

it("renders dashboard with data", () => {
cy.intercept(routeSelectors.REPLICAS, {
cy.intercept(routeSelectors.TRANSFERS, {
fixture: "transfers/replicas.json",
}).as("replicas");
cy.intercept(routeSelectors.MIGRATIONS, {
fixture: "transfers/migrations.json",
}).as("migrations");
}).as("transfers");
cy.intercept(routeSelectors.ENDPOINTS, {
fixture: "endpoints/endpoints.json",
}).as("endpoints");

cy.visit("/");
waitForAll();
cy.wait(["@replicas", "@migrations", "@endpoints"]);
cy.wait(["@transfers", "@endpoints"]);

cy.loadFixtures(
[
"transfers/replicas.json",
"transfers/migrations.json",
"endpoints/endpoints.json",
],
results => {
const [replicasFixture, migrationsFixture, endpointsFixture] = results;
const [transfersFixture, endpointsFixture] = results;
const replicasCount = transfersFixture.transfers.filter(transfer => transfer.scenario === "replica").length;
const migrationsCount = transfersFixture.transfers.filter(transfer => transfer.scenario === "live_migration").length;

cy.get("div[class^='DashboardInfoCount__CountBlock']").should(
"contain.text",
`${replicasFixture.replicas.length}Replicas${migrationsFixture.migrations.length}Migrations${endpointsFixture.endpoints.length}Endpoints`
`${replicasCount}Replicas${migrationsCount}Migrations${endpointsFixture.endpoints.length}Endpoints`
);

const checkItem = (type: "migration" | "replica", item: any) => {
const checkItem = (type: "transfer", item: any) => {
cy.get("div[class^='NotificationDropdown__ItemDescription']").should(
"contain.text",
`New ${type} ${item.id.substr(
Expand All @@ -104,12 +103,8 @@ describe("Dashboard", () => {
);
};

migrationsFixture.migrations.forEach((migration: any) => {
checkItem("migration", migration);
});

replicasFixture.replicas.forEach((replica: any) => {
checkItem("replica", replica);
transfersFixture.transfers.forEach((transfer: any) => {
checkItem("transfer", transfer);
});
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { routeSelectors } from "../../support/routeSelectors";

describe("Migrations list", () => {
describe("Deployments list", () => {
beforeEach(() => {
cy.setProjectIdCookie();

Expand All @@ -20,28 +20,27 @@ describe("Migrations list", () => {
};

it("renders empty list", () => {
cy.intercept(routeSelectors.MIGRATIONS, {
body: { replicas: [] },
}).as("migrations");
cy.intercept(routeSelectors.DEPLOYMENTS, {
body: { deployments: [] },
}).as("deployments");

cy.visit("/migrations");
cy.visit("/deployments");
waitForAll();

cy.wait(["@migrations"]);
cy.wait(["@deployments"]);

cy.get("div[class^='MainList__EmptyListMessage']").should(
"contain.text",
"don't have any Migrations in this project"
"don't have any Deployments in this project"
);
cy.get("button").should("contain.text", "Create a Migration");
});

it("filters list", () => {
cy.visit("/migrations");
cy.visit("/deployments");
waitForAll();

cy.loadFixtures(["transfers/migrations"], (results: any[]) => {
const migrations = results[0].migrations;
const deployments = results[0].deployments;

cy.get("div[class^='MainListFilter__FilterItem']")
.contains("Running")
Expand All @@ -53,57 +52,57 @@ describe("Migrations list", () => {
.click();
cy.get("div[class^='TransferListItem__Wrapper']").should(
"have.length",
migrations.filter(r => r.last_execution_status === "ERROR").length
deployments.filter(r => r.last_execution_status === "ERROR").length
);

cy.get("div[class^='MainListFilter__FilterItem']")
.contains("Completed")
.click();
cy.get("div[class^='TransferListItem__Wrapper']").should(
"have.length",
migrations.filter(r => r.last_execution_status === "COMPLETED").length
deployments.filter(r => r.last_execution_status === "COMPLETED").length
);

cy.get("div[class^='MainListFilter__FilterItem']")
.contains("Canceled")
.click();
cy.get("div[class^='TransferListItem__Wrapper']").should(
"have.length",
migrations.filter(r => r.last_execution_status === "CANCELED").length
deployments.filter(r => r.last_execution_status === "CANCELED").length
);

cy.get("div[class^='MainListFilter__FilterItem']")
.contains("All")
.click();
cy.get("div[class^='TransferListItem__Wrapper']").should(
"have.length",
migrations.length
deployments.length
);

cy.get("div[class^='SearchButton__Wrapper']").click();
cy.get("input[class*='SearchInput']").type("ol88-uefi");
cy.get("div[class^='TransferListItem__Wrapper']").should(
"have.length",
migrations.filter(r => r.instances.find(i => i.includes("ol88-uefi")))
deployments.filter(r => r.instances.find(i => i.includes("ol88-uefi")))
.length
);
cy.get("div[class^='TextInput__Close']").click();
});
});

it("does bulk actions", () => {
cy.visit("/migrations");
cy.visit("/deployments");
waitForAll();

cy.loadFixtures(["transfers/migrations"], (results: any[]) => {
const migrations: any[] = results[0].migrations;
const deployments: any[] = results[0].deployments;

cy.get("div[class*='TransferListItem__Checkbox']").eq(0).click();
cy.get("div[class^='SearchButton__Wrapper']").click();
cy.get("input[class*='SearchInput']").type("ol88-uefi");
cy.get("div[class^='TransferListItem__Wrapper']").should(
"have.length",
migrations.filter(r => r.instances.find(i => i.includes("ol88-uefi")))
deployments.filter(r => r.instances.find(i => i.includes("ol88-uefi")))
.length
);
cy.get("div[class*='TransferListItem__Checkbox']").eq(0).click();
Expand All @@ -114,29 +113,20 @@ describe("Migrations list", () => {

cy.get("div[class^='ActionDropdown__Wrapper']").click();
cy.get("div[class^='ActionDropdown__ListItem']")
.contains("Recreate Migrations")
.contains("Recreate Deployments")
.click();
cy.get("div[class^='AlertModal__Message']").should(
"contain.text",
"Are you sure you want to recreate"
);

let postCount = 0;
cy.intercept("POST", routeSelectors.MIGRATIONS, req => {
postCount += 1;
if (postCount === 1) {
expect(req.body.migration.instances).to.deep.eq([
"Datacenter/ol88-bios",
]);
} else if (postCount === 2) {
expect(req.body.migration.instances).to.deep.eq([
"Datacenter/ol88-uefi",
]);
}
}).as("migrations-recreate");
cy.intercept("POST", routeSelectors.DEPLOYMENTS, req => {
expect(req.body.deployment.transfer_id,
"Transfer ID should be present in the request body").to.exist;
}).as("deployments-recreate");

cy.get("button").contains("Yes").click();
cy.wait(["@migrations-recreate"]);
cy.wait(["@deployments-recreate"]);
});
});
});
10 changes: 5 additions & 5 deletions cypress/e2e/page header/page-header.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe("Page header", () => {
};

it("switches project", () => {
cy.visit("/replicas");
cy.visit("/transfers");
waitForAll();

cy.get("div[class^='Dropdown__Wrapper']").contains("admin").click();
Expand All @@ -44,15 +44,15 @@ describe("Page header", () => {
});

it("redirects to user info", () => {
cy.visit("/replicas");
cy.visit("/transfers");
waitForAll();
cy.get("div[class^='UserDropdown__Wrapper']").click();
cy.get("a[class^='UserDropdown__Username']").click();
cy.url().should("include", "/users");
});

it("shows about coriolis", () => {
cy.visit("/replicas");
cy.visit("/transfers");
waitForAll();
cy.get("div[class^='UserDropdown__Wrapper']").click();

Expand Down Expand Up @@ -82,7 +82,7 @@ describe("Page header", () => {
});

it("redirects to help", () => {
cy.visit("/replicas", {
cy.visit("/transfers", {
onBeforeLoad(win) {
cy.stub(win, "open").as("winOpen");
},
Expand All @@ -98,7 +98,7 @@ describe("Page header", () => {
});

it("logs out", () => {
cy.visit("/replicas");
cy.visit("/transfers");
waitForAll();

cy.get("div[class^='UserDropdown__Wrapper']").click();
Expand Down
Loading
Loading