tests for dashboard

This commit is contained in:
Karolina Rakoczy 2021-02-11 13:20:00 +01:00
parent fe9f55ee81
commit 27e5d912e4
14 changed files with 81 additions and 49 deletions

View file

@ -55,10 +55,10 @@ class Channels {
});
}
deleteChannel(channelId, targetChennelId) {
deleteChannel(channelId, targetChannelId) {
const deleteChannelMutation = `mutation{
channelDelete(id: "${channelId}", input:{
targetChannel: "${targetChennelId}"
targetChannel: "${targetChannelId}"
}){
channel{
name

View file

@ -50,7 +50,7 @@ class Checkout {
}`;
return cy.sendRequestWithQuery(mutation);
}
compliteCheckout(checkoutId) {
completeCheckout(checkoutId) {
const mutation = `mutation{
checkoutComplete(checkoutId:"${checkoutId}"){
order{

View file

@ -1,11 +1,10 @@
export const DASHBOARD_SELECTORS = {
sales: "div:nth-child(1) > [class*='HomeAnalyticsCard-cardContent']",
orders: "div:nth-child(2) > [class*='HomeAnalyticsCard-cardContent']",
activity: "[class*='Grid-root'] > div:nth-child(2) > [class*='MuiPaper']",
topProducts:
"[class*='Grid-root'] > div:nth-child(1) > [class*='MuiPaper']:nth-child(4)",
ordersReadyToFulfill: "[class*='HomeNotificationTable'] > tr:nth-child(1)",
paymentsWaitingForCapture:
"[class*='HomeNotificationTable'] > tr:nth-child(2)",
productsOutOfStock: "[class*='HomeNotificationTable'] > tr:nth-child(3)"
sales: "[data-test-id='sales-analytics']",
orders: "[data-test-id='orders-analytics']",
activity: "[data-test-id='activity-card']",
topProducts: "[data-test-id='top-products']",
ordersReadyToFulfill: "[data-test-id='orders-to-fulfill']",
paymentsWaitingForCapture: "[data-test-id='orders-to-capture']",
productsOutOfStock: "[data-test-id='products-out-of-stock']",
dataAreLoading: "[class*='Skeleton-skeleton']"
};

View file

@ -30,15 +30,15 @@ describe("User authorization", () => {
cy.clearSessionData().loginUserViaRequest();
});
xit("should all elements be visible on the dashboard", () => {
cy.visit("/");
softAssertVisibility(DASHBOARD_SELECTORS.sales);
softAssertVisibility(DASHBOARD_SELECTORS.orders);
softAssertVisibility(DASHBOARD_SELECTORS.activity);
softAssertVisibility(DASHBOARD_SELECTORS.topProducts);
softAssertVisibility(DASHBOARD_SELECTORS.ordersReadyToFulfill);
softAssertVisibility(DASHBOARD_SELECTORS.paymentsWaitingForCapture);
softAssertVisibility(DASHBOARD_SELECTORS.productsOutOfStock);
it("should all elements be visible on the dashboard", () => {
cy.visit("/")
.softAssertVisibility(DASHBOARD_SELECTORS.sales)
.softAssertVisibility(DASHBOARD_SELECTORS.orders)
.softAssertVisibility(DASHBOARD_SELECTORS.activity)
.softAssertVisibility(DASHBOARD_SELECTORS.topProducts)
.softAssertVisibility(DASHBOARD_SELECTORS.ordersReadyToFulfill)
.softAssertVisibility(DASHBOARD_SELECTORS.paymentsWaitingForCapture)
.softAssertVisibility(DASHBOARD_SELECTORS.productsOutOfStock);
});
it("should correct amount of orders be displayed", () => {
@ -47,6 +47,9 @@ describe("User authorization", () => {
const randomNameProductOutOfStock = `${startsWith}${faker.random.number()}`;
const shippingPrice = 12;
const productPrice = 22;
let sales = productPrice * 2 + shippingPrice;
// Create channel, customer, product - everything needed to create order
cy.fixture("addresses").then(json => {
channels
.createChannel(true, randomName, randomName, json.plAddress.currency)
@ -87,12 +90,16 @@ describe("User authorization", () => {
)
.then(() => {
const variantsList = productsUtils.getCreatedVariants();
ordersUtils.createReadyToFullfillOrder(
// Create order ready to fulfill
ordersUtils.createReadyToFulfillOrder(
customerId,
shippingId,
channelId,
variantsList
);
// Create order waiting for capture
ordersUtils.createWaitingForCaptureOrder(
channelSlug,
customerEmail,
@ -100,6 +107,8 @@ describe("User authorization", () => {
shippingId
);
});
// Create product out of stock
productsUtils.createProductInChannel(
randomNameProductOutOfStock,
channelId,
@ -120,18 +129,18 @@ describe("User authorization", () => {
.click()
.get(HEADER_SELECTORS.channelSelectList)
.contains(randomName)
.click();
.click()
.get(DASHBOARD_SELECTORS.dataAreLoading)
.should("not.exist");
const regex = /^1\D+/;
sales = sales.toFixed(2).replace(".", ",");
cy.softAssertMatch(DASHBOARD_SELECTORS.ordersReadyToFulfill, regex)
.softAssertMatch(DASHBOARD_SELECTORS.paymentsWaitingForCapture, regex)
.softAssertMatch(DASHBOARD_SELECTORS.productsOutOfStock, regex)
.softAssertMatch(
DASHBOARD_SELECTORS.sales,
new RegExp(`\\D+${sales}\\D+`)
)
.softAssertMatch(DASHBOARD_SELECTORS.orders, /\D+2\D*/);
});
function softAssertVisibility(selector) {
cy.get(selector).then(element => chai.softExpect(element).to.be.visible);
}
function softAssertMatch(selector, regexp) {
cy.get(selector)
.invoke("text")
.then(text =>
chai.softExpect(assert.match(text, regexp, "regexp matches"))
);
}
});

View file

@ -76,3 +76,14 @@ afterEach(() => {
errors = [];
isSoftAssertion = false;
});
Cypress.Commands.add("softAssertMatch", (selector, regexp) => {
cy.get(selector)
.invoke("text")
.then(text =>
chai.softExpect(assert.match(text, regexp, "regexp matches"))
);
});
Cypress.Commands.add("softAssertVisibility", selector => {
cy.get(selector).then(element => chai.softExpect(element).to.be.visible);
});

View file

@ -19,11 +19,11 @@ class OrdersUtils {
.then(() =>
checkout
.addPayment(checkoutId, "mirumee.payments.dummy", "not-charged")
.then(() => checkout.compliteCheckout(checkoutId))
.then(() => checkout.completeCheckout(checkoutId))
);
});
}
createReadyToFullfillOrder(
createReadyToFulfillOrder(
customerId,
shippingMethodId,
channelId,

View file

@ -121,4 +121,4 @@ class ProductsUtils {
});
}
}
export default productsUtils;
export default ProductsUtils;

View file

@ -38,6 +38,7 @@ const AppChannelSelect: React.FC<AppChannelSelectProps> = ({
return (
<div className={classes.root}>
<SingleSelectField
testId="app-channel-select"
choices={mapNodeToChoice(channels)}
disabled={disabled}
value={selectedChannelId}

View file

@ -35,6 +35,7 @@ export interface Choice {
export type Choices = Choice[];
interface SingleSelectFieldProps {
testId?: string;
choices: Choices;
className?: string;
disabled?: boolean;
@ -62,7 +63,8 @@ export const SingleSelectField: React.FC<SingleSelectFieldProps> = props => {
hint,
selectProps,
placeholder,
InputProps
InputProps,
testId
} = props;
const classes = useStyles(props);
@ -84,6 +86,7 @@ export const SingleSelectField: React.FC<SingleSelectFieldProps> = props => {
{label}
</InputLabel>
<Select
data-test-id={testId}
variant="outlined"
fullWidth
renderValue={choiceValue =>

View file

@ -30,16 +30,17 @@ const useStyles = makeStyles(
interface HomeActivityCardProps {
activities: Home_activities_edges_node[];
testId?: string;
}
const HomeActivityCard: React.FC<HomeActivityCardProps> = props => {
const { activities } = props;
const { activities, testId } = props;
const classes = useStyles(props);
const intl = useIntl();
return (
<Card>
<Card data-test-id={testId}>
<CardTitle
title={intl.formatMessage({
defaultMessage: "Activity",

View file

@ -53,19 +53,20 @@ const useStyles = makeStyles(
);
interface HomeAnalyticsCardProps {
testId?: string;
icon: React.ReactElement<IconProps>;
title: string;
children?: React.ReactNode;
}
const HomeAnalyticsCard: React.FC<HomeAnalyticsCardProps> = props => {
const { children, title, icon } = props;
const { children, title, icon, testId } = props;
const classes = useStyles(props);
return (
<Card className={classes.cardSpacing}>
<CardContent className={classes.cardContent}>
<CardContent className={classes.cardContent} data-test-id={testId}>
<div>
<Typography className={classes.cardTitle} variant="subtitle1">
{title}

View file

@ -111,7 +111,7 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
>
<TableRow hover={true} onClick={onOrdersToFulfillClick}>
<TableCell>
<TableCell data-test-id="orders-to-fulfill">
{ordersToFulfill === undefined ? (
<Skeleton />
) : ordersToFulfill === 0 ? (
@ -131,7 +131,7 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
</TableCell>
</TableRow>
<TableRow hover={true} onClick={onOrdersToCaptureClick}>
<TableCell>
<TableCell data-test-id="orders-to-capture">
{ordersToCapture === undefined ? (
<Skeleton />
) : ordersToCapture === 0 ? (
@ -156,7 +156,7 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
requiredPermissions={[PermissionEnum.MANAGE_PRODUCTS]}
>
<TableRow hover={true} onClick={onProductsOutOfStockClick}>
<TableCell>
<TableCell data-test-id="products-out-of-stock">
{productsOutOfStock === undefined ? (
<Skeleton />
) : productsOutOfStock === 0 ? (

View file

@ -95,6 +95,7 @@ const HomePage: React.FC<HomePageProps> = props => {
<div className={classes.cardContainer}>
<HomeAnalyticsCard
title={"Sales"}
testId="sales-analytics"
icon={
<Sales
className={classes.icon}
@ -113,6 +114,7 @@ const HomePage: React.FC<HomePageProps> = props => {
</HomeAnalyticsCard>
<HomeAnalyticsCard
title={"Orders"}
testId="orders-analytics"
icon={
<Orders
className={classes.icon}
@ -152,6 +154,7 @@ const HomePage: React.FC<HomePageProps> = props => {
]}
>
<HomeProductListCard
testId="top-products"
onRowClick={onProductClick}
topProducts={topProducts}
/>
@ -165,7 +168,10 @@ const HomePage: React.FC<HomePageProps> = props => {
userPermissions={userPermissions}
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
>
<HomeActivityCard activities={activities} />
<HomeActivityCard
activities={activities}
testId="activity-card"
/>
</RequirePermissions>
</div>
)}

View file

@ -46,18 +46,19 @@ const useStyles = makeStyles(
);
interface HomeProductListProps {
testId?: string;
topProducts: Home_productTopToday_edges_node[];
onRowClick: (productId: string, variantId: string) => void;
}
export const HomeProductList: React.FC<HomeProductListProps> = props => {
const { topProducts, onRowClick } = props;
const { topProducts, onRowClick, testId } = props;
const classes = useStyles(props);
const intl = useIntl();
return (
<Card>
<Card data-test-id={testId}>
<CardTitle
title={intl.formatMessage({
defaultMessage: "Top Products",