Saleor 3873 tests for navigation (#1234)
* add test for creating menu * tests for navigation * fix imports
This commit is contained in:
parent
99507d5bed
commit
f1b313ea69
21 changed files with 311 additions and 10 deletions
68
cypress/apiRequests/Menu.js
Normal file
68
cypress/apiRequests/Menu.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
export function getMenu(menuId) {
|
||||
const query = `query{
|
||||
menu(id:"${menuId}"){
|
||||
id
|
||||
name
|
||||
items{
|
||||
name
|
||||
category{
|
||||
name
|
||||
}
|
||||
collection{
|
||||
name
|
||||
}
|
||||
page{
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy.sendRequestWithQuery(query).its("body.data.menu");
|
||||
}
|
||||
|
||||
export function getMenus(first, search) {
|
||||
const mutation = `query{
|
||||
menus(first:${first}, filter:{
|
||||
search:"${search}"
|
||||
}){
|
||||
edges{
|
||||
node{
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy
|
||||
.sendRequestWithQuery(mutation)
|
||||
.then(resp => resp.body.data.menus.edges);
|
||||
}
|
||||
|
||||
export function deleteMenu(menuId) {
|
||||
const mutation = `mutation{
|
||||
menuDelete(id:"${menuId}"){
|
||||
errors{
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy.sendRequestWithQuery(mutation);
|
||||
}
|
||||
|
||||
export function createMenu(name) {
|
||||
const mutation = `mutation{
|
||||
menuCreate(input:{
|
||||
name:"${name}"
|
||||
}){
|
||||
errors{
|
||||
field
|
||||
message
|
||||
}
|
||||
menu{
|
||||
id
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy.sendRequestWithQuery(mutation).its("body.data.menuCreate");
|
||||
}
|
18
cypress/apiRequests/Page.js
Normal file
18
cypress/apiRequests/Page.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
export function createPage({ title, pageTypeId }) {
|
||||
const mutation = `mutation{
|
||||
pageCreate(input:{
|
||||
title:"${title}"
|
||||
pageType:"${pageTypeId}"
|
||||
}){
|
||||
errors{
|
||||
field
|
||||
message
|
||||
}
|
||||
page{
|
||||
title
|
||||
id
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy.sendRequestWithQuery(mutation).its("body.data.pageCreate");
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import { getValueWithDefault } from "./utils/Utils";
|
||||
|
||||
export function getPageType(pageTypeId) {
|
||||
const query = `query{
|
||||
pageType(id:"${pageTypeId}"){
|
||||
|
@ -11,9 +13,14 @@ export function getPageType(pageTypeId) {
|
|||
return cy.sendRequestWithQuery(query).its("body.data.pageType");
|
||||
}
|
||||
|
||||
export function createPageType(name) {
|
||||
export function createPageType({ name, attributeId }) {
|
||||
const attributeLine = getValueWithDefault(
|
||||
attributeId,
|
||||
`addAttributes:["${attributeId}"]`
|
||||
);
|
||||
|
||||
const mutation = `mutation{
|
||||
pageTypeCreate(input:{ name: "${name}"}){
|
||||
pageTypeCreate(input:{ name: "${name}" ${attributeLine}}){
|
||||
pageType{
|
||||
name
|
||||
id
|
||||
|
@ -26,3 +33,33 @@ export function createPageType(name) {
|
|||
}`;
|
||||
return cy.sendRequestWithQuery(mutation).its("body.data.pageTypeCreate");
|
||||
}
|
||||
|
||||
export function getPageTypes(first, search) {
|
||||
const query = `query{
|
||||
pageTypes(first: ${first}, filter:{
|
||||
search:"${search}"
|
||||
}){
|
||||
edges{
|
||||
node{
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy
|
||||
.sendRequestWithQuery(query)
|
||||
.then(resp => resp.body.data.pageTypes.edges);
|
||||
}
|
||||
|
||||
export function deletePageType(pageTypeId) {
|
||||
const mutation = `mutation{
|
||||
pageTypeDelete(id:"${pageTypeId}"){
|
||||
errors{
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy.sendRequestWithQuery(mutation);
|
||||
}
|
||||
|
|
10
cypress/elements/navigation/menu-details.js
Normal file
10
cypress/elements/navigation/menu-details.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
export const MENU_DETAILS = {
|
||||
createNewMenuItemButton: '[data-test-id="createNewMenuItem"]',
|
||||
newMenuItemForm: {
|
||||
nameInput: '[name="name"]',
|
||||
autocompleteSelectReference: '[data-test-id="containerAutocompleteSelect"]',
|
||||
categoryItem: '[data-test-id="category"]',
|
||||
collectionItem: '[data-test-id="collection"]',
|
||||
pageItem: '[data-test-id="page"]'
|
||||
}
|
||||
};
|
6
cypress/elements/navigation/menu-list.js
Normal file
6
cypress/elements/navigation/menu-list.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
export const MENU_LIST = {
|
||||
addMenuButton: '[data-test-id="addMenu"]',
|
||||
createMenuForm: {
|
||||
nameInput: '[name="name"]'
|
||||
}
|
||||
};
|
|
@ -6,6 +6,8 @@ export const SHARED_ELEMENTS = {
|
|||
table: 'table[class*="Table"]',
|
||||
tableRow: '[data-test="id"]',
|
||||
confirmationMsg: "[data-test='notification-success']",
|
||||
notificationSuccess: '[data-test="notification-success"]',
|
||||
dialog: '[role="dialog"]',
|
||||
searchInput: '[data-test-id="searchInput"]',
|
||||
selectOption: '[data-test="selectFieldOption"]',
|
||||
richTextEditor: {
|
||||
|
|
|
@ -6,8 +6,8 @@ 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";
|
||||
import { deleteAttributesStartsWith } from "../../../../utils/attributes/attributeUtils";
|
||||
import { expectCorrectDataInAttribute } from "../../../../utils/attributes/checkAttributeData";
|
||||
|
||||
describe("Create attribute with type", () => {
|
||||
const startsWith = "AttrCreate";
|
||||
|
|
|
@ -5,8 +5,8 @@ import { ATTRIBUTES_DETAILS } from "../../../../elements/attribute/attributes_de
|
|||
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";
|
||||
import { deleteAttributesStartsWith } from "../../../../utils/attributes/attributeUtils";
|
||||
import { expectCorrectDataInAttribute } from "../../../../utils/attributes/checkAttributeData";
|
||||
|
||||
describe("Create content attribute", () => {
|
||||
const startsWith = "AttrCont";
|
||||
|
|
66
cypress/integration/allEnv/configuration/navigation.js
Normal file
66
cypress/integration/allEnv/configuration/navigation.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
import faker from "faker";
|
||||
|
||||
import {
|
||||
createMenu as createMenuViaApi,
|
||||
getMenu
|
||||
} from "../../../apiRequests/Menu";
|
||||
import {
|
||||
createMenu,
|
||||
createNewMenuItem,
|
||||
MENU_ITEM_TYPES
|
||||
} from "../../../steps/navigationSteps";
|
||||
import { deleteMenusStartsWith } from "../../../utils/navigationUtils";
|
||||
|
||||
describe("Tests for menu navigation", () => {
|
||||
const startsWith = "Navigation";
|
||||
const randomName = `${startsWith}${faker.datatype.number()}`;
|
||||
|
||||
let menu;
|
||||
|
||||
before(() => {
|
||||
cy.clearSessionData().loginUserViaRequest();
|
||||
deleteMenusStartsWith(startsWith);
|
||||
createMenuViaApi(randomName).then(
|
||||
({ menu: menuResp }) => (menu = menuResp)
|
||||
);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.clearSessionData().loginUserViaRequest();
|
||||
});
|
||||
|
||||
it("should create a menu", () => {
|
||||
const name = `${startsWith}${faker.datatype.number()}`;
|
||||
|
||||
createMenu(name)
|
||||
.then(menuResp => {
|
||||
getMenu(menuResp.id);
|
||||
})
|
||||
.then(menuResp => {
|
||||
expect(menuResp.name).to.eq(name);
|
||||
});
|
||||
});
|
||||
|
||||
["category", "collection", "page"].forEach(itemType => {
|
||||
it(`should add new ${itemType} item to menu`, () => {
|
||||
const itemName = `${startsWith}${faker.datatype.number()}`;
|
||||
let selectedItem;
|
||||
|
||||
createNewMenuItem({
|
||||
menuId: menu.id,
|
||||
name: itemName,
|
||||
menuItemType: MENU_ITEM_TYPES[itemType]
|
||||
})
|
||||
.then(selectedItemResp => {
|
||||
selectedItem = selectedItemResp;
|
||||
getMenu(menu.id);
|
||||
})
|
||||
.then(({ items }) => {
|
||||
const item = items.find(element => element.name === itemName);
|
||||
const itemOfType = item[itemType];
|
||||
const name = itemType !== "page" ? "name" : "title";
|
||||
expect(itemOfType[name]).to.eq(selectedItem);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
56
cypress/steps/navigationSteps.js
Normal file
56
cypress/steps/navigationSteps.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
import { MENU_DETAILS } from "../elements/navigation/menu-details";
|
||||
import { MENU_LIST } from "../elements/navigation/menu-list";
|
||||
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
|
||||
import { SHARED_ELEMENTS } from "../elements/shared/sharedElements";
|
||||
import { menuDetailsUrl, urlList } from "../url/urlList";
|
||||
import { confirmationMessageShouldDisappear } from "./shared/confirmationMessage";
|
||||
|
||||
export function createMenu(name) {
|
||||
cy.visit(urlList.navigation)
|
||||
.get(MENU_LIST.addMenuButton)
|
||||
.click()
|
||||
.get(MENU_LIST.createMenuForm.nameInput)
|
||||
.type(name)
|
||||
.addAliasToGraphRequest("MenuCreate")
|
||||
.get(BUTTON_SELECTORS.submit)
|
||||
.click();
|
||||
confirmationMessageShouldDisappear();
|
||||
return cy.wait("@MenuCreate").its("response.body.data.menuCreate.menu");
|
||||
}
|
||||
|
||||
export function createNewMenuItem({ menuId, name, menuItemType }) {
|
||||
let selectedItem;
|
||||
|
||||
return cy
|
||||
.visit(menuDetailsUrl(menuId))
|
||||
.get(MENU_DETAILS.createNewMenuItemButton)
|
||||
.click()
|
||||
.get(SHARED_ELEMENTS.dialog)
|
||||
.find(MENU_DETAILS.newMenuItemForm.nameInput)
|
||||
.type(name)
|
||||
.get(MENU_DETAILS.newMenuItemForm.autocompleteSelectReference)
|
||||
.click()
|
||||
.get(SHARED_ELEMENTS.progressBar)
|
||||
.should("be.not.visible")
|
||||
.get(MENU_DETAILS.newMenuItemForm[menuItemType])
|
||||
.click()
|
||||
.get(MENU_DETAILS.newMenuItemForm[menuItemType])
|
||||
.first()
|
||||
.click()
|
||||
.invoke("text")
|
||||
.then(text => {
|
||||
selectedItem = text;
|
||||
cy.addAliasToGraphRequest("MenuItemCreate")
|
||||
.get(BUTTON_SELECTORS.submit)
|
||||
.click();
|
||||
confirmationMessageShouldDisappear();
|
||||
cy.wait("@MenuItemCreate");
|
||||
})
|
||||
.then(() => selectedItem);
|
||||
}
|
||||
|
||||
export const MENU_ITEM_TYPES = {
|
||||
category: "categoryItem",
|
||||
collection: "collectionItem",
|
||||
page: "pageItem"
|
||||
};
|
|
@ -11,6 +11,7 @@ export const urlList = {
|
|||
draftOrders: "orders/drafts/",
|
||||
homePage: "/",
|
||||
newPassword: "new-password/",
|
||||
navigation: "navigation/",
|
||||
orders: "orders/",
|
||||
pageTypes: "page-types/",
|
||||
permissionsGroups: "permission-groups/",
|
||||
|
@ -50,6 +51,8 @@ export const warehouseDetailsUrl = warehouseId =>
|
|||
export const productTypeDetailsUrl = productTypeId =>
|
||||
`${urlList.productTypes}${productTypeId}`;
|
||||
|
||||
export const menuDetailsUrl = menuId => `${urlList.navigation}${menuId}`;
|
||||
|
||||
export const customerDetailsUrl = customerId =>
|
||||
`${urlList.customers}${customerId}`;
|
||||
|
||||
|
|
5
cypress/utils/navigationUtils.js
Normal file
5
cypress/utils/navigationUtils.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { deleteMenu, getMenus } from "../apiRequests/Menu";
|
||||
|
||||
export function deleteMenusStartsWith(startsWith) {
|
||||
cy.deleteElementsStartsWith(deleteMenu, getMenus, startsWith);
|
||||
}
|
|
@ -6,7 +6,7 @@ import {
|
|||
deleteProductType,
|
||||
getProductTypes
|
||||
} from "../../apiRequests/productType";
|
||||
import { deleteAttributesStartsWith } from "../attributes.js/attributeUtils";
|
||||
import { deleteAttributesStartsWith } from "../attributes/attributeUtils";
|
||||
|
||||
export function createProductInChannel({
|
||||
name,
|
||||
|
|
|
@ -27,6 +27,7 @@ export interface AutocompleteSelectMenuProps {
|
|||
loading: boolean;
|
||||
name: string;
|
||||
options: IMenu;
|
||||
testIds?: string[];
|
||||
placeholder: string;
|
||||
onChange: (event: React.ChangeEvent<any>) => void;
|
||||
onInputChange?: (value: string) => void;
|
||||
|
@ -72,6 +73,7 @@ const AutocompleteSelectMenu: React.FC<AutocompleteSelectMenuProps> = props => {
|
|||
loading,
|
||||
name,
|
||||
options,
|
||||
testIds,
|
||||
placeholder,
|
||||
onChange,
|
||||
onInputChange
|
||||
|
@ -110,7 +112,10 @@ const AutocompleteSelectMenu: React.FC<AutocompleteSelectMenuProps> = props => {
|
|||
onSelect={handleChange}
|
||||
>
|
||||
{({ getItemProps, isOpen, openMenu, closeMenu, selectItem }) => (
|
||||
<div className={classes.container}>
|
||||
<div
|
||||
className={classes.container}
|
||||
data-test-id="containerAutocompleteSelect"
|
||||
>
|
||||
<TextField
|
||||
InputProps={{
|
||||
endAdornment: loading && <CircularProgress size={16} />,
|
||||
|
@ -157,6 +162,7 @@ const AutocompleteSelectMenu: React.FC<AutocompleteSelectMenuProps> = props => {
|
|||
: options
|
||||
).map((suggestion, index) => (
|
||||
<MenuItem
|
||||
data-test-id={testIds[index]}
|
||||
key={suggestion.value}
|
||||
component="div"
|
||||
{...getItemProps({ item: suggestion })}
|
||||
|
|
|
@ -82,6 +82,7 @@ const MenuCreateDialog: React.FC<MenuCreateDialogProps> = ({
|
|||
color="primary"
|
||||
variant="contained"
|
||||
onClick={submit}
|
||||
data-test="submit"
|
||||
>
|
||||
<FormattedMessage {...buttonMessages.save} />
|
||||
</ConfirmButton>
|
||||
|
|
|
@ -116,6 +116,7 @@ const MenuItemDialog: React.FC<MenuItemDialogProps> = ({
|
|||
|
||||
const mutationErrors = errors.filter(err => err.field === null);
|
||||
const formErrors = getFormErrors(["name"], errors);
|
||||
const testIds = ["category", "collection", "page", "url"];
|
||||
const idError = ["category", "collection", "page", "url"]
|
||||
.map(field => getFieldError(errors, field))
|
||||
.reduce((acc, err) => acc || err);
|
||||
|
@ -270,6 +271,7 @@ const MenuItemDialog: React.FC<MenuItemDialogProps> = ({
|
|||
displayValue={displayValue}
|
||||
loading={loading}
|
||||
options={options}
|
||||
testIds={testIds}
|
||||
error={!!idError}
|
||||
helperText={getMenuErrorMessage(idError, intl)}
|
||||
placeholder={intl.formatMessage({
|
||||
|
@ -294,6 +296,7 @@ const MenuItemDialog: React.FC<MenuItemDialogProps> = ({
|
|||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<ConfirmButton
|
||||
data-test="submit"
|
||||
transitionState={confirmButtonState}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
|
|
|
@ -273,7 +273,11 @@ const MenuItems: React.FC<MenuItemsProps> = props => {
|
|||
)}
|
||||
</div>
|
||||
<CardActions className={classes.actions}>
|
||||
<Button color="primary" onClick={onItemAdd}>
|
||||
<Button
|
||||
color="primary"
|
||||
onClick={onItemAdd}
|
||||
data-test-id="createNewMenuItem"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create new item"
|
||||
description="add new menu item"
|
||||
|
|
|
@ -32,7 +32,12 @@ const MenuListPage: React.FC<MenuListPageProps> = ({
|
|||
{intl.formatMessage(sectionNames.configuration)}
|
||||
</AppHeader>
|
||||
<PageHeader title={intl.formatMessage(sectionNames.navigation)}>
|
||||
<Button color="primary" variant="contained" onClick={onAdd}>
|
||||
<Button
|
||||
color="primary"
|
||||
variant="contained"
|
||||
onClick={onAdd}
|
||||
data-test-id="addMenu"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Create Menu"
|
||||
description="button"
|
||||
|
|
|
@ -3644,6 +3644,7 @@ exports[`Storyshots Generics / Autocomplete Menu default 1`] = `
|
|||
>
|
||||
<div
|
||||
class="AutocompleteSelectMenu-container-id"
|
||||
data-test-id="containerAutocompleteSelect"
|
||||
>
|
||||
<div
|
||||
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
|
||||
|
@ -3697,6 +3698,7 @@ exports[`Storyshots Generics / Autocomplete Menu error 1`] = `
|
|||
>
|
||||
<div
|
||||
class="AutocompleteSelectMenu-container-id"
|
||||
data-test-id="containerAutocompleteSelect"
|
||||
>
|
||||
<div
|
||||
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
|
||||
|
@ -3756,6 +3758,7 @@ exports[`Storyshots Generics / Autocomplete Menu interactive 1`] = `
|
|||
<form>
|
||||
<div
|
||||
class="AutocompleteSelectMenu-container-id"
|
||||
data-test-id="containerAutocompleteSelect"
|
||||
>
|
||||
<div
|
||||
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
|
||||
|
@ -3810,6 +3813,7 @@ exports[`Storyshots Generics / Autocomplete Menu loading 1`] = `
|
|||
>
|
||||
<div
|
||||
class="AutocompleteSelectMenu-container-id"
|
||||
data-test-id="containerAutocompleteSelect"
|
||||
>
|
||||
<div
|
||||
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
|
||||
|
@ -109180,6 +109184,7 @@ exports[`Storyshots Views / Navigation / Menu details default 1`] = `
|
|||
>
|
||||
<button
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
|
||||
data-test-id="createNewMenuItem"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
|
@ -109925,6 +109930,7 @@ exports[`Storyshots Views / Navigation / Menu details form errors 1`] = `
|
|||
>
|
||||
<button
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
|
||||
data-test-id="createNewMenuItem"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
|
@ -110080,6 +110086,7 @@ exports[`Storyshots Views / Navigation / Menu details loading 1`] = `
|
|||
>
|
||||
<button
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
|
||||
data-test-id="createNewMenuItem"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
|
@ -110243,6 +110250,7 @@ exports[`Storyshots Views / Navigation / Menu details no data 1`] = `
|
|||
>
|
||||
<button
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-text-id MuiButton-textPrimary-id"
|
||||
data-test-id="createNewMenuItem"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
|
@ -110285,6 +110293,7 @@ exports[`Storyshots Views / Navigation / Menu list default 1`] = `
|
|||
>
|
||||
<button
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
|
||||
data-test-id="addMenu"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
|
@ -110679,6 +110688,7 @@ exports[`Storyshots Views / Navigation / Menu list loading 1`] = `
|
|||
>
|
||||
<button
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
|
||||
data-test-id="addMenu"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
|
@ -111018,6 +111028,7 @@ exports[`Storyshots Views / Navigation / Menu list no data 1`] = `
|
|||
>
|
||||
<button
|
||||
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
|
||||
data-test-id="addMenu"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
|
|
Loading…
Reference in a new issue