Skip to content

Commit

Permalink
Merge branch 'develop' into issue#6279
Browse files Browse the repository at this point in the history
  • Loading branch information
Pranshu1902 authored Sep 13, 2023
2 parents f9d7f62 + cc6b570 commit f18eccb
Show file tree
Hide file tree
Showing 24 changed files with 321 additions and 130 deletions.
7 changes: 3 additions & 4 deletions .env
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Whitelabelling envs

REACT_APP_TITLE="CARE"
REACT_APP_META_DESCRIPTION="CoronaSafe Network is an open-source public utility designed by a multi-disciplinary team of innovators and volunteers. CoronaSafe Care is a Digital Public Good recognised by United Nations."
REACT_APP_TITLE=CARE
REACT_APP_META_DESCRIPTION=CoronaSafe Network is an open-source public utility designed by a multi-disciplinary team of innovators and volunteers. CoronaSafe Care is a Digital Public Good recognised by United Nations.
REACT_APP_COVER_IMAGE=https://cdn.coronasafe.network/care_logo.svg
REACT_APP_COVER_IMAGE_ALT=https://cdn.coronasafe.network/care_logo.svg
REACT_APP_CONFIG=""
REACT_PUBLIC_URL="https://care.coronasafe.in"
REACT_PUBLIC_URL=https://care.coronasafe.in

# Dev envs
ESLINT_NO_DEV_ERRORS=true
26 changes: 14 additions & 12 deletions .github/workflows/cypress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,22 @@ jobs:
repository: coronasafe/care
path: care

- name: Run docker compose up on care 🐳
run: cd care && touch .env && make docker_config_file=docker-compose.pre-built.yaml up && cd .. && sleep 60s
# Voluntarily kept 60 seconds delay to wait for migrations to complete.
- name: Start care docker containers 🐳
run: |
cd care
make docker_config_file=docker-compose.pre-built.yaml up
while docker compose exec backend bash -c "python manage.py showmigrations 2>/dev/null | cat | grep -q '\[ \]'"; do
>&2 echo "Migrations are not yet applied - sleeping"
sleep 5
done
echo "Migrations are applied"
cd ..
- name: Run Django collectstatic and load dummy data on care 🐍
- name: Load dummy data into care backend 📂
run: |
docker exec care python manage.py load_dummy_data
cd care
docker compose exec backend bash -c "python manage.py load_dummy_data"
cd ..
- name: Check care is up ♻
run: curl -o /dev/null -s -w "%{http_code}\n" http://localhost:9000
Expand Down Expand Up @@ -92,10 +101,3 @@ jobs:
name: cypress-screenshots
path: cypress/screenshots

# Test run video was always captured, so this action uses "always()" condition
- name: Upload cypress videos 📹
uses: actions/upload-artifact@v3
if: always()
with:
name: cypress-videos
path: cypress/videos
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public/build-meta.json
# Using NPM
yarn.lock
pnpm-lock.yaml
bun.lockb

# Cypress
cypress/downloads
Expand Down
89 changes: 89 additions & 0 deletions cypress/e2e/assets_spec/asset_homepage.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/// <reference types="cypress" />

import { cy, describe, before, beforeEach, it, afterEach } from "local-cypress";
import { AssetSearchPage } from "../../pageobject/Asset/AssetSearch";
import { AssetQRScanPage } from "../../pageobject/Asset/AssetQRScan";
import { AssetPagination } from "../../pageobject/Asset/AssetPagination";
import { AssetFilters } from "../../pageobject/Asset/AssetFilters";
import LoginPage from "../../pageobject/Login/LoginPage";
import { v4 as uuidv4 } from "uuid";

describe("Asset Tab", () => {
const assetSearchPage = new AssetSearchPage();
const assetQRScanPage = new AssetQRScanPage();
const assetPagination = new AssetPagination();
const assetFilters = new AssetFilters();
const loginPage = new LoginPage();
const assetName = "Dummy Camera 10";
const qrCode = uuidv4();
const serialNumber = Math.floor(Math.random() * 10 ** 10).toString();

before(() => {
loginPage.loginAsDisctrictAdmin();
cy.saveLocalStorage();
});

beforeEach(() => {
cy.restoreLocalStorage();
cy.awaitUrl("/assets");
});

// search for a element

it("Search Asset Name/QR_ID/Serial_number", () => {
assetSearchPage.typeSearchKeyword(assetName);
assetSearchPage.pressEnter();
assetSearchPage.verifyBadgeContent(assetName);
assetSearchPage.clickAssetByName(assetName);
assetSearchPage.clickUpdateButton();
assetSearchPage.clearAndTypeQRCode(qrCode);
assetSearchPage.clearAndTypeSerialNumber(serialNumber);
assetSearchPage.clickAssetSubmitButton();
assetSearchPage.visitAssetsPage();
assetSearchPage.typeSearchKeyword(qrCode);
assetSearchPage.pressEnter();
assetSearchPage.verifyAssetListContains(assetName);
assetSearchPage.verifyBadgeContent(qrCode);
assetSearchPage.typeSearchKeyword(serialNumber);
assetSearchPage.verifyAssetListContains(assetName);
assetSearchPage.verifyBadgeContent(serialNumber);
});

// scan a asset qr code

it("Scan Asset QR", () => {
assetQRScanPage.scanAssetQR();
});

// filter the asset and verify the badges are there

it("Filter Asset", () => {
assetFilters.filterAssets(
"Dummy Facility 1",
"INTERNAL",
"ACTIVE",
"ONVIF Camera",
"Camera Loc"
);
assetFilters.clickadvancefilter();
assetFilters.clickslideoverbackbutton(); // to verify the back button doesn't clear applied filters
assetFilters.assertFacilityText("Dummy Facility 1");
assetFilters.assertAssetTypeText("INTERNAL");
assetFilters.assertAssetClassText("ONVIF");
assetFilters.assertStatusText("ACTIVE");
assetFilters.assertLocationText("Camera Locations");
assetFilters.clickadvancefilter();
assetFilters.clearFilters();
});

// Verify the pagination in the page

it("Next/Previous Page", () => {
assetPagination.navigateToNextPage();
assetPagination.navigateToPreviousPage();
});

afterEach(() => {
cy.saveLocalStorage();
});
});
61 changes: 0 additions & 61 deletions cypress/e2e/assets_spec/asset_tab.cy.ts

This file was deleted.

39 changes: 38 additions & 1 deletion cypress/pageobject/Asset/AssetFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ export class AssetFilters {
facilityName: string,
assetType: string,
assetStatus: string,
assetClass: string
assetClass: string,
assetLocation: string
) {
cy.contains("Advanced Filters").click();
cy.get("input[name='Facilities']")
Expand All @@ -27,6 +28,42 @@ export class AssetFilters {
.then(() => {
cy.get("[role='option']").contains(assetClass).click();
});
cy.get("#Facilities-location")
.click()
.type(assetLocation)
.then(() => {
cy.get("[role='option']").contains(assetLocation).click();
});
cy.contains("Apply").click();
}
clearFilters() {
cy.intercept("GET", "**/api/v1/asset/**").as("clearAssets");
cy.get("#clear-filter").click();
cy.wait("@clearAssets").its("response.statusCode").should("eq", 200);
cy.url().should("match", /\/assets$/);
}
clickadvancefilter() {
cy.intercept("GET", "**/api/v1/getallfacilities/**").as("advancefilter");
cy.get("#advanced-filter").click();
cy.wait("@advancefilter").its("response.statusCode").should("eq", 200);
}
clickslideoverbackbutton() {
cy.get("#close-slide-over").click();
}
// Assertions
assertFacilityText(text) {
cy.get("[data-testid=Facility]").should("contain", text);
}
assertAssetTypeText(text) {
cy.get("[data-testid='Asset Type']").should("contain", text);
}
assertAssetClassText(text) {
cy.get("[data-testid='Asset Class']").should("contain", text);
}
assertStatusText(text) {
cy.get("[data-testid=Status]").should("contain", text);
}
assertLocationText(text) {
cy.get("[data-testid=Location]").should("contain", text);
}
}
49 changes: 44 additions & 5 deletions cypress/pageobject/Asset/AssetSearch.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,60 @@
export class AssetSearchPage {
typeSearchKeyword(keyword: string) {
cy.get("[name='search']").type(keyword);
cy.get("#search").click().clear();
cy.get("#search").click().type(keyword);
}

pressEnter() {
cy.get("[name='search']").type("{enter}");
}

verifyUrlChanged(initialUrl: string) {
cy.url().should((currentUrl) => {
expect(currentUrl).not.to.equal(initialUrl);
});
clickAssetByName(assetName: string) {
cy.intercept("GET", "**/api/v1/asset/**").as("clearAssets");
cy.get("[data-testid='created-asset-list']").contains(assetName).click();
cy.wait("@clearAssets").its("response.statusCode").should("eq", 200);
}

verifyBadgeContent(expectedText: string) {
cy.get("[data-testid='Name/Serial No./QR ID']").should(
"contain",
expectedText
);
}

verifyAssetIsPresent(assetName: string) {
cy.get("[data-testid=created-asset-list]")
.first()
.should("contain", assetName);
}

clickUpdateButton() {
cy.get("[data-testid='asset-update-button']").contains("Update").click();
}

clearAndTypeQRCode(qrCode: string) {
cy.get("#qr_code_id").clear();
cy.get("#qr_code_id").click().type(qrCode);
}

clearAndTypeSerialNumber(serialNumber: string) {
cy.get("#serial-number").clear();
cy.get("#serial-number").click().type(serialNumber);
}

clickAssetSubmitButton() {
cy.intercept("GET", "**/api/v1/asset/**").as("getAssets");
cy.get("#submit").click();
cy.wait("@getAssets").its("response.statusCode").should("eq", 200);
}

visitAssetsPage() {
cy.visit("/assets");
}

verifyAssetListContains(dummyCameraText: string) {
cy.get("[data-testid='created-asset-list']").should(
"contain",
dummyCameraText
);
}
}
1 change: 1 addition & 0 deletions src/CAREUI/interactive/SlideOver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export default function SlideOver({
>
<div className="flex items-center gap-2 p-2 pt-4">
<button
id="close-slide-over"
className="flex h-8 w-8 items-center justify-center rounded-lg text-2xl hover:bg-black/20"
onClick={() => {
setOpen(false);
Expand Down
3 changes: 2 additions & 1 deletion src/Common/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ export const ADMITTED_TO = [
{ id: "2", text: "ICU" },
{ id: "6", text: "Bed with oxygen support" },
{ id: "7", text: "Regular" },
{ id: "None", text: "No bed assigned" },
];

export const RESPIRATORY_SUPPORT = [
Expand Down Expand Up @@ -993,7 +994,7 @@ export const XLSXAssetImportSchema = {
return ip;
},
},
"Config: Camera Access Key": {
"Config - Camera Access Key": {
prop: "camera_access_key",
type: String,
},
Expand Down
10 changes: 4 additions & 6 deletions src/Common/hooks/useAppHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ export default function useAppHistory() {
const resetHistory = useContext(ResetHistoryContext);

const goBack = (fallbackUrl?: string) => {
if (history.length > 1)
// Navigate to history present in the app navigation history stack.
return navigate(history[1]);

if (fallbackUrl)
// Otherwise, use provided fallback url if provided.
// use provided fallback url if provided.
return navigate(fallbackUrl);

if (history.length > 1)
// Otherwise, navigate to history present in the app navigation history stack.
return navigate(history[1]);
// Otherwise, fallback to browser's go back behaviour.
window.history.back();
};
Expand Down
8 changes: 4 additions & 4 deletions src/Components/Assets/AssetFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ function AssetFilter(props: any) {
const applyFilter = () => {
const data = {
facility: facilityId,
asset_type: asset_type,
asset_class: asset_class,
status: asset_status,
asset_type: asset_type ?? "",
asset_class: asset_class ?? "",
status: asset_status ?? "",
location: locationId,
};
onChange(data);
Expand Down Expand Up @@ -148,7 +148,7 @@ function AssetFilter(props: any) {
<div className="w-full flex-none">
<FieldLabel>Location</FieldLabel>
<LocationSelect
name="Facilities"
name="Facilities-location"
setSelected={(selectedId) =>
handleLocationSelect((selectedId as string) || "")
}
Expand Down
Loading

0 comments on commit f18eccb

Please sign in to comment.