Merge branch 'master' of github.com:mirumee/saleor-dashboard into feature/unconfirmed-order-line-manipulation
This commit is contained in:
commit
5d63968a6f
171 changed files with 34016 additions and 1879 deletions
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -21,6 +21,8 @@ greatly reduce the amount of work needed to review your work. -->
|
||||||
1. [ ] Data-test are added for new elements.
|
1. [ ] Data-test are added for new elements.
|
||||||
1. [ ] Type definitions are up to date.
|
1. [ ] Type definitions are up to date.
|
||||||
1. [ ] Changes are mentioned in the changelog.
|
1. [ ] Changes are mentioned in the changelog.
|
||||||
|
1. [ ] The changes are tested in different browsers (Chrome, Firefox, Safari).
|
||||||
|
1. [ ] The changes are tested in light and dark mode.
|
||||||
|
|
||||||
### Test environment config
|
### Test environment config
|
||||||
|
|
||||||
|
|
2
.github/workflows/deploy-staging.yaml
vendored
2
.github/workflows/deploy-staging.yaml
vendored
|
@ -8,7 +8,7 @@ jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
API_URI: https://master.staging.saleor.cloud/graphql/
|
API_URI: /graphql/
|
||||||
APP_MOUNT_URI: /dashboard/
|
APP_MOUNT_URI: /dashboard/
|
||||||
STATIC_URL: /dashboard/static/
|
STATIC_URL: /dashboard/static/
|
||||||
SENTRY_ORG: saleor
|
SENTRY_ORG: saleor
|
||||||
|
|
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
|
@ -70,6 +70,7 @@ jobs:
|
||||||
npm run test
|
npm run test
|
||||||
|
|
||||||
cypress-run:
|
cypress-run:
|
||||||
|
if: github.event.pull_request.head.repo.full_name == 'mirumee/saleor-dashboard'
|
||||||
runs-on: ubuntu-16.04
|
runs-on: ubuntu-16.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -90,11 +91,12 @@ jobs:
|
||||||
env:
|
env:
|
||||||
API_URI: ${{ steps.api_uri.outputs.custom_api_uri || secrets.API_URI }}
|
API_URI: ${{ steps.api_uri.outputs.custom_api_uri || secrets.API_URI }}
|
||||||
APP_MOUNT_URI: ${{ secrets.APP_MOUNT_URI }}
|
APP_MOUNT_URI: ${{ secrets.APP_MOUNT_URI }}
|
||||||
|
CYPRESS_baseUrl: ${{ secrets.CYPRESS_BASEURL }}
|
||||||
CYPRESS_USER_NAME: ${{ secrets.CYPRESS_USER_NAME }}
|
CYPRESS_USER_NAME: ${{ secrets.CYPRESS_USER_NAME }}
|
||||||
CYPRESS_USER_PASSWORD: ${{ secrets.CYPRESS_USER_PASSWORD }}
|
CYPRESS_USER_PASSWORD: ${{ secrets.CYPRESS_USER_PASSWORD }}
|
||||||
with:
|
with:
|
||||||
build: npm run build
|
build: npm run build
|
||||||
start: npx http-server -a localhost -p 9000 build/dashboard
|
start: npx local-web-server --spa index.html
|
||||||
wait-on: http://localhost:9000/
|
wait-on: http://localhost:9000/
|
||||||
wait-on-timeout: 120
|
wait-on-timeout: 120
|
||||||
- uses: actions/upload-artifact@v1
|
- uses: actions/upload-artifact@v1
|
||||||
|
|
|
@ -19,6 +19,9 @@ All notable, unreleased changes to this project will be documented in this file.
|
||||||
- Drop descriptionJson and contentJson fields - #950 by @jwm0
|
- Drop descriptionJson and contentJson fields - #950 by @jwm0
|
||||||
- Add error tracking with Sentry adapter - #956 by @jwm0
|
- Add error tracking with Sentry adapter - #956 by @jwm0
|
||||||
- Add OAuth2 login with OpenID support - #963 by @orzechdev
|
- Add OAuth2 login with OpenID support - #963 by @orzechdev
|
||||||
|
- Fix no channels crash - #984 by @dominik-zeglen
|
||||||
|
- Update webhooks - #982 by @piotrgrundas
|
||||||
|
- Fix trigger form change when collections are being added to list of product collections - #987 by @gax97
|
||||||
- Unconfirmed order manipulation - #967 by @tomaszszymanski129
|
- Unconfirmed order manipulation - #967 by @tomaszszymanski129
|
||||||
|
|
||||||
# 2.11.1
|
# 2.11.1
|
||||||
|
|
|
@ -8,8 +8,8 @@ ARG APP_MOUNT_URI
|
||||||
ARG API_URI
|
ARG API_URI
|
||||||
ARG STATIC_URL
|
ARG STATIC_URL
|
||||||
ENV API_URI ${API_URI:-http://localhost:8000/graphql/}
|
ENV API_URI ${API_URI:-http://localhost:8000/graphql/}
|
||||||
ENV APP_MOUNT_URI ${APP_MOUNT_URI:-/dashboard/}
|
ENV APP_MOUNT_URI ${APP_MOUNT_URI:-/}
|
||||||
ENV STATIC_URL ${STATIC_URL:-/dashboard/}
|
ENV STATIC_URL ${STATIC_URL:-/}
|
||||||
|
|
||||||
EXPOSE 9000
|
EXPOSE 9000
|
||||||
CMD npm start -- --host 0.0.0.0
|
CMD npm start -- --host 0.0.0.0
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"baseUrl": "http://localhost:9000",
|
"baseUrl": "http://localhost:9000/dashboard/",
|
||||||
"defaultCommandTimeout": 15000,
|
"defaultCommandTimeout": 15000,
|
||||||
"requestTimeout": 15000,
|
"requestTimeout": 15000,
|
||||||
"viewportWidth": 1400,
|
"viewportWidth": 1400,
|
||||||
|
|
51
cypress/apiRequests/Attribute.js
Normal file
51
cypress/apiRequests/Attribute.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
class Attribute {
|
||||||
|
createAttribute(name) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
attributeCreate(input:{
|
||||||
|
name:"${name}"
|
||||||
|
valueRequired:false
|
||||||
|
type:PRODUCT_TYPE
|
||||||
|
}){
|
||||||
|
attribute{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
attributeErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAttributes(first, search) {
|
||||||
|
const mutation = `query{
|
||||||
|
attributes(first:${first}, filter:{
|
||||||
|
search:"${search}"
|
||||||
|
}){
|
||||||
|
edges{
|
||||||
|
node{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy
|
||||||
|
.sendRequestWithQuery(mutation)
|
||||||
|
.then(resp => resp.body.data.attributes.edges);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteAttribute(attributeId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
attributeDelete(id:"${attributeId}"){
|
||||||
|
attributeErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Attribute;
|
45
cypress/apiRequests/Category.js
Normal file
45
cypress/apiRequests/Category.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
class Category {
|
||||||
|
createCategory(name, slug = name) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
categoryCreate(input:{name:"${name}", slug: "${slug}"}){
|
||||||
|
productErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
category{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
getCategories(first, search) {
|
||||||
|
const mutation = `query{
|
||||||
|
categories(first:${first}, filter:{
|
||||||
|
search:"${search}"
|
||||||
|
}){
|
||||||
|
edges{
|
||||||
|
node{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy
|
||||||
|
.sendRequestWithQuery(mutation)
|
||||||
|
.then(resp => resp.body.data.categories.edges);
|
||||||
|
}
|
||||||
|
deleteCategory(categoryId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
categoryDelete(id:"${categoryId}"){
|
||||||
|
productErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Category;
|
53
cypress/apiRequests/Channels.js
Normal file
53
cypress/apiRequests/Channels.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
class Channels {
|
||||||
|
createChannel(isActive, name, slug, currencyCode) {
|
||||||
|
const createChannelMutation = `mutation{
|
||||||
|
channelCreate(input: {
|
||||||
|
isActive: ${isActive}
|
||||||
|
name: "${name}"
|
||||||
|
slug: "${slug}"
|
||||||
|
currencyCode: "${currencyCode}"
|
||||||
|
}){
|
||||||
|
channel{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
channelErrors{
|
||||||
|
code
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(createChannelMutation);
|
||||||
|
}
|
||||||
|
getChannels() {
|
||||||
|
const getChannelsInfoQuery = `query{
|
||||||
|
channels{
|
||||||
|
name
|
||||||
|
id
|
||||||
|
isActive
|
||||||
|
slug
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy.sendRequestWithQuery(getChannelsInfoQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteChannel(channelId, targetChannelId) {
|
||||||
|
const deleteChannelMutation = `mutation{
|
||||||
|
channelDelete(id: "${channelId}", input:{
|
||||||
|
targetChannel: "${targetChannelId}"
|
||||||
|
}){
|
||||||
|
channel{
|
||||||
|
name
|
||||||
|
}
|
||||||
|
channelErrors{
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(deleteChannelMutation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Channels;
|
69
cypress/apiRequests/Checkout.js
Normal file
69
cypress/apiRequests/Checkout.js
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
class Checkout {
|
||||||
|
createCheckout(channelSlug, email, productQuantity, variantsList) {
|
||||||
|
const lines = variantsList.map(
|
||||||
|
variant => `{quantity:${productQuantity}
|
||||||
|
variantId:"${variant.id}"}`
|
||||||
|
);
|
||||||
|
const mutation = `mutation{
|
||||||
|
checkoutCreate(input:{
|
||||||
|
channel:"${channelSlug}"
|
||||||
|
email:"${email}"
|
||||||
|
lines: [${lines.join()}]
|
||||||
|
}){
|
||||||
|
checkoutErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
created
|
||||||
|
checkout{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
addShippingMethod(checkoutId, shippingMethodId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
checkoutShippingMethodUpdate(checkoutId:"${checkoutId}",
|
||||||
|
shippingMethodId:"${shippingMethodId}"){
|
||||||
|
checkoutErrors{
|
||||||
|
message
|
||||||
|
field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
addPayment(checkoutId, gateway, token) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
checkoutPaymentCreate(checkoutId:"${checkoutId}",
|
||||||
|
input:{
|
||||||
|
gateway: "${gateway}"
|
||||||
|
token:"${token}"
|
||||||
|
}){
|
||||||
|
paymentErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
completeCheckout(checkoutId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
checkoutComplete(checkoutId:"${checkoutId}"){
|
||||||
|
order{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
confirmationNeeded
|
||||||
|
confirmationData
|
||||||
|
checkoutErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Checkout;
|
85
cypress/apiRequests/Customer.js
Normal file
85
cypress/apiRequests/Customer.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
export class Customer {
|
||||||
|
createCustomer(email, customerName, address, isActive = false) {
|
||||||
|
const mutation = `
|
||||||
|
mutation{
|
||||||
|
customerCreate(input:{
|
||||||
|
firstName: "${customerName}"
|
||||||
|
lastName: "${customerName}"
|
||||||
|
email: "${email}"
|
||||||
|
isActive: ${isActive}
|
||||||
|
defaultBillingAddress: {
|
||||||
|
companyName: "${address.companyName}"
|
||||||
|
streetAddress1: "${address.streetAddress1}"
|
||||||
|
streetAddress2: "${address.streetAddress2}"
|
||||||
|
city: "${address.city}"
|
||||||
|
postalCode: "${address.postalCode}"
|
||||||
|
country: ${address.country}
|
||||||
|
phone: "${address.phone}"
|
||||||
|
}
|
||||||
|
defaultShippingAddress: {
|
||||||
|
companyName: "${address.companyName}"
|
||||||
|
streetAddress1: "${address.streetAddress1}"
|
||||||
|
streetAddress2: "${address.streetAddress2}"
|
||||||
|
city: "${address.city}"
|
||||||
|
postalCode: "${address.postalCode}"
|
||||||
|
country: ${address.country}
|
||||||
|
phone: "${address.phone}"
|
||||||
|
}
|
||||||
|
}){
|
||||||
|
user{
|
||||||
|
id
|
||||||
|
email
|
||||||
|
}
|
||||||
|
accountErrors{
|
||||||
|
code
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteCustomers(startsWith) {
|
||||||
|
this.getCustomers(startsWith).then(resp => {
|
||||||
|
if (resp.body.data.customers) {
|
||||||
|
const customers = resp.body.data.customers.edges;
|
||||||
|
customers.forEach(element => {
|
||||||
|
if (element.node.email.includes(startsWith)) {
|
||||||
|
this.deleteCustomer(element.node.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteCustomer(customerId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
customerDelete(id:"${customerId}"){
|
||||||
|
accountErrors{
|
||||||
|
code
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
getCustomers(startsWith) {
|
||||||
|
const query = `query{
|
||||||
|
customers(first:100, filter: {
|
||||||
|
search: "${startsWith}"
|
||||||
|
}){
|
||||||
|
edges{
|
||||||
|
node{
|
||||||
|
id
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy.sendRequestWithQuery(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Customer;
|
37
cypress/apiRequests/HomePage.js
Normal file
37
cypress/apiRequests/HomePage.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
class HomePage {
|
||||||
|
getSalesForChannel(channelSlug, period) {
|
||||||
|
const query = `query{
|
||||||
|
ordersTotal(period: ${period}, channel:"${channelSlug}"){
|
||||||
|
gross{
|
||||||
|
amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(query);
|
||||||
|
}
|
||||||
|
getOrdersForChannel(channelSlug, created) {
|
||||||
|
const query = `query{
|
||||||
|
orders(created: ${created}, channel:"${channelSlug}"){
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(query);
|
||||||
|
}
|
||||||
|
getOrdersWithStatus(status, channelSlug) {
|
||||||
|
const query = `query{
|
||||||
|
orders(status: ${status}, channel:"${channelSlug}"){
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(query);
|
||||||
|
}
|
||||||
|
getProductsOutOfStock(channelSlug) {
|
||||||
|
const query = `query{
|
||||||
|
products(stockAvailability: OUT_OF_STOCK, channel:"${channelSlug}"){
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default HomePage;
|
60
cypress/apiRequests/Order.js
Normal file
60
cypress/apiRequests/Order.js
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
class Order {
|
||||||
|
markOrderAsPaid(orderId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
orderMarkAsPaid(id:"${orderId}"){
|
||||||
|
orderErrors{
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
addProductToOrder(orderId, variantId, quantity = 1) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
draftOrderLinesCreate(id:"${orderId}", input:{
|
||||||
|
quantity:${quantity}
|
||||||
|
variantId: "${variantId}"
|
||||||
|
}){
|
||||||
|
orderErrors{
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
createDraftOrder(customerId, shippingMethodId, channelId) {
|
||||||
|
const mutation = `
|
||||||
|
mutation{
|
||||||
|
draftOrderCreate(input:{
|
||||||
|
user:"${customerId}"
|
||||||
|
shippingMethod:"${shippingMethodId}"
|
||||||
|
channel: "${channelId}"
|
||||||
|
}){
|
||||||
|
orderErrors{
|
||||||
|
message
|
||||||
|
}
|
||||||
|
order{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
completeOrder(orderId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
draftOrderComplete(id:"${orderId}"){
|
||||||
|
order{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
orderErrors{
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Order;
|
200
cypress/apiRequests/Product.js
Normal file
200
cypress/apiRequests/Product.js
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
import Utils from "./utils/Utils";
|
||||||
|
|
||||||
|
class Product {
|
||||||
|
utils = new Utils();
|
||||||
|
getFirstProducts(first, search) {
|
||||||
|
const filter = search
|
||||||
|
? `, filter:{
|
||||||
|
search:"${search}"
|
||||||
|
}`
|
||||||
|
: "";
|
||||||
|
const query = `query{
|
||||||
|
products(first:${first}${filter}){
|
||||||
|
edges{
|
||||||
|
node{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
variants{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy
|
||||||
|
.sendRequestWithQuery(query)
|
||||||
|
.then(resp => resp.body.data.products.edges);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateChannelInProduct({
|
||||||
|
productId,
|
||||||
|
channelId,
|
||||||
|
isPublished = true,
|
||||||
|
isAvailableForPurchase = true,
|
||||||
|
visibleInListings = true
|
||||||
|
}) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
productChannelListingUpdate(id:"${productId}",
|
||||||
|
input:{
|
||||||
|
addChannels:{
|
||||||
|
channelId:"${channelId}"
|
||||||
|
isPublished:${isPublished}
|
||||||
|
isAvailableForPurchase:${isAvailableForPurchase}
|
||||||
|
visibleInListings:${visibleInListings}
|
||||||
|
}
|
||||||
|
}){
|
||||||
|
product{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateChannelPriceInVariant(variantId, channelId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
productVariantChannelListingUpdate(id: "${variantId}", input: {
|
||||||
|
channelId: "${channelId}"
|
||||||
|
price: 10
|
||||||
|
costPrice: 10
|
||||||
|
}){
|
||||||
|
productChannelListingErrors{
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} `;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
createProduct(attributeId, name, productType, category) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
productCreate(input:{
|
||||||
|
attributes:[{
|
||||||
|
id:"${attributeId}"
|
||||||
|
}]
|
||||||
|
name:"${name}"
|
||||||
|
productType:"${productType}"
|
||||||
|
category:"${category}"
|
||||||
|
}){
|
||||||
|
product{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
productErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
createVariant(
|
||||||
|
productId,
|
||||||
|
sku,
|
||||||
|
warehouseId,
|
||||||
|
quantity,
|
||||||
|
channelId,
|
||||||
|
price = 1,
|
||||||
|
costPrice = 1
|
||||||
|
) {
|
||||||
|
const channelListings = this.utils.getValueWithDefault(
|
||||||
|
channelId,
|
||||||
|
`channelListings:{
|
||||||
|
channelId:"${channelId}"
|
||||||
|
price:"${price}"
|
||||||
|
costPrice:"${costPrice}"
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const stocks = this.utils.getValueWithDefault(
|
||||||
|
warehouseId,
|
||||||
|
`stocks:{
|
||||||
|
warehouse:"${warehouseId}"
|
||||||
|
quantity:${quantity}
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const mutation = `mutation{
|
||||||
|
productVariantBulkCreate(product: "${productId}", variants: {
|
||||||
|
attributes: []
|
||||||
|
sku: "${sku}"
|
||||||
|
${channelListings}
|
||||||
|
${stocks}
|
||||||
|
}) {
|
||||||
|
productVariants{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
bulkProductErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
createTypeProduct(name, attributeId, slug = name) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
productTypeCreate(input: {
|
||||||
|
name: "${name}"
|
||||||
|
slug: "${slug}"
|
||||||
|
isShippingRequired: true
|
||||||
|
productAttributes: "${attributeId}"
|
||||||
|
}){
|
||||||
|
productErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
productType{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} `;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteProduct(productId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
productDelete(id: "${productId}"){
|
||||||
|
productErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} `;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
getProductTypes(first, search) {
|
||||||
|
const query = `query{
|
||||||
|
productTypes(first:${first}, filter:{
|
||||||
|
search:"${search}"
|
||||||
|
}){
|
||||||
|
edges{
|
||||||
|
node{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy
|
||||||
|
.sendRequestWithQuery(query)
|
||||||
|
.then(resp => resp.body.data.productTypes.edges);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteProductType(productTypeId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
productTypeDelete(id:"${productTypeId}"){
|
||||||
|
productErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Product;
|
86
cypress/apiRequests/ShippingMethod.js
Normal file
86
cypress/apiRequests/ShippingMethod.js
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
class ShippingMethod {
|
||||||
|
createShippingRate(name, shippingZone) {
|
||||||
|
const mutation = `
|
||||||
|
mutation{
|
||||||
|
shippingPriceCreate(input:{
|
||||||
|
name: "${name}"
|
||||||
|
shippingZone: "${shippingZone}"
|
||||||
|
type: PRICE
|
||||||
|
}){
|
||||||
|
shippingMethod{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
createShippingZone(name, country) {
|
||||||
|
const mutation = `
|
||||||
|
mutation{
|
||||||
|
shippingZoneCreate(input:{
|
||||||
|
name: "${name}"
|
||||||
|
countries: "${country}"
|
||||||
|
}){
|
||||||
|
shippingZone{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
addChannelToShippingMethod(shippingRateId, channelId, price) {
|
||||||
|
const mutation = `
|
||||||
|
mutation{
|
||||||
|
shippingMethodChannelListingUpdate(id:"${shippingRateId}", input:{
|
||||||
|
addChannels: {
|
||||||
|
channelId:"${channelId}"
|
||||||
|
price: ${price}
|
||||||
|
}
|
||||||
|
}){
|
||||||
|
shippingMethod{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
shippingErrors{
|
||||||
|
code
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteShippingZone(shippingZoneId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
shippingZoneDelete(id:"${shippingZoneId}"){
|
||||||
|
shippingErrors{
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
|
||||||
|
getShippingZones() {
|
||||||
|
const query = `query{
|
||||||
|
shippingZones(first:100){
|
||||||
|
edges{
|
||||||
|
node{
|
||||||
|
name
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return cy
|
||||||
|
.sendRequestWithQuery(query)
|
||||||
|
.then(resp => resp.body.data.shippingZones.edges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ShippingMethod;
|
57
cypress/apiRequests/Warehouse.js
Normal file
57
cypress/apiRequests/Warehouse.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
class Warehouse {
|
||||||
|
createWarehouse(name, shippingZone, address, slug = name) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
createWarehouse(input:{
|
||||||
|
name:"${name}"
|
||||||
|
slug:"${slug}"
|
||||||
|
shippingZones:"${shippingZone}"
|
||||||
|
address:{
|
||||||
|
streetAddress1: "${address.streetAddress1}"
|
||||||
|
streetAddress2: "${address.streetAddress2}"
|
||||||
|
city: "${address.city}"
|
||||||
|
postalCode: "${address.postalCode}"
|
||||||
|
country: ${address.country}
|
||||||
|
phone: "${address.phone}"
|
||||||
|
}
|
||||||
|
}){
|
||||||
|
warehouseErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
warehouse{
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
getWarehouses(first, search) {
|
||||||
|
const query = `query{
|
||||||
|
warehouses(first:${first}, filter:{
|
||||||
|
search:"${search}"
|
||||||
|
}){
|
||||||
|
edges{
|
||||||
|
node{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy
|
||||||
|
.sendRequestWithQuery(query)
|
||||||
|
.then(resp => resp.body.data.warehouses.edges);
|
||||||
|
}
|
||||||
|
deleteWarehouse(warehouseId) {
|
||||||
|
const mutation = `mutation{
|
||||||
|
deleteWarehouse(id:"${warehouseId}"){
|
||||||
|
warehouseErrors{
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Warehouse;
|
18
cypress/apiRequests/storeFront/ProductDetails.js
Normal file
18
cypress/apiRequests/storeFront/ProductDetails.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
class ProductDetails {
|
||||||
|
getProductDetails(productId, channelId) {
|
||||||
|
const query = `fragment BasicProductFields on Product {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
query ProductDetails{
|
||||||
|
product(id: "${productId}", channel: "${channelId}") {
|
||||||
|
...BasicProductFields
|
||||||
|
isAvailable
|
||||||
|
isAvailableForPurchase
|
||||||
|
availableForPurchase
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(query, "token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ProductDetails;
|
20
cypress/apiRequests/storeFront/Search.js
Normal file
20
cypress/apiRequests/storeFront/Search.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
class Search {
|
||||||
|
searchInShop(searchQuery) {
|
||||||
|
const query = `query SearchProducts {
|
||||||
|
products(channel: "default-channel", filter:{
|
||||||
|
search: "${searchQuery}"
|
||||||
|
}, first:10){
|
||||||
|
totalCount
|
||||||
|
edges{
|
||||||
|
node{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
return cy.sendRequestWithQuery(query, "token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Search;
|
6
cypress/apiRequests/utils/Utils.js
Normal file
6
cypress/apiRequests/utils/Utils.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
class Utils {
|
||||||
|
getValueWithDefault(condition, value, defaultValue = "") {
|
||||||
|
return condition ? value : defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Utils;
|
|
@ -1,4 +1,7 @@
|
||||||
/* eslint-disable sort-keys */
|
|
||||||
export const LEFT_MENU_SELECTORS = {
|
export const LEFT_MENU_SELECTORS = {
|
||||||
catalog: "[data-test-id='catalogue']"
|
catalog: "[data-test='menu-item-label'][data-test-id='catalogue']",
|
||||||
|
configuration: "[data-test='menu-item-label'][data-test-id='configure']",
|
||||||
|
home: "[data-test='menu-item-label'][data-test-id='home']",
|
||||||
|
orders: "[data-test='menu-item-label'][data-test-id=orders']",
|
||||||
|
products: "[data-test='submenu-item-label'][data-test-id='products']"
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* eslint-disable sort-keys */
|
/* eslint-disable sort-keys */
|
||||||
export const PRODUCTS_SELECTORS = {
|
export const PRODUCTS_SELECTORS = {
|
||||||
|
productsList: "[data-test-id][data-test='id']",
|
||||||
products: "[data-test='submenu-item-label'][data-test-id='products']",
|
products: "[data-test='submenu-item-label'][data-test-id='products']",
|
||||||
createProductBtn: "[data-test='add-product']",
|
createProductBtn: "[data-test='add-product']",
|
||||||
productNameInput: "[name='name']",
|
productNameInput: "[name='name']",
|
||||||
|
@ -11,5 +12,21 @@ export const PRODUCTS_SELECTORS = {
|
||||||
visibleRadioBtn: "[name='isPublished']",
|
visibleRadioBtn: "[name='isPublished']",
|
||||||
saveBtn: "[data-test='button-bar-confirm']",
|
saveBtn: "[data-test='button-bar-confirm']",
|
||||||
confirmationMsg: "[data-test='notification-success']",
|
confirmationMsg: "[data-test='notification-success']",
|
||||||
channelAvailabilityItem: "[data-test='channel-availability-item']"
|
channelAvailabilityItem: "[data-test='channel-availability-item']",
|
||||||
|
searchProducts: "[placeholder='Search Products...']",
|
||||||
|
availableManageButton:
|
||||||
|
"[data-test-id='channels-availiability-manage-button']",
|
||||||
|
channelsAvailabilityForm:
|
||||||
|
"[data-test-id='manage-products-channels-availiability-list']",
|
||||||
|
channelAvailabilityColumn:
|
||||||
|
"[data-test='availability'][data-test-availability='true']",
|
||||||
|
channelAvailabilityList: "ul[role='menu']",
|
||||||
|
goBackButton: "[data-test-id='app-header-back-button']",
|
||||||
|
assignedChannels: "[data-test='channel-availability-item']",
|
||||||
|
publishedRadioButtons: "[name*='isPublished']",
|
||||||
|
availableForPurchaseRadioButtons: "[name*='isAvailableForPurchase']",
|
||||||
|
radioButtonsValueTrue: "[value='true']",
|
||||||
|
radioButtonsValueFalse: "[value='false']",
|
||||||
|
visibleInListingsButton: "[name*='visibleInListings']",
|
||||||
|
emptyProductRow: "[class*='Skeleton']"
|
||||||
};
|
};
|
||||||
|
|
12
cypress/elements/channels/add-channel-form-selectors.js
Normal file
12
cypress/elements/channels/add-channel-form-selectors.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
export const ADD_CHANNEL_FORM_SELECTORS = {
|
||||||
|
channelName: "[name='name']",
|
||||||
|
slug: "[name='slug']",
|
||||||
|
currency: "[data-test-id='channel-currency-select-input']",
|
||||||
|
currencyOptions: "[data-test='singleautocomplete-select-option']",
|
||||||
|
saveButton: "[data-test='button-bar-confirm']",
|
||||||
|
backToChannelsList: "[data-test-id='app-header-back-button']",
|
||||||
|
currencyValidationMessage: "[data-testid='currency-text-input-helper-text']",
|
||||||
|
slugValidationMessage: "[data-testid='slug-text-input-helper-text']",
|
||||||
|
currencyAutocompleteDropdown:
|
||||||
|
"[data-test='singleautocomplete-select-option'][data-test-type='custom']"
|
||||||
|
};
|
5
cypress/elements/channels/channel-form-selectors.js
Normal file
5
cypress/elements/channels/channel-form-selectors.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export const CHANNEL_FORM_SELECTORS = {
|
||||||
|
channelSelect: "[id='mui-component-select-channels']",
|
||||||
|
channelOption: "[data-test='selectFieldOption']",
|
||||||
|
confirmButton: "[data-test='submit']"
|
||||||
|
};
|
5
cypress/elements/channels/channels-selectors.js
Normal file
5
cypress/elements/channels/channels-selectors.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export const CHANNELS_SELECTORS = {
|
||||||
|
createChannelButton: "[data-test='add-channel']",
|
||||||
|
channelsTable: "[class='MuiTableBody-root']",
|
||||||
|
channelName: "[data-test='name']"
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
/* eslint-disable sort-keys */
|
||||||
|
export const CONFIGURATION_SELECTORS = {
|
||||||
|
channels: "[data-testid='channels']"
|
||||||
|
};
|
4
cypress/elements/header/header-selectors.js
Normal file
4
cypress/elements/header/header-selectors.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export const HEADER_SELECTORS = {
|
||||||
|
channelSelect: "[data-test-id='app-channel-select']",
|
||||||
|
channelSelectList: "[class*='MuiMenu-paper']"
|
||||||
|
};
|
9
cypress/elements/homePage/homePage-selectors.js
Normal file
9
cypress/elements/homePage/homePage-selectors.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export const HOMEPAGE_SELECTORS = {
|
||||||
|
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']"
|
||||||
|
};
|
3
cypress/elements/orders/draft-order-selectors.js
Normal file
3
cypress/elements/orders/draft-order-selectors.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export const DRAFT_ORDER_SELECTORS = {
|
||||||
|
addProducts: "[data-test-id='add-products-button']"
|
||||||
|
};
|
4
cypress/elements/orders/orders-selectors.js
Normal file
4
cypress/elements/orders/orders-selectors.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export const ORDERS_SELECTORS = {
|
||||||
|
orders: "[data-test='submenu-item-label'][data-test-id='orders']",
|
||||||
|
createOrder: "[data-test-id='create-order-button']"
|
||||||
|
};
|
13
cypress/fixtures/addresses.json
Normal file
13
cypress/fixtures/addresses.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"plAddress": {
|
||||||
|
"companyName": "Test3",
|
||||||
|
"streetAddress1": "Smolna",
|
||||||
|
"streetAddress2": "13/1",
|
||||||
|
"city": "Wrocław",
|
||||||
|
"postalCode": "53-346",
|
||||||
|
"country": "PL",
|
||||||
|
"countryArea": "Dolny Śląsk",
|
||||||
|
"phone": "123456787",
|
||||||
|
"currency": "PLN"
|
||||||
|
}
|
||||||
|
}
|
149
cypress/integration/channels.js
Normal file
149
cypress/integration/channels.js
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
// <reference types="cypress" />
|
||||||
|
import faker from "faker";
|
||||||
|
|
||||||
|
import Channels from "../apiRequests/Channels";
|
||||||
|
import { LEFT_MENU_SELECTORS } from "../elements/account/left-menu/left-menu-selectors";
|
||||||
|
import { PRODUCTS_SELECTORS } from "../elements/catalog/product-selectors";
|
||||||
|
import { ADD_CHANNEL_FORM_SELECTORS } from "../elements/channels/add-channel-form-selectors";
|
||||||
|
import { CHANNEL_FORM_SELECTORS } from "../elements/channels/channel-form-selectors";
|
||||||
|
import { CHANNELS_SELECTORS } from "../elements/channels/channels-selectors";
|
||||||
|
import { CONFIGURATION_SELECTORS } from "../elements/configuration/configuration-selectors";
|
||||||
|
import { HEADER_SELECTORS } from "../elements/header/header-selectors";
|
||||||
|
import { DRAFT_ORDER_SELECTORS } from "../elements/orders/draft-order-selectors";
|
||||||
|
import { ORDERS_SELECTORS } from "../elements/orders/orders-selectors";
|
||||||
|
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
|
||||||
|
import ChannelsSteps from "../steps/channelsSteps";
|
||||||
|
import { urlList } from "../url/urlList";
|
||||||
|
import ChannelsUtils from "../utils/channelsUtils";
|
||||||
|
|
||||||
|
describe("Channels", () => {
|
||||||
|
const channelStartsWith = "Cypress:";
|
||||||
|
const currency = "PLN";
|
||||||
|
const channels = new Channels();
|
||||||
|
const channelsUtils = new ChannelsUtils();
|
||||||
|
const channelsSteps = new ChannelsSteps();
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
channelsUtils.deleteChannels(channelStartsWith);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should navigate to channels page", () => {
|
||||||
|
cy.visit(urlList.homePage)
|
||||||
|
.get(LEFT_MENU_SELECTORS.configuration)
|
||||||
|
.click()
|
||||||
|
.get(CONFIGURATION_SELECTORS.channels)
|
||||||
|
.click()
|
||||||
|
.location("pathname")
|
||||||
|
.should("contain", "channels");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create new channel", () => {
|
||||||
|
const randomChannel = `${channelStartsWith} ${faker.random.number()}`;
|
||||||
|
cy.addAliasToGraphRequest("Channels");
|
||||||
|
cy.visit(urlList.channels);
|
||||||
|
cy.wait("@Channels");
|
||||||
|
cy.addAliasToGraphRequest("Channel");
|
||||||
|
channelsSteps.createChannelByView(randomChannel, currency);
|
||||||
|
// New channel should be visible in channels list
|
||||||
|
cy.wait("@Channel")
|
||||||
|
.get(ADD_CHANNEL_FORM_SELECTORS.backToChannelsList)
|
||||||
|
.click()
|
||||||
|
.get(CHANNELS_SELECTORS.channelsTable)
|
||||||
|
.contains(randomChannel);
|
||||||
|
|
||||||
|
// new channel should be visible in channel selector
|
||||||
|
cy.visit(urlList.homePage)
|
||||||
|
.get(HEADER_SELECTORS.channelSelect)
|
||||||
|
.click()
|
||||||
|
.get(HEADER_SELECTORS.channelSelectList)
|
||||||
|
.contains(randomChannel)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
// new channel should be visible at product availability form
|
||||||
|
cy.addAliasToGraphRequest("InitialProductFilterData");
|
||||||
|
cy.visit(urlList.products);
|
||||||
|
cy.wait("@InitialProductFilterData");
|
||||||
|
cy.get(PRODUCTS_SELECTORS.productsList)
|
||||||
|
.first()
|
||||||
|
.click()
|
||||||
|
.get(PRODUCTS_SELECTORS.availableManageButton)
|
||||||
|
.click()
|
||||||
|
.get(PRODUCTS_SELECTORS.channelsAvailabilityForm)
|
||||||
|
.contains(randomChannel);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should validate slug name", () => {
|
||||||
|
const randomChannel = `${channelStartsWith} ${faker.random.number()}`;
|
||||||
|
channels.createChannel(false, randomChannel, randomChannel, currency);
|
||||||
|
cy.visit(urlList.channels);
|
||||||
|
channelsSteps.createChannelByView(randomChannel, currency);
|
||||||
|
cy.get(ADD_CHANNEL_FORM_SELECTORS.slugValidationMessage).should(
|
||||||
|
"be.visible"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should validate currency", () => {
|
||||||
|
const randomChannel = `${channelStartsWith} ${faker.random.number()}`;
|
||||||
|
cy.visit(urlList.channels);
|
||||||
|
channelsSteps.createChannelByView(
|
||||||
|
randomChannel,
|
||||||
|
currency,
|
||||||
|
"notExistingCurrency"
|
||||||
|
);
|
||||||
|
cy.get(ADD_CHANNEL_FORM_SELECTORS.currencyValidationMessage).should(
|
||||||
|
"be.visible"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should delete channel", () => {
|
||||||
|
const randomChannelToDelete = `${channelStartsWith} ${faker.random.number()}`;
|
||||||
|
channels.createChannel(
|
||||||
|
false,
|
||||||
|
randomChannelToDelete,
|
||||||
|
randomChannelToDelete,
|
||||||
|
currency
|
||||||
|
);
|
||||||
|
cy.addAliasToGraphRequest("Channels");
|
||||||
|
cy.visit(urlList.channels);
|
||||||
|
cy.wait("@Channels");
|
||||||
|
cy.get(CHANNELS_SELECTORS.channelName)
|
||||||
|
.contains(randomChannelToDelete)
|
||||||
|
.parentsUntil(CHANNELS_SELECTORS.channelsTable)
|
||||||
|
.find("button")
|
||||||
|
.click();
|
||||||
|
cy.addAliasToGraphRequest("Channels");
|
||||||
|
cy.get(BUTTON_SELECTORS.submit).click();
|
||||||
|
cy.wait("@Channels");
|
||||||
|
|
||||||
|
cy.get(CHANNELS_SELECTORS.channelName)
|
||||||
|
.contains(randomChannelToDelete)
|
||||||
|
.should("not.exist");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not be possible to add products to order with inactive channel", () => {
|
||||||
|
const randomChannel = `${channelStartsWith} ${faker.random.number()}`;
|
||||||
|
channels.createChannel(false, randomChannel, randomChannel, currency);
|
||||||
|
cy.visit(urlList.orders)
|
||||||
|
.get(ORDERS_SELECTORS.createOrder)
|
||||||
|
.click()
|
||||||
|
.get(CHANNEL_FORM_SELECTORS.channelSelect)
|
||||||
|
.click()
|
||||||
|
.get(CHANNEL_FORM_SELECTORS.channelOption)
|
||||||
|
.contains(randomChannel)
|
||||||
|
.click()
|
||||||
|
.get(CHANNEL_FORM_SELECTORS.confirmButton)
|
||||||
|
.click();
|
||||||
|
cy.location()
|
||||||
|
.should(loc => {
|
||||||
|
const urlRegex = new RegExp(`${urlList.orders}.+`, "g");
|
||||||
|
expect(loc.pathname).to.match(urlRegex);
|
||||||
|
})
|
||||||
|
.get(DRAFT_ORDER_SELECTORS.addProducts)
|
||||||
|
.should("not.exist");
|
||||||
|
});
|
||||||
|
});
|
235
cypress/integration/homePage.js
Normal file
235
cypress/integration/homePage.js
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
import faker from "faker";
|
||||||
|
|
||||||
|
import Customer from "../apiRequests/Customer";
|
||||||
|
import { HOMEPAGE_SELECTORS } from "../elements/homePage/homePage-selectors";
|
||||||
|
import HomePageSteps from "../steps/homePageSteps";
|
||||||
|
import { urlList } from "../url/urlList";
|
||||||
|
import ChannelsUtils from "../utils/channelsUtils";
|
||||||
|
import HomePageUtils from "../utils/homePageUtils";
|
||||||
|
import OrdersUtils from "../utils/ordersUtils";
|
||||||
|
import ProductsUtils from "../utils/productsUtils";
|
||||||
|
import ShippingUtils from "../utils/shippingUtils";
|
||||||
|
|
||||||
|
// <reference types="cypress" />
|
||||||
|
describe("Homepage analytics", () => {
|
||||||
|
const startsWith = "Cy-";
|
||||||
|
|
||||||
|
const customer = new Customer();
|
||||||
|
const productsUtils = new ProductsUtils();
|
||||||
|
const shippingUtils = new ShippingUtils();
|
||||||
|
const ordersUtils = new OrdersUtils();
|
||||||
|
const channelsUtils = new ChannelsUtils();
|
||||||
|
const homePageUtils = new HomePageUtils();
|
||||||
|
const homePageSteps = new HomePageSteps();
|
||||||
|
|
||||||
|
let customerId;
|
||||||
|
let defaultChannel;
|
||||||
|
const productPrice = 22;
|
||||||
|
const shippingPrice = 12;
|
||||||
|
const randomName = startsWith + faker.random.number();
|
||||||
|
const randomEmail = randomName + "@example.com";
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
productsUtils.deleteProperProducts(startsWith);
|
||||||
|
customer.deleteCustomers(startsWith);
|
||||||
|
shippingUtils.deleteShipping(startsWith);
|
||||||
|
let addresses;
|
||||||
|
|
||||||
|
channelsUtils
|
||||||
|
.getDefaultChannel()
|
||||||
|
.then(channel => {
|
||||||
|
defaultChannel = channel;
|
||||||
|
cy.fixture("addresses");
|
||||||
|
})
|
||||||
|
.then(addressesFixture => (addresses = addressesFixture))
|
||||||
|
.then(() =>
|
||||||
|
customer.createCustomer(randomEmail, randomName, addresses.plAddress)
|
||||||
|
)
|
||||||
|
.then(resp => {
|
||||||
|
customerId = resp.body.data.customerCreate.user.id;
|
||||||
|
shippingUtils.createShipping({
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
name: randomName,
|
||||||
|
address: addresses.plAddress,
|
||||||
|
price: shippingPrice
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
productsUtils.createTypeAttributeAndCategoryForProduct(randomName);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const warehouse = shippingUtils.getWarehouse();
|
||||||
|
const productType = productsUtils.getProductType();
|
||||||
|
const attribute = productsUtils.getAttribute();
|
||||||
|
const category = productsUtils.getCategory();
|
||||||
|
productsUtils.createProductInChannel({
|
||||||
|
name: randomName,
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
warehouseId: warehouse.id,
|
||||||
|
quantityInWarehouse: 20,
|
||||||
|
productTypeId: productType.id,
|
||||||
|
attributeId: attribute.id,
|
||||||
|
categoryId: category.id,
|
||||||
|
price: productPrice
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
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");
|
||||||
|
|
||||||
|
ordersUtils.createReadyToFulfillOrder(
|
||||||
|
customerId,
|
||||||
|
shippingUtils.getShippingMethod().id,
|
||||||
|
defaultChannel.id,
|
||||||
|
productsUtils.getCreatedVariants()
|
||||||
|
);
|
||||||
|
cy.get("@ordersReadyToFulfill").then(ordersReadyToFulfillBefore => {
|
||||||
|
const allOrdersReadyToFulfill = ordersReadyToFulfillBefore + 1;
|
||||||
|
const notANumberRegex = "\\D*";
|
||||||
|
const ordersReadyToFulfillRegexp = new RegExp(
|
||||||
|
`${notANumberRegex}${allOrdersReadyToFulfill}${notANumberRegex}`
|
||||||
|
);
|
||||||
|
cy.visit(urlList.homePage);
|
||||||
|
homePageSteps.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");
|
||||||
|
const variantsList = productsUtils.getCreatedVariants();
|
||||||
|
|
||||||
|
ordersUtils.createWaitingForCaptureOrder(
|
||||||
|
defaultChannel.slug,
|
||||||
|
randomEmail,
|
||||||
|
variantsList,
|
||||||
|
shippingUtils.getShippingMethod().id
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get("@ordersReadyForCapture").then(ordersReadyForCaptureBefore => {
|
||||||
|
const allOrdersReadyForCapture = ordersReadyForCaptureBefore + 1;
|
||||||
|
const notANumberRegex = "\\D*";
|
||||||
|
const ordersReadyForCaptureRegexp = new RegExp(
|
||||||
|
`${notANumberRegex}${allOrdersReadyForCapture}${notANumberRegex}`
|
||||||
|
);
|
||||||
|
cy.visit(urlList.homePage);
|
||||||
|
homePageSteps.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.random.number();
|
||||||
|
const productsOutOfStockUtils = new ProductsUtils();
|
||||||
|
const warehouse = shippingUtils.getWarehouse();
|
||||||
|
const productType = productsUtils.getProductType();
|
||||||
|
const attribute = productsUtils.getAttribute();
|
||||||
|
const category = productsUtils.getCategory();
|
||||||
|
|
||||||
|
productsOutOfStockUtils.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);
|
||||||
|
homePageSteps.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");
|
||||||
|
|
||||||
|
ordersUtils.createReadyToFulfillOrder(
|
||||||
|
customerId,
|
||||||
|
shippingUtils.getShippingMethod().id,
|
||||||
|
defaultChannel.id,
|
||||||
|
productsUtils.getCreatedVariants()
|
||||||
|
);
|
||||||
|
|
||||||
|
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 = totalAmountIntegerValue.replace(
|
||||||
|
/(\d)(?=(\d{3})+(?!\d))/g,
|
||||||
|
"1[,.]*"
|
||||||
|
);
|
||||||
|
const totalAmountWithSeparators = `${totalAmountIntegerWithThousandsSeparator}${decimalSeparator}${totalAmountDecimalValue}`;
|
||||||
|
const notANumberRegex = "\\D*";
|
||||||
|
const salesAmountRegexp = new RegExp(
|
||||||
|
`${notANumberRegex}${totalAmountWithSeparators}${notANumberRegex}`
|
||||||
|
);
|
||||||
|
cy.visit(urlList.homePage);
|
||||||
|
homePageSteps.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");
|
||||||
|
|
||||||
|
ordersUtils.createReadyToFulfillOrder(
|
||||||
|
customerId,
|
||||||
|
shippingUtils.getShippingMethod().id,
|
||||||
|
defaultChannel.id,
|
||||||
|
productsUtils.getCreatedVariants()
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get("@todaysOrders").then(ordersBefore => {
|
||||||
|
const allOrders = ordersBefore + 1;
|
||||||
|
const notANumberRegex = "\\D*";
|
||||||
|
const ordersRegexp = new RegExp(
|
||||||
|
`${notANumberRegex}${allOrders}${notANumberRegex}`
|
||||||
|
);
|
||||||
|
cy.visit(urlList.homePage);
|
||||||
|
homePageSteps.changeChannel(defaultChannel.name);
|
||||||
|
cy.contains(HOMEPAGE_SELECTORS.orders, ordersRegexp).should("be.visible");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,19 +1,20 @@
|
||||||
import { LOGIN_SELECTORS } from "../elements/account/login-selectors";
|
|
||||||
|
|
||||||
// <reference types="cypress" />
|
// <reference types="cypress" />
|
||||||
|
import { LOGIN_SELECTORS } from "../elements/account/login-selectors";
|
||||||
|
import { urlList } from "../url/urlList";
|
||||||
|
|
||||||
describe("User authorization", () => {
|
describe("User authorization", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.clearSessionData();
|
cy.clearSessionData();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should successfully log in an user", () => {
|
it("should successfully log in an user", () => {
|
||||||
cy.visit("/");
|
cy.visit(urlList.homePage);
|
||||||
cy.loginUser();
|
cy.loginUser();
|
||||||
cy.get(LOGIN_SELECTORS.welcomePage);
|
cy.get(LOGIN_SELECTORS.welcomePage);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fail for wrong password", () => {
|
it("should fail for wrong password", () => {
|
||||||
cy.visit("/")
|
cy.visit(urlList.homePage)
|
||||||
.get(LOGIN_SELECTORS.emailAddressInput)
|
.get(LOGIN_SELECTORS.emailAddressInput)
|
||||||
.type("admin@example.com")
|
.type("admin@example.com")
|
||||||
.get(LOGIN_SELECTORS.emailPasswordInput)
|
.get(LOGIN_SELECTORS.emailPasswordInput)
|
||||||
|
@ -27,7 +28,7 @@ describe("User authorization", () => {
|
||||||
cy.window().then(win => {
|
cy.window().then(win => {
|
||||||
win.sessionStorage.clear();
|
win.sessionStorage.clear();
|
||||||
});
|
});
|
||||||
cy.visit("/");
|
cy.visit(urlList.homePage);
|
||||||
cy.loginUser();
|
cy.loginUser();
|
||||||
cy.get(LOGIN_SELECTORS.userMenu)
|
cy.get(LOGIN_SELECTORS.userMenu)
|
||||||
.click()
|
.click()
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
import faker from "faker";
|
||||||
|
|
||||||
|
import ProductSteps from "../../../steps/productSteps";
|
||||||
|
import { productDetailsUrl } from "../../../url/urlList";
|
||||||
|
import ChannelsUtils from "../../../utils/channelsUtils";
|
||||||
|
import ProductsUtils from "../../../utils/productsUtils";
|
||||||
|
import ShippingUtils from "../../../utils/shippingUtils";
|
||||||
|
import { isProductAvailableForPurchase } from "../../../utils/storeFront/storeFrontProductUtils";
|
||||||
|
|
||||||
|
// <reference types="cypress" />
|
||||||
|
describe("Products available in listings", () => {
|
||||||
|
const shippingUtils = new ShippingUtils();
|
||||||
|
const channelsUtils = new ChannelsUtils();
|
||||||
|
const productsUtils = new ProductsUtils();
|
||||||
|
const productSteps = new ProductSteps();
|
||||||
|
const startsWith = "Cy-";
|
||||||
|
const name = `${startsWith}${faker.random.number()}`;
|
||||||
|
let productType;
|
||||||
|
let attribute;
|
||||||
|
let category;
|
||||||
|
let defaultChannel;
|
||||||
|
let warehouse;
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
shippingUtils.deleteShipping(startsWith);
|
||||||
|
productsUtils.deleteProperProducts(startsWith);
|
||||||
|
|
||||||
|
channelsUtils
|
||||||
|
.getDefaultChannel()
|
||||||
|
.then(channel => {
|
||||||
|
defaultChannel = channel;
|
||||||
|
cy.fixture("addresses");
|
||||||
|
})
|
||||||
|
.then(addressesFixture => {
|
||||||
|
shippingUtils.createShipping({
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
name,
|
||||||
|
address: addressesFixture.plAddress
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
warehouse = shippingUtils.getWarehouse();
|
||||||
|
});
|
||||||
|
|
||||||
|
productsUtils.createTypeAttributeAndCategoryForProduct(name).then(() => {
|
||||||
|
productType = productsUtils.getProductType();
|
||||||
|
attribute = productsUtils.getAttribute();
|
||||||
|
category = productsUtils.getCategory();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should update product to available for purchase", () => {
|
||||||
|
const productName = `${startsWith}${faker.random.number()}`;
|
||||||
|
productsUtils
|
||||||
|
.createProductInChannel({
|
||||||
|
name: productName,
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
warehouseId: warehouse.id,
|
||||||
|
productTypeId: productType.id,
|
||||||
|
attributeId: attribute.id,
|
||||||
|
categoryId: category.id,
|
||||||
|
isAvailableForPurchase: false
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const productUrl = productDetailsUrl(
|
||||||
|
productsUtils.getCreatedProduct().id
|
||||||
|
);
|
||||||
|
productSteps.updateProductIsAvailableForPurchase(productUrl, true);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
isProductAvailableForPurchase(
|
||||||
|
productsUtils.getCreatedProduct().id,
|
||||||
|
defaultChannel.slug,
|
||||||
|
productName
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then(isVisibleResp => {
|
||||||
|
expect(isVisibleResp).to.be.eq(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("should update product to not available for purchase", () => {
|
||||||
|
const productName = `${startsWith}${faker.random.number()}`;
|
||||||
|
productsUtils
|
||||||
|
.createProductInChannel({
|
||||||
|
name: productName,
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
warehouseId: warehouse.id,
|
||||||
|
productTypeId: productType.id,
|
||||||
|
attributeId: attribute.id,
|
||||||
|
categoryId: category.id
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const productUrl = productDetailsUrl(
|
||||||
|
productsUtils.getCreatedProduct().id
|
||||||
|
);
|
||||||
|
productSteps.updateProductIsAvailableForPurchase(productUrl, false);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
isProductAvailableForPurchase(
|
||||||
|
productsUtils.getCreatedProduct().id,
|
||||||
|
defaultChannel.slug,
|
||||||
|
productName
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then(isProductVisible => {
|
||||||
|
expect(isProductVisible).to.be.eq(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,95 @@
|
||||||
|
import faker from "faker";
|
||||||
|
|
||||||
|
import ProductSteps from "../../../steps/productSteps";
|
||||||
|
import { productDetailsUrl } from "../../../url/urlList";
|
||||||
|
import ChannelsUtils from "../../../utils/channelsUtils";
|
||||||
|
import ProductsUtils from "../../../utils/productsUtils";
|
||||||
|
import { isProductVisible } from "../../../utils/storeFront/storeFrontProductUtils";
|
||||||
|
|
||||||
|
// <reference types="cypress" />
|
||||||
|
describe("Published products", () => {
|
||||||
|
const channelsUtils = new ChannelsUtils();
|
||||||
|
const productsUtils = new ProductsUtils();
|
||||||
|
const productSteps = new ProductSteps();
|
||||||
|
|
||||||
|
const startsWith = "Cy-";
|
||||||
|
const name = `${startsWith}${faker.random.number()}`;
|
||||||
|
let productType;
|
||||||
|
let attribute;
|
||||||
|
let category;
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
productsUtils.deleteProperProducts(startsWith);
|
||||||
|
productsUtils.createTypeAttributeAndCategoryForProduct(name).then(() => {
|
||||||
|
productType = productsUtils.getProductType();
|
||||||
|
attribute = productsUtils.getAttribute();
|
||||||
|
category = productsUtils.getCategory();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
});
|
||||||
|
it("should update product to published", () => {
|
||||||
|
const productName = `${startsWith}${faker.random.number()}`;
|
||||||
|
let defaultChannel;
|
||||||
|
channelsUtils
|
||||||
|
.getDefaultChannel()
|
||||||
|
.then(channel => {
|
||||||
|
defaultChannel = channel;
|
||||||
|
productsUtils.createProductInChannel({
|
||||||
|
name: productName,
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
productTypeId: productType.id,
|
||||||
|
attributeId: attribute.id,
|
||||||
|
categoryId: category.id,
|
||||||
|
isPublished: false,
|
||||||
|
isAvailableForPurchase: false
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const product = productsUtils.getCreatedProduct();
|
||||||
|
const productUrl = productDetailsUrl(product.id);
|
||||||
|
productSteps.updateProductPublish(productUrl, true);
|
||||||
|
isProductVisible(product.id, defaultChannel.slug, productName);
|
||||||
|
})
|
||||||
|
.then(isVisible => {
|
||||||
|
expect(isVisible).to.be.eq(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("should update product to not published", () => {
|
||||||
|
const productName = `${startsWith}${faker.random.number()}`;
|
||||||
|
let defaultChannel;
|
||||||
|
let product;
|
||||||
|
|
||||||
|
channelsUtils
|
||||||
|
.getDefaultChannel()
|
||||||
|
.then(channel => {
|
||||||
|
defaultChannel = channel;
|
||||||
|
productsUtils.createProductInChannel({
|
||||||
|
name: productName,
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
productTypeId: productType.id,
|
||||||
|
attributeId: attribute.id,
|
||||||
|
categoryId: category.id
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
product = productsUtils.getCreatedProduct();
|
||||||
|
const productUrl = productDetailsUrl(product.id);
|
||||||
|
productSteps.updateProductPublish(productUrl, false);
|
||||||
|
isProductVisible(product.id, defaultChannel.slug, productName);
|
||||||
|
})
|
||||||
|
.then(isVisible => {
|
||||||
|
expect(isVisible).to.be.eq(false);
|
||||||
|
cy.loginInShop();
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
isProductVisible(product.id, defaultChannel.slug, productName);
|
||||||
|
})
|
||||||
|
.then(isVisible => {
|
||||||
|
expect(isVisible).to.be.eq(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,95 @@
|
||||||
|
import faker from "faker";
|
||||||
|
|
||||||
|
import ProductSteps from "../../../steps/productSteps";
|
||||||
|
import { productDetailsUrl } from "../../../url/urlList";
|
||||||
|
import ChannelsUtils from "../../../utils/channelsUtils";
|
||||||
|
import ProductsUtils from "../../../utils/productsUtils";
|
||||||
|
import { isProductVisibleInSearchResult } from "../../../utils/storeFront/storeFrontProductUtils";
|
||||||
|
|
||||||
|
// <reference types="cypress" />
|
||||||
|
describe("Products displayed in listings", () => {
|
||||||
|
const channelsUtils = new ChannelsUtils();
|
||||||
|
const productsUtils = new ProductsUtils();
|
||||||
|
const productSteps = new ProductSteps();
|
||||||
|
|
||||||
|
const startsWith = "Cy-";
|
||||||
|
const name = `${startsWith}${faker.random.number()}`;
|
||||||
|
let productType;
|
||||||
|
let attribute;
|
||||||
|
let category;
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
productsUtils.deleteProperProducts(startsWith);
|
||||||
|
productsUtils.createTypeAttributeAndCategoryForProduct(name).then(() => {
|
||||||
|
productType = productsUtils.getProductType();
|
||||||
|
attribute = productsUtils.getAttribute();
|
||||||
|
category = productsUtils.getCategory();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
});
|
||||||
|
it("should update product to visible in listings", () => {
|
||||||
|
const productName = `${startsWith}${faker.random.number()}`;
|
||||||
|
let defaultChannel;
|
||||||
|
channelsUtils
|
||||||
|
.getDefaultChannel()
|
||||||
|
.then(channel => {
|
||||||
|
defaultChannel = channel;
|
||||||
|
productsUtils.createProductInChannel({
|
||||||
|
name: productName,
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
productTypeId: productType.id,
|
||||||
|
attributeId: attribute.id,
|
||||||
|
categoryId: category.id,
|
||||||
|
visibleInListings: false,
|
||||||
|
isAvailableForPurchase: false
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const product = productsUtils.getCreatedProduct();
|
||||||
|
const productUrl = productDetailsUrl(product.id);
|
||||||
|
productSteps.updateProductVisibleInListings(productUrl);
|
||||||
|
isProductVisibleInSearchResult(productName, defaultChannel.slug);
|
||||||
|
})
|
||||||
|
.then(isProductVisible => {
|
||||||
|
expect(isProductVisible).to.be.eq(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("should update product to not visible in listings", () => {
|
||||||
|
const productName = `${startsWith}${faker.random.number()}`;
|
||||||
|
let defaultChannel;
|
||||||
|
channelsUtils
|
||||||
|
.getDefaultChannel()
|
||||||
|
.then(channel => {
|
||||||
|
defaultChannel = channel;
|
||||||
|
productsUtils.createProductInChannel({
|
||||||
|
name: productName,
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
productTypeId: productType.id,
|
||||||
|
attributeId: attribute.id,
|
||||||
|
categoryId: category.id,
|
||||||
|
visibleInListings: true
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const product = productsUtils.getCreatedProduct();
|
||||||
|
const productUrl = productDetailsUrl(product.id);
|
||||||
|
productSteps.updateProductVisibleInListings(productUrl);
|
||||||
|
isProductVisibleInSearchResult(productName, defaultChannel.slug).then(
|
||||||
|
isProductVisible => {
|
||||||
|
expect(isProductVisible).to.be.eq(false);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
cy.loginInShop();
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
isProductVisibleInSearchResult(productName, defaultChannel.slug);
|
||||||
|
})
|
||||||
|
.then(isProductVisible => {
|
||||||
|
expect(isProductVisible).to.be.eq(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,18 +1,25 @@
|
||||||
import { LEFT_MENU_SELECTORS } from "../elements/account/left-menu/left-menu-selectors";
|
|
||||||
import { PRODUCTS_SELECTORS } from "../elements/catalog/product-selectors";
|
|
||||||
|
|
||||||
// <reference types="cypress" />
|
// <reference types="cypress" />
|
||||||
|
import { LEFT_MENU_SELECTORS } from "../../elements/account/left-menu/left-menu-selectors";
|
||||||
|
import { PRODUCTS_SELECTORS } from "../../elements/catalog/product-selectors";
|
||||||
|
import { urlList } from "../../url/urlList";
|
||||||
|
|
||||||
describe("Products", () => {
|
describe("Products", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.clearSessionData().loginUserViaRequest();
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should add new visible product", () => {
|
it("should navigate to channels page", () => {
|
||||||
cy.visit("/")
|
cy.visit(urlList.homePage)
|
||||||
.get(LEFT_MENU_SELECTORS.catalog)
|
.get(LEFT_MENU_SELECTORS.catalog)
|
||||||
.click()
|
.click()
|
||||||
.get(PRODUCTS_SELECTORS.products)
|
.get(LEFT_MENU_SELECTORS.products)
|
||||||
.click()
|
.click()
|
||||||
|
.location("pathname")
|
||||||
|
.should("contain", "/products");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should add new visible product", () => {
|
||||||
|
cy.visit(urlList.products)
|
||||||
.get(PRODUCTS_SELECTORS.createProductBtn)
|
.get(PRODUCTS_SELECTORS.createProductBtn)
|
||||||
.click()
|
.click()
|
||||||
.get(PRODUCTS_SELECTORS.productNameInput)
|
.get(PRODUCTS_SELECTORS.productNameInput)
|
|
@ -1,11 +1,13 @@
|
||||||
// <reference types="cypress" />
|
// <reference types="cypress" />
|
||||||
|
import { urlList } from "../url/urlList";
|
||||||
|
|
||||||
describe("Warehouse settings", () => {
|
describe("Warehouse settings", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.clearSessionData();
|
cy.clearSessionData();
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("Warehouse section visible in the configuration", () => {
|
xit("Warehouse section visible in the configuration", () => {
|
||||||
cy.visit("/configuration/")
|
cy.visit(urlList.configuration)
|
||||||
.loginUser()
|
.loginUser()
|
||||||
.get("[data-test-id=warehouses][data-test=settingsSubsection]")
|
.get("[data-test-id=warehouses][data-test=settingsSubsection]")
|
||||||
.click();
|
.click();
|
||||||
|
@ -13,7 +15,7 @@ describe("Warehouse settings", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("Editing warehouse is available", () => {
|
xit("Editing warehouse is available", () => {
|
||||||
cy.visit(`/warehouses`)
|
cy.visit(urlList.warehouses)
|
||||||
.loginUser()
|
.loginUser()
|
||||||
.get("[data-test=editButton]")
|
.get("[data-test=editButton]")
|
||||||
.first()
|
.first()
|
||||||
|
|
|
@ -16,7 +16,13 @@
|
||||||
* @type {Cypress.PluginConfig}
|
* @type {Cypress.PluginConfig}
|
||||||
*/
|
*/
|
||||||
module.exports = (on, config) => {
|
module.exports = (on, config) => {
|
||||||
|
// make env variables visible for cypress
|
||||||
config.env.API_URI = process.env.API_URI;
|
config.env.API_URI = process.env.API_URI;
|
||||||
|
config.env.APP_MOUNT_URI = process.env.APP_MOUNT_URI;
|
||||||
|
|
||||||
|
on("before:browser:launch", (browser = {}, launchOptions) => {
|
||||||
|
launchOptions.args.push("--proxy-bypass-list=<-loopback>");
|
||||||
|
return launchOptions;
|
||||||
|
});
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
26
cypress/steps/channelsSteps.js
Normal file
26
cypress/steps/channelsSteps.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import { ADD_CHANNEL_FORM_SELECTORS } from "../elements/channels/add-channel-form-selectors";
|
||||||
|
import { CHANNELS_SELECTORS } from "../elements/channels/channels-selectors";
|
||||||
|
|
||||||
|
class ChannelsSteps {
|
||||||
|
createChannelByView(name, currency, otherCurrency, slug = name) {
|
||||||
|
cy.get(CHANNELS_SELECTORS.createChannelButton)
|
||||||
|
.click()
|
||||||
|
.get(ADD_CHANNEL_FORM_SELECTORS.channelName)
|
||||||
|
.type(name)
|
||||||
|
.get(ADD_CHANNEL_FORM_SELECTORS.slug)
|
||||||
|
.type(slug)
|
||||||
|
.get(ADD_CHANNEL_FORM_SELECTORS.currency)
|
||||||
|
.click();
|
||||||
|
if (!otherCurrency) {
|
||||||
|
cy.get(ADD_CHANNEL_FORM_SELECTORS.currency).type(currency);
|
||||||
|
cy.get(`[data-test-value=${currency}]`).click();
|
||||||
|
} else {
|
||||||
|
cy.get(ADD_CHANNEL_FORM_SELECTORS.currency)
|
||||||
|
.type(otherCurrency)
|
||||||
|
.get(ADD_CHANNEL_FORM_SELECTORS.currencyAutocompleteDropdown)
|
||||||
|
.click();
|
||||||
|
}
|
||||||
|
cy.get(ADD_CHANNEL_FORM_SELECTORS.saveButton).click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ChannelsSteps;
|
12
cypress/steps/homePageSteps.js
Normal file
12
cypress/steps/homePageSteps.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { HEADER_SELECTORS } from "../elements/header/header-selectors";
|
||||||
|
class HomePageSteps {
|
||||||
|
changeChannel(channelName) {
|
||||||
|
cy.get(HEADER_SELECTORS.channelSelect).click();
|
||||||
|
cy.addAliasToGraphRequest("Home");
|
||||||
|
cy.get(HEADER_SELECTORS.channelSelectList)
|
||||||
|
.contains(channelName)
|
||||||
|
.click();
|
||||||
|
cy.wait("@Home");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default HomePageSteps;
|
37
cypress/steps/productSteps.js
Normal file
37
cypress/steps/productSteps.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { PRODUCTS_SELECTORS } from "../elements/catalog/product-selectors";
|
||||||
|
|
||||||
|
class ProductSteps {
|
||||||
|
valueTrue = PRODUCTS_SELECTORS.radioButtonsValueTrue;
|
||||||
|
valueFalse = PRODUCTS_SELECTORS.radioButtonsValueFalse;
|
||||||
|
|
||||||
|
updateProductIsAvailableForPurchase(productUrl, isAvailableForPurchase) {
|
||||||
|
const isAvailableForPurchaseSelector = isAvailableForPurchase
|
||||||
|
? this.valueTrue
|
||||||
|
: this.valueFalse;
|
||||||
|
const availableForPurchaseSelector = `${PRODUCTS_SELECTORS.availableForPurchaseRadioButtons}${isAvailableForPurchaseSelector}`;
|
||||||
|
this.updateProductMenageInChannel(productUrl, availableForPurchaseSelector);
|
||||||
|
}
|
||||||
|
updateProductPublish(productUrl, isPublished) {
|
||||||
|
const isPublishedSelector = isPublished ? this.valueTrue : this.valueFalse;
|
||||||
|
const publishedSelector = `${PRODUCTS_SELECTORS.publishedRadioButtons}${isPublishedSelector}`;
|
||||||
|
this.updateProductMenageInChannel(productUrl, publishedSelector);
|
||||||
|
}
|
||||||
|
updateProductVisibleInListings(productUrl) {
|
||||||
|
this.updateProductMenageInChannel(
|
||||||
|
productUrl,
|
||||||
|
PRODUCTS_SELECTORS.visibleInListingsButton
|
||||||
|
);
|
||||||
|
}
|
||||||
|
updateProductMenageInChannel(productUrl, menageSelector) {
|
||||||
|
cy.visit(productUrl)
|
||||||
|
.get(PRODUCTS_SELECTORS.assignedChannels)
|
||||||
|
.click()
|
||||||
|
.get(menageSelector)
|
||||||
|
.click();
|
||||||
|
cy.addAliasToGraphRequest("ProductChannelListingUpdate");
|
||||||
|
cy.get(PRODUCTS_SELECTORS.saveBtn)
|
||||||
|
.click()
|
||||||
|
.wait("@ProductChannelListingUpdate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ProductSteps;
|
18
cypress/support/deleteElement/index.js
Normal file
18
cypress/support/deleteElement/index.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
Cypress.Commands.add(
|
||||||
|
"handleDeleteElement",
|
||||||
|
(element, deleteFunction, startsWith) => {
|
||||||
|
if (element.node.name.includes(startsWith)) {
|
||||||
|
deleteFunction(element.node.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Cypress.Commands.add(
|
||||||
|
"deleteProperElements",
|
||||||
|
(deleteFunction, getFunction, startsWith, name) => {
|
||||||
|
getFunction(100, startsWith).then(elements => {
|
||||||
|
elements.forEach(element => {
|
||||||
|
cy.handleDeleteElement(element, deleteFunction, startsWith);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
|
@ -1,19 +1,55 @@
|
||||||
import "./user";
|
import "./user";
|
||||||
|
import "./softAssertions";
|
||||||
|
import "./deleteElement/index.js";
|
||||||
|
|
||||||
|
import { urlList } from "../url/urlList";
|
||||||
|
|
||||||
Cypress.Commands.add("clearSessionData", () => {
|
Cypress.Commands.add("clearSessionData", () => {
|
||||||
// Because of known cypress bug, not all local storage data are cleared.
|
// Because of known cypress bug, not all local storage data are cleared.
|
||||||
// Here is workaround to ensure tests have no side effects.
|
// Here is workaround to ensure tests have no side effects.
|
||||||
// Suggested usage:
|
// Suggested usage:
|
||||||
|
|
||||||
// beforeEach(() => {
|
// beforeEach(() => {
|
||||||
// cy.clearSessionData();
|
// cy.clearSessionData();
|
||||||
// });
|
// });
|
||||||
|
|
||||||
cy.clearCookies();
|
cy.clearCookies();
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
cy.visit("/", {
|
cy.visit(urlList.homePage, {
|
||||||
onBeforeLoad: win => {
|
onBeforeLoad: win => {
|
||||||
win.sessionStorage.clear();
|
win.sessionStorage.clear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add("addAliasToGraphRequest", operationName => {
|
||||||
|
cy.intercept("POST", urlList.apiUri, req => {
|
||||||
|
req.statusCode = 200;
|
||||||
|
const requestBody = req.body;
|
||||||
|
if (Array.isArray(requestBody)) {
|
||||||
|
requestBody.forEach(element => {
|
||||||
|
if (element.operationName === operationName) {
|
||||||
|
req.alias = operationName;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (requestBody.operationName === operationName) {
|
||||||
|
req.alias = operationName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add("sendRequestWithQuery", (query, authorization = "auth") =>
|
||||||
|
cy.request({
|
||||||
|
body: {
|
||||||
|
method: "POST",
|
||||||
|
query,
|
||||||
|
url: urlList.apiUri
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
Authorization: `JWT ${window.sessionStorage.getItem(authorization)}`
|
||||||
|
},
|
||||||
|
method: "POST",
|
||||||
|
url: urlList.apiUri
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
89
cypress/support/softAssertions/index.js
Normal file
89
cypress/support/softAssertions/index.js
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
let isSoftAssertion = false;
|
||||||
|
let errors = [];
|
||||||
|
|
||||||
|
chai.softExpect = function(...args) {
|
||||||
|
isSoftAssertion = true;
|
||||||
|
return chai.expect(...args);
|
||||||
|
};
|
||||||
|
chai.softAssert = function(...args) {
|
||||||
|
isSoftAssertion = true;
|
||||||
|
return chai.assert(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
const origAssert = chai.Assertion.prototype.assert;
|
||||||
|
chai.Assertion.prototype.assert = function(...args) {
|
||||||
|
if (isSoftAssertion) {
|
||||||
|
try {
|
||||||
|
origAssert.call(this, ...args);
|
||||||
|
} catch (error) {
|
||||||
|
errors.push(error);
|
||||||
|
}
|
||||||
|
isSoftAssertion = false;
|
||||||
|
} else {
|
||||||
|
origAssert.call(this, ...args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// monkey-patch `Cypress.log` so that the last `cy.then()` isn't logged to command log
|
||||||
|
const origLog = Cypress.log;
|
||||||
|
Cypress.log = function(data) {
|
||||||
|
if (data && data.error && /soft assertions/i.test(data.error.message)) {
|
||||||
|
data.error.message = "\n\n\t" + data.error.message + "\n\n";
|
||||||
|
throw data.error;
|
||||||
|
}
|
||||||
|
return origLog.call(Cypress, ...arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
// monkey-patch `it` callback so we insert `cy.then()` as a last command
|
||||||
|
// to each test case where we'll assert if there are any soft assertion errors
|
||||||
|
function itCallback(func) {
|
||||||
|
func();
|
||||||
|
cy.then(() => {
|
||||||
|
if (errors.length) {
|
||||||
|
const _ = Cypress._;
|
||||||
|
let msg = "";
|
||||||
|
|
||||||
|
if (Cypress.browser.isHeaded) {
|
||||||
|
msg = "Failed soft assertions... check log above ↑";
|
||||||
|
} else {
|
||||||
|
_.each(errors, error => {
|
||||||
|
msg += "\n" + error;
|
||||||
|
});
|
||||||
|
|
||||||
|
msg = msg.replace(/^/gm, "\t");
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const origIt = window.it;
|
||||||
|
window.it = (title, func) => {
|
||||||
|
origIt(title, func && (() => itCallback(func)));
|
||||||
|
};
|
||||||
|
window.it.only = (title, func) => {
|
||||||
|
origIt.only(title, func && (() => itCallback(func)));
|
||||||
|
};
|
||||||
|
window.it.skip = (title, func) => {
|
||||||
|
origIt.skip(title, func);
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
errors = [];
|
||||||
|
});
|
||||||
|
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);
|
||||||
|
});
|
|
@ -1,4 +1,3 @@
|
||||||
/* eslint-disable sort-keys */
|
|
||||||
import { LOGIN_SELECTORS } from "../../elements/account/login-selectors";
|
import { LOGIN_SELECTORS } from "../../elements/account/login-selectors";
|
||||||
|
|
||||||
Cypress.Commands.add("loginUser", () =>
|
Cypress.Commands.add("loginUser", () =>
|
||||||
|
@ -11,38 +10,30 @@ Cypress.Commands.add("loginUser", () =>
|
||||||
.click()
|
.click()
|
||||||
);
|
);
|
||||||
|
|
||||||
Cypress.Commands.add("loginUserViaRequest", () => {
|
Cypress.Commands.add("loginInShop", () => {
|
||||||
const logInMutationQuery = `mutation TokenAuth($email: String!, $password: String!) {
|
cy.loginUserViaRequest("token");
|
||||||
tokenCreate(email: $email, password: $password) {
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add("loginUserViaRequest", (authorization = "auth") => {
|
||||||
|
const mutation = `mutation TokenAuth{
|
||||||
|
tokenCreate(email: "${Cypress.env("USER_NAME")}", password: "${Cypress.env(
|
||||||
|
"USER_PASSWORD"
|
||||||
|
)}") {
|
||||||
token
|
token
|
||||||
errors: accountErrors {
|
errors: accountErrors {
|
||||||
code
|
code
|
||||||
field
|
field
|
||||||
message
|
message
|
||||||
__typename
|
|
||||||
}
|
}
|
||||||
user {
|
user {
|
||||||
id
|
id
|
||||||
__typename
|
|
||||||
}
|
}
|
||||||
__typename
|
|
||||||
}
|
}
|
||||||
}`;
|
}`;
|
||||||
|
return cy.sendRequestWithQuery(mutation, authorization).then(resp => {
|
||||||
return cy
|
window.sessionStorage.setItem(
|
||||||
.request({
|
authorization,
|
||||||
method: "POST",
|
resp.body.data.tokenCreate.token
|
||||||
url: Cypress.env("API_URI"),
|
);
|
||||||
body: {
|
});
|
||||||
operationName: "TokenAuth",
|
|
||||||
variables: {
|
|
||||||
email: Cypress.env("USER_NAME"),
|
|
||||||
password: Cypress.env("USER_PASSWORD")
|
|
||||||
},
|
|
||||||
query: logInMutationQuery
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(resp => {
|
|
||||||
window.sessionStorage.setItem("auth", resp.body.data.tokenCreate.token);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
10
cypress/url/urlList.js
Normal file
10
cypress/url/urlList.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
export const urlList = {
|
||||||
|
apiUri: Cypress.env("API_URI"),
|
||||||
|
channels: "channels/",
|
||||||
|
configuration: "configuration/",
|
||||||
|
homePage: "/",
|
||||||
|
orders: "orders/",
|
||||||
|
products: "products/",
|
||||||
|
warehouses: "warehouses/"
|
||||||
|
};
|
||||||
|
export const productDetailsUrl = productId => `${urlList.products}${productId}`;
|
41
cypress/utils/channelsUtils.js
Normal file
41
cypress/utils/channelsUtils.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import Channels from "../apiRequests/Channels";
|
||||||
|
|
||||||
|
class ChannelsUtils {
|
||||||
|
channels = new Channels();
|
||||||
|
|
||||||
|
deleteChannels(nameStartsWith) {
|
||||||
|
this.channels.getChannels().then(resp => {
|
||||||
|
const channelsArray = new Set(resp.body.data.channels);
|
||||||
|
if (!channelsArray) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
channelsArray.forEach(element => {
|
||||||
|
if (element.name.startsWith(nameStartsWith)) {
|
||||||
|
const targetChannels = Array.from(channelsArray).filter(function(
|
||||||
|
channelElement
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
element.currencyCode === channelElement.currencyCode &&
|
||||||
|
element.id !== channelElement.id
|
||||||
|
);
|
||||||
|
});
|
||||||
|
if (targetChannels[0]) {
|
||||||
|
this.channels.deleteChannel(element.id, targetChannels[0].id);
|
||||||
|
channelsArray.delete(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getDefaultChannel() {
|
||||||
|
return this.channels.getChannels().then(resp => {
|
||||||
|
const channelsArray = resp.body.data.channels;
|
||||||
|
return (this.defaultChannel = channelsArray.find(function(
|
||||||
|
channelElement
|
||||||
|
) {
|
||||||
|
return channelElement.slug === "default-channel";
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ChannelsUtils;
|
30
cypress/utils/homePageUtils.js
Normal file
30
cypress/utils/homePageUtils.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import HomePage from "../apiRequests/HomePage";
|
||||||
|
class HomePageUtils {
|
||||||
|
homePage = new HomePage();
|
||||||
|
getOrdersReadyToFulfill(channelSlug) {
|
||||||
|
return this.homePage
|
||||||
|
.getOrdersWithStatus("READY_TO_FULFILL", channelSlug)
|
||||||
|
.then(resp => resp.body.data.orders.totalCount);
|
||||||
|
}
|
||||||
|
getOrdersReadyForCapture(channelSlug) {
|
||||||
|
return this.homePage
|
||||||
|
.getOrdersWithStatus("READY_TO_CAPTURE", channelSlug)
|
||||||
|
.then(resp => resp.body.data.orders.totalCount);
|
||||||
|
}
|
||||||
|
getProductsOutOfStock(channelSlug) {
|
||||||
|
return this.homePage
|
||||||
|
.getProductsOutOfStock(channelSlug)
|
||||||
|
.then(resp => resp.body.data.products.totalCount);
|
||||||
|
}
|
||||||
|
getSalesAmount(channelSlug) {
|
||||||
|
return this.homePage
|
||||||
|
.getSalesForChannel(channelSlug, "TODAY")
|
||||||
|
.then(resp => resp.body.data.ordersTotal.gross.amount);
|
||||||
|
}
|
||||||
|
getTodaysOrders(channelSlug) {
|
||||||
|
return this.homePage
|
||||||
|
.getOrdersForChannel(channelSlug, "TODAY")
|
||||||
|
.then(resp => resp.body.data.orders.totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default HomePageUtils;
|
60
cypress/utils/ordersUtils.js
Normal file
60
cypress/utils/ordersUtils.js
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import Checkout from "../apiRequests/Checkout";
|
||||||
|
import Order from "../apiRequests/Order";
|
||||||
|
|
||||||
|
class OrdersUtils {
|
||||||
|
checkoutRequest = new Checkout();
|
||||||
|
orderRequest = new Order();
|
||||||
|
|
||||||
|
checkout;
|
||||||
|
order;
|
||||||
|
|
||||||
|
createWaitingForCaptureOrder(
|
||||||
|
channelSlug,
|
||||||
|
email,
|
||||||
|
variantsList,
|
||||||
|
shippingMethodId
|
||||||
|
) {
|
||||||
|
return this.createCheckout(channelSlug, email, variantsList)
|
||||||
|
.then(() =>
|
||||||
|
this.checkoutRequest.addShippingMethod(
|
||||||
|
this.checkout.id,
|
||||||
|
shippingMethodId
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then(() => this.addPayment(this.checkout.id))
|
||||||
|
.then(() => this.checkoutRequest.completeCheckout(this.checkout.id));
|
||||||
|
}
|
||||||
|
createReadyToFulfillOrder(
|
||||||
|
customerId,
|
||||||
|
shippingMethodId,
|
||||||
|
channelId,
|
||||||
|
variantsList
|
||||||
|
) {
|
||||||
|
return this.createDraftOrder(customerId, shippingMethodId, channelId)
|
||||||
|
.then(() => {
|
||||||
|
variantsList.forEach(variantElement => {
|
||||||
|
this.orderRequest.addProductToOrder(this.order.id, variantElement.id);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => this.orderRequest.markOrderAsPaid(this.order.id))
|
||||||
|
.then(() => this.orderRequest.completeOrder(this.order.id));
|
||||||
|
}
|
||||||
|
createDraftOrder(customerId, shippingMethodId, channelId) {
|
||||||
|
return this.orderRequest
|
||||||
|
.createDraftOrder(customerId, shippingMethodId, channelId)
|
||||||
|
.then(resp => (this.order = resp.body.data.draftOrderCreate.order));
|
||||||
|
}
|
||||||
|
createCheckout(channelSlug, email, variantsList) {
|
||||||
|
return this.checkoutRequest
|
||||||
|
.createCheckout(channelSlug, email, 1, variantsList)
|
||||||
|
.then(resp => (this.checkout = resp.body.data.checkoutCreate.checkout));
|
||||||
|
}
|
||||||
|
addPayment(checkoutId) {
|
||||||
|
return this.checkoutRequest.addPayment(
|
||||||
|
checkoutId,
|
||||||
|
"mirumee.payments.dummy",
|
||||||
|
"not-charged"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default OrdersUtils;
|
152
cypress/utils/productsUtils.js
Normal file
152
cypress/utils/productsUtils.js
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
import Attribute from "../apiRequests/Attribute";
|
||||||
|
import Category from "../apiRequests/Category";
|
||||||
|
import Product from "../apiRequests/Product";
|
||||||
|
|
||||||
|
class ProductsUtils {
|
||||||
|
productRequest = new Product();
|
||||||
|
attributeRequest = new Attribute();
|
||||||
|
categoryRequest = new Category();
|
||||||
|
|
||||||
|
product;
|
||||||
|
variants;
|
||||||
|
productType;
|
||||||
|
attribute;
|
||||||
|
category;
|
||||||
|
|
||||||
|
createProductWithVariant(name, attributeId, productTypeId, categoryId) {
|
||||||
|
return this.createProduct(
|
||||||
|
attributeId,
|
||||||
|
name,
|
||||||
|
productTypeId,
|
||||||
|
categoryId
|
||||||
|
).then(() => this.createVariant(this.product.id, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
createProductInChannel({
|
||||||
|
name,
|
||||||
|
channelId,
|
||||||
|
warehouseId = null,
|
||||||
|
quantityInWarehouse = 10,
|
||||||
|
productTypeId,
|
||||||
|
attributeId,
|
||||||
|
categoryId,
|
||||||
|
price = 1,
|
||||||
|
isPublished = true,
|
||||||
|
isAvailableForPurchase = true,
|
||||||
|
visibleInListings = true
|
||||||
|
}) {
|
||||||
|
return this.createProduct(attributeId, name, productTypeId, categoryId)
|
||||||
|
.then(() =>
|
||||||
|
this.productRequest.updateChannelInProduct({
|
||||||
|
productId: this.product.id,
|
||||||
|
channelId,
|
||||||
|
isPublished,
|
||||||
|
isAvailableForPurchase,
|
||||||
|
visibleInListings
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
this.createVariant(
|
||||||
|
this.product.id,
|
||||||
|
name,
|
||||||
|
warehouseId,
|
||||||
|
quantityInWarehouse,
|
||||||
|
channelId,
|
||||||
|
price
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createTypeAttributeAndCategoryForProduct(name) {
|
||||||
|
return this.createAttribute(name)
|
||||||
|
.then(() => this.createTypeProduct(name, this.attribute.id))
|
||||||
|
.then(() => this.createCategory(name));
|
||||||
|
}
|
||||||
|
createAttribute(name) {
|
||||||
|
return this.attributeRequest
|
||||||
|
.createAttribute(name)
|
||||||
|
.then(
|
||||||
|
resp => (this.attribute = resp.body.data.attributeCreate.attribute)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
createTypeProduct(name, attributeId) {
|
||||||
|
return this.productRequest
|
||||||
|
.createTypeProduct(name, attributeId)
|
||||||
|
.then(
|
||||||
|
resp =>
|
||||||
|
(this.productType = resp.body.data.productTypeCreate.productType)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
createCategory(name) {
|
||||||
|
return this.categoryRequest
|
||||||
|
.createCategory(name)
|
||||||
|
.then(resp => (this.category = resp.body.data.categoryCreate.category));
|
||||||
|
}
|
||||||
|
createProduct(attributeId, name, productTypeId, categoryId) {
|
||||||
|
return this.productRequest
|
||||||
|
.createProduct(attributeId, name, productTypeId, categoryId)
|
||||||
|
.then(resp => (this.product = resp.body.data.productCreate.product));
|
||||||
|
}
|
||||||
|
createVariant(
|
||||||
|
productId,
|
||||||
|
name,
|
||||||
|
warehouseId,
|
||||||
|
quantityInWarehouse,
|
||||||
|
channelId,
|
||||||
|
price
|
||||||
|
) {
|
||||||
|
return this.productRequest
|
||||||
|
.createVariant(
|
||||||
|
productId,
|
||||||
|
name,
|
||||||
|
warehouseId,
|
||||||
|
quantityInWarehouse,
|
||||||
|
channelId,
|
||||||
|
price
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
resp =>
|
||||||
|
(this.variants =
|
||||||
|
resp.body.data.productVariantBulkCreate.productVariants)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
getCreatedProduct() {
|
||||||
|
return this.product;
|
||||||
|
}
|
||||||
|
getCreatedVariants() {
|
||||||
|
return this.variants;
|
||||||
|
}
|
||||||
|
getProductType() {
|
||||||
|
return this.productType;
|
||||||
|
}
|
||||||
|
getAttribute() {
|
||||||
|
return this.attribute;
|
||||||
|
}
|
||||||
|
getCategory() {
|
||||||
|
return this.category;
|
||||||
|
}
|
||||||
|
deleteProperProducts(startsWith) {
|
||||||
|
const product = new Product();
|
||||||
|
const attribute = new Attribute();
|
||||||
|
const category = new Category();
|
||||||
|
cy.deleteProperElements(
|
||||||
|
product.deleteProductType,
|
||||||
|
product.getProductTypes,
|
||||||
|
startsWith,
|
||||||
|
"productType"
|
||||||
|
);
|
||||||
|
cy.deleteProperElements(
|
||||||
|
attribute.deleteAttribute,
|
||||||
|
attribute.getAttributes,
|
||||||
|
startsWith,
|
||||||
|
"attributes"
|
||||||
|
);
|
||||||
|
cy.deleteProperElements(
|
||||||
|
category.deleteCategory,
|
||||||
|
category.getCategories,
|
||||||
|
startsWith,
|
||||||
|
"categories"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ProductsUtils;
|
77
cypress/utils/shippingUtils.js
Normal file
77
cypress/utils/shippingUtils.js
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
import ShippingMethod from "../apiRequests/ShippingMethod";
|
||||||
|
import Warehouse from "../apiRequests/Warehouse";
|
||||||
|
class ShippingUtils {
|
||||||
|
shippingMethodRequest = new ShippingMethod();
|
||||||
|
warehouseRequest = new Warehouse();
|
||||||
|
|
||||||
|
shippingMethod;
|
||||||
|
shippingZone;
|
||||||
|
warehouse;
|
||||||
|
|
||||||
|
createShipping({ channelId, name, address, price = 1 }) {
|
||||||
|
return this.createShippingZone(name, address.country)
|
||||||
|
.then(() => this.createWarehouse(name, this.shippingZone.id, address))
|
||||||
|
.then(() => this.createShippingRate(name, this.shippingZone.id))
|
||||||
|
.then(() =>
|
||||||
|
this.shippingMethodRequest.addChannelToShippingMethod(
|
||||||
|
this.shippingMethod.id,
|
||||||
|
channelId,
|
||||||
|
price
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
createShippingZone(name, country) {
|
||||||
|
return this.shippingMethodRequest
|
||||||
|
.createShippingZone(name, country)
|
||||||
|
.then(resp => {
|
||||||
|
this.shippingZone = resp.body.data.shippingZoneCreate.shippingZone;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
createWarehouse(name, shippingZoneId, address) {
|
||||||
|
return this.warehouseRequest
|
||||||
|
.createWarehouse(name, shippingZoneId, address)
|
||||||
|
.then(resp => {
|
||||||
|
this.warehouse = resp.body.data.createWarehouse.warehouse;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
createShippingRate(name, shippingZoneId) {
|
||||||
|
return this.shippingMethodRequest
|
||||||
|
.createShippingRate(name, shippingZoneId)
|
||||||
|
.then(
|
||||||
|
resp =>
|
||||||
|
(this.shippingMethod =
|
||||||
|
resp.body.data.shippingPriceCreate.shippingMethod)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getShippingMethod() {
|
||||||
|
return this.shippingMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
getShippingZone() {
|
||||||
|
return this.shippingZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
getWarehouse() {
|
||||||
|
return this.warehouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteShipping(startsWith) {
|
||||||
|
const shippingMethod = new ShippingMethod();
|
||||||
|
const warehouse = new Warehouse();
|
||||||
|
cy.deleteProperElements(
|
||||||
|
shippingMethod.deleteShippingZone,
|
||||||
|
shippingMethod.getShippingZones,
|
||||||
|
startsWith,
|
||||||
|
"shippingZONE"
|
||||||
|
);
|
||||||
|
cy.deleteProperElements(
|
||||||
|
warehouse.deleteWarehouse,
|
||||||
|
warehouse.getWarehouses,
|
||||||
|
startsWith,
|
||||||
|
"Warehouse"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ShippingUtils;
|
32
cypress/utils/storeFront/storeFrontProductUtils.js
Normal file
32
cypress/utils/storeFront/storeFrontProductUtils.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import ProductDetails from "../../apiRequests/storeFront/ProductDetails";
|
||||||
|
import Search from "../../apiRequests/storeFront/Search";
|
||||||
|
|
||||||
|
export const isProductVisible = (productId, channelSlug, name) => {
|
||||||
|
const productDetails = new ProductDetails();
|
||||||
|
return productDetails
|
||||||
|
.getProductDetails(productId, channelSlug)
|
||||||
|
.then(productDetailsResp => {
|
||||||
|
const product = productDetailsResp.body.data.product;
|
||||||
|
return product !== null && product.name === name;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isProductAvailableForPurchase = (productId, channelSlug) => {
|
||||||
|
const productDetails = new ProductDetails();
|
||||||
|
return productDetails
|
||||||
|
.getProductDetails(productId, channelSlug)
|
||||||
|
.then(
|
||||||
|
productDetailsResp =>
|
||||||
|
productDetailsResp.body.data.product.isAvailableForPurchase
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export const isProductVisibleInSearchResult = (productName, channelSlug) => {
|
||||||
|
const search = new Search();
|
||||||
|
return search
|
||||||
|
.searchInShop(productName, channelSlug)
|
||||||
|
.then(
|
||||||
|
resp =>
|
||||||
|
resp.body.data.products.totalCount !== 0 &&
|
||||||
|
resp.body.data.products.edges[0].node.name === productName
|
||||||
|
);
|
||||||
|
};
|
|
@ -5603,13 +5603,6 @@
|
||||||
"context": "label",
|
"context": "label",
|
||||||
"string": "Shipping rate name"
|
"string": "Shipping rate name"
|
||||||
},
|
},
|
||||||
"src_dot_shipping_dot_components_dot_ShippingRateZipCodeRangeRemoveDialog_dot_3640694505": {
|
|
||||||
"string": "Are you sure you want to remove this postal code rule?"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingRateZipCodeRangeRemoveDialog_dot_76039652": {
|
|
||||||
"context": "header",
|
|
||||||
"string": "Remove postal codes from Shipping Rate"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingWeightUnitForm_dot_2863708228": {
|
"src_dot_shipping_dot_components_dot_ShippingWeightUnitForm_dot_2863708228": {
|
||||||
"string": "This unit will be used as default shipping weight"
|
"string": "This unit will be used as default shipping weight"
|
||||||
},
|
},
|
||||||
|
@ -5693,6 +5686,54 @@
|
||||||
"context": "label",
|
"context": "label",
|
||||||
"string": "Shipping zone name"
|
"string": "Shipping zone name"
|
||||||
},
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodeRangeDialog_dot_3070993206": {
|
||||||
|
"context": "range input label",
|
||||||
|
"string": "Postal codes (end)"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodeRangeDialog_dot_3099331554": {
|
||||||
|
"context": "add postal code range, button",
|
||||||
|
"string": "Add"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodeRangeDialog_dot_3419096551": {
|
||||||
|
"context": "range input label",
|
||||||
|
"string": "Postal codes (start)"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodeRangeDialog_dot_3668595137": {
|
||||||
|
"string": "Please provide range of postal codes you want to add to the include/exclude list."
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodeRangeDialog_dot_3849853790": {
|
||||||
|
"context": "dialog header",
|
||||||
|
"string": "Add postal codes"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodes_dot_1301350004": {
|
||||||
|
"string": "This shipping rate has no postal codes assigned"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodes_dot_1680649143": {
|
||||||
|
"context": "action",
|
||||||
|
"string": "Include postal codes"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodes_dot_1779803917": {
|
||||||
|
"string": "Added postal codes will be excluded from using this delivery methods. If none are added all postal codes will be able to use that shipping rate"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodes_dot_1909179974": {
|
||||||
|
"context": "button",
|
||||||
|
"string": "Add postal code range"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodes_dot_2274108851": {
|
||||||
|
"context": "number of postal code ranges",
|
||||||
|
"string": "{number} postal code ranges"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodes_dot_2965119249": {
|
||||||
|
"string": "Only added postal codes will be able to use this shipping rate"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodes_dot_3782353530": {
|
||||||
|
"context": "postal codes, header",
|
||||||
|
"string": "Postal codes"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZonePostalCodes_dot_399764149": {
|
||||||
|
"context": "action",
|
||||||
|
"string": "Exclude postal codes"
|
||||||
|
},
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneRatesCreatePage_dot_1161979494": {
|
"src_dot_shipping_dot_components_dot_ShippingZoneRatesCreatePage_dot_1161979494": {
|
||||||
"context": "page title",
|
"context": "page title",
|
||||||
"string": "Price Rate Create"
|
"string": "Price Rate Create"
|
||||||
|
@ -5753,54 +5794,6 @@
|
||||||
"context": "input placeholder",
|
"context": "input placeholder",
|
||||||
"string": "Select Warehouse"
|
"string": "Select Warehouse"
|
||||||
},
|
},
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_3070993206": {
|
|
||||||
"context": "range input label",
|
|
||||||
"string": "Postal codes (end)"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_3099331554": {
|
|
||||||
"context": "add postal code range, button",
|
|
||||||
"string": "Add"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_3419096551": {
|
|
||||||
"context": "range input label",
|
|
||||||
"string": "Postal codes (start)"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_3668595137": {
|
|
||||||
"string": "Please provide range of postal codes you want to add to the include/exclude list."
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodeRangeDialog_dot_3849853790": {
|
|
||||||
"context": "dialog header",
|
|
||||||
"string": "Add postal codes"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_1301350004": {
|
|
||||||
"string": "This shipping rate has no postal codes assigned"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_1680649143": {
|
|
||||||
"context": "action",
|
|
||||||
"string": "Include postal codes"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_1779803917": {
|
|
||||||
"string": "Added postal codes will be excluded from using this delivery methods. If none are added all postal codes will be able to use that shipping rate"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_1909179974": {
|
|
||||||
"context": "button",
|
|
||||||
"string": "Add postal code range"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_2274108851": {
|
|
||||||
"context": "number of postal code ranges",
|
|
||||||
"string": "{number} postal code ranges"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_2965119249": {
|
|
||||||
"string": "Only added postal codes will be able to use this shipping rate"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_3782353530": {
|
|
||||||
"context": "postal codes, header",
|
|
||||||
"string": "Postal codes"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneZipCodes_dot_399764149": {
|
|
||||||
"context": "action",
|
|
||||||
"string": "Exclude postal codes"
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZonesListPage_dot_1325966144": {
|
"src_dot_shipping_dot_components_dot_ShippingZonesListPage_dot_1325966144": {
|
||||||
"context": "header",
|
"context": "header",
|
||||||
"string": "Shipping"
|
"string": "Shipping"
|
||||||
|
@ -5860,10 +5853,6 @@
|
||||||
"src_dot_shipping_dot_views_dot_PriceRatesUpdate_dot_3823295269": {
|
"src_dot_shipping_dot_views_dot_PriceRatesUpdate_dot_3823295269": {
|
||||||
"string": "Manage Channel Availability"
|
"string": "Manage Channel Availability"
|
||||||
},
|
},
|
||||||
"src_dot_shipping_dot_views_dot_PriceRatesUpdate_dot_4243341946": {
|
|
||||||
"context": "postal code range add error text",
|
|
||||||
"string": "Cannot add specified postal codes range."
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_views_dot_PriceRatesUpdate_dot_870815507": {
|
"src_dot_shipping_dot_views_dot_PriceRatesUpdate_dot_870815507": {
|
||||||
"context": "unassign products from shipping method, button",
|
"context": "unassign products from shipping method, button",
|
||||||
"string": "Unassign"
|
"string": "Unassign"
|
||||||
|
@ -5886,10 +5875,6 @@
|
||||||
"src_dot_shipping_dot_views_dot_WeightRatesUpdate_dot_3014453080": {
|
"src_dot_shipping_dot_views_dot_WeightRatesUpdate_dot_3014453080": {
|
||||||
"string": "Manage Channels Availability"
|
"string": "Manage Channels Availability"
|
||||||
},
|
},
|
||||||
"src_dot_shipping_dot_views_dot_WeightRatesUpdate_dot_4243341946": {
|
|
||||||
"context": "postal code range add error text",
|
|
||||||
"string": "Cannot add specified postal codes range."
|
|
||||||
},
|
|
||||||
"src_dot_shipping_dot_views_dot_WeightRatesUpdate_dot_870815507": {
|
"src_dot_shipping_dot_views_dot_WeightRatesUpdate_dot_870815507": {
|
||||||
"context": "unassign products from shipping method, button",
|
"context": "unassign products from shipping method, button",
|
||||||
"string": "Unassign"
|
"string": "Unassign"
|
||||||
|
@ -6767,6 +6752,10 @@
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "All events"
|
"string": "All events"
|
||||||
},
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2745028894": {
|
||||||
|
"context": "event",
|
||||||
|
"string": "Page deleted"
|
||||||
|
},
|
||||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2862596150": {
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2862596150": {
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "Invoice sent"
|
"string": "Invoice sent"
|
||||||
|
@ -6795,6 +6784,14 @@
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "Order cancelled"
|
"string": "Order cancelled"
|
||||||
},
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3618648517": {
|
||||||
|
"context": "event",
|
||||||
|
"string": "Page updated"
|
||||||
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3671033983": {
|
||||||
|
"context": "event",
|
||||||
|
"string": "Product deleted"
|
||||||
|
},
|
||||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3907151399": {
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3907151399": {
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "Order fulfilled"
|
"string": "Order fulfilled"
|
||||||
|
@ -6803,10 +6800,6 @@
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "Customer created"
|
"string": "Customer created"
|
||||||
},
|
},
|
||||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_40035964": {
|
|
||||||
"context": "event",
|
|
||||||
"string": "Changed quantity in checkout"
|
|
||||||
},
|
|
||||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_4186057882": {
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_4186057882": {
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "Invoice requested"
|
"string": "Invoice requested"
|
||||||
|
@ -6815,6 +6808,14 @@
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "Fulfillment created"
|
"string": "Fulfillment created"
|
||||||
},
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_679080833": {
|
||||||
|
"context": "event",
|
||||||
|
"string": "Page created"
|
||||||
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_787792649": {
|
||||||
|
"context": "event",
|
||||||
|
"string": "Customer updated"
|
||||||
|
},
|
||||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_1690209105": {
|
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_1690209105": {
|
||||||
"context": "webhook",
|
"context": "webhook",
|
||||||
"string": "Target URL"
|
"string": "Target URL"
|
||||||
|
|
4
lws.config.js
Normal file
4
lws.config.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = {
|
||||||
|
directory: "build/dashboard/",
|
||||||
|
port: 9000
|
||||||
|
};
|
29032
package-lock.json
generated
29032
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "saleor-dashboard",
|
"name": "saleor-dashboard",
|
||||||
"version": "3.0.0-a.0",
|
"version": "3.0.0-a.5",
|
||||||
"main": "src/index.tsx",
|
"main": "src/index.tsx",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
"@material-ui/icons": "^4.5.1",
|
"@material-ui/icons": "^4.5.1",
|
||||||
"@material-ui/styles": "^4.5.2",
|
"@material-ui/styles": "^4.5.2",
|
||||||
"@saleor/macaw-ui": "^0.1.1-9",
|
"@saleor/macaw-ui": "^0.1.1-9",
|
||||||
|
"@types/faker": "^5.1.6",
|
||||||
"@sentry/react": "^6.0.0",
|
"@sentry/react": "^6.0.0",
|
||||||
"apollo": "^2.21.2",
|
"apollo": "^2.21.2",
|
||||||
"apollo-cache-inmemory": "^1.6.5",
|
"apollo-cache-inmemory": "^1.6.5",
|
||||||
|
@ -42,7 +43,9 @@
|
||||||
"downshift": "^1.31.16",
|
"downshift": "^1.31.16",
|
||||||
"editorjs-inline-tool": "^0.4.0",
|
"editorjs-inline-tool": "^0.4.0",
|
||||||
"editorjs-undo": "^0.1.4",
|
"editorjs-undo": "^0.1.4",
|
||||||
|
"faker": "^5.1.0",
|
||||||
"fast-array-diff": "^0.2.0",
|
"fast-array-diff": "^0.2.0",
|
||||||
|
"fsevents": "^1.2.9",
|
||||||
"fuzzaldrin": "^2.1.0",
|
"fuzzaldrin": "^2.1.0",
|
||||||
"graphql": "^14.4.2",
|
"graphql": "^14.4.2",
|
||||||
"graphql-tag": "^2.11.0",
|
"graphql-tag": "^2.11.0",
|
||||||
|
@ -130,7 +133,7 @@
|
||||||
"codecov": "^3.7.1",
|
"codecov": "^3.7.1",
|
||||||
"core-js": "^3.7.0",
|
"core-js": "^3.7.0",
|
||||||
"cross-env": "^6.0.3",
|
"cross-env": "^6.0.3",
|
||||||
"cypress": "^4.9.0",
|
"cypress": "^6.4.0",
|
||||||
"enzyme": "^3.11.0",
|
"enzyme": "^3.11.0",
|
||||||
"enzyme-adapter-react-16": "^1.15.5",
|
"enzyme-adapter-react-16": "^1.15.5",
|
||||||
"enzyme-to-json": "^3.6.1",
|
"enzyme-to-json": "^3.6.1",
|
||||||
|
|
109
schema.graphql
109
schema.graphql
|
@ -671,7 +671,7 @@ type Category implements Node & ObjectWithMetadata {
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
description: JSONString!
|
description: JSONString
|
||||||
slug: String!
|
slug: String!
|
||||||
parent: Category
|
parent: Category
|
||||||
level: Int!
|
level: Int!
|
||||||
|
@ -746,7 +746,7 @@ type CategoryTranslatableContent implements Node {
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
description: JSONString!
|
description: JSONString
|
||||||
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
||||||
translation(languageCode: LanguageCodeEnum!): CategoryTranslation
|
translation(languageCode: LanguageCodeEnum!): CategoryTranslation
|
||||||
category: Category
|
category: Category
|
||||||
|
@ -763,7 +763,7 @@ type CategoryTranslation implements Node {
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
description: JSONString!
|
description: JSONString
|
||||||
language: LanguageDisplay!
|
language: LanguageDisplay!
|
||||||
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
||||||
}
|
}
|
||||||
|
@ -1050,7 +1050,7 @@ type Collection implements Node & ObjectWithMetadata {
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
description: JSONString!
|
description: JSONString
|
||||||
slug: String!
|
slug: String!
|
||||||
privateMetadata: [MetadataItem]!
|
privateMetadata: [MetadataItem]!
|
||||||
metadata: [MetadataItem]!
|
metadata: [MetadataItem]!
|
||||||
|
@ -1205,7 +1205,7 @@ type CollectionTranslatableContent implements Node {
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
description: JSONString!
|
description: JSONString
|
||||||
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
||||||
translation(languageCode: LanguageCodeEnum!): CollectionTranslation
|
translation(languageCode: LanguageCodeEnum!): CollectionTranslation
|
||||||
collection: Collection
|
collection: Collection
|
||||||
|
@ -1222,7 +1222,7 @@ type CollectionTranslation implements Node {
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
description: JSONString!
|
description: JSONString
|
||||||
language: LanguageDisplay!
|
language: LanguageDisplay!
|
||||||
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
||||||
}
|
}
|
||||||
|
@ -2055,10 +2055,6 @@ type GatewayConfigLine {
|
||||||
|
|
||||||
scalar GenericScalar
|
scalar GenericScalar
|
||||||
|
|
||||||
type Geolocalization {
|
|
||||||
country: CountryDisplay
|
|
||||||
}
|
|
||||||
|
|
||||||
type GiftCard implements Node {
|
type GiftCard implements Node {
|
||||||
code: String
|
code: String
|
||||||
user: User
|
user: User
|
||||||
|
@ -2590,8 +2586,6 @@ type Mutation {
|
||||||
shopAddressUpdate(input: AddressInput): ShopAddressUpdate
|
shopAddressUpdate(input: AddressInput): ShopAddressUpdate
|
||||||
orderSettingsUpdate(input: OrderSettingsUpdateInput!): OrderSettingsUpdate
|
orderSettingsUpdate(input: OrderSettingsUpdateInput!): OrderSettingsUpdate
|
||||||
shippingMethodChannelListingUpdate(id: ID!, input: ShippingMethodChannelListingInput!): ShippingMethodChannelListingUpdate
|
shippingMethodChannelListingUpdate(id: ID!, input: ShippingMethodChannelListingInput!): ShippingMethodChannelListingUpdate
|
||||||
shippingMethodZipCodeRulesCreate(input: ShippingZipCodeRulesCreateInput!, shippingMethodId: ID!): ShippingZipCodeRulesCreate
|
|
||||||
shippingMethodZipCodeRulesDelete(id: ID!): ShippingZipCodeRulesDelete
|
|
||||||
shippingPriceCreate(input: ShippingPriceInput!): ShippingPriceCreate
|
shippingPriceCreate(input: ShippingPriceInput!): ShippingPriceCreate
|
||||||
shippingPriceDelete(id: ID!): ShippingPriceDelete
|
shippingPriceDelete(id: ID!): ShippingPriceDelete
|
||||||
shippingPriceBulkDelete(ids: [ID]!): ShippingPriceBulkDelete
|
shippingPriceBulkDelete(ids: [ID]!): ShippingPriceBulkDelete
|
||||||
|
@ -3311,7 +3305,7 @@ type Page implements Node & ObjectWithMetadata {
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
id: ID!
|
id: ID!
|
||||||
title: String!
|
title: String!
|
||||||
content: JSONString!
|
content: JSONString
|
||||||
publicationDate: Date
|
publicationDate: Date
|
||||||
isPublished: Boolean!
|
isPublished: Boolean!
|
||||||
slug: String!
|
slug: String!
|
||||||
|
@ -3319,7 +3313,7 @@ type Page implements Node & ObjectWithMetadata {
|
||||||
created: DateTime!
|
created: DateTime!
|
||||||
privateMetadata: [MetadataItem]!
|
privateMetadata: [MetadataItem]!
|
||||||
metadata: [MetadataItem]!
|
metadata: [MetadataItem]!
|
||||||
contentJson: String! @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.")
|
contentJson: JSONString! @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.")
|
||||||
translation(languageCode: LanguageCodeEnum!): PageTranslation
|
translation(languageCode: LanguageCodeEnum!): PageTranslation
|
||||||
attributes: [SelectedAttribute!]!
|
attributes: [SelectedAttribute!]!
|
||||||
}
|
}
|
||||||
|
@ -3445,8 +3439,8 @@ type PageTranslatableContent implements Node {
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
id: ID!
|
id: ID!
|
||||||
title: String!
|
title: String!
|
||||||
content: JSONString!
|
content: JSONString
|
||||||
contentJson: String @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.")
|
contentJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.")
|
||||||
translation(languageCode: LanguageCodeEnum!): PageTranslation
|
translation(languageCode: LanguageCodeEnum!): PageTranslation
|
||||||
page: Page
|
page: Page
|
||||||
}
|
}
|
||||||
|
@ -3462,9 +3456,9 @@ type PageTranslation implements Node {
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
id: ID!
|
id: ID!
|
||||||
title: String!
|
title: String!
|
||||||
content: JSONString!
|
content: JSONString
|
||||||
language: LanguageDisplay!
|
language: LanguageDisplay!
|
||||||
contentJson: String @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.")
|
contentJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.")
|
||||||
}
|
}
|
||||||
|
|
||||||
input PageTranslationInput {
|
input PageTranslationInput {
|
||||||
|
@ -3657,7 +3651,6 @@ input PaymentInput {
|
||||||
gateway: String!
|
gateway: String!
|
||||||
token: String
|
token: String
|
||||||
amount: PositiveDecimal
|
amount: PositiveDecimal
|
||||||
billingAddress: AddressInput
|
|
||||||
returnUrl: String
|
returnUrl: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3829,6 +3822,11 @@ input PluginUpdateInput {
|
||||||
|
|
||||||
scalar PositiveDecimal
|
scalar PositiveDecimal
|
||||||
|
|
||||||
|
enum PostalCodeRuleInclusionTypeEnum {
|
||||||
|
INCLUDE
|
||||||
|
EXCLUDE
|
||||||
|
}
|
||||||
|
|
||||||
input PriceRangeInput {
|
input PriceRangeInput {
|
||||||
gte: Float
|
gte: Float
|
||||||
lte: Float
|
lte: Float
|
||||||
|
@ -3839,7 +3837,7 @@ type Product implements Node & ObjectWithMetadata {
|
||||||
seoTitle: String
|
seoTitle: String
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
name: String!
|
name: String!
|
||||||
description: JSONString!
|
description: JSONString
|
||||||
productType: ProductType!
|
productType: ProductType!
|
||||||
slug: String!
|
slug: String!
|
||||||
category: Category
|
category: Category
|
||||||
|
@ -3853,8 +3851,8 @@ type Product implements Node & ObjectWithMetadata {
|
||||||
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
||||||
url: String! @deprecated(reason: "This field will be removed after 2020-07-31.")
|
url: String! @deprecated(reason: "This field will be removed after 2020-07-31.")
|
||||||
thumbnail(size: Int): Image
|
thumbnail(size: Int): Image
|
||||||
pricing: ProductPricingInfo
|
pricing(address: AddressInput): ProductPricingInfo
|
||||||
isAvailable: Boolean
|
isAvailable(address: AddressInput): Boolean
|
||||||
taxType: TaxType
|
taxType: TaxType
|
||||||
attributes: [SelectedAttribute!]!
|
attributes: [SelectedAttribute!]!
|
||||||
channelListings: [ProductChannelListing!]
|
channelListings: [ProductChannelListing!]
|
||||||
|
@ -3906,7 +3904,7 @@ type ProductChannelListing implements Node {
|
||||||
purchaseCost: MoneyRange
|
purchaseCost: MoneyRange
|
||||||
margin: Margin
|
margin: Margin
|
||||||
isAvailableForPurchase: Boolean
|
isAvailableForPurchase: Boolean
|
||||||
pricing: ProductPricingInfo
|
pricing(address: AddressInput): ProductPricingInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
input ProductChannelListingAddInput {
|
input ProductChannelListingAddInput {
|
||||||
|
@ -4109,6 +4107,7 @@ input ProductOrder {
|
||||||
|
|
||||||
enum ProductOrderField {
|
enum ProductOrderField {
|
||||||
NAME
|
NAME
|
||||||
|
RANK
|
||||||
PRICE
|
PRICE
|
||||||
MINIMAL_PRICE
|
MINIMAL_PRICE
|
||||||
DATE
|
DATE
|
||||||
|
@ -4144,7 +4143,7 @@ type ProductTranslatableContent implements Node {
|
||||||
seoTitle: String
|
seoTitle: String
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
name: String!
|
name: String!
|
||||||
description: JSONString!
|
description: JSONString
|
||||||
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
||||||
translation(languageCode: LanguageCodeEnum!): ProductTranslation
|
translation(languageCode: LanguageCodeEnum!): ProductTranslation
|
||||||
product: Product
|
product: Product
|
||||||
|
@ -4161,7 +4160,7 @@ type ProductTranslation implements Node {
|
||||||
seoTitle: String
|
seoTitle: String
|
||||||
seoDescription: String
|
seoDescription: String
|
||||||
name: String!
|
name: String!
|
||||||
description: JSONString!
|
description: JSONString
|
||||||
language: LanguageDisplay!
|
language: LanguageDisplay!
|
||||||
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.")
|
||||||
}
|
}
|
||||||
|
@ -4177,7 +4176,6 @@ type ProductType implements Node & ObjectWithMetadata {
|
||||||
privateMetadata: [MetadataItem]!
|
privateMetadata: [MetadataItem]!
|
||||||
metadata: [MetadataItem]!
|
metadata: [MetadataItem]!
|
||||||
products(channel: String, before: String, after: String, first: Int, last: Int): ProductCountableConnection @deprecated(reason: "Use the top-level `products` query with the `productTypes` filter.")
|
products(channel: String, before: String, after: String, first: Int, last: Int): ProductCountableConnection @deprecated(reason: "Use the top-level `products` query with the `productTypes` filter.")
|
||||||
taxRate: TaxRateType
|
|
||||||
taxType: TaxType
|
taxType: TaxType
|
||||||
variantAttributes(variantSelection: VariantAttributeScope): [Attribute]
|
variantAttributes(variantSelection: VariantAttributeScope): [Attribute]
|
||||||
productAttributes: [Attribute]
|
productAttributes: [Attribute]
|
||||||
|
@ -4281,7 +4279,7 @@ type ProductVariant implements Node & ObjectWithMetadata {
|
||||||
privateMetadata: [MetadataItem]!
|
privateMetadata: [MetadataItem]!
|
||||||
metadata: [MetadataItem]!
|
metadata: [MetadataItem]!
|
||||||
channelListings: [ProductVariantChannelListing!]
|
channelListings: [ProductVariantChannelListing!]
|
||||||
pricing: VariantPricingInfo
|
pricing(address: AddressInput): VariantPricingInfo
|
||||||
attributes(variantSelection: VariantAttributeScope): [SelectedAttribute!]!
|
attributes(variantSelection: VariantAttributeScope): [SelectedAttribute!]!
|
||||||
costPrice: Money
|
costPrice: Money
|
||||||
margin: Int
|
margin: Int
|
||||||
|
@ -4290,8 +4288,8 @@ type ProductVariant implements Node & ObjectWithMetadata {
|
||||||
images: [ProductImage]
|
images: [ProductImage]
|
||||||
translation(languageCode: LanguageCodeEnum!): ProductVariantTranslation
|
translation(languageCode: LanguageCodeEnum!): ProductVariantTranslation
|
||||||
digitalContent: DigitalContent
|
digitalContent: DigitalContent
|
||||||
stocks(countryCode: CountryCode): [Stock]
|
stocks(address: AddressInput, countryCode: CountryCode): [Stock]
|
||||||
quantityAvailable(countryCode: CountryCode): Int!
|
quantityAvailable(address: AddressInput, countryCode: CountryCode): Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductVariantBulkCreate {
|
type ProductVariantBulkCreate {
|
||||||
|
@ -4751,7 +4749,7 @@ type ShippingMethod implements Node & ObjectWithMetadata {
|
||||||
price: Money
|
price: Money
|
||||||
maximumOrderPrice: Money
|
maximumOrderPrice: Money
|
||||||
minimumOrderPrice: Money
|
minimumOrderPrice: Money
|
||||||
zipCodeRules: [ShippingMethodZipCodeRule]
|
postalCodeRules: [ShippingMethodPostalCodeRule]
|
||||||
excludedProducts(before: String, after: String, first: Int, last: Int): ProductCountableConnection
|
excludedProducts(before: String, after: String, first: Int, last: Int): ProductCountableConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4781,6 +4779,13 @@ type ShippingMethodChannelListingUpdate {
|
||||||
shippingErrors: [ShippingError!]!
|
shippingErrors: [ShippingError!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShippingMethodPostalCodeRule implements Node {
|
||||||
|
start: String
|
||||||
|
end: String
|
||||||
|
inclusionType: PostalCodeRuleInclusionTypeEnum
|
||||||
|
id: ID!
|
||||||
|
}
|
||||||
|
|
||||||
type ShippingMethodTranslatableContent implements Node {
|
type ShippingMethodTranslatableContent implements Node {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
|
@ -4799,10 +4804,9 @@ enum ShippingMethodTypeEnum {
|
||||||
WEIGHT
|
WEIGHT
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShippingMethodZipCodeRule implements Node {
|
input ShippingPostalCodeRulesCreateInputRange {
|
||||||
start: String
|
start: String!
|
||||||
end: String
|
end: String
|
||||||
id: ID!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShippingPriceBulkDelete {
|
type ShippingPriceBulkDelete {
|
||||||
|
@ -4843,6 +4847,9 @@ input ShippingPriceInput {
|
||||||
minimumDeliveryDays: Int
|
minimumDeliveryDays: Int
|
||||||
type: ShippingMethodTypeEnum
|
type: ShippingMethodTypeEnum
|
||||||
shippingZone: ID
|
shippingZone: ID
|
||||||
|
addPostalCodeRules: [ShippingPostalCodeRulesCreateInputRange!]
|
||||||
|
deletePostalCodeRules: [ID!]
|
||||||
|
inclusionType: PostalCodeRuleInclusionTypeEnum
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShippingPriceRemoveProductFromExclude {
|
type ShippingPriceRemoveProductFromExclude {
|
||||||
|
@ -4864,29 +4871,6 @@ type ShippingPriceUpdate {
|
||||||
shippingErrors: [ShippingError!]!
|
shippingErrors: [ShippingError!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShippingZipCodeRulesCreate {
|
|
||||||
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
|
||||||
zipCodeRules: [ShippingMethodZipCodeRule]
|
|
||||||
shippingMethod: ShippingMethod
|
|
||||||
shippingErrors: [ShippingError!]!
|
|
||||||
}
|
|
||||||
|
|
||||||
input ShippingZipCodeRulesCreateInput {
|
|
||||||
zipCodeRules: [ShippingZipCodeRulesCreateInputRange]!
|
|
||||||
}
|
|
||||||
|
|
||||||
input ShippingZipCodeRulesCreateInputRange {
|
|
||||||
start: String!
|
|
||||||
end: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShippingZipCodeRulesDelete {
|
|
||||||
errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.")
|
|
||||||
shippingMethod: ShippingMethod
|
|
||||||
shippingErrors: [ShippingError!]!
|
|
||||||
shippingMethodZipCodeRule: ShippingMethodZipCodeRule
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShippingZone implements Node & ObjectWithMetadata {
|
type ShippingZone implements Node & ObjectWithMetadata {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
|
@ -4956,7 +4940,6 @@ type Shop {
|
||||||
availablePaymentGateways(currency: String): [PaymentGateway!]!
|
availablePaymentGateways(currency: String): [PaymentGateway!]!
|
||||||
availableExternalAuthentications: [ExternalAuthentication!]!
|
availableExternalAuthentications: [ExternalAuthentication!]!
|
||||||
availableShippingMethods(channel: String!, address: AddressInput): [ShippingMethod]
|
availableShippingMethods(channel: String!, address: AddressInput): [ShippingMethod]
|
||||||
geolocalization: Geolocalization
|
|
||||||
countries(languageCode: LanguageCodeEnum): [CountryDisplay!]!
|
countries(languageCode: LanguageCodeEnum): [CountryDisplay!]!
|
||||||
defaultCountry: CountryDisplay
|
defaultCountry: CountryDisplay
|
||||||
defaultMailSenderName: String
|
defaultMailSenderName: String
|
||||||
|
@ -5833,12 +5816,16 @@ enum WebhookEventTypeEnum {
|
||||||
INVOICE_DELETED
|
INVOICE_DELETED
|
||||||
INVOICE_SENT
|
INVOICE_SENT
|
||||||
CUSTOMER_CREATED
|
CUSTOMER_CREATED
|
||||||
|
CUSTOMER_UPDATED
|
||||||
PRODUCT_CREATED
|
PRODUCT_CREATED
|
||||||
PRODUCT_UPDATED
|
PRODUCT_UPDATED
|
||||||
CHECKOUT_QUANTITY_CHANGED
|
PRODUCT_DELETED
|
||||||
CHECKOUT_CREATED
|
CHECKOUT_CREATED
|
||||||
CHECKOUT_UPDATED
|
CHECKOUT_UPDATED
|
||||||
FULFILLMENT_CREATED
|
FULFILLMENT_CREATED
|
||||||
|
PAGE_CREATED
|
||||||
|
PAGE_UPDATED
|
||||||
|
PAGE_DELETED
|
||||||
}
|
}
|
||||||
|
|
||||||
enum WebhookSampleEventTypeEnum {
|
enum WebhookSampleEventTypeEnum {
|
||||||
|
@ -5852,12 +5839,16 @@ enum WebhookSampleEventTypeEnum {
|
||||||
INVOICE_DELETED
|
INVOICE_DELETED
|
||||||
INVOICE_SENT
|
INVOICE_SENT
|
||||||
CUSTOMER_CREATED
|
CUSTOMER_CREATED
|
||||||
|
CUSTOMER_UPDATED
|
||||||
PRODUCT_CREATED
|
PRODUCT_CREATED
|
||||||
PRODUCT_UPDATED
|
PRODUCT_UPDATED
|
||||||
CHECKOUT_QUANTITY_CHANGED
|
PRODUCT_DELETED
|
||||||
CHECKOUT_CREATED
|
CHECKOUT_CREATED
|
||||||
CHECKOUT_UPDATED
|
CHECKOUT_UPDATED
|
||||||
FULFILLMENT_CREATED
|
FULFILLMENT_CREATED
|
||||||
|
PAGE_CREATED
|
||||||
|
PAGE_UPDATED
|
||||||
|
PAGE_DELETED
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebhookUpdate {
|
type WebhookUpdate {
|
||||||
|
|
|
@ -86,7 +86,7 @@ const LoginView: React.FC<LoginViewProps> = ({ params }) => {
|
||||||
externalAuthentications={
|
externalAuthentications={
|
||||||
externalAuthentications?.shop?.availableExternalAuthentications
|
externalAuthentications?.shop?.availableExternalAuthentications
|
||||||
}
|
}
|
||||||
loading={externalAuthenticationsLoading}
|
loading={externalAuthenticationsLoading || tokenAuthLoading}
|
||||||
onExternalAuthentication={handleRequestExternalAuthentication}
|
onExternalAuthentication={handleRequestExternalAuthentication}
|
||||||
onPasswordRecovery={() => navigate(passwordResetUrl)}
|
onPasswordRecovery={() => navigate(passwordResetUrl)}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
|
|
@ -39,7 +39,7 @@ export interface CategoryCreate_categoryCreate_category {
|
||||||
backgroundImage: CategoryCreate_categoryCreate_category_backgroundImage | null;
|
backgroundImage: CategoryCreate_categoryCreate_category_backgroundImage | null;
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
parent: CategoryCreate_categoryCreate_category_parent | null;
|
parent: CategoryCreate_categoryCreate_category_parent | null;
|
||||||
|
|
|
@ -165,7 +165,7 @@ export interface CategoryDetails_category {
|
||||||
backgroundImage: CategoryDetails_category_backgroundImage | null;
|
backgroundImage: CategoryDetails_category_backgroundImage | null;
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
parent: CategoryDetails_category_parent | null;
|
parent: CategoryDetails_category_parent | null;
|
||||||
|
|
|
@ -39,7 +39,7 @@ export interface CategoryUpdate_categoryUpdate_category {
|
||||||
backgroundImage: CategoryUpdate_categoryUpdate_category_backgroundImage | null;
|
backgroundImage: CategoryUpdate_categoryUpdate_category_backgroundImage | null;
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
parent: CategoryUpdate_categoryUpdate_category_parent | null;
|
parent: CategoryUpdate_categoryUpdate_category_parent | null;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
|
import { getParsedDataForJsonStringField } from "@saleor/translations/utils";
|
||||||
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
|
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
|
||||||
import {
|
import {
|
||||||
useMetadataUpdate,
|
useMetadataUpdate,
|
||||||
|
@ -48,7 +49,7 @@ export const CategoryCreateView: React.FC<CategoryCreateViewProps> = ({
|
||||||
const result = await createCategory({
|
const result = await createCategory({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
description: JSON.stringify(formData.description),
|
description: getParsedDataForJsonStringField(formData.description),
|
||||||
name: formData.name,
|
name: formData.name,
|
||||||
seo: {
|
seo: {
|
||||||
description: formData.seoDescription,
|
description: formData.seoDescription,
|
||||||
|
|
|
@ -13,6 +13,7 @@ import usePaginator, {
|
||||||
createPaginationState
|
createPaginationState
|
||||||
} from "@saleor/hooks/usePaginator";
|
} from "@saleor/hooks/usePaginator";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
|
import { getParsedDataForJsonStringField } from "@saleor/translations/utils";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
|
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
|
||||||
import { mapNodeToChoice } from "@saleor/utils/maps";
|
import { mapNodeToChoice } from "@saleor/utils/maps";
|
||||||
|
@ -188,7 +189,7 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
|
||||||
id,
|
id,
|
||||||
input: {
|
input: {
|
||||||
backgroundImageAlt: formData.backgroundImageAlt,
|
backgroundImageAlt: formData.backgroundImageAlt,
|
||||||
description: JSON.stringify(formData.description),
|
description: getParsedDataForJsonStringField(formData.description),
|
||||||
name: formData.name,
|
name: formData.name,
|
||||||
seo: {
|
seo: {
|
||||||
description: formData.seoDescription,
|
description: formData.seoDescription,
|
||||||
|
|
|
@ -10,8 +10,8 @@ import ChannelDeleteDialog, {
|
||||||
|
|
||||||
const props: ChannelDeleteDialogProps = {
|
const props: ChannelDeleteDialogProps = {
|
||||||
channelsChoices: mapNodeToChoice(channelsList),
|
channelsChoices: mapNodeToChoice(channelsList),
|
||||||
hasOrders: true,
|
|
||||||
confirmButtonState: "default",
|
confirmButtonState: "default",
|
||||||
|
hasOrders: true,
|
||||||
onBack: () => undefined,
|
onBack: () => undefined,
|
||||||
onClose: () => undefined,
|
onClose: () => undefined,
|
||||||
onConfirm: () => undefined,
|
onConfirm: () => undefined,
|
||||||
|
|
|
@ -13,16 +13,20 @@ import { defineMessages, useIntl } from "react-intl";
|
||||||
import { useStyles } from "../styles";
|
import { useStyles } from "../styles";
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
needToBeMoved: {
|
deleteChannel: {
|
||||||
defaultMessage:
|
defaultMessage: "Delete Channel",
|
||||||
"All order information from this channel need to be moved to a different channel. Please select channel orders need to be moved to:.",
|
description: "dialog header"
|
||||||
description: "delete channel"
|
|
||||||
},
|
},
|
||||||
deletingAllProductData: {
|
deletingAllProductData: {
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
"Deleting channel will delete all product data regarding this channel. Are you sure you want to delete this channel?",
|
"Deleting channel will delete all product data regarding this channel. Are you sure you want to delete this channel?",
|
||||||
description: "delete channel"
|
description: "delete channel"
|
||||||
},
|
},
|
||||||
|
needToBeMoved: {
|
||||||
|
defaultMessage:
|
||||||
|
"All order information from this channel need to be moved to a different channel. Please select channel orders need to be moved to:.",
|
||||||
|
description: "delete channel"
|
||||||
|
},
|
||||||
noAvailableChannel: {
|
noAvailableChannel: {
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
"There is no available channel to move order information to. Please create a channel with same currency so that information can be moved to it.",
|
"There is no available channel to move order information to. Please create a channel with same currency so that information can be moved to it.",
|
||||||
|
@ -31,10 +35,6 @@ const messages = defineMessages({
|
||||||
selectChannel: {
|
selectChannel: {
|
||||||
defaultMessage: "Select Channel",
|
defaultMessage: "Select Channel",
|
||||||
description: "dialog header"
|
description: "dialog header"
|
||||||
},
|
|
||||||
deleteChannel: {
|
|
||||||
defaultMessage: "Delete Channel",
|
|
||||||
description: "dialog header"
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,8 @@ export const channelsList: Channels_channels[] = [
|
||||||
{
|
{
|
||||||
__typename: "Channel",
|
__typename: "Channel",
|
||||||
currencyCode: "euro",
|
currencyCode: "euro",
|
||||||
id: "Q2hhbm5lbDo5w0z",
|
|
||||||
hasOrders: false,
|
hasOrders: false,
|
||||||
|
id: "Q2hhbm5lbDo5w0z",
|
||||||
isActive: true,
|
isActive: true,
|
||||||
name: "Channel USD",
|
name: "Channel USD",
|
||||||
slug: "channel-usd1"
|
slug: "channel-usd1"
|
||||||
|
|
|
@ -102,7 +102,7 @@ export interface CollectionDetails_collection {
|
||||||
privateMetadata: (CollectionDetails_collection_privateMetadata | null)[];
|
privateMetadata: (CollectionDetails_collection_privateMetadata | null)[];
|
||||||
backgroundImage: CollectionDetails_collection_backgroundImage | null;
|
backgroundImage: CollectionDetails_collection_backgroundImage | null;
|
||||||
slug: string;
|
slug: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
products: CollectionDetails_collection_products | null;
|
products: CollectionDetails_collection_products | null;
|
||||||
|
|
|
@ -48,7 +48,7 @@ export interface CollectionUpdate_collectionUpdate_collection {
|
||||||
privateMetadata: (CollectionUpdate_collectionUpdate_collection_privateMetadata | null)[];
|
privateMetadata: (CollectionUpdate_collectionUpdate_collection_privateMetadata | null)[];
|
||||||
backgroundImage: CollectionUpdate_collectionUpdate_collection_backgroundImage | null;
|
backgroundImage: CollectionUpdate_collectionUpdate_collection_backgroundImage | null;
|
||||||
slug: string;
|
slug: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ export interface CreateCollection_collectionCreate_collection {
|
||||||
privateMetadata: (CreateCollection_collectionCreate_collection_privateMetadata | null)[];
|
privateMetadata: (CreateCollection_collectionCreate_collection_privateMetadata | null)[];
|
||||||
backgroundImage: CreateCollection_collectionCreate_collection_backgroundImage | null;
|
backgroundImage: CreateCollection_collectionCreate_collection_backgroundImage | null;
|
||||||
slug: string;
|
slug: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import useChannels from "@saleor/hooks/useChannels";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
|
import { getParsedDataForJsonStringField } from "@saleor/translations/utils";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
|
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
|
||||||
import {
|
import {
|
||||||
|
@ -102,7 +103,7 @@ export const CollectionCreate: React.FC<CollectionCreateProps> = ({
|
||||||
input: {
|
input: {
|
||||||
backgroundImage: formData.backgroundImage.value,
|
backgroundImage: formData.backgroundImage.value,
|
||||||
backgroundImageAlt: formData.backgroundImageAlt,
|
backgroundImageAlt: formData.backgroundImageAlt,
|
||||||
description: JSON.stringify(formData.description),
|
description: getParsedDataForJsonStringField(formData.description),
|
||||||
name: formData.name,
|
name: formData.name,
|
||||||
seo: {
|
seo: {
|
||||||
description: formData.seoDescription,
|
description: formData.seoDescription,
|
||||||
|
|
|
@ -21,6 +21,7 @@ import usePaginator, {
|
||||||
} from "@saleor/hooks/usePaginator";
|
} from "@saleor/hooks/usePaginator";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import useProductSearch from "@saleor/searches/useProductSearch";
|
import useProductSearch from "@saleor/searches/useProductSearch";
|
||||||
|
import { getParsedDataForJsonStringField } from "@saleor/translations/utils";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
|
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
|
||||||
import {
|
import {
|
||||||
|
@ -198,7 +199,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||||
const handleUpdate = async (formData: CollectionUpdateData) => {
|
const handleUpdate = async (formData: CollectionUpdateData) => {
|
||||||
const input: CollectionInput = {
|
const input: CollectionInput = {
|
||||||
backgroundImageAlt: formData.backgroundImageAlt,
|
backgroundImageAlt: formData.backgroundImageAlt,
|
||||||
description: JSON.stringify(formData.description),
|
description: getParsedDataForJsonStringField(formData.description),
|
||||||
name: formData.name,
|
name: formData.name,
|
||||||
seo: {
|
seo: {
|
||||||
description: formData.seoDescription,
|
description: formData.seoDescription,
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const AppChannelProvider: React.FC = ({ children }) => {
|
||||||
|
|
||||||
const [isPickerActive, setPickerActive] = React.useState(false);
|
const [isPickerActive, setPickerActive] = React.useState(false);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!selectedChannel && channelData?.channels) {
|
if (!selectedChannel && channelData?.channels?.length > 0) {
|
||||||
setSelectedChannel(channelData.channels[0].id);
|
setSelectedChannel(channelData.channels[0].id);
|
||||||
}
|
}
|
||||||
}, [channelData]);
|
}, [channelData]);
|
||||||
|
|
|
@ -26,26 +26,26 @@ const messages = defineMessages({
|
||||||
defaultAddress: {
|
defaultAddress: {
|
||||||
defaultMessage: "Default Address"
|
defaultMessage: "Default Address"
|
||||||
},
|
},
|
||||||
defaultShippingAddress: {
|
|
||||||
defaultMessage: "Default Shipping Address"
|
|
||||||
},
|
|
||||||
defaultBillingAddress: {
|
defaultBillingAddress: {
|
||||||
defaultMessage: "Default Billing Address"
|
defaultMessage: "Default Billing Address"
|
||||||
},
|
},
|
||||||
setDefaultShipping: {
|
defaultShippingAddress: {
|
||||||
defaultMessage: "Set as default shipping address",
|
defaultMessage: "Default Shipping Address"
|
||||||
description: "button"
|
|
||||||
},
|
},
|
||||||
setDefaultBilling: {
|
deleteAddress: {
|
||||||
defaultMessage: "Set as default billing address",
|
defaultMessage: "Delete Address",
|
||||||
description: "button"
|
description: "button"
|
||||||
},
|
},
|
||||||
editAddress: {
|
editAddress: {
|
||||||
defaultMessage: "Edit Address",
|
defaultMessage: "Edit Address",
|
||||||
description: "button"
|
description: "button"
|
||||||
},
|
},
|
||||||
deleteAddress: {
|
setDefaultBilling: {
|
||||||
defaultMessage: "Delete Address",
|
defaultMessage: "Set as default billing address",
|
||||||
|
description: "button"
|
||||||
|
},
|
||||||
|
setDefaultShipping: {
|
||||||
|
defaultMessage: "Set as default shipping address",
|
||||||
description: "button"
|
description: "button"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,6 +23,14 @@ export interface CustomerAddressListPageProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
addAddress: {
|
||||||
|
defaultMessage: "Add address",
|
||||||
|
description: "button"
|
||||||
|
},
|
||||||
|
doesntHaveAddresses: {
|
||||||
|
defaultMessage:
|
||||||
|
"This customer doesn’t have any adresses added to his address book. You can add address using the button below."
|
||||||
|
},
|
||||||
fullNameAddress: {
|
fullNameAddress: {
|
||||||
defaultMessage: "{fullName}'s Address Book",
|
defaultMessage: "{fullName}'s Address Book",
|
||||||
description: "customer's address book, header"
|
description: "customer's address book, header"
|
||||||
|
@ -31,16 +39,8 @@ const messages = defineMessages({
|
||||||
defaultMessage: "{fullName} Details",
|
defaultMessage: "{fullName} Details",
|
||||||
description: "customer details, header"
|
description: "customer details, header"
|
||||||
},
|
},
|
||||||
addAddress: {
|
|
||||||
defaultMessage: "Add address",
|
|
||||||
description: "button"
|
|
||||||
},
|
|
||||||
noAddressToShow: {
|
noAddressToShow: {
|
||||||
defaultMessage: "There is no address to show for this customer"
|
defaultMessage: "There is no address to show for this customer"
|
||||||
},
|
|
||||||
doesntHaveAddresses: {
|
|
||||||
defaultMessage:
|
|
||||||
"This customer doesn’t have any adresses added to his address book. You can add address using the button below."
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ const CustomerDetailsPage: React.FC<CustomerDetailsPageProps> = ({
|
||||||
firstName: customer?.firstName || "",
|
firstName: customer?.firstName || "",
|
||||||
isActive: customer?.isActive || false,
|
isActive: customer?.isActive || false,
|
||||||
lastName: customer?.lastName || "",
|
lastName: customer?.lastName || "",
|
||||||
note: customer?.note || "",
|
|
||||||
metadata: customer?.metadata.map(mapMetadataItemToInput),
|
metadata: customer?.metadata.map(mapMetadataItemToInput),
|
||||||
|
note: customer?.note || "",
|
||||||
privateMetadata: customer?.privateMetadata.map(mapMetadataItemToInput)
|
privateMetadata: customer?.privateMetadata.map(mapMetadataItemToInput)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -946,8 +946,6 @@ export const customerList: ListCustomers_customers_edges_node[] = [
|
||||||
];
|
];
|
||||||
export const customer: CustomerDetails_user & CustomerAddresses_user = {
|
export const customer: CustomerDetails_user & CustomerAddresses_user = {
|
||||||
__typename: "User",
|
__typename: "User",
|
||||||
metadata: [],
|
|
||||||
privateMetadata: [],
|
|
||||||
addresses: [
|
addresses: [
|
||||||
{
|
{
|
||||||
__typename: "Address",
|
__typename: "Address",
|
||||||
|
@ -1046,6 +1044,7 @@ export const customer: CustomerDetails_user & CustomerAddresses_user = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
metadata: [],
|
||||||
note: null,
|
note: null,
|
||||||
orders: {
|
orders: {
|
||||||
__typename: "OrderCountableConnection",
|
__typename: "OrderCountableConnection",
|
||||||
|
@ -1069,5 +1068,6 @@ export const customer: CustomerDetails_user & CustomerAddresses_user = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
privateMetadata: []
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,11 +17,12 @@ export const shippingZoneFragment = gql`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const shippingMethodWithZipCodesFragment = gql`
|
export const shippingMethodWithPostalCodesFragment = gql`
|
||||||
fragment ShippingMethodWithZipCodesFragment on ShippingMethod {
|
fragment ShippingMethodWithPostalCodesFragment on ShippingMethod {
|
||||||
id
|
id
|
||||||
zipCodeRules {
|
postalCodeRules {
|
||||||
id
|
id
|
||||||
|
inclusionType
|
||||||
start
|
start
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
@ -30,9 +31,9 @@ export const shippingMethodWithZipCodesFragment = gql`
|
||||||
export const shippingMethodFragment = gql`
|
export const shippingMethodFragment = gql`
|
||||||
${metadataFragment}
|
${metadataFragment}
|
||||||
${fragmentMoney}
|
${fragmentMoney}
|
||||||
${shippingMethodWithZipCodesFragment}
|
${shippingMethodWithPostalCodesFragment}
|
||||||
fragment ShippingMethodFragment on ShippingMethod {
|
fragment ShippingMethodFragment on ShippingMethod {
|
||||||
...ShippingMethodWithZipCodesFragment
|
...ShippingMethodWithPostalCodesFragment
|
||||||
...MetadataFragment
|
...MetadataFragment
|
||||||
minimumOrderWeight {
|
minimumOrderWeight {
|
||||||
unit
|
unit
|
||||||
|
|
|
@ -37,7 +37,7 @@ export interface CategoryDetailsFragment {
|
||||||
backgroundImage: CategoryDetailsFragment_backgroundImage | null;
|
backgroundImage: CategoryDetailsFragment_backgroundImage | null;
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
parent: CategoryDetailsFragment_parent | null;
|
parent: CategoryDetailsFragment_parent | null;
|
||||||
|
|
|
@ -14,7 +14,7 @@ export interface CategoryTranslationFragment_translation_language {
|
||||||
export interface CategoryTranslationFragment_translation {
|
export interface CategoryTranslationFragment_translation {
|
||||||
__typename: "CategoryTranslation";
|
__typename: "CategoryTranslation";
|
||||||
id: string;
|
id: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
language: CategoryTranslationFragment_translation_language;
|
language: CategoryTranslationFragment_translation_language;
|
||||||
name: string;
|
name: string;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
|
@ -25,7 +25,7 @@ export interface CategoryTranslationFragment_category {
|
||||||
__typename: "Category";
|
__typename: "Category";
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ export interface CollectionDetailsFragment {
|
||||||
privateMetadata: (CollectionDetailsFragment_privateMetadata | null)[];
|
privateMetadata: (CollectionDetailsFragment_privateMetadata | null)[];
|
||||||
backgroundImage: CollectionDetailsFragment_backgroundImage | null;
|
backgroundImage: CollectionDetailsFragment_backgroundImage | null;
|
||||||
slug: string;
|
slug: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ export interface CollectionTranslationFragment_collection {
|
||||||
__typename: "Collection";
|
__typename: "Collection";
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ export interface CollectionTranslationFragment_translation_language {
|
||||||
export interface CollectionTranslationFragment_translation {
|
export interface CollectionTranslationFragment_translation {
|
||||||
__typename: "CollectionTranslation";
|
__typename: "CollectionTranslation";
|
||||||
id: string;
|
id: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
language: CollectionTranslationFragment_translation_language;
|
language: CollectionTranslationFragment_translation_language;
|
||||||
name: string;
|
name: string;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
|
|
|
@ -109,7 +109,7 @@ export interface PageDetailsFragment {
|
||||||
pageType: PageDetailsFragment_pageType;
|
pageType: PageDetailsFragment_pageType;
|
||||||
metadata: (PageDetailsFragment_metadata | null)[];
|
metadata: (PageDetailsFragment_metadata | null)[];
|
||||||
privateMetadata: (PageDetailsFragment_privateMetadata | null)[];
|
privateMetadata: (PageDetailsFragment_privateMetadata | null)[];
|
||||||
content: any;
|
content: any | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
publicationDate: any | null;
|
publicationDate: any | null;
|
||||||
|
|
|
@ -17,7 +17,7 @@ export interface PageTranslatableFragment_translation_language {
|
||||||
export interface PageTranslatableFragment_translation {
|
export interface PageTranslatableFragment_translation {
|
||||||
__typename: "PageTranslation";
|
__typename: "PageTranslation";
|
||||||
id: string;
|
id: string;
|
||||||
content: any;
|
content: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -27,7 +27,7 @@ export interface PageTranslatableFragment_translation {
|
||||||
export interface PageTranslatableFragment {
|
export interface PageTranslatableFragment {
|
||||||
__typename: "PageTranslatableContent";
|
__typename: "PageTranslatableContent";
|
||||||
id: string;
|
id: string;
|
||||||
content: any;
|
content: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
title: string;
|
title: string;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { LanguageCodeEnum } from "./../../types/globalTypes";
|
||||||
export interface PageTranslationFragment_page {
|
export interface PageTranslationFragment_page {
|
||||||
__typename: "Page";
|
__typename: "Page";
|
||||||
id: string;
|
id: string;
|
||||||
content: any;
|
content: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -26,7 +26,7 @@ export interface PageTranslationFragment_translation_language {
|
||||||
export interface PageTranslationFragment_translation {
|
export interface PageTranslationFragment_translation {
|
||||||
__typename: "PageTranslation";
|
__typename: "PageTranslation";
|
||||||
id: string;
|
id: string;
|
||||||
content: any;
|
content: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
title: string;
|
title: string;
|
||||||
|
|
|
@ -253,7 +253,7 @@ export interface Product {
|
||||||
privateMetadata: (Product_privateMetadata | null)[];
|
privateMetadata: (Product_privateMetadata | null)[];
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
rating: number | null;
|
rating: number | null;
|
||||||
|
|
|
@ -12,7 +12,7 @@ export interface ProductTranslationFragment_product {
|
||||||
__typename: "Product";
|
__typename: "Product";
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ export interface ProductTranslationFragment_translation_language {
|
||||||
export interface ProductTranslationFragment_translation {
|
export interface ProductTranslationFragment_translation {
|
||||||
__typename: "ProductTranslation";
|
__typename: "ProductTranslation";
|
||||||
id: string;
|
id: string;
|
||||||
description: any;
|
description: any | null;
|
||||||
language: ProductTranslationFragment_translation_language;
|
language: ProductTranslationFragment_translation_language;
|
||||||
name: string;
|
name: string;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
|
|
|
@ -2,15 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
import { PostalCodeRuleInclusionTypeEnum, WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: ShippingMethodFragment
|
// GraphQL fragment: ShippingMethodFragment
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface ShippingMethodFragment_zipCodeRules {
|
export interface ShippingMethodFragment_postalCodeRules {
|
||||||
__typename: "ShippingMethodZipCodeRule";
|
__typename: "ShippingMethodPostalCodeRule";
|
||||||
id: string;
|
id: string;
|
||||||
|
inclusionType: PostalCodeRuleInclusionTypeEnum | null;
|
||||||
start: string | null;
|
start: string | null;
|
||||||
end: string | null;
|
end: string | null;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +77,7 @@ export interface ShippingMethodFragment_channelListings {
|
||||||
export interface ShippingMethodFragment {
|
export interface ShippingMethodFragment {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
zipCodeRules: (ShippingMethodFragment_zipCodeRules | null)[] | null;
|
postalCodeRules: (ShippingMethodFragment_postalCodeRules | null)[] | null;
|
||||||
metadata: (ShippingMethodFragment_metadata | null)[];
|
metadata: (ShippingMethodFragment_metadata | null)[];
|
||||||
privateMetadata: (ShippingMethodFragment_privateMetadata | null)[];
|
privateMetadata: (ShippingMethodFragment_privateMetadata | null)[];
|
||||||
minimumOrderWeight: ShippingMethodFragment_minimumOrderWeight | null;
|
minimumOrderWeight: ShippingMethodFragment_minimumOrderWeight | null;
|
||||||
|
|
|
@ -2,15 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
import { PostalCodeRuleInclusionTypeEnum, WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: ShippingMethodWithExcludedProductsFragment
|
// GraphQL fragment: ShippingMethodWithExcludedProductsFragment
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface ShippingMethodWithExcludedProductsFragment_zipCodeRules {
|
export interface ShippingMethodWithExcludedProductsFragment_postalCodeRules {
|
||||||
__typename: "ShippingMethodZipCodeRule";
|
__typename: "ShippingMethodPostalCodeRule";
|
||||||
id: string;
|
id: string;
|
||||||
|
inclusionType: PostalCodeRuleInclusionTypeEnum | null;
|
||||||
start: string | null;
|
start: string | null;
|
||||||
end: string | null;
|
end: string | null;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +108,7 @@ export interface ShippingMethodWithExcludedProductsFragment_excludedProducts {
|
||||||
export interface ShippingMethodWithExcludedProductsFragment {
|
export interface ShippingMethodWithExcludedProductsFragment {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
zipCodeRules: (ShippingMethodWithExcludedProductsFragment_zipCodeRules | null)[] | null;
|
postalCodeRules: (ShippingMethodWithExcludedProductsFragment_postalCodeRules | null)[] | null;
|
||||||
metadata: (ShippingMethodWithExcludedProductsFragment_metadata | null)[];
|
metadata: (ShippingMethodWithExcludedProductsFragment_metadata | null)[];
|
||||||
privateMetadata: (ShippingMethodWithExcludedProductsFragment_privateMetadata | null)[];
|
privateMetadata: (ShippingMethodWithExcludedProductsFragment_privateMetadata | null)[];
|
||||||
minimumOrderWeight: ShippingMethodWithExcludedProductsFragment_minimumOrderWeight | null;
|
minimumOrderWeight: ShippingMethodWithExcludedProductsFragment_minimumOrderWeight | null;
|
||||||
|
|
23
src/fragments/types/ShippingMethodWithPostalCodesFragment.ts
Normal file
23
src/fragments/types/ShippingMethodWithPostalCodesFragment.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { PostalCodeRuleInclusionTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL fragment: ShippingMethodWithPostalCodesFragment
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ShippingMethodWithPostalCodesFragment_postalCodeRules {
|
||||||
|
__typename: "ShippingMethodPostalCodeRule";
|
||||||
|
id: string;
|
||||||
|
inclusionType: PostalCodeRuleInclusionTypeEnum | null;
|
||||||
|
start: string | null;
|
||||||
|
end: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShippingMethodWithPostalCodesFragment {
|
||||||
|
__typename: "ShippingMethod";
|
||||||
|
id: string;
|
||||||
|
postalCodeRules: (ShippingMethodWithPostalCodesFragment_postalCodeRules | null)[] | null;
|
||||||
|
}
|
|
@ -2,13 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { PostalCodeRuleInclusionTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: ShippingMethodWithZipCodesFragment
|
// GraphQL fragment: ShippingMethodWithZipCodesFragment
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface ShippingMethodWithZipCodesFragment_zipCodeRules {
|
export interface ShippingMethodWithZipCodesFragment_postalCodeRules {
|
||||||
__typename: "ShippingMethodZipCodeRule";
|
__typename: "ShippingMethodPostalCodeRule";
|
||||||
id: string;
|
id: string;
|
||||||
|
inclusionType: PostalCodeRuleInclusionTypeEnum | null;
|
||||||
start: string | null;
|
start: string | null;
|
||||||
end: string | null;
|
end: string | null;
|
||||||
}
|
}
|
||||||
|
@ -16,5 +19,5 @@ export interface ShippingMethodWithZipCodesFragment_zipCodeRules {
|
||||||
export interface ShippingMethodWithZipCodesFragment {
|
export interface ShippingMethodWithZipCodesFragment {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
zipCodeRules: (ShippingMethodWithZipCodesFragment_zipCodeRules | null)[] | null;
|
postalCodeRules: (ShippingMethodWithZipCodesFragment_postalCodeRules | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
import { PostalCodeRuleInclusionTypeEnum, WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: ShippingZoneDetailsFragment
|
// GraphQL fragment: ShippingZoneDetailsFragment
|
||||||
|
@ -26,9 +26,10 @@ export interface ShippingZoneDetailsFragment_countries {
|
||||||
country: string;
|
country: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShippingZoneDetailsFragment_shippingMethods_zipCodeRules {
|
export interface ShippingZoneDetailsFragment_shippingMethods_postalCodeRules {
|
||||||
__typename: "ShippingMethodZipCodeRule";
|
__typename: "ShippingMethodPostalCodeRule";
|
||||||
id: string;
|
id: string;
|
||||||
|
inclusionType: PostalCodeRuleInclusionTypeEnum | null;
|
||||||
start: string | null;
|
start: string | null;
|
||||||
end: string | null;
|
end: string | null;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +95,7 @@ export interface ShippingZoneDetailsFragment_shippingMethods_channelListings {
|
||||||
export interface ShippingZoneDetailsFragment_shippingMethods {
|
export interface ShippingZoneDetailsFragment_shippingMethods {
|
||||||
__typename: "ShippingMethod";
|
__typename: "ShippingMethod";
|
||||||
id: string;
|
id: string;
|
||||||
zipCodeRules: (ShippingZoneDetailsFragment_shippingMethods_zipCodeRules | null)[] | null;
|
postalCodeRules: (ShippingZoneDetailsFragment_shippingMethods_postalCodeRules | null)[] | null;
|
||||||
metadata: (ShippingZoneDetailsFragment_shippingMethods_metadata | null)[];
|
metadata: (ShippingZoneDetailsFragment_shippingMethods_metadata | null)[];
|
||||||
privateMetadata: (ShippingZoneDetailsFragment_shippingMethods_privateMetadata | null)[];
|
privateMetadata: (ShippingZoneDetailsFragment_shippingMethods_privateMetadata | null)[];
|
||||||
minimumOrderWeight: ShippingZoneDetailsFragment_shippingMethods_minimumOrderWeight | null;
|
minimumOrderWeight: ShippingZoneDetailsFragment_shippingMethods_minimumOrderWeight | null;
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -116,7 +116,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 ? (
|
||||||
|
@ -136,7 +136,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 ? (
|
||||||
|
@ -161,7 +161,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",
|
||||||
|
|
|
@ -167,8 +167,8 @@ const Routes: React.FC = () => {
|
||||||
|
|
||||||
dispatchAppState({
|
dispatchAppState({
|
||||||
payload: {
|
payload: {
|
||||||
errorId,
|
error: "unhandled",
|
||||||
error: "unhandled"
|
errorId
|
||||||
},
|
},
|
||||||
type: "displayError"
|
type: "displayError"
|
||||||
});
|
});
|
||||||
|
|
|
@ -117,7 +117,7 @@ export interface PageCreate_pageCreate_page {
|
||||||
pageType: PageCreate_pageCreate_page_pageType;
|
pageType: PageCreate_pageCreate_page_pageType;
|
||||||
metadata: (PageCreate_pageCreate_page_metadata | null)[];
|
metadata: (PageCreate_pageCreate_page_metadata | null)[];
|
||||||
privateMetadata: (PageCreate_pageCreate_page_privateMetadata | null)[];
|
privateMetadata: (PageCreate_pageCreate_page_privateMetadata | null)[];
|
||||||
content: any;
|
content: any | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
publicationDate: any | null;
|
publicationDate: any | null;
|
||||||
|
|
|
@ -109,7 +109,7 @@ export interface PageDetails_page {
|
||||||
pageType: PageDetails_page_pageType;
|
pageType: PageDetails_page_pageType;
|
||||||
metadata: (PageDetails_page_metadata | null)[];
|
metadata: (PageDetails_page_metadata | null)[];
|
||||||
privateMetadata: (PageDetails_page_privateMetadata | null)[];
|
privateMetadata: (PageDetails_page_privateMetadata | null)[];
|
||||||
content: any;
|
content: any | null;
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
seoDescription: string | null;
|
seoDescription: string | null;
|
||||||
publicationDate: any | null;
|
publicationDate: any | null;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue