tests for dashboard
This commit is contained in:
parent
fe9f55ee81
commit
27e5d912e4
14 changed files with 81 additions and 49 deletions
|
@ -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
|
||||
|
|
|
@ -50,7 +50,7 @@ class Checkout {
|
|||
}`;
|
||||
return cy.sendRequestWithQuery(mutation);
|
||||
}
|
||||
compliteCheckout(checkoutId) {
|
||||
completeCheckout(checkoutId) {
|
||||
const mutation = `mutation{
|
||||
checkoutComplete(checkoutId:"${checkoutId}"){
|
||||
order{
|
||||
|
|
|
@ -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']"
|
||||
};
|
||||
|
|
|
@ -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"))
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -121,4 +121,4 @@ class ProductsUtils {
|
|||
});
|
||||
}
|
||||
}
|
||||
export default productsUtils;
|
||||
export default ProductsUtils;
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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 =>
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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 ? (
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue