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{
|
const deleteChannelMutation = `mutation{
|
||||||
channelDelete(id: "${channelId}", input:{
|
channelDelete(id: "${channelId}", input:{
|
||||||
targetChannel: "${targetChennelId}"
|
targetChannel: "${targetChannelId}"
|
||||||
}){
|
}){
|
||||||
channel{
|
channel{
|
||||||
name
|
name
|
||||||
|
|
|
@ -50,7 +50,7 @@ class Checkout {
|
||||||
}`;
|
}`;
|
||||||
return cy.sendRequestWithQuery(mutation);
|
return cy.sendRequestWithQuery(mutation);
|
||||||
}
|
}
|
||||||
compliteCheckout(checkoutId) {
|
completeCheckout(checkoutId) {
|
||||||
const mutation = `mutation{
|
const mutation = `mutation{
|
||||||
checkoutComplete(checkoutId:"${checkoutId}"){
|
checkoutComplete(checkoutId:"${checkoutId}"){
|
||||||
order{
|
order{
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
export const DASHBOARD_SELECTORS = {
|
export const DASHBOARD_SELECTORS = {
|
||||||
sales: "div:nth-child(1) > [class*='HomeAnalyticsCard-cardContent']",
|
sales: "[data-test-id='sales-analytics']",
|
||||||
orders: "div:nth-child(2) > [class*='HomeAnalyticsCard-cardContent']",
|
orders: "[data-test-id='orders-analytics']",
|
||||||
activity: "[class*='Grid-root'] > div:nth-child(2) > [class*='MuiPaper']",
|
activity: "[data-test-id='activity-card']",
|
||||||
topProducts:
|
topProducts: "[data-test-id='top-products']",
|
||||||
"[class*='Grid-root'] > div:nth-child(1) > [class*='MuiPaper']:nth-child(4)",
|
ordersReadyToFulfill: "[data-test-id='orders-to-fulfill']",
|
||||||
ordersReadyToFulfill: "[class*='HomeNotificationTable'] > tr:nth-child(1)",
|
paymentsWaitingForCapture: "[data-test-id='orders-to-capture']",
|
||||||
paymentsWaitingForCapture:
|
productsOutOfStock: "[data-test-id='products-out-of-stock']",
|
||||||
"[class*='HomeNotificationTable'] > tr:nth-child(2)",
|
dataAreLoading: "[class*='Skeleton-skeleton']"
|
||||||
productsOutOfStock: "[class*='HomeNotificationTable'] > tr:nth-child(3)"
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,15 +30,15 @@ describe("User authorization", () => {
|
||||||
cy.clearSessionData().loginUserViaRequest();
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("should all elements be visible on the dashboard", () => {
|
it("should all elements be visible on the dashboard", () => {
|
||||||
cy.visit("/");
|
cy.visit("/")
|
||||||
softAssertVisibility(DASHBOARD_SELECTORS.sales);
|
.softAssertVisibility(DASHBOARD_SELECTORS.sales)
|
||||||
softAssertVisibility(DASHBOARD_SELECTORS.orders);
|
.softAssertVisibility(DASHBOARD_SELECTORS.orders)
|
||||||
softAssertVisibility(DASHBOARD_SELECTORS.activity);
|
.softAssertVisibility(DASHBOARD_SELECTORS.activity)
|
||||||
softAssertVisibility(DASHBOARD_SELECTORS.topProducts);
|
.softAssertVisibility(DASHBOARD_SELECTORS.topProducts)
|
||||||
softAssertVisibility(DASHBOARD_SELECTORS.ordersReadyToFulfill);
|
.softAssertVisibility(DASHBOARD_SELECTORS.ordersReadyToFulfill)
|
||||||
softAssertVisibility(DASHBOARD_SELECTORS.paymentsWaitingForCapture);
|
.softAssertVisibility(DASHBOARD_SELECTORS.paymentsWaitingForCapture)
|
||||||
softAssertVisibility(DASHBOARD_SELECTORS.productsOutOfStock);
|
.softAssertVisibility(DASHBOARD_SELECTORS.productsOutOfStock);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should correct amount of orders be displayed", () => {
|
it("should correct amount of orders be displayed", () => {
|
||||||
|
@ -47,6 +47,9 @@ describe("User authorization", () => {
|
||||||
const randomNameProductOutOfStock = `${startsWith}${faker.random.number()}`;
|
const randomNameProductOutOfStock = `${startsWith}${faker.random.number()}`;
|
||||||
const shippingPrice = 12;
|
const shippingPrice = 12;
|
||||||
const productPrice = 22;
|
const productPrice = 22;
|
||||||
|
let sales = productPrice * 2 + shippingPrice;
|
||||||
|
|
||||||
|
// Create channel, customer, product - everything needed to create order
|
||||||
cy.fixture("addresses").then(json => {
|
cy.fixture("addresses").then(json => {
|
||||||
channels
|
channels
|
||||||
.createChannel(true, randomName, randomName, json.plAddress.currency)
|
.createChannel(true, randomName, randomName, json.plAddress.currency)
|
||||||
|
@ -87,12 +90,16 @@ describe("User authorization", () => {
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const variantsList = productsUtils.getCreatedVariants();
|
const variantsList = productsUtils.getCreatedVariants();
|
||||||
ordersUtils.createReadyToFullfillOrder(
|
|
||||||
|
// Create order ready to fulfill
|
||||||
|
ordersUtils.createReadyToFulfillOrder(
|
||||||
customerId,
|
customerId,
|
||||||
shippingId,
|
shippingId,
|
||||||
channelId,
|
channelId,
|
||||||
variantsList
|
variantsList
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Create order waiting for capture
|
||||||
ordersUtils.createWaitingForCaptureOrder(
|
ordersUtils.createWaitingForCaptureOrder(
|
||||||
channelSlug,
|
channelSlug,
|
||||||
customerEmail,
|
customerEmail,
|
||||||
|
@ -100,6 +107,8 @@ describe("User authorization", () => {
|
||||||
shippingId
|
shippingId
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Create product out of stock
|
||||||
productsUtils.createProductInChannel(
|
productsUtils.createProductInChannel(
|
||||||
randomNameProductOutOfStock,
|
randomNameProductOutOfStock,
|
||||||
channelId,
|
channelId,
|
||||||
|
@ -120,18 +129,18 @@ describe("User authorization", () => {
|
||||||
.click()
|
.click()
|
||||||
.get(HEADER_SELECTORS.channelSelectList)
|
.get(HEADER_SELECTORS.channelSelectList)
|
||||||
.contains(randomName)
|
.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 = [];
|
errors = [];
|
||||||
isSoftAssertion = false;
|
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(() =>
|
.then(() =>
|
||||||
checkout
|
checkout
|
||||||
.addPayment(checkoutId, "mirumee.payments.dummy", "not-charged")
|
.addPayment(checkoutId, "mirumee.payments.dummy", "not-charged")
|
||||||
.then(() => checkout.compliteCheckout(checkoutId))
|
.then(() => checkout.completeCheckout(checkoutId))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
createReadyToFullfillOrder(
|
createReadyToFulfillOrder(
|
||||||
customerId,
|
customerId,
|
||||||
shippingMethodId,
|
shippingMethodId,
|
||||||
channelId,
|
channelId,
|
||||||
|
|
|
@ -121,4 +121,4 @@ class ProductsUtils {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default productsUtils;
|
export default ProductsUtils;
|
||||||
|
|
|
@ -38,6 +38,7 @@ const AppChannelSelect: React.FC<AppChannelSelectProps> = ({
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<SingleSelectField
|
<SingleSelectField
|
||||||
|
testId="app-channel-select"
|
||||||
choices={mapNodeToChoice(channels)}
|
choices={mapNodeToChoice(channels)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={selectedChannelId}
|
value={selectedChannelId}
|
||||||
|
|
|
@ -35,6 +35,7 @@ export interface Choice {
|
||||||
|
|
||||||
export type Choices = Choice[];
|
export type Choices = Choice[];
|
||||||
interface SingleSelectFieldProps {
|
interface SingleSelectFieldProps {
|
||||||
|
testId?: string;
|
||||||
choices: Choices;
|
choices: Choices;
|
||||||
className?: string;
|
className?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
@ -62,7 +63,8 @@ export const SingleSelectField: React.FC<SingleSelectFieldProps> = props => {
|
||||||
hint,
|
hint,
|
||||||
selectProps,
|
selectProps,
|
||||||
placeholder,
|
placeholder,
|
||||||
InputProps
|
InputProps,
|
||||||
|
testId
|
||||||
} = props;
|
} = props;
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
|
|
||||||
|
@ -84,6 +86,7 @@ export const SingleSelectField: React.FC<SingleSelectFieldProps> = props => {
|
||||||
{label}
|
{label}
|
||||||
</InputLabel>
|
</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
|
data-test-id={testId}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
fullWidth
|
fullWidth
|
||||||
renderValue={choiceValue =>
|
renderValue={choiceValue =>
|
||||||
|
|
|
@ -30,16 +30,17 @@ const useStyles = makeStyles(
|
||||||
|
|
||||||
interface HomeActivityCardProps {
|
interface HomeActivityCardProps {
|
||||||
activities: Home_activities_edges_node[];
|
activities: Home_activities_edges_node[];
|
||||||
|
testId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const HomeActivityCard: React.FC<HomeActivityCardProps> = props => {
|
const HomeActivityCard: React.FC<HomeActivityCardProps> = props => {
|
||||||
const { activities } = props;
|
const { activities, testId } = props;
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card data-test-id={testId}>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
defaultMessage: "Activity",
|
defaultMessage: "Activity",
|
||||||
|
|
|
@ -53,19 +53,20 @@ const useStyles = makeStyles(
|
||||||
);
|
);
|
||||||
|
|
||||||
interface HomeAnalyticsCardProps {
|
interface HomeAnalyticsCardProps {
|
||||||
|
testId?: string;
|
||||||
icon: React.ReactElement<IconProps>;
|
icon: React.ReactElement<IconProps>;
|
||||||
title: string;
|
title: string;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const HomeAnalyticsCard: React.FC<HomeAnalyticsCardProps> = props => {
|
const HomeAnalyticsCard: React.FC<HomeAnalyticsCardProps> = props => {
|
||||||
const { children, title, icon } = props;
|
const { children, title, icon, testId } = props;
|
||||||
|
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className={classes.cardSpacing}>
|
<Card className={classes.cardSpacing}>
|
||||||
<CardContent className={classes.cardContent}>
|
<CardContent className={classes.cardContent} data-test-id={testId}>
|
||||||
<div>
|
<div>
|
||||||
<Typography className={classes.cardTitle} variant="subtitle1">
|
<Typography className={classes.cardTitle} variant="subtitle1">
|
||||||
{title}
|
{title}
|
||||||
|
|
|
@ -111,7 +111,7 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||||
>
|
>
|
||||||
<TableRow hover={true} onClick={onOrdersToFulfillClick}>
|
<TableRow hover={true} onClick={onOrdersToFulfillClick}>
|
||||||
<TableCell>
|
<TableCell data-test-id="orders-to-fulfill">
|
||||||
{ordersToFulfill === undefined ? (
|
{ordersToFulfill === undefined ? (
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
) : ordersToFulfill === 0 ? (
|
) : ordersToFulfill === 0 ? (
|
||||||
|
@ -131,7 +131,7 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow hover={true} onClick={onOrdersToCaptureClick}>
|
<TableRow hover={true} onClick={onOrdersToCaptureClick}>
|
||||||
<TableCell>
|
<TableCell data-test-id="orders-to-capture">
|
||||||
{ordersToCapture === undefined ? (
|
{ordersToCapture === undefined ? (
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
) : ordersToCapture === 0 ? (
|
) : ordersToCapture === 0 ? (
|
||||||
|
@ -156,7 +156,7 @@ const HomeNotificationTable: React.FC<HomeNotificationTableProps> = props => {
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
requiredPermissions={[PermissionEnum.MANAGE_PRODUCTS]}
|
||||||
>
|
>
|
||||||
<TableRow hover={true} onClick={onProductsOutOfStockClick}>
|
<TableRow hover={true} onClick={onProductsOutOfStockClick}>
|
||||||
<TableCell>
|
<TableCell data-test-id="products-out-of-stock">
|
||||||
{productsOutOfStock === undefined ? (
|
{productsOutOfStock === undefined ? (
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
) : productsOutOfStock === 0 ? (
|
) : productsOutOfStock === 0 ? (
|
||||||
|
|
|
@ -95,6 +95,7 @@ const HomePage: React.FC<HomePageProps> = props => {
|
||||||
<div className={classes.cardContainer}>
|
<div className={classes.cardContainer}>
|
||||||
<HomeAnalyticsCard
|
<HomeAnalyticsCard
|
||||||
title={"Sales"}
|
title={"Sales"}
|
||||||
|
testId="sales-analytics"
|
||||||
icon={
|
icon={
|
||||||
<Sales
|
<Sales
|
||||||
className={classes.icon}
|
className={classes.icon}
|
||||||
|
@ -113,6 +114,7 @@ const HomePage: React.FC<HomePageProps> = props => {
|
||||||
</HomeAnalyticsCard>
|
</HomeAnalyticsCard>
|
||||||
<HomeAnalyticsCard
|
<HomeAnalyticsCard
|
||||||
title={"Orders"}
|
title={"Orders"}
|
||||||
|
testId="orders-analytics"
|
||||||
icon={
|
icon={
|
||||||
<Orders
|
<Orders
|
||||||
className={classes.icon}
|
className={classes.icon}
|
||||||
|
@ -152,6 +154,7 @@ const HomePage: React.FC<HomePageProps> = props => {
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<HomeProductListCard
|
<HomeProductListCard
|
||||||
|
testId="top-products"
|
||||||
onRowClick={onProductClick}
|
onRowClick={onProductClick}
|
||||||
topProducts={topProducts}
|
topProducts={topProducts}
|
||||||
/>
|
/>
|
||||||
|
@ -165,7 +168,10 @@ const HomePage: React.FC<HomePageProps> = props => {
|
||||||
userPermissions={userPermissions}
|
userPermissions={userPermissions}
|
||||||
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
requiredPermissions={[PermissionEnum.MANAGE_ORDERS]}
|
||||||
>
|
>
|
||||||
<HomeActivityCard activities={activities} />
|
<HomeActivityCard
|
||||||
|
activities={activities}
|
||||||
|
testId="activity-card"
|
||||||
|
/>
|
||||||
</RequirePermissions>
|
</RequirePermissions>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -46,18 +46,19 @@ const useStyles = makeStyles(
|
||||||
);
|
);
|
||||||
|
|
||||||
interface HomeProductListProps {
|
interface HomeProductListProps {
|
||||||
|
testId?: string;
|
||||||
topProducts: Home_productTopToday_edges_node[];
|
topProducts: Home_productTopToday_edges_node[];
|
||||||
onRowClick: (productId: string, variantId: string) => void;
|
onRowClick: (productId: string, variantId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const HomeProductList: React.FC<HomeProductListProps> = props => {
|
export const HomeProductList: React.FC<HomeProductListProps> = props => {
|
||||||
const { topProducts, onRowClick } = props;
|
const { topProducts, onRowClick, testId } = props;
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card data-test-id={testId}>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
defaultMessage: "Top Products",
|
defaultMessage: "Top Products",
|
||||||
|
|
Loading…
Reference in a new issue