Skip to content
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
1 change: 1 addition & 0 deletions calm-hub-ui/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_BASE_URL=http://localhost:5173
17 changes: 17 additions & 0 deletions calm-hub-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ You may also see any lint errors in the console.
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `npm run start-cypress`

End to End tests are written with cypress. Cypress can be run in headless and headed modes.
The above command runs in headed mode and allows the developer to locally run through the spec
files and observe the test runs. [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) queries and paradigm for testing feature
heavily in these tests as these help maintainability by organising tests around how the UI is used
and not how its implemented. [Cypress and its best practices](https://docs.cypress.io/app/core-concepts/best-practices) are also used in writing and updating
these tests.

You need to set an environment variable VITE_BASE_URL which should be the address where the vite server is being run
A default in .env.example has been added. This can also be set in CI to whatever the intended vite port should be

#### Test Stubbing
The tests are all stubbed to return desired responses. These will need to be maintained in tandem with
calm-hub API. This section can be updated when a different and more reliable integration strategy is devised


### `npm run build`

Builds the app for production to the `build` folder.\
Expand Down
8 changes: 8 additions & 0 deletions calm-hub-ui/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "cypress";
import 'dotenv/config';

export default defineConfig({
e2e: {
baseUrl: process.env.VITE_BASE_URL,
},
});
44 changes: 44 additions & 0 deletions calm-hub-ui/cypress/e2e/adrs.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const expectedNamespace = "finos"
const expectedAdrId = 1;
const expectedAdrRevision = 2;

describe('ADR Tests', () => {
beforeEach(() => {
cy.intercept("/calm/namespaces", {"values": [expectedNamespace]});
cy.intercept("/calm/namespaces/finos/adrs", {"values": [expectedAdrId]});
cy.intercept("/calm/namespaces/finos/adrs/1/revisions", {"values": [expectedAdrRevision]});
cy.intercept(`/calm/namespaces/finos/adrs/1/revisions/${expectedAdrRevision}`, {
fixture: "example-adr"
});
})

it("Displays ADR JSON successfully", () => {
cy.visit("/");
cy.findByText(expectedNamespace).click();
cy.findByText(/adrs/i).click();
cy.findByText(/1/i).click();
cy.findByText(expectedAdrRevision).click();

cy.fixture('example-adr').then(data => {
cy.contains(/id/i).should("exist");
cy.contains(data.id).should("exist");

cy.contains(/namespace/i).should("exist");
cy.contains(data.namespace).should("exist");

cy.contains(data.revision).should("exist");

cy.contains(data.adr.title).should("exist");
cy.contains(data.adr.status, {
matchCase: false
}).should("exist");
cy.contains(/context and problem/i).should("exist")
cy.contains(data.adr.contextAndProblemStatement).should("exist");

cy.contains(/decision drivers/i).should("exist")
cy.contains(/considered options/i).should("exist")
cy.contains(/decision outcome/i).should("exist")

});
})
})
52 changes: 52 additions & 0 deletions calm-hub-ui/cypress/e2e/architectures.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const expectedNamespace = "finos"
const expectedArchitectureId = 1;
const expectedArchitectureVersion = "1.0.0";

describe('Architecture Tests', () => {
beforeEach(() => {
cy.intercept("/calm/namespaces", {"values": [expectedNamespace]});
cy.intercept("/calm/namespaces/finos/architectures", {"values": [expectedArchitectureId]});
cy.intercept("/calm/namespaces/finos/architectures/1/versions", {"values": [expectedArchitectureVersion]});
cy.intercept("/calm/namespaces/finos/architectures/1/versions/1.0.0", {
fixture: "three-tier-calm.json"
});
})

it("Displays architecture JSON successfully", () => {
cy.visit("/");
cy.findByText(expectedNamespace).click();
cy.findByText(/architectures/i).click();
cy.findByText(/1/i).click();
cy.findByText(/1.0.0/i).click();

cy.findByText(/relationship descriptions/i).should("exist");
cy.findByText(/node descriptions/i).should("exist");

cy.findByRole("tab", { name: /json/i}).click();

cy.fixture('three-tier-calm').then(data => {
cy.contains(/\$schema/i).should("exist");
cy.contains(data.$schema).should("exist");
cy.contains(/id/i).should("exist");

cy.contains(/nodes/i).should("exist");

Object.entries(data.nodes[0]).forEach(([key, value]) => {
cy.contains(key).should("exist");
cy.contains(value as string).should("exist");
});

cy.contains(/unique-id/i).should("exist");
cy.contains(data.nodes[0]["unique-id"]).should("exist");

cy.contains(/name/i).should("exist");
cy.contains(data.nodes[0]["name"]).should("exist");

cy.contains(/description/i).should("exist");
cy.contains(data.nodes[0]["description"]).should("exist");

cy.contains(/node-type/i).should("exist");
cy.contains(data.nodes[0]["node-type"]).should("exist");
});
})
})
47 changes: 47 additions & 0 deletions calm-hub-ui/cypress/e2e/flows.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const expectedNamespace = "finos"
const expectedFlowId = 1;
const expectedFlowVersion = "1.0.0";

describe('Flow Tests', () => {
beforeEach(() => {
cy.intercept("/calm/namespaces", {"values": [expectedNamespace]});
cy.intercept("/calm/namespaces/finos/flows", {"values": [expectedFlowId]});
cy.intercept("/calm/namespaces/finos/flows/1/versions", {"values": [expectedFlowVersion]});
cy.intercept("/calm/namespaces/finos/flows/1/versions/1.0.0", {
fixture: "update-account-flow"
});
})

it("Displays flow JSON successfully", () => {
cy.visit("/");
cy.findByText(expectedNamespace).click();
cy.findByText(/flows/i).click();
cy.findByText(/1/i).click();
cy.findByText(/1.0.0/i).click();

cy.fixture('update-account-flow').then(data => {
cy.contains(/\$schema/i).should("exist");
cy.contains(data.$schema).should("exist");

cy.contains(/\$id/i).should("exist");
cy.contains(data.$id).should("exist");

cy.contains(/unique-id/i).should("exist");
cy.contains(data["unique-id"]).should("exist");

cy.contains(/name/i).should("exist");
cy.contains(data.name).should("exist");

cy.contains(/description/i).should("exist");
cy.contains(data.description).should("exist");

cy.contains(/transitions/i).should("exist");

Object.entries(data.transitions[0]).forEach(([key, value]) => {
cy.contains(key).should("exist");
cy.contains(value as string).should("exist");
});

});
})
})
36 changes: 36 additions & 0 deletions calm-hub-ui/cypress/e2e/home.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {namespaces, resourceTypes} from "../fixtures/constants.js";

describe('Home page tests', () => {
beforeEach(() => {
cy.intercept("/calm/namespaces", {"values": namespaces})
})

it('Loads initial screen successfully', () => {
cy.visit('/');
cy.findByText("Explore").should("exist");
cy.findByText("Namespaces").should("exist");
namespaces.forEach(namespace => cy.findByText(namespace).should("exist"));
cy.findByText(namespaces[0]).click();
resourceTypes.forEach(resourceType => { cy.findByText(resourceType).should("exist"); });
})

context("Wide screen tests", () => {
it("Finds navigation items", () => {
cy.viewport('macbook-16')
cy.visit('/');
cy.findByRole("link", { name: "Hub" })
cy.findByRole("link", { name: "Visualizer" })
})

})

context("Collapsed screen tests", () => {
it("Finds navigation items", () => {
cy.viewport(1000, 600)
cy.visit('/');
cy.findByRole("button", { name: "Open Menu" }).click();
cy.findByRole("link", { name: "Hub" })
cy.findByRole("link", { name: "Visualizer" })
})
})
})
43 changes: 43 additions & 0 deletions calm-hub-ui/cypress/e2e/patterns.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const expectedNamespace = "finos"
const expectedPatternId = 1;
const expectedPatternVersion = "1.0.0";

describe('Pattern Tests', () => {
beforeEach(() => {
cy.intercept("/calm/namespaces", {"values": [expectedNamespace]});
cy.intercept("/calm/namespaces/finos/patterns", {"values": [expectedPatternId]});
cy.intercept("/calm/namespaces/finos/patterns/1/versions", {"values": [expectedPatternVersion]});
cy.intercept("/calm/namespaces/finos/patterns/1/versions/1.0.0", {
fixture: "conference-signup-pattern"
});
})

it("Displays pattern JSON successfully", () => {
cy.visit("/");
cy.findByText(expectedNamespace).click();
cy.findByText(/patterns/i).click();
cy.findByText(/1/i).click();
cy.findByText(/1.0.0/i).click();

cy.fixture('conference-signup-pattern').then(data => {
cy.contains(/\$schema/i).should("exist");
cy.contains(data.$schema).should("exist");

cy.contains(/\$id/i).should("exist");
cy.contains(data.$id).should("exist");

cy.contains(/title/i).should("exist");
cy.contains(data.title).should("exist");

cy.contains(/description/i).should("exist");
cy.contains(data.description).should("exist");

cy.contains(/minItems/i).should("exist");
cy.contains(data.properties.nodes.minItems).should("exist");

cy.contains(data.properties.nodes.minItems).should("exist");

cy.contains(/prefixItems/i).should("exist");
});
})
})
18 changes: 18 additions & 0 deletions calm-hub-ui/cypress/e2e/visualizer.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
describe("Visualizer page tests", () => {
it("Displays visualizer on navigation", () => {
cy.viewport('macbook-16')
cy.visit("/");

cy.findByRole("link", { name: "Visualizer" }).click();

cy.get('canvas').should("not.exist");
cy.findByText(/drag and drop your file here/i).should("exist");

cy.fixture("three-tier-calm", null).as('architecture');
cy.get('input[type=file]').selectFile("@architecture", {force: true})

cy.get('canvas').should("exist");
cy.findByText(/relationship descriptions/i).should("exist");
cy.findByText(/node descriptions/i).should("exist");
})
})
Loading
Loading