Saleor 3626 tests for attributes (#1198)

* tests for attributes

* add tests for content attribute
This commit is contained in:
Karolina Rakoczy 2021-07-09 11:43:45 +02:00 committed by GitHub
parent 47ac2a94e4
commit 4faafd2489
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 433 additions and 3 deletions

View file

@ -58,3 +58,21 @@ export function deleteAttribute(attributeId) {
}`;
return cy.sendRequestWithQuery(mutation);
}
export function getAttribute(attributeId) {
const query = `query{
attribute(id:"${attributeId}"){
id
inputType
name
slug
type
entityType
valueRequired
visibleInStorefront
availableInGrid
unit
}
}`;
return cy.sendRequestWithQuery(query).its("body.data.attribute");
}

View file

@ -0,0 +1,39 @@
export const ATTRIBUTES_DETAILS = {
nameInput: '[name="name"]',
codeInput: '[name="slug"]',
inputTypeSelect: '[id="mui-component-select-inputType"]',
assignValuesButton: '[data-test-id="assignValueButton"]',
valueRequired: '[name="valueRequired"]',
valueNameInput: '[data-test-id="valueName"]',
attributesInputTypes: {
DROPDOWN: '[data-test-id="DROPDOWN"]',
MULTISELECT: '[data-test-id="MULTISELECT"]',
FILE: '[data-test-id="FILE"]',
REFERENCE: '[data-test-id="REFERENCE"]',
RICH_TEXT: '[data-test-id="RICH_TEXT"]',
NUMERIC: '[data-test-id="NUMERIC"]',
BOOLEAN: '[data-test-id="BOOLEAN"]'
},
entityTypeSelect: '[id="mui-component-select-entityType"]',
entityTypeOptions: {
PRODUCT: '[data-test-id="PRODUCT"]',
PAGE: '[data-test-id="PAGE"]'
},
selectUnitCheckbox: '[name="selectUnit"]',
unitSystemSelect: '[data-test-id="unit-system"]',
unitSystemsOptions: {
IMPERIAL: '[data-test-id="imperial"]',
METRIC: '[data-test-id="metric"]'
},
unitOfSelect: '[data-test-id="unit-of"]',
unitsOfOptions: {
VOLUME: '[data-test-id="volume"]',
DISTANCE: '[data-test-id="distance"]'
},
unitSelect: '[data-test-id="unit"]',
unitsOptions: {
CUBIC_CENTIMETER: '[data-test-id="CUBIC_CENTIMETER"]',
FT: '[data-test-id="FT"]'
},
pageTypeAttributeCheckbox: '[value="PAGE_TYPE"]'
};

View file

@ -0,0 +1,3 @@
export const ATTRIBUTES_LIST = {
createAttributeButton: '[data-test-id="createAttributeButton"]'
};

View file

@ -0,0 +1,120 @@
// <reference types="cypress" />
import faker from "faker";
import { getAttribute } from "../../../../apiRequests/Attribute";
import { ATTRIBUTES_LIST } from "../../../../elements/attribute/attributes_list";
import { createAttributeWithInputType } from "../../../../steps/attributesSteps";
import { urlList } from "../../../../url/urlList";
import { deleteAttributesStartsWith } from "../../../../utils/attributes.js/attributeUtils";
import { expectCorrectDataInAttribute } from "../../../../utils/attributes.js/checkAttributeData";
describe("Create attribute with type", () => {
const startsWith = "AttrCreate";
const attributesTypes = [
"DROPDOWN",
"MULTISELECT",
"FILE",
"RICH_TEXT",
"BOOLEAN"
];
const attributeReferenceType = ["PRODUCT", "PAGE"];
const attributeNumericType = [
{ unitSystem: "IMPERIAL", unitsOf: "DISTANCE", unit: "FT" },
{ unitSystem: "METRIC", unitsOf: "VOLUME", unit: "CUBIC_CENTIMETER" },
{ unitSystem: "without selecting unit" }
];
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteAttributesStartsWith(startsWith);
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.attributes)
.get(ATTRIBUTES_LIST.createAttributeButton)
.click();
});
attributesTypes.forEach(attributeType => {
it(`should create ${attributeType} attribute`, () => {
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({ name: attributeName, attributeType })
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType
});
});
});
});
attributeReferenceType.forEach(entityType => {
it(`should create reference ${entityType} attribute`, () => {
const attributeType = "REFERENCE";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
entityType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
entityType
});
});
});
});
attributeNumericType.forEach(numericSystemType => {
it(`should create numeric attribute - ${numericSystemType.unitSystem}`, () => {
const attributeType = "NUMERIC";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
numericSystemType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
unit: numericSystemType.unit
});
});
});
});
it("should create attribute without required value", () => {
const attributeType = "BOOLEAN";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
valueRequired: false
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
valueRequired: false
});
});
});
});

View file

@ -0,0 +1,120 @@
import faker from "faker";
import { getAttribute } from "../../../../apiRequests/Attribute";
import { ATTRIBUTES_DETAILS } from "../../../../elements/attribute/attributes_details";
import { ATTRIBUTES_LIST } from "../../../../elements/attribute/attributes_list";
import { createAttributeWithInputType } from "../../../../steps/attributesSteps";
import { urlList } from "../../../../url/urlList";
import { deleteAttributesStartsWith } from "../../../../utils/attributes.js/attributeUtils";
import { expectCorrectDataInAttribute } from "../../../../utils/attributes.js/checkAttributeData";
describe("Create content attribute", () => {
const startsWith = "AttrCont";
const attributesTypes = [
"DROPDOWN",
"MULTISELECT",
"FILE",
"RICH_TEXT",
"BOOLEAN"
];
const attributeReferenceType = ["PRODUCT", "PAGE"];
const attributeNumericType = [
{ unitSystem: "IMPERIAL", unitsOf: "DISTANCE", unit: "FT" },
{ unitSystem: "METRIC", unitsOf: "VOLUME", unit: "CUBIC_CENTIMETER" },
{ unitSystem: "without selecting unit" }
];
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteAttributesStartsWith(startsWith);
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.attributes)
.get(ATTRIBUTES_LIST.createAttributeButton)
.click()
.get(ATTRIBUTES_DETAILS.pageTypeAttributeCheckbox)
.click();
});
attributesTypes.forEach(attributeType => {
it(`should create ${attributeType} attribute`, () => {
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({ name: attributeName, attributeType })
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType
});
});
});
});
attributeReferenceType.forEach(entityType => {
it(`should create reference ${entityType} attribute`, () => {
const attributeType = "REFERENCE";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
entityType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
entityType
});
});
});
});
attributeNumericType.forEach(numericSystemType => {
it(`should create numeric attribute - ${numericSystemType.unitSystem}`, () => {
const attributeType = "NUMERIC";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
numericSystemType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
unit: numericSystemType.unit
});
});
});
});
it("should create attribute without required value", () => {
const attributeType = "BOOLEAN";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
valueRequired: false
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
valueRequired: false
});
});
});
});

View file

@ -0,0 +1,82 @@
import { ATTRIBUTES_DETAILS } from "../elements/attribute/attributes_details";
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
export function createAttributeWithInputType({
name,
attributeType,
entityType,
numericSystemType,
valueRequired = true
}) {
fillUpAttributeCreateFields({ name, attributeType, valueRequired });
if (attributeType === "DROPDOWN" || attributeType === "MULTISELECT") {
addSingleValue(name);
}
if (attributeType === "REFERENCE") {
selectEntityType(entityType);
}
if (attributeType === "NUMERIC" && numericSystemType.unitsOf) {
selectNumericSystem(numericSystemType);
}
return saveAttribute();
}
export function fillUpAttributeCreateFields({
name,
attributeType,
valueRequired
}) {
cy.get(ATTRIBUTES_DETAILS.nameInput)
.type(name)
.get(ATTRIBUTES_DETAILS.codeInput)
.type(name)
.get(ATTRIBUTES_DETAILS.inputTypeSelect)
.click()
.get(ATTRIBUTES_DETAILS.attributesInputTypes[attributeType])
.click();
if (!valueRequired) {
cy.get(ATTRIBUTES_DETAILS.valueRequired).click();
}
}
export function saveAttribute() {
return cy
.addAliasToGraphRequest("AttributeCreate")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@AttributeCreate")
.its("response.body.data.attributeCreate");
}
export function addSingleValue(valueName) {
cy.get(ATTRIBUTES_DETAILS.assignValuesButton)
.click()
.get(ATTRIBUTES_DETAILS.valueNameInput)
.type(valueName)
.get(BUTTON_SELECTORS.submit)
.click();
}
export function selectEntityType(entityType) {
cy.get(ATTRIBUTES_DETAILS.entityTypeSelect)
.click()
.get(ATTRIBUTES_DETAILS.entityTypeOptions[entityType])
.click();
}
export function selectNumericSystem({ unitSystem, unitsOf, unit }) {
cy.get(ATTRIBUTES_DETAILS.selectUnitCheckbox)
.click()
.get(ATTRIBUTES_DETAILS.unitSystemSelect)
.click()
.get(ATTRIBUTES_DETAILS.unitSystemsOptions[unitSystem])
.click()
.get(ATTRIBUTES_DETAILS.unitOfSelect)
.click()
.get(ATTRIBUTES_DETAILS.unitsOfOptions[unitsOf])
.click()
.get(ATTRIBUTES_DETAILS.unitSelect)
.click()
.get(ATTRIBUTES_DETAILS.unitsOptions[unit])
.click();
}

View file

@ -14,6 +14,7 @@ export const urlList = {
staffMembers: "staff/",
newPassword: "new-password/",
permissionsGroups: "permission-groups/",
attributes: "attributes/",
productTypes: "product-types/"
};
export const productDetailsUrl = productId => `${urlList.products}${productId}`;
@ -33,4 +34,4 @@ export const warehouseDetailsUrl = warehouseId =>
`${urlList.warehouses}${warehouseId}`;
export const productTypeDetailsUrl = productTypeId =>
`${urlList.productTypes}${productTypeId}`;
`${urlList.productTypes}${productTypeId}`;

View file

@ -0,0 +1,5 @@
import { deleteAttribute, getAttributes } from "../../apiRequests/Attribute";
export function deleteAttributesStartsWith(startsWith) {
cy.deleteElementsStartsWith(deleteAttribute, getAttributes, startsWith);
}

View file

@ -0,0 +1,19 @@
const { softExpect } = chai;
export function expectCorrectDataInAttribute(
attribute,
{
attributeName,
attributeType,
entityType = null,
unit = null,
valueRequired = true
}
) {
softExpect(attribute.name).to.eq(attributeName);
softExpect(attribute.slug).to.eq(attributeName);
softExpect(attribute.inputType).to.eq(attributeType);
softExpect(attribute.entityType).to.eq(entityType);
softExpect(attribute.unit).to.eq(unit);
softExpect(attribute.valueRequired).to.eq(valueRequired);
}

View file

@ -6,6 +6,7 @@ import {
deleteProductType,
getProductTypes
} from "../../apiRequests/productType";
import { deleteAttributesStartsWith } from "../attributes.js/attributeUtils";
export function createProductInChannel({
name,
@ -85,6 +86,7 @@ export function createTypeAttributeAndCategoryForProduct(
});
}
export function deleteProductsStartsWith(startsWith) {
deleteAttributesStartsWith(startsWith);
cy.deleteElementsStartsWith(deleteProductType, getProductTypes, startsWith);
cy.deleteElementsStartsWith(
attributeRequest.deleteAttribute,

View file

@ -58,7 +58,12 @@ const AttributeListPage: React.FC<AttributeListPageProps> = ({
<FormattedMessage {...sectionNames.configuration} />
</AppHeader>
<PageHeader title={intl.formatMessage(sectionNames.attributes)}>
<Button onClick={onAdd} color="primary" variant="contained">
<Button
onClick={onAdd}
color="primary"
variant="contained"
data-test-id="createAttributeButton"
>
<FormattedMessage
defaultMessage="Create attribute"
description="button"

View file

@ -68,6 +68,7 @@ const AttributeValueEditDialog: React.FC<AttributeValueEditDialogProps> = ({
<>
<DialogContent>
<TextField
data-test-id="valueName"
autoFocus
disabled={disabled}
error={!!formErrors.name}
@ -90,6 +91,7 @@ const AttributeValueEditDialog: React.FC<AttributeValueEditDialogProps> = ({
<FormattedMessage {...buttonMessages.back} />
</Button>
<ConfirmButton
data-test="submit"
transitionState={confirmButtonState}
color="primary"
variant="contained"

View file

@ -86,7 +86,12 @@ const AttributeValues: React.FC<AttributeValuesProps> = ({
description: "section header"
})}
toolbar={
<Button color="primary" variant="text" onClick={onValueAdd}>
<Button
color="primary"
variant="text"
onClick={onValueAdd}
data-test-id="assignValueButton"
>
<FormattedMessage
defaultMessage="Assign value"
description="assign attribute value button"

View file

@ -36744,6 +36744,7 @@ exports[`Storyshots Views / Attributes / Attribute details create 1`] = `
>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
data-test-id="assignValueButton"
tabindex="0"
type="button"
>
@ -37831,6 +37832,7 @@ exports[`Storyshots Views / Attributes / Attribute details default 1`] = `
>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
data-test-id="assignValueButton"
tabindex="0"
type="button"
>
@ -38966,6 +38968,7 @@ exports[`Storyshots Views / Attributes / Attribute details form errors 1`] = `
>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
data-test-id="assignValueButton"
tabindex="0"
type="button"
>
@ -40105,6 +40108,7 @@ exports[`Storyshots Views / Attributes / Attribute details loading 1`] = `
>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
data-test-id="assignValueButton"
tabindex="0"
type="button"
>
@ -40985,6 +40989,7 @@ exports[`Storyshots Views / Attributes / Attribute details multiple select input
>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
data-test-id="assignValueButton"
tabindex="0"
type="button"
>
@ -42115,6 +42120,7 @@ exports[`Storyshots Views / Attributes / Attribute details no values 1`] = `
>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
data-test-id="assignValueButton"
tabindex="0"
type="button"
>
@ -42946,6 +42952,7 @@ exports[`Storyshots Views / Attributes / Attribute list default 1`] = `
>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="createAttributeButton"
tabindex="0"
type="button"
>
@ -44148,6 +44155,7 @@ exports[`Storyshots Views / Attributes / Attribute list loading 1`] = `
>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="createAttributeButton"
tabindex="0"
type="button"
>
@ -44584,6 +44592,7 @@ exports[`Storyshots Views / Attributes / Attribute list no data 1`] = `
>
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="createAttributeButton"
tabindex="0"
type="button"
>