diff --git a/.github/workflows/critical-tests.yml b/.github/workflows/critical-tests.yml
new file mode 100644
index 000000000..ae976a587
--- /dev/null
+++ b/.github/workflows/critical-tests.yml
@@ -0,0 +1,67 @@
+name: RUN_CRITICAL_TESTS
+
+# Only trigger, when the build workflow succeeded
+on:
+ workflow_run:
+ workflows: [TEST-ENV-DEPLOYMENT]
+ types: [completed]
+
+jobs:
+ cypress-run-critical:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v1
+
+ - name: Get API_URI
+ id: api_uri
+ # Search for API_URI in PR description and use default if not defined
+ env:
+ pull_request_body: ${{ github.event.pull_request.body }}
+ prefix: API_URI=
+ pattern: (http|https)://[a-zA-Z0-9.-]+/graphql/?
+ fallback_uri: ${{ secrets.CYPRESS_API_URI }}
+ run: |
+ echo "::set-output name=custom_api_uri::$(echo $pull_request_body | grep -Eo "$prefix$pattern" | sed s/$prefix// | head -n 1 | { read custom_uri; if [ -z "$custom_uri" ]; then echo "$fallback_uri"; else echo "$custom_uri"; fi })"
+ - name: Get base_URL
+ id: base_URL
+ run: |
+ echo "::set-output name=base_URL::https://$(echo ${GITHUB_HEAD_REF}).dashboard.saleor.rocks"
+ - name: Setup Node
+ uses: actions/setup-node@v1
+ with:
+ node-version: 14
+
+ - name: Cache node modules
+ uses: actions/cache@v2
+ env:
+ cache-name: cache-node-modules
+ with:
+ path: ~/.npm
+ key: ${{ runner.os }}-qa-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-qa-${{ env.cache-name }}-
+ ${{ runner.os }}-qa-
+ ${{ runner.os }}-
+
+ - name: Install Dependencies
+ if: steps.cache-node-modules.outputs.cache-hit != 'true'
+ run: npm install
+
+ - name: Cypress run critical
+ uses: cypress-io/github-action@v2
+ env:
+ API_URI: ${{ steps.api_uri.outputs.custom_api_uri }}
+ APP_MOUNT_URI: ${{ secrets.APP_MOUNT_URI }}
+ CYPRESS_baseUrl: ${{ steps.base_URL.outputs.base_URL }}
+ CYPRESS_USER_NAME: ${{ secrets.CYPRESS_USER_NAME }}
+ CYPRESS_SECOND_USER_NAME: ${{ secrets.CYPRESS_SECOND_USER_NAME }}
+ CYPRESS_USER_PASSWORD: ${{ secrets.CYPRESS_USER_PASSWORD }}
+ CYPRESS_PERMISSIONS_USERS_PASSWORD: ${{ secrets.CYPRESS_PERMISSIONS_USERS_PASSWORD }}
+ with:
+ command: npm run cy:run:critical
+ wait-on: ${{ steps.base_URL.outputs.base_URL }}
+ - uses: actions/upload-artifact@v1
+ with:
+ name: cypress-videos
+ path: cypress/videos
\ No newline at end of file
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 90516815c..aaef1f3d7 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -69,45 +69,4 @@ jobs:
if: ${{ failure() }}
with:
name: cypress-videos
- path: cypress/videos
-
- cypress-run-critical:
- if: github.event.pull_request.head.repo.full_name == 'saleor/saleor-dashboard' && ((github.event.label.name != 'run e2e') || !(contains(github.event.pull_request.labels.*.name, 'run e2e')))
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v1
-
- - name: Get API_URI
- id: api_uri
- # Search for CYPRESS_API_URI in PR description and use default if not defined
- env:
- pull_request_body: ${{ github.event.pull_request.body }}
- prefix: CYPRESS_API_URI=
- pattern: (http|https)://[a-zA-Z0-9.-]+/graphql/?
- fallback_uri: ${{ secrets.CYPRESS_API_URI }}
- run: |
- echo "::set-output name=custom_api_uri::$(echo $pull_request_body | grep -Eo "$prefix$pattern" | sed s/$prefix// | head -n 1 | { read custom_uri; if [ -z "$custom_uri" ]; then echo "$fallback_uri"; else echo "$custom_uri"; fi })"
-
- - name: Cypress run critical
- if: ${{ steps.api_uri.outputs.custom_api_uri != 'https://qa.staging.saleor.cloud/graphql/' }}
- uses: cypress-io/github-action@v2
- env:
- API_URI: ${{ steps.api_uri.outputs.custom_api_uri }}
- APP_MOUNT_URI: ${{ secrets.APP_MOUNT_URI }}
- CYPRESS_baseUrl: ${{ secrets.CYPRESS_BASEURL }}
- CYPRESS_USER_NAME: ${{ secrets.CYPRESS_USER_NAME }}
- CYPRESS_SECOND_USER_NAME: ${{ secrets.CYPRESS_SECOND_USER_NAME }}
- CYPRESS_USER_PASSWORD: ${{ secrets.CYPRESS_USER_PASSWORD }}
- CYPRESS_PERMISSIONS_USERS_PASSWORD: ${{ secrets.CYPRESS_PERMISSIONS_USERS_PASSWORD }}
- with:
- build: npm run build
- start: npx local-web-server --spa index.html
- wait-on: http://localhost:9000/
- wait-on-timeout: 120
- command: npm run cy:run:critical
- - uses: actions/upload-artifact@v1
- if: ${{ failure() }}
- with:
- name: cypress-videos
- path: cypress/videos
+ path: cypress/videos
\ No newline at end of file
diff --git a/cypress.json b/cypress.json
index add66683b..ac36119b8 100644
--- a/cypress.json
+++ b/cypress.json
@@ -6,5 +6,6 @@
"defaultCommandTimeout": 15000,
"requestTimeout": 15000,
"viewportWidth": 1400,
- "viewportHeight": 660
+ "viewportHeight": 660,
+ "videos": false
}
\ No newline at end of file
diff --git a/cypress/fixtures/permissionsUsers.js b/cypress/fixtures/permissionsUsers.js
index 22105318b..bece4f5d1 100644
--- a/cypress/fixtures/permissionsUsers.js
+++ b/cypress/fixtures/permissionsUsers.js
@@ -4,65 +4,81 @@ import { ONE_PERMISSION_USERS, TEST_ADMIN_USER } from "./users";
export const PERMISSIONS_OPTIONS = {
all: {
user: TEST_ADMIN_USER,
- permissions: Object.values(PERMISSIONS)
+ permissions: Object.values(PERMISSIONS),
+ testCase: "TC: SALEOR_3401"
},
app: {
user: ONE_PERMISSION_USERS.app,
- permissions: [PERMISSIONS.app]
+ permissions: [PERMISSIONS.app],
+ testCase: "TC: SALEOR_3402"
},
channel: {
user: ONE_PERMISSION_USERS.channel,
- permissions: [PERMISSIONS.channel]
+ permissions: [PERMISSIONS.channel],
+ testCase: "TC: SALEOR_3403"
},
customer: {
user: ONE_PERMISSION_USERS.user,
- permissions: [PERMISSIONS.customer]
+ permissions: [PERMISSIONS.customer],
+ testCase: "TC: SALEOR_3404"
},
discount: {
user: ONE_PERMISSION_USERS.discount,
- permissions: [PERMISSIONS.discounts]
+ permissions: [PERMISSIONS.discounts],
+ testCase: "TC: SALEOR_3405"
},
giftCard: {
- user: ONE_PERMISSION_USERS.giftCard
+ user: ONE_PERMISSION_USERS.giftCard,
+ testCase: "TC: SALEOR_3406"
},
order: {
user: ONE_PERMISSION_USERS.order,
- permissions: [PERMISSIONS.order]
+ permissions: [PERMISSIONS.order],
+ testCase: "TC: SALEOR_3407"
},
page: {
user: ONE_PERMISSION_USERS.page,
- permissions: [PERMISSIONS.page]
+ permissions: [PERMISSIONS.page],
+ testCase: "TC: SALEOR_3408"
},
plugin: {
user: ONE_PERMISSION_USERS.plugin,
- permissions: [PERMISSIONS.plugin]
+ permissions: [PERMISSIONS.plugin],
+ testCase: "TC: SALEOR_3409"
},
product: {
user: ONE_PERMISSION_USERS.product,
- permissions: [PERMISSIONS.product, PERMISSIONS.warehouse]
+ permissions: [PERMISSIONS.product, PERMISSIONS.warehouse],
+ testCase: "TC: SALEOR_3410"
},
productTypeAndAttribute: {
user: ONE_PERMISSION_USERS.productTypeAndAttribute,
- permissions: [PERMISSIONS.productTypeAndAttribute]
+ permissions: [PERMISSIONS.productTypeAndAttribute],
+ testCase: "TC: SALEOR_3411"
},
pageTypeAndAttribute: {
user: ONE_PERMISSION_USERS.pageTypeAndAttribute,
- permissions: [PERMISSIONS.pageTypeAndAttribute]
+ permissions: [PERMISSIONS.pageTypeAndAttribute],
+ testCase: "TC: SALEOR_3412"
},
settings: {
user: ONE_PERMISSION_USERS.settings,
- permissions: [PERMISSIONS.settings]
+ permissions: [PERMISSIONS.settings],
+ testCase: "TC: SALEOR_3413"
},
shipping: {
user: ONE_PERMISSION_USERS.shipping,
- permissions: [PERMISSIONS.shipping]
+ permissions: [PERMISSIONS.shipping],
+ testCase: "TC: SALEOR_3415"
},
staff: {
user: ONE_PERMISSION_USERS.staff,
- permissions: [PERMISSIONS.staff]
+ permissions: [PERMISSIONS.staff],
+ testCase: "TC: SALEOR_3414"
},
translations: {
user: ONE_PERMISSION_USERS.translations,
- permissions: [PERMISSIONS.translations]
+ permissions: [PERMISSIONS.translations],
+ testCase: "TC: SALEOR_3416"
}
};
diff --git a/cypress/integration/checkout/purchaseWithProductTypes.js b/cypress/integration/checkout/purchaseWithProductTypes.js
index 658bc80c7..a4c7a6e6b 100644
--- a/cypress/integration/checkout/purchaseWithProductTypes.js
+++ b/cypress/integration/checkout/purchaseWithProductTypes.js
@@ -3,21 +3,13 @@
import faker from "faker";
-import { createAttribute } from "../../support/api/requests/Attribute";
-import { createCategory } from "../../support/api/requests/Category";
import {
checkoutShippingAddressUpdate,
- checkoutShippingMethodUpdate,
checkoutVariantsUpdate,
completeCheckout,
createCheckout
} from "../../support/api/requests/Checkout";
import { getOrder } from "../../support/api/requests/Order";
-import {
- createDigitalContent,
- createTypeProduct
-} from "../../support/api/requests/ProductType";
-import { getDefaultChannel } from "../../support/api/utils/channelsUtils";
import {
addPayment,
createAndCompleteCheckoutWithoutShipping,
@@ -25,110 +17,46 @@ import {
getShippingMethodIdFromCheckout,
updateShippingInCheckout
} from "../../support/api/utils/ordersUtils";
-import {
- addDigitalContentAndUpdateProductType,
- createProductInChannel,
- deleteProductsStartsWith
-} from "../../support/api/utils/products/productsUtils";
-import {
- createShipping,
- deleteShippingStartsWith
-} from "../../support/api/utils/shippingUtils";
+import { createDigitalAndPhysicalProductWithNewDataAndDefaultChannel } from "../../support/api/utils/products/productsUtils";
import filterTests from "../../support/filterTests";
-filterTests({ definedTags: ["all", "critical"] }, () => {
- describe("Purchase products with all products types", () => {
+filterTests({ definedTags: ["all", "critical", "refactored"] }, () => {
+ describe("As an unlogged customer I want to order physical and digital products", () => {
const startsWith = `CyPurchaseByType`;
- const name = `${startsWith}${faker.datatype.number()}`;
const email = `${startsWith}@example.com`;
const testsMessage = "Check order status";
+ const digitalName = `${startsWith}${faker.datatype.number()}`;
+ const physicalName = `${startsWith}${faker.datatype.number()}`;
const { softExpect } = chai;
let defaultChannel;
let address;
- let warehouse;
- let attribute;
- let category;
let shippingMethod;
- let createProductData;
+ let digitalVariants;
+ let physicalVariants;
before(() => {
cy.clearSessionData().loginUserViaRequest();
- deleteProductsStartsWith(startsWith);
- deleteShippingStartsWith(startsWith);
- getDefaultChannel().then(channelResp => (defaultChannel = channelResp));
- cy.fixture("addresses")
- .then(addresses => {
- address = addresses.usAddress;
- createShipping({
- channelId: defaultChannel.id,
- name,
- address,
- price: 10
- });
- })
- .then(
- ({
- warehouse: warehouseResp,
- shippingMethod: shippingMethodResp
- }) => {
- warehouse = warehouseResp;
- shippingMethod = shippingMethodResp;
- }
- );
- createAttribute({ name })
- .then(attributeResp => {
- attribute = attributeResp;
- createCategory({ name });
- })
- .then(categoryResp => {
- category = categoryResp;
- });
+ createDigitalAndPhysicalProductWithNewDataAndDefaultChannel({
+ physicalProductName: physicalName,
+ digitalProductName: digitalName
+ }).then(resp => {
+ defaultChannel = resp.defaultChannel;
+ address = resp.address;
+ shippingMethod = resp.shippingMethod;
+ digitalVariants = resp.digitalVariants;
+ physicalVariants = resp.physicalVariants;
+ });
});
- beforeEach(() => {
- cy.clearSessionData().loginUserViaRequest();
- createProductData = {
- channelId: defaultChannel.id,
- warehouseId: warehouse.id,
- quantityInWarehouse: 10,
- attributeId: attribute.id,
- categoryId: category.id,
- price: 10
- };
- });
-
- it("should purchase digital product", () => {
- const digitalName = `${startsWith}${faker.datatype.number()}`;
- let variants;
-
- createTypeProduct({
- name: digitalName,
- attributeId: attribute.id,
- shippable: false
+ it("should purchase digital product as unlogged customer. TC: SALEOR_0402", () => {
+ createAndCompleteCheckoutWithoutShipping({
+ channelSlug: defaultChannel.slug,
+ email,
+ billingAddress: address,
+ variantsList: digitalVariants,
+ auth: "token"
})
- .then(productType => {
- createProductData.name = digitalName;
- createProductData.productTypeId = productType.id;
- createProductInChannel(createProductData);
- })
- .then(({ variantsList }) => {
- variants = variantsList;
- addDigitalContentAndUpdateProductType(
- variants[0].id,
- createProductData.productTypeId,
- defaultChannel.id
- );
- })
- .then(() => {
- createAndCompleteCheckoutWithoutShipping({
- channelSlug: defaultChannel.slug,
- email,
- billingAddress: address,
- variantsList: variants,
- auth: "token"
- });
- })
.then(({ order }) => {
getOrder(order.id);
})
@@ -141,27 +69,14 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
});
});
- it("should purchase physical product", () => {
- const physicalName = `${startsWith}${faker.datatype.number()}`;
- createTypeProduct({
- name: physicalName,
- attributeId: attribute.id,
- shippable: true
+ it("should purchase physical product as unlogged customer. TC: SALEOR_0403", () => {
+ createWaitingForCaptureOrder({
+ channelSlug: defaultChannel.slug,
+ email,
+ variantsList: physicalVariants,
+ shippingMethodName: shippingMethod.name,
+ address
})
- .then(productType => {
- createProductData.name = physicalName;
- createProductData.productTypeId = productType.id;
- createProductInChannel(createProductData);
- })
- .then(({ variantsList }) => {
- createWaitingForCaptureOrder({
- channelSlug: defaultChannel.slug,
- email,
- variantsList,
- shippingMethodName: shippingMethod.name,
- address
- });
- })
.then(({ order }) => {
getOrder(order.id);
})
@@ -174,52 +89,22 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
});
});
- it("should purchase multiple products with all product types", () => {
- const physicalName = `${startsWith}${faker.datatype.number()}`;
- const digitalName = `${startsWith}${faker.datatype.number()}`;
- let digitalProductVariantsList;
+ it("should purchase multiple products with all product types as unlogged customer. TC: SALEOR_0404", () => {
let checkout;
- createTypeProduct({
- name: digitalName,
- attributeId: attribute.id,
- shippable: false
+
+ createCheckout({
+ channelSlug: defaultChannel.slug,
+ email,
+ variantsList: digitalVariants,
+ billingAddress: address,
+ auth: "token"
})
- .then(productType => {
- createProductData.name = digitalName;
- createProductData.productTypeId = productType.id;
- createProductInChannel(createProductData);
- })
- .then(({ variantsList }) => {
- digitalProductVariantsList = variantsList;
- createDigitalContent(variantsList[0].id);
- })
- .then(() => {
- createCheckout({
- channelSlug: defaultChannel.slug,
- email,
- variantsList: digitalProductVariantsList,
- billingAddress: address,
- auth: "token"
- });
- })
.then(({ checkout: checkoutResp }) => {
checkout = checkoutResp;
addPayment(checkout.id);
})
.then(() => {
- createTypeProduct({
- name: physicalName,
- attributeId: attribute.id,
- shippable: true
- });
- })
- .then(productType => {
- createProductData.name = physicalName;
- createProductData.productTypeId = productType.id;
- createProductInChannel(createProductData);
- })
- .then(({ variantsList }) => {
- checkoutVariantsUpdate(checkout.id, variantsList);
+ checkoutVariantsUpdate(checkout.id, physicalVariants);
})
.then(() => {
const shippingMethodId = getShippingMethodIdFromCheckout(
diff --git a/cypress/integration/checkout/stocksInCheckout.js b/cypress/integration/checkout/stocksInCheckout.js
index 6619cd1cc..598948357 100644
--- a/cypress/integration/checkout/stocksInCheckout.js
+++ b/cypress/integration/checkout/stocksInCheckout.js
@@ -8,114 +8,70 @@ import {
createCheckout
} from "../../support/api/requests/Checkout";
import { getVariants } from "../../support/api/requests/Product";
-import { getDefaultChannel } from "../../support/api/utils/channelsUtils";
-import { createOrderWithNewProduct } from "../../support/api/utils/ordersUtils";
-import {
- createProductInChannel,
- createTypeAttributeAndCategoryForProduct,
- deleteProductsStartsWith
-} from "../../support/api/utils/products/productsUtils";
-import {
- createShipping,
- deleteShippingStartsWith
-} from "../../support/api/utils/shippingUtils";
+import { createWaitingForCaptureOrder } from "../../support/api/utils/ordersUtils";
+import { createNewProductWithSeveralVariants } from "../../support/api/utils/products/productsUtils";
import filterTests from "../../support/filterTests";
-filterTests({ definedTags: ["all", "critical"] }, () => {
- describe("Products stocks in checkout", () => {
+filterTests({ definedTags: ["all", "critical", "refactored"] }, () => {
+ describe("Manage products stocks in checkout", () => {
const startsWith = "CyStocksCheckout-";
const name = `${startsWith}${faker.datatype.number()}`;
let defaultChannel;
let address;
- let warehouse;
- let attribute;
- let category;
- let productType;
let shippingMethod;
+ let variantsWithLowStock;
+ let variantsWithoutTrackInventory;
+ let lastVariantInStock;
before(() => {
cy.clearSessionData().loginUserViaRequest();
- deleteProductsStartsWith(startsWith);
- deleteShippingStartsWith(startsWith);
- cy.fixture("addresses")
- .then(addresses => {
- address = addresses.usAddress;
- getDefaultChannel();
- })
- .then(channel => {
- defaultChannel = channel;
- createShipping({
- channelId: defaultChannel.id,
- name,
- address
- });
- })
- .then(
- ({
- warehouse: warehouseResp,
- shippingMethod: shippingMethodResp
- }) => {
- warehouse = warehouseResp;
- shippingMethod = shippingMethodResp;
- createTypeAttributeAndCategoryForProduct({ name });
- }
- )
- .then(
- ({
- attribute: attributeResp,
- category: categoryResp,
- productType: productTypeResp
- }) => {
- attribute = attributeResp;
- category = categoryResp;
- productType = productTypeResp;
- }
- );
- });
- it("should create checkout with last product in stock", () => {
- const productName = `${startsWith}${faker.datatype.number()}`;
- createOrderWithNewProduct({
- attributeId: attribute.id,
- categoryId: category.id,
- productTypeId: productType.id,
- channel: defaultChannel,
- name: productName,
- warehouseId: warehouse.id,
- shippingMethod,
- address
- }).then(({ order }) => {
- expect(order, "order should be created").to.be.ok;
+ const variantsData = [
+ {
+ name: "variantsWithLowStock",
+ trackInventory: true,
+ quantityInWarehouse: 1
+ },
+ {
+ name: "variantsWithoutTrackInventory",
+ trackInventory: false,
+ quantityInWarehouse: 0
+ },
+ {
+ name: "lastVariantInStock",
+ trackInventory: true,
+ quantityInWarehouse: 1
+ }
+ ];
+
+ createNewProductWithSeveralVariants(name, variantsData).then(resp => {
+ defaultChannel = resp.defaultChannel;
+ address = resp.address;
+ shippingMethod = resp.shippingMethod;
+ variantsWithLowStock = resp.createdVariants.find(
+ variant => variant.name === "variantsWithLowStock"
+ );
+ variantsWithoutTrackInventory = resp.createdVariants.find(
+ variant => variant.name === "variantsWithoutTrackInventory"
+ );
+ lastVariantInStock = resp.createdVariants.find(
+ variant => variant.name === "lastVariantInStock"
+ );
});
});
- it("should not be possible to add product with quantity greater than stock", () => {
- const productName = `${startsWith}${faker.datatype.number()}`;
- let variants;
-
- createProductInChannel({
- attributeId: attribute.id,
- categoryId: category.id,
- productTypeId: productType.id,
- channelId: defaultChannel.id,
- name: productName,
- warehouseId: warehouse.id,
- quantityInWarehouse: 1
+ it("should not be possible to add product with quantity greater than stock to checkout. TC: SALEOR_0405", () => {
+ createCheckout({
+ channelSlug: defaultChannel.slug,
+ address,
+ billingAddress: address,
+ email: "email@example.com",
+ variantsList: [variantsWithLowStock],
+ auth: "token"
})
- .then(({ variantsList }) => {
- variants = variantsList;
- createCheckout({
- channelSlug: defaultChannel.slug,
- address,
- billingAddress: address,
- email: "email@example.com",
- variantsList,
- auth: "token"
- });
- })
.then(({ checkout: checkout }) => {
- addProductsToCheckout(checkout.id, variants, 2);
+ addProductsToCheckout(checkout.id, [variantsWithLowStock], 2);
})
.then(({ errors }) => {
expect(
@@ -125,46 +81,34 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
});
});
- it("should buy product with no quantity if tracking is not set", () => {
- const productName = `${startsWith}${faker.datatype.number()}`;
-
- createOrderWithNewProduct({
- attributeId: attribute.id,
- categoryId: category.id,
- productTypeId: productType.id,
- channel: defaultChannel,
- name: productName,
- warehouseId: warehouse.id,
- quantityInWarehouse: 0,
- trackInventory: false,
- shippingMethod,
- address
+ it("should buy product with no quantity if tracking is not set. TC: SALEOR_0406", () => {
+ createWaitingForCaptureOrder({
+ address,
+ channelSlug: defaultChannel.slug,
+ email: "example@example.com",
+ shippingMethodName: shippingMethod.name,
+ variantsList: [variantsWithoutTrackInventory]
}).then(({ order }) => {
expect(order, "order should be created").to.be.ok;
});
});
- it("should change product stock after purchase", () => {
- const productName = `${startsWith}${faker.datatype.number()}`;
-
- createOrderWithNewProduct({
- attributeId: attribute.id,
- categoryId: category.id,
- productTypeId: productType.id,
- channel: defaultChannel,
- name: productName,
- warehouseId: warehouse.id,
- quantityInWarehouse: 10,
- trackInventory: true,
- shippingMethod,
- address
+ it("should create checkout with last product in stock. TC: SALEOR_0419", () => {
+ createWaitingForCaptureOrder({
+ address,
+ channelSlug: defaultChannel.slug,
+ email: "example@example.com",
+ shippingMethodName: shippingMethod.name,
+ variantsList: [lastVariantInStock]
})
- .then(({ variantsList }) => {
- getVariants(variantsList);
+ .then(({ order }) => {
+ expect(order, "order should be created").to.be.ok;
+ getVariants([lastVariantInStock]);
})
.then(variantsList => {
const variant = variantsList.edges[0];
expect(variant.node.stocks[0].quantityAllocated).to.eq(1);
+ expect(variant.node.stocks[0].quantity).to.eq(1);
});
});
});
diff --git a/cypress/integration/homePage/homePageAnalitics.js b/cypress/integration/homePage/homePageAnalitics.js
index d53fbfd69..b7496af29 100644
--- a/cypress/integration/homePage/homePageAnalitics.js
+++ b/cypress/integration/homePage/homePageAnalitics.js
@@ -5,28 +5,32 @@ import faker from "faker";
import { HOMEPAGE_SELECTORS } from "../../elements/homePage/homePage-selectors";
import { urlList } from "../../fixtures/urlList";
-import {
- createCustomer,
- deleteCustomersStartsWith
-} from "../../support/api/requests/Customer";
-import { getDefaultChannel } from "../../support/api/utils/channelsUtils";
+import { createCustomer } from "../../support/api/requests/Customer";
import * as homePageUtils from "../../support/api/utils/homePageUtils";
import {
createReadyToFulfillOrder,
createWaitingForCaptureOrder
} from "../../support/api/utils/ordersUtils";
import * as productsUtils from "../../support/api/utils/products/productsUtils";
-import * as shippingUtils from "../../support/api/utils/shippingUtils";
import filterTests from "../../support/filterTests";
-import { changeChannel } from "../../support/pages/homePage";
+import {
+ changeChannel,
+ getOrdersReadyForCaptureRegex,
+ getOrdersReadyToFulfillRegex,
+ getProductsOutOfStockRegex,
+ getSalesAmountRegex,
+ getTodaysOrdersRegex
+} from "../../support/pages/homePage";
-//
-
-filterTests({ definedTags: ["all", "critical"] }, () => {
- describe("Homepage analytics", () => {
+filterTests({ definedTags: ["all", "critical", "refactored"] }, () => {
+ describe("As an admin I want to see correct information on dashboard home page", () => {
const startsWith = "CyHomeAnalytics";
+ const productPrice = 22;
+ const shippingPrice = 12;
+ const randomName = startsWith + faker.datatype.number();
+ const randomEmail = `${startsWith}${randomName}@example.com`;
- let customerId;
+ let customer;
let defaultChannel;
let createdVariants;
let productType;
@@ -34,72 +38,108 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
let category;
let warehouse;
let shippingMethod;
- let addresses;
-
- const productPrice = 22;
- const shippingPrice = 12;
- const randomName = startsWith + faker.datatype.number();
- const randomEmail = `${startsWith}${randomName}@example.com`;
+ let address;
+ let ordersReadyToFulfillRegexp;
+ let ordersReadyForCaptureRegexp;
+ let productsOutOfStockRegexp;
+ let salesAmountRegexp;
+ let ordersRegexp;
before(() => {
cy.clearSessionData().loginUserViaRequest();
- productsUtils.deleteProductsStartsWith(startsWith);
- deleteCustomersStartsWith(startsWith);
- shippingUtils.deleteShippingStartsWith(startsWith);
- getDefaultChannel()
- .then(channel => {
- defaultChannel = channel;
- cy.fixture("addresses");
+ productsUtils
+ .createProductWithShipping({
+ name: randomName,
+ productPrice,
+ shippingPrice
})
- .then(addressesFixture => (addresses = addressesFixture))
- .then(() =>
- createCustomer(randomEmail, randomName, addresses.plAddress)
- )
.then(resp => {
- customerId = resp.user.id;
- shippingUtils.createShipping({
- channelId: defaultChannel.id,
- name: randomName,
- address: addresses.plAddress,
- price: shippingPrice
- });
+ createdVariants = resp.variantsList;
+ address = resp.address;
+ warehouse = resp.warehouse;
+ defaultChannel = resp.defaultChannel;
+ shippingMethod = resp.shippingMethod;
+ attribute = resp.attribute;
+ category = resp.category;
+ productType = resp.productType;
+
+ createCustomer(randomEmail, randomName, address).then(
+ customerResp => (customer = customerResp)
+ );
+
+ homePageUtils
+ .getOrdersReadyToFulfill(defaultChannel.slug)
+ .then(ordersReadyToFulfillBefore => {
+ ordersReadyToFulfillRegexp = getOrdersReadyToFulfillRegex(
+ ordersReadyToFulfillBefore,
+ 1
+ );
+ });
+
+ homePageUtils
+ .getOrdersReadyForCapture(defaultChannel.slug)
+ .then(ordersReadyForCaptureBefore => {
+ ordersReadyForCaptureRegexp = getOrdersReadyForCaptureRegex(
+ ordersReadyForCaptureBefore,
+ 1
+ );
+ });
+
+ homePageUtils
+ .getProductsOutOfStock(defaultChannel.slug)
+ .then(productsOutOfStockBefore => {
+ productsOutOfStockRegexp = getProductsOutOfStockRegex(
+ productsOutOfStockBefore,
+ 1
+ );
+ });
+
+ homePageUtils
+ .getSalesAmount(defaultChannel.slug)
+ .then(salesAmount => {
+ salesAmountRegexp = getSalesAmountRegex(
+ salesAmount,
+ productPrice * 2 + shippingPrice
+ );
+ });
+
+ homePageUtils
+ .getTodaysOrders(defaultChannel.slug)
+ .then(ordersBefore => {
+ ordersRegexp = getTodaysOrdersRegex(ordersBefore, 2);
+ });
})
- .then(
- ({
- warehouse: warehouseResp,
- shippingMethod: shippingMethodResp
- }) => {
- warehouse = warehouseResp;
- shippingMethod = shippingMethodResp;
- productsUtils.createTypeAttributeAndCategoryForProduct({
- name: randomName
- });
- }
- )
- .then(
- ({
- productType: productTypeResp,
- attribute: attributeResp,
- category: categoryResp
- }) => {
- productType = productTypeResp;
- attribute = attributeResp;
- category = categoryResp;
- productsUtils.createProductInChannel({
- name: randomName,
- channelId: defaultChannel.id,
- warehouseId: warehouse.id,
- quantityInWarehouse: 20,
- productTypeId: productType.id,
- attributeId: attribute.id,
- categoryId: category.id,
- price: productPrice
- });
- }
- )
- .then(({ variantsList: variantsResp }) => {
- createdVariants = variantsResp;
+ .then(() => {
+ createReadyToFulfillOrder({
+ customerId: customer.id,
+ shippingMethodId: shippingMethod.id,
+ channelId: defaultChannel.id,
+ variantsList: createdVariants,
+ address
+ });
+
+ createWaitingForCaptureOrder({
+ channelSlug: defaultChannel.slug,
+ email: randomEmail,
+ variantsList: createdVariants,
+ shippingMethodName: shippingMethod.name,
+ address
+ });
+
+ const productOutOfStockRandomName =
+ startsWith + faker.datatype.number();
+
+ productsUtils.createProductInChannel({
+ name: productOutOfStockRandomName,
+ channelId: defaultChannel.id,
+ warehouseId: warehouse.id,
+ quantityInWarehouse: 0,
+ productTypeId: productType.id,
+ attributeId: attribute.id,
+ categoryId: category.id,
+ price: productPrice
+ });
});
});
@@ -107,161 +147,25 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
cy.clearSessionData().loginUserViaRequest();
});
- it("should all elements be visible on the dashboard", () => {
- cy.visit(urlList.homePage)
- .softAssertVisibility(HOMEPAGE_SELECTORS.sales)
- .softAssertVisibility(HOMEPAGE_SELECTORS.orders)
- .softAssertVisibility(HOMEPAGE_SELECTORS.activity)
- .softAssertVisibility(HOMEPAGE_SELECTORS.topProducts)
- .softAssertVisibility(HOMEPAGE_SELECTORS.ordersReadyToFulfill)
- .softAssertVisibility(HOMEPAGE_SELECTORS.paymentsWaitingForCapture)
- .softAssertVisibility(HOMEPAGE_SELECTORS.productsOutOfStock);
- });
-
- it("should correct amount of ready to fullfil orders be displayed", () => {
- homePageUtils
- .getOrdersReadyToFulfill(defaultChannel.slug)
- .as("ordersReadyToFulfill");
- createReadyToFulfillOrder({
- customerId,
- shippingMethodId: shippingMethod.id,
- channelId: defaultChannel.id,
- variantsList: createdVariants,
- address: addresses.plAddress
- });
- cy.get("@ordersReadyToFulfill").then(ordersReadyToFulfillBefore => {
- const allOrdersReadyToFulfill = ordersReadyToFulfillBefore + 1;
- const notANumberRegex = "\\D*";
- const ordersReadyToFulfillRegexp = new RegExp(
- `${notANumberRegex}${allOrdersReadyToFulfill}${notANumberRegex}`
- );
- cy.visit(urlList.homePage);
- changeChannel(defaultChannel.name);
- cy.contains(
- HOMEPAGE_SELECTORS.ordersReadyToFulfill,
- ordersReadyToFulfillRegexp
- ).should("be.visible");
- });
- });
-
- it("should correct amount of payments waiting for capture be displayed", () => {
- homePageUtils
- .getOrdersReadyForCapture(defaultChannel.slug)
- .as("ordersReadyForCapture");
-
- createWaitingForCaptureOrder({
- channelSlug: defaultChannel.slug,
- email: randomEmail,
- variantsList: createdVariants,
- shippingMethodName: shippingMethod.name,
- address: addresses.plAddress
- });
-
- cy.get("@ordersReadyForCapture").then(ordersReadyForCaptureBefore => {
- const allOrdersReadyForCapture = ordersReadyForCaptureBefore + 1;
- const notANumberRegex = "\\D*";
- const ordersReadyForCaptureRegexp = new RegExp(
- `${notANumberRegex}${allOrdersReadyForCapture}${notANumberRegex}`
- );
- cy.visit(urlList.homePage);
- changeChannel(defaultChannel.name);
- cy.contains(
- HOMEPAGE_SELECTORS.ordersReadyForCapture,
- ordersReadyForCaptureRegexp
- ).should("be.visible");
- });
- });
-
- it("should correct amount of products out of stock be displayed", () => {
- homePageUtils
- .getProductsOutOfStock(defaultChannel.slug)
- .as("productsOutOfStock");
- const productOutOfStockRandomName = startsWith + faker.datatype.number();
-
- productsUtils.createProductInChannel({
- name: productOutOfStockRandomName,
- channelId: defaultChannel.id,
- warehouseId: warehouse.id,
- quantityInWarehouse: 0,
- productTypeId: productType.id,
- attributeId: attribute.id,
- categoryId: category.id,
- price: productPrice
- });
-
- cy.get("@productsOutOfStock").then(productsOutOfStockBefore => {
- const allProductsOutOfStock = productsOutOfStockBefore + 1;
- const notANumberRegex = "\\D*";
- const productsOutOfStockRegexp = new RegExp(
- `${notANumberRegex}${allProductsOutOfStock}${notANumberRegex}`
- );
- cy.visit(urlList.homePage);
- changeChannel(defaultChannel.name);
- cy.contains(
- HOMEPAGE_SELECTORS.productsOutOfStock,
- productsOutOfStockRegexp
- ).should("be.visible");
- });
- });
-
- it("should correct amount of sales be displayed", () => {
- homePageUtils.getSalesAmount(defaultChannel.slug).as("salesAmount");
-
- createReadyToFulfillOrder({
- customerId,
- shippingMethodId: shippingMethod.id,
- channelId: defaultChannel.id,
- variantsList: createdVariants,
- address: addresses.plAddress
- });
-
- cy.get("@salesAmount").then(salesAmount => {
- const totalAmount = salesAmount + productPrice;
- const totalAmountString = totalAmount.toFixed(2);
- const totalAmountIntegerValue = totalAmountString.split(".")[0];
- const totalAmountDecimalValue = totalAmountString.split(".")[1];
- const decimalSeparator = "[,.]";
- const totalAmountIntegerWithThousandsSeparator = new Intl.NumberFormat(
- "en"
- )
- .format(totalAmountIntegerValue)
- .replaceAll(",", "[,.]*");
- const totalAmountWithSeparators = `${totalAmountIntegerWithThousandsSeparator}${decimalSeparator}${totalAmountDecimalValue}`;
- const notANumberRegex = "\\D*";
- const salesAmountRegexp = new RegExp(
- `${notANumberRegex}${totalAmountWithSeparators}${notANumberRegex}`
- );
- cy.visit(urlList.homePage);
- changeChannel(defaultChannel.name);
- cy.contains(HOMEPAGE_SELECTORS.sales, salesAmountRegexp).should(
- "be.visible"
- );
- });
- });
-
- it("should correct amount of orders be displayed", () => {
- homePageUtils.getTodaysOrders(defaultChannel.slug).as("todaysOrders");
-
- createReadyToFulfillOrder({
- customerId,
- shippingMethodId: shippingMethod.id,
- channelId: defaultChannel.id,
- variantsList: createdVariants,
- address: addresses.plAddress
- });
-
- cy.get("@todaysOrders").then(ordersBefore => {
- const allOrders = ordersBefore + 1;
- const notANumberRegex = "\\D*";
- const ordersRegexp = new RegExp(
- `${notANumberRegex}${allOrders}${notANumberRegex}`
- );
- cy.visit(urlList.homePage);
- changeChannel(defaultChannel.name);
- cy.contains(HOMEPAGE_SELECTORS.orders, ordersRegexp).should(
- "be.visible"
- );
- });
+ it("should display correct information on dashboard home page. SALEOR_2004", () => {
+ cy.visit(urlList.homePage);
+ changeChannel(defaultChannel.name);
+ cy.contains(HOMEPAGE_SELECTORS.orders, ordersRegexp).should("be.visible");
+ cy.contains(
+ HOMEPAGE_SELECTORS.ordersReadyToFulfill,
+ ordersReadyToFulfillRegexp
+ ).should("be.visible");
+ cy.contains(
+ HOMEPAGE_SELECTORS.ordersReadyForCapture,
+ ordersReadyForCaptureRegexp
+ ).should("be.visible");
+ cy.contains(HOMEPAGE_SELECTORS.sales, salesAmountRegexp).should(
+ "be.visible"
+ );
+ cy.contains(
+ HOMEPAGE_SELECTORS.productsOutOfStock,
+ productsOutOfStockRegexp
+ ).should("be.visible");
});
});
});
diff --git a/cypress/integration/navigation.js b/cypress/integration/navigation.js
index d0386cd30..e22d8913c 100644
--- a/cypress/integration/navigation.js
+++ b/cypress/integration/navigation.js
@@ -5,11 +5,12 @@ import { PERMISSIONS_OPTIONS } from "../fixtures/permissionsUsers";
import filterTests from "../support/filterTests";
import * as permissionsSteps from "../support/pages/permissionsPage";
-describe("Navigation for users with different permissions", () => {
+describe("As a staff user I want to navigate through shop using different permissions", () => {
Object.keys(PERMISSIONS_OPTIONS).forEach(key => {
- const tags = key === "all" ? ["critical", "all"] : ["all"];
+ const tags =
+ key === "all" ? ["critical", "all", "refactored"] : ["all", "refactored"];
filterTests({ definedTags: tags }, () => {
- it(`should navigate as an user with ${key} permission`, () => {
+ it(`should be able to navigate through shop as a staff member using ${key} permission. ${PERMISSIONS_OPTIONS[key].testCase}`, () => {
const permissionOption = PERMISSIONS_OPTIONS[key];
const permissions = permissionOption.permissions;
cy.clearSessionData();
diff --git a/cypress/integration/products/createProduct.js b/cypress/integration/products/createProduct.js
index da1e25e54..6048a195c 100644
--- a/cypress/integration/products/createProduct.js
+++ b/cypress/integration/products/createProduct.js
@@ -14,7 +14,6 @@ import {
expectCorrectProductInformation,
expectCorrectProductVariantInformation
} from "../../support/api/utils/products/checkProductInfo";
-import * as productUtils from "../../support/api/utils/products/productsUtils";
import filterTests from "../../support/filterTests";
import { metadataForms } from "../../support/pages/catalog/metadataComponent";
import {
@@ -25,7 +24,7 @@ import { fillUpCommonFieldsForAllProductTypes } from "../../support/pages/catalo
import { selectChannelInDetailsPages } from "../../support/pages/channelsPage";
filterTests({ definedTags: ["all", "critical"] }, () => {
- describe("Create product", () => {
+ describe("As an admin I should be able to create product", () => {
const startsWith = "CyCreateProduct-";
const name = `${startsWith}${faker.datatype.number()}`;
const generalInfo = {
@@ -53,7 +52,6 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
before(() => {
cy.clearSessionData().loginUserViaRequest();
- productUtils.deleteProductsStartsWith(startsWith);
createAttribute({ name }).then(attributeResp => {
attribute = attributeResp;
});
@@ -62,7 +60,7 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
cy.clearSessionData().loginUserViaRequest();
});
- it("should create product with variants", () => {
+ it("should be able to create product with variants as an admin. SALEOR_2701", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
seo.slug = randomName;
const productData = {
@@ -89,7 +87,7 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
});
});
- it("should create product without variants", () => {
+ it("should be able to create product without variants as an admin. SALEOR_2702", () => {
const prices = { sellingPrice: 6, costPrice: 3 };
const randomName = `${startsWith}${faker.datatype.number()}`;
seo.slug = randomName;
diff --git a/cypress/integration/products/images.js b/cypress/integration/products/images.js
index a58b112e3..7f6369f55 100644
--- a/cypress/integration/products/images.js
+++ b/cypress/integration/products/images.js
@@ -7,7 +7,7 @@ import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
import { demoProductsNames } from "../../fixtures/products";
import { productDetailsUrl, urlList } from "../../fixtures/urlList";
import { getFirstProducts } from "../../support/api/requests/Product";
-import { deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel } from "../../support/api/utils/products/productsUtils";
+import { createNewProductWithNewDataAndDefaultChannel } from "../../support/api/utils/products/productsUtils";
import filterTests from "../../support/filterTests";
filterTests({ definedTags: ["all"] }, () => {
@@ -71,7 +71,7 @@ filterTests({ definedTags: ["all"] }, () => {
const name = "CyImages";
cy.clearSessionData().loginUserViaRequest();
- deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel({ name })
+ createNewProductWithNewDataAndDefaultChannel({ name })
.then(({ product }) => {
cy.visit(productDetailsUrl(product.id))
.waitForProgressBarToNotBeVisible()
diff --git a/cypress/integration/products/productsVariants.js b/cypress/integration/products/productsVariants.js
index 55501971a..97aa3f09e 100644
--- a/cypress/integration/products/productsVariants.js
+++ b/cypress/integration/products/productsVariants.js
@@ -10,10 +10,7 @@ import {
createProduct,
updateChannelInProduct
} from "../../support/api/requests/Product";
-import {
- deleteChannelsStartsWith,
- getDefaultChannel
-} from "../../support/api/utils/channelsUtils";
+import { getDefaultChannel } from "../../support/api/utils/channelsUtils";
import * as productUtils from "../../support/api/utils/products/productsUtils";
import * as shippingUtils from "../../support/api/utils/shippingUtils";
import { getProductVariants } from "../../support/api/utils/storeFront/storeFrontProductUtils";
@@ -23,10 +20,13 @@ import {
createVariant,
variantsShouldBeVisible
} from "../../support/pages/catalog/products/VariantsPage";
-import { enterHomePageChangeChannelAndReturn } from "../../support/pages/channelsPage";
+import {
+ enterHomePageChangeChannelAndReturn,
+ selectChannelInHeader
+} from "../../support/pages/channelsPage";
-filterTests({ definedTags: ["all", "critical"] }, () => {
- describe("Creating variants", () => {
+filterTests({ definedTags: ["all", "critical", "refactored"] }, () => {
+ describe("As an admin I should be able to create variant", () => {
const startsWith = "CyCreateVariants-";
const attributeValues = ["value1", "value2"];
@@ -38,43 +38,22 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
let newChannel;
before(() => {
- cy.clearSessionData().loginUserViaRequest();
- shippingUtils.deleteShippingStartsWith(startsWith);
- productUtils.deleteProductsStartsWith(startsWith);
- deleteChannelsStartsWith(startsWith);
-
const name = `${startsWith}${faker.datatype.number()}`;
- getDefaultChannel()
- .then(channel => {
- defaultChannel = channel;
- cy.fixture("addresses");
- })
- .then(fixtureAddresses =>
- shippingUtils.createShipping({
- channelId: defaultChannel.id,
- name,
- address: fixtureAddresses.plAddress
- })
- )
- .then(({ warehouse: warehouseResp }) => {
- warehouse = warehouseResp;
+
+ cy.clearSessionData().loginUserViaRequest();
+
+ productUtils
+ .createShippingProductTypeAttributeAndCategory(name, attributeValues)
+ .then(resp => {
+ attribute = resp.attribute;
+ productType = resp.productType;
+ category = resp.category;
+ defaultChannel = resp.defaultChannel;
+ warehouse = resp.warehouse;
+
createChannel({ isActive: true, name, currencyCode: "USD" });
})
.then(resp => (newChannel = resp));
-
- productUtils
- .createTypeAttributeAndCategoryForProduct({ name, attributeValues })
- .then(
- ({
- attribute: attributeResp,
- productType: productTypeResp,
- category: categoryResp
- }) => {
- attribute = attributeResp;
- productType = productTypeResp;
- category = categoryResp;
- }
- );
});
beforeEach(() => {
@@ -84,7 +63,7 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
);
});
- it("should create variant visible on frontend", () => {
+ it("should be able to create variant visible for the customers in all channels. TC: SALEOR_2901", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const price = 10;
let createdProduct;
@@ -101,6 +80,10 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
productId: createdProduct.id,
channelId: defaultChannel.id
});
+ updateChannelInProduct({
+ productId: createdProduct.id,
+ channelId: newChannel.id
+ });
cy.visit(`${urlList.products}${createdProduct.id}`);
createFirstVariant({
sku: name,
@@ -111,13 +94,25 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
variantsShouldBeVisible({ name, price });
getProductVariants(createdProduct.id, defaultChannel.slug);
})
+ .then(([variant]) => {
+ expect(variant).to.have.property("name", attributeValues[0]);
+ expect(variant).to.have.property("price", price);
+ selectChannelInHeader(newChannel.name);
+ variantsShouldBeVisible({ name, price });
+ getProductVariants(createdProduct.id, defaultChannel.slug);
+ })
+ .then(([variant]) => {
+ expect(variant).to.have.property("name", attributeValues[0]);
+ expect(variant).to.have.property("price", price);
+ getProductVariants(createdProduct.id, newChannel.slug);
+ })
.then(([variant]) => {
expect(variant).to.have.property("name", attributeValues[0]);
expect(variant).to.have.property("price", price);
});
});
- it("should create several variants", () => {
+ it("should be able to create several variants visible for the customers. TC: SALEOR_2902", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const secondVariantSku = `${startsWith}${faker.datatype.number()}`;
const variants = [{ price: 7 }, { name: attributeValues[1], price: 16 }];
@@ -157,52 +152,5 @@ filterTests({ definedTags: ["all", "critical"] }, () => {
expect(secondVariant).to.have.property("price", variants[1].price);
});
});
-
- it("should create variant for many channels", () => {
- const name = `${startsWith}${faker.datatype.number()}`;
- const variantsPrice = 10;
- let createdProduct;
- createProduct({
- attributeId: attribute.id,
- name,
- productTypeId: productType.id,
- categoryId: category.id
- })
- .then(productResp => {
- createdProduct = productResp;
- updateChannelInProduct({
- productId: createdProduct.id,
- channelId: defaultChannel.id
- });
- })
- .then(() => {
- updateChannelInProduct({
- productId: createdProduct.id,
- channelId: newChannel.id
- });
- })
- .then(() => {
- cy.visit(`${urlList.products}${createdProduct.id}`);
- createFirstVariant({
- sku: name,
- price: variantsPrice,
- attribute: attributeValues[0]
- });
- enterHomePageChangeChannelAndReturn(defaultChannel.name);
- variantsShouldBeVisible({ name, price: variantsPrice });
- enterHomePageChangeChannelAndReturn(newChannel.name);
- variantsShouldBeVisible({ name, price: variantsPrice });
- getProductVariants(createdProduct.id, defaultChannel.slug);
- })
- .then(([variant]) => {
- expect(variant).to.have.property("name", attributeValues[0]);
- expect(variant).to.have.property("price", variantsPrice);
- getProductVariants(createdProduct.id, newChannel.slug);
- })
- .then(([variant]) => {
- expect(variant).to.have.property("name", attributeValues[0]);
- expect(variant).to.have.property("price", variantsPrice);
- });
- });
});
});
diff --git a/cypress/integration/products/productsWithoutSku/productsWithoutSkuInOrder.js b/cypress/integration/products/productsWithoutSku/productsWithoutSkuInOrder.js
index 864c46d8f..0677281c6 100644
--- a/cypress/integration/products/productsWithoutSku/productsWithoutSkuInOrder.js
+++ b/cypress/integration/products/productsWithoutSku/productsWithoutSkuInOrder.js
@@ -1,30 +1,18 @@
///
///
-import {
- createCustomer,
- deleteCustomersStartsWith
-} from "../../../support/api/requests/Customer";
+import faker from "faker";
+
+import { createCustomer } from "../../../support/api/requests/Customer";
import { createReadyToFulfillOrder } from "../../../support/api/utils/ordersUtils";
-import {
- createProductWithShipping,
- deleteProductsStartsWith
-} from "../../../support/api/utils/products/productsUtils";
-import { deleteShippingStartsWith } from "../../../support/api/utils/shippingUtils";
+import { createProductWithShipping } from "../../../support/api/utils/products/productsUtils";
import filterTests from "../../../support/filterTests";
-filterTests({ definedTags: ["all", "critical"] }, () => {
- const name = "ProductsWithoutSkuInOrder";
+filterTests({ definedTags: ["all", "critical", "refactored"] }, () => {
+ const name = `ProductsWithoutSkuInOrder${faker.datatype.number()}`;
- describe("Add productWithout SKU to order", () => {
- before(() => {
- cy.clearSessionData().loginUserViaRequest();
- deleteProductsStartsWith(name);
- deleteShippingStartsWith(name);
- deleteCustomersStartsWith(name);
- });
-
- it("should create order with variant product without sku", () => {
+ describe("As an admin I should be able to create order with variant without SKU", () => {
+ it("should create order with variant product without sku. SALEOR_2801", () => {
let variants;
let channel;
let shippingMethodId;
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
index 49f524f12..051aa1547 100644
--- a/cypress/plugins/index.js
+++ b/cypress/plugins/index.js
@@ -22,7 +22,7 @@ const graphql = require("graphql-request");
module.exports = async (on, config) => {
// make env variables visible for cypress
- require("cypress-mochawesome-reporter/plugin")(on);
+ // require("cypress-mochawesome-reporter/plugin")(on); - uncomment to run reports
config.env.API_URI = process.env.API_URI;
config.env.APP_MOUNT_URI = process.env.APP_MOUNT_URI;
config.env.mailHogUrl = process.env.CYPRESS_MAILHOG;
diff --git a/cypress/support/api/requests/Product.js b/cypress/support/api/requests/Product.js
index 591671e68..8c833fc79 100644
--- a/cypress/support/api/requests/Product.js
+++ b/cypress/support/api/requests/Product.js
@@ -148,7 +148,7 @@ export function createVariant({
productId,
sku,
warehouseId,
- quantityInWarehouse,
+ quantityInWarehouse = 1,
channelId,
attributeId,
price = 1,
diff --git a/cypress/support/api/utils/products/productsUtils.js b/cypress/support/api/utils/products/productsUtils.js
index e68ec18c9..9ac23f1d9 100644
--- a/cypress/support/api/utils/products/productsUtils.js
+++ b/cypress/support/api/utils/products/productsUtils.js
@@ -12,9 +12,11 @@ import {
setProductTypeAsDigital
} from "../../requests/ProductType";
import { deleteAttributesStartsWith } from "../attributes/attributeUtils";
-import { deleteCollectionsStartsWith } from "../catalog/collectionsUtils";
import { getDefaultChannel } from "../channelsUtils";
-import { createShipping, deleteShippingStartsWith } from "../shippingUtils";
+import {
+ createShipping,
+ createShippingWithDefaultChannelAndAddress
+} from "../shippingUtils";
export function createProductInChannel({
name,
@@ -116,7 +118,7 @@ export function deleteProductsStartsWith(startsWith) {
);
}
-export function deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel({
+export function createNewProductWithNewDataAndDefaultChannel({
name,
description = name,
warehouseId,
@@ -128,9 +130,9 @@ export function deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel({
let defaultChannel;
let collection;
let attribute;
+ let category;
+ let productType;
- deleteProductsStartsWith(name);
- deleteCollectionsStartsWith(name);
return getDefaultChannel()
.then(channel => {
defaultChannel = channel;
@@ -140,23 +142,37 @@ export function deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel({
collection = collectionResp;
createTypeAttributeAndCategoryForProduct({ name, attributeValues });
})
- .then(({ attribute: attributeResp, category, productType }) => {
- attribute = attributeResp;
- createProductInChannel({
- attributeId: attribute.id,
- categoryId: category.id,
- productTypeId: productType.id,
- channelId: defaultChannel.id,
- name,
- collectionId: collection.id,
- description,
- warehouseId,
- price: productPrice,
- preorder,
- sku
- });
- })
- .then(({ product, variantsList }) => ({ product, variantsList }));
+ .then(
+ ({
+ attribute: attributeResp,
+ category: categoryResp,
+ productType: productTypeResp
+ }) => {
+ attribute = attributeResp;
+ category = categoryResp;
+ productType = productTypeResp;
+ createProductInChannel({
+ attributeId: attribute.id,
+ categoryId: category.id,
+ productTypeId: productType.id,
+ channelId: defaultChannel.id,
+ name,
+ collectionId: collection.id,
+ description,
+ warehouseId,
+ price: productPrice,
+ preorder,
+ sku
+ });
+ }
+ )
+ .then(({ product, variantsList }) => ({
+ product,
+ variantsList,
+ attribute,
+ category,
+ productType
+ }));
}
export function createProductWithShipping({
@@ -173,7 +189,6 @@ export function createProductWithShipping({
let defaultChannel;
let shippingZone;
- deleteShippingStartsWith(name);
return cy
.fixture("addresses")
.then(addresses => {
@@ -198,7 +213,7 @@ export function createProductWithShipping({
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
shippingZone = shippingZoneResp;
- deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel({
+ createNewProductWithNewDataAndDefaultChannel({
name,
warehouseId: warehouse.id,
productPrice,
@@ -208,14 +223,17 @@ export function createProductWithShipping({
});
}
)
- .then(({ variantsList, product }) => ({
+ .then(({ variantsList, product, attribute, category, productType }) => ({
variantsList,
product,
warehouse,
shippingZone,
defaultChannel,
shippingMethod,
- address
+ address,
+ attribute,
+ category,
+ productType
}));
}
@@ -264,3 +282,166 @@ export function addDigitalContentAndUpdateProductType(
setProductTypeAsDigital(productTypeId);
productRequest.updateVariantPrice({ variantId, channelId, price });
}
+
+export function createDigitalAndPhysicalProductWithNewDataAndDefaultChannel({
+ physicalProductName,
+ digitalProductName
+}) {
+ let physicalVariants;
+ let digitalVariants;
+ let warehouse;
+ let attribute;
+ let shippingMethod;
+ let defaultChannel;
+ let address;
+ let category;
+ let digitalProductType;
+
+ return createProductWithShipping({
+ name: physicalProductName,
+ attributeValues: ["physical"]
+ })
+ .then(resp => {
+ physicalVariants = resp.variantsList;
+ warehouse = resp.warehouse;
+ shippingMethod = resp.shippingMethod;
+ attribute = resp.attribute;
+ defaultChannel = resp.defaultChannel;
+ address = resp.address;
+ category = resp.category;
+
+ createTypeProduct({
+ name: digitalProductName,
+ shippable: false,
+ attributeId: attribute.id
+ });
+ })
+ .then(productType => {
+ digitalProductType = productType;
+ createProductInChannel({
+ attributeId: attribute.id,
+ productTypeId: productType.id,
+ categoryId: category.id,
+ channelId: defaultChannel.id,
+ name: digitalProductName,
+ warehouseId: warehouse.id
+ });
+ })
+ .then(({ variantsList }) => {
+ digitalVariants = variantsList;
+ addDigitalContentAndUpdateProductType(
+ digitalVariants[0].id,
+ digitalProductType.id,
+ defaultChannel.id
+ );
+ })
+ .then(() => ({
+ digitalVariants,
+ physicalVariants,
+ shippingMethod,
+ defaultChannel,
+ address
+ }));
+}
+
+export function createNewProductWithSeveralVariants(name, variantsData) {
+ let address;
+ let defaultChannel;
+ let warehouse;
+ let shippingMethod;
+ const createdVariants = [];
+ let attribute;
+ let productType;
+ let category;
+
+ return cy
+ .fixture("addresses")
+ .then(addresses => {
+ address = addresses.usAddress;
+ getDefaultChannel();
+ })
+ .then(channel => {
+ defaultChannel = channel;
+ createShipping({
+ channelId: defaultChannel.id,
+ name,
+ address
+ });
+ })
+ .then(
+ ({ warehouse: warehouseResp, shippingMethod: shippingMethodResp }) => {
+ warehouse = warehouseResp;
+ shippingMethod = shippingMethodResp;
+
+ const attributeValues = [];
+ variantsData.forEach(variant => {
+ attributeValues.push(variant.name);
+ });
+
+ createTypeAttributeAndCategoryForProduct({
+ name,
+ attributeValues
+ });
+ }
+ )
+ .then(
+ ({
+ attribute: attributeResp,
+ category: categoryResp,
+ productType: productTypeResp
+ }) => {
+ attribute = attributeResp;
+ category = categoryResp;
+ productType = productTypeResp;
+
+ createProductInChannelWithoutVariants({
+ attributeId: attribute.id,
+ categoryId: category.id,
+ productTypeId: productType.id,
+ channelId: defaultChannel.id,
+ name
+ });
+ }
+ )
+ .then(product => {
+ variantsData.forEach(variant => {
+ productRequest
+ .createVariant({
+ productId: product.id,
+ attributeId: attribute.id,
+ channelId: defaultChannel.id,
+ attributeName: variant.name,
+ trackInventory: variant.trackInventory,
+ warehouseId: warehouse.id,
+ quantityInWarehouse: variant.quantityInWarehouse
+ })
+ .then(variants => {
+ createdVariants.push(variants[0]);
+ });
+ });
+ })
+ .then(() => ({ createdVariants, address, shippingMethod, defaultChannel }));
+}
+
+export function createShippingProductTypeAttributeAndCategory(
+ name,
+ attributeValues
+) {
+ let warehouse;
+ let defaultChannel;
+
+ return createShippingWithDefaultChannelAndAddress(name)
+ .then(({ warehouse: warehouseResp, defaultChannel: channel }) => {
+ warehouse = warehouseResp;
+ defaultChannel = channel;
+
+ createTypeAttributeAndCategoryForProduct({ name, attributeValues });
+ })
+ .then(({ attribute, productType, category }) => ({
+ attribute,
+ productType,
+ category,
+ warehouse,
+ defaultChannel
+ }));
+}
diff --git a/cypress/support/api/utils/shippingUtils.js b/cypress/support/api/utils/shippingUtils.js
index 2b5130987..da66a1eb0 100644
--- a/cypress/support/api/utils/shippingUtils.js
+++ b/cypress/support/api/utils/shippingUtils.js
@@ -1,5 +1,6 @@
import * as shippingMethodRequest from "../requests/ShippingMethod";
import * as warehouseRequest from "../requests/Warehouse";
+import { getDefaultChannel } from "./channelsUtils";
export function createShipping({
channelId,
@@ -40,6 +41,30 @@ export function createShipping({
})
.then(() => ({ shippingMethod, shippingZone, warehouse }));
}
+
+export function createShippingWithDefaultChannelAndAddress(name) {
+ let defaultChannel;
+
+ return getDefaultChannel()
+ .then(channel => {
+ defaultChannel = channel;
+ cy.fixture("addresses");
+ })
+ .then(fixtureAddresses =>
+ createShipping({
+ channelId: defaultChannel.id,
+ name,
+ address: fixtureAddresses.plAddress
+ })
+ )
+ .then(({ shippingMethod, shippingZone, warehouse }) => ({
+ shippingMethod,
+ shippingZone,
+ warehouse,
+ defaultChannel
+ }));
+}
+
export function createShippingRate({ name, shippingZoneId }) {
return shippingMethodRequest
.createShippingRate({ name, shippingZone: shippingZoneId })
diff --git a/cypress/support/index.js b/cypress/support/index.js
index 3e31cfecf..0b60eb0bc 100644
--- a/cypress/support/index.js
+++ b/cypress/support/index.js
@@ -21,20 +21,8 @@ commandTimings();
import { urlList } from "../fixtures/urlList";
Cypress.Commands.add("clearSessionData", () => {
- // Because of known cypress bug, not all local storage data are cleared.
- // Here is workaround to ensure tests have no side effects.
- // Suggested usage:
- // beforeEach(() => {
- // cy.clearSessionData();
- // });
-
cy.clearCookies();
cy.clearLocalStorage();
- cy.visit(urlList.homePage, {
- onBeforeLoad: win => {
- win.sessionStorage.clear();
- }
- });
});
Cypress.Commands.add("addAliasToGraphRequest", operationName => {
diff --git a/cypress/support/pages/homePage.js b/cypress/support/pages/homePage.js
index 443f0298a..09abf4a0c 100644
--- a/cypress/support/pages/homePage.js
+++ b/cypress/support/pages/homePage.js
@@ -18,3 +18,61 @@ export function expectWelcomeMessageIncludes(name) {
expect(text, `welcome message should contains ${name}`).to.contains(name);
});
}
+
+export function getOrdersReadyToFulfillRegex(
+ ordersReadyToFulfillBefore,
+ quantityOfNewOrders
+) {
+ const allOrdersReadyToFulfill =
+ ordersReadyToFulfillBefore + quantityOfNewOrders;
+ const notANumberRegex = "\\D*";
+ return new RegExp(
+ `${notANumberRegex}${allOrdersReadyToFulfill}${notANumberRegex}`
+ );
+}
+
+export function getOrdersReadyForCaptureRegex(
+ ordersReadyForCaptureBefore,
+ quantityOfNewOrders
+) {
+ const allOrdersReadyForCapture =
+ ordersReadyForCaptureBefore + quantityOfNewOrders;
+ const notANumberRegex = "\\D*";
+ return new RegExp(
+ `${notANumberRegex}${allOrdersReadyForCapture}${notANumberRegex}`
+ );
+}
+
+export function getProductsOutOfStockRegex(
+ productsOutOfStockBefore,
+ quantityOfNewProducts
+) {
+ const allProductsOutOfStock =
+ productsOutOfStockBefore + quantityOfNewProducts;
+ const notANumberRegex = "\\D*";
+ return new RegExp(
+ `${notANumberRegex}${allProductsOutOfStock}${notANumberRegex}`
+ );
+}
+
+export function getSalesAmountRegex(salesAmountBefore, addedAmount) {
+ const totalAmount = salesAmountBefore + addedAmount;
+ const totalAmountString = totalAmount.toFixed(2);
+ const totalAmountIntegerValue = totalAmountString.split(".")[0];
+ const totalAmountDecimalValue = totalAmountString.split(".")[1];
+ const decimalSeparator = "[,.]";
+ const totalAmountIntegerWithThousandsSeparator = new Intl.NumberFormat("en")
+ .format(totalAmountIntegerValue)
+ .replaceAll(",", "[,.]*");
+ const totalAmountWithSeparators = `${totalAmountIntegerWithThousandsSeparator}${decimalSeparator}${totalAmountDecimalValue}`;
+ const notANumberRegex = "\\D*";
+ return new RegExp(
+ `${notANumberRegex}${totalAmountWithSeparators}${notANumberRegex}`
+ );
+}
+
+export function getTodaysOrdersRegex(ordersBefore, quantityOfNewOrders) {
+ const allOrders = ordersBefore + quantityOfNewOrders;
+ const notANumberRegex = "\\D*";
+ return new RegExp(`${notANumberRegex}${allOrders}${notANumberRegex}`);
+}
diff --git a/package.json b/package.json
index 3bbc427f6..d15cf702e 100644
--- a/package.json
+++ b/package.json
@@ -272,7 +272,9 @@
"cy:run:dashboard": "cypress run --record --key 1fe833f5-fca4-4454-ac55-943815b91c6c",
"cy:run:record": "npm run cy:run -- --record",
"cy:open": "cypress open",
- "cy:run:critical": "cypress run --env tags=critical --spec 'cypress/integration/navigation.js','cypress/integration/products/*.js','cypress/integration/checkout/*.js' --record --key 1fe833f5-fca4-4454-ac55-943815b91c6c",
+ "cy:run:critical:locally": "cypress run --env tags=critical --spec 'cypress/integration/navigation.js','cypress/integration/products/createProduct.js', 'cypress/integration/products/productsVariants.js','cypress/integration/checkout/purchaseWithProductTypes.js','cypress/integration/checkout/stocksInCheckout.js' --reporter cypress-mochawesome-reporter --reporter-options reportDir='cypress/reports',overwrite=true,charts=true",
+ "cy:run:refactored:locally": "cypress run --env tags=refactored --spec 'cypress/integration/navigation.js','cypress/integration/products/createProduct.js', 'cypress/integration/products/productsVariants.js','cypress/integration/checkout/purchaseWithProductTypes.js','cypress/integration/checkout/stocksInCheckout.js' --reporter cypress-mochawesome-reporter --reporter-options reportDir='cypress/reports',overwrite=true,charts=true",
+ "cy:run:critical": "cypress run --env tags=critical --spec 'cypress/integration/navigation.js','cypress/integration/products/*.js','cypress/integration/checkout/*.js'",
"cy:run:allEnv": "cypress run --env tags=all --record --key 1fe833f5-fca4-4454-ac55-943815b91c6c",
"test:e2e:run": "start-server-and-test start http://localhost:9000 cy:run",
"test:e2e:run:record": "start-server-and-test start http://localhost:9000 cy:run:record",