mirror of
https://github.com/strapi/strapi.git
synced 2025-06-27 00:41:25 +00:00
Add cypress in monorepo and split by package
This commit is contained in:
parent
efd1ed4a05
commit
d98db6415b
2
.gitignore
vendored
2
.gitignore
vendored
@ -103,6 +103,8 @@ package-lock.json
|
||||
|
||||
testApp
|
||||
coverage
|
||||
cypress/screenshots
|
||||
cypress/videos
|
||||
|
||||
|
||||
############################
|
||||
|
11
cypress.json
Normal file
11
cypress.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"chromeWebSecurity": false,
|
||||
"backendUrl": "http://localhost:1337",
|
||||
"baseUrl": "http://localhost:1337",
|
||||
"frontLoadingDelay": 3000,
|
||||
"animDelay": 1000,
|
||||
"serverRestartDelay": 11000,
|
||||
"viewportHeight": 900,
|
||||
"viewportWidth": 1440,
|
||||
"integrationFolder": "./packages"
|
||||
}
|
23
cypress/fixtures/api/category.json
Normal file
23
cypress/fixtures/api/category.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "category",
|
||||
"description": "",
|
||||
"connection": "default",
|
||||
"attributes": [
|
||||
{
|
||||
"name": "name",
|
||||
"params": {
|
||||
"required": true,
|
||||
"unique": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "products",
|
||||
"params": {
|
||||
"key": "category",
|
||||
"nature": "oneToMany",
|
||||
"target": "product"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
59
cypress/fixtures/api/product.json
Normal file
59
cypress/fixtures/api/product.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "product",
|
||||
"description": "",
|
||||
"connection": "default",
|
||||
"attributes": [
|
||||
{
|
||||
"name": "name",
|
||||
"params": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"params": {
|
||||
"type": "text",
|
||||
"appearance": {
|
||||
"WYSIWYG": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "price",
|
||||
"params": {
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "bool",
|
||||
"params": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "bool1",
|
||||
"params": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"params": {
|
||||
"type": "email"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"params": {
|
||||
"dominant": true,
|
||||
"key": "products",
|
||||
"nature": "manyToMany",
|
||||
"target": "tag"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
14
cypress/fixtures/api/tag.json
Normal file
14
cypress/fixtures/api/tag.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "tag",
|
||||
"description": "",
|
||||
"connection": "default",
|
||||
"attributes": [
|
||||
{
|
||||
"name": "name",
|
||||
"params": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
17
cypress/fixtures/seeds/category.json
Normal file
17
cypress/fixtures/seeds/category.json
Normal file
@ -0,0 +1,17 @@
|
||||
[
|
||||
{
|
||||
"name": "cat1"
|
||||
},
|
||||
{
|
||||
"name": "cat2"
|
||||
},
|
||||
{
|
||||
"name": "cat3"
|
||||
},
|
||||
{
|
||||
"name": "drinks"
|
||||
},
|
||||
{
|
||||
"name": "french food"
|
||||
}
|
||||
]
|
18
cypress/fixtures/seeds/product.json
Normal file
18
cypress/fixtures/seeds/product.json
Normal file
@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"name": "name",
|
||||
"description": "This is a super description",
|
||||
"price": 1337,
|
||||
"bool": true,
|
||||
"bool1": false,
|
||||
"email": "hi@strapi.io"
|
||||
},
|
||||
{
|
||||
"name": "name1",
|
||||
"description": "This description is not cool",
|
||||
"price": 4000,
|
||||
"bool": false,
|
||||
"bool1": true,
|
||||
"email": "yo@strapi.io"
|
||||
}
|
||||
]
|
14
cypress/fixtures/seeds/tag.json
Normal file
14
cypress/fixtures/seeds/tag.json
Normal file
@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"name": "tag1"
|
||||
},
|
||||
{
|
||||
"name": "tag2"
|
||||
},
|
||||
{
|
||||
"name": "tag3"
|
||||
},
|
||||
{
|
||||
"name": "special tag"
|
||||
}
|
||||
]
|
17
cypress/plugins/index.js
Normal file
17
cypress/plugins/index.js
Normal file
@ -0,0 +1,17 @@
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
}
|
184
cypress/support/commands.js
Normal file
184
cypress/support/commands.js
Normal file
@ -0,0 +1,184 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add("login", (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
const stringify = JSON.stringify;
|
||||
const backendUrl = Cypress.config('backendUrl');
|
||||
const serverRestartDelay = Cypress.config('serverRestartDelay');
|
||||
|
||||
Cypress.Commands.add('createUser', () => {
|
||||
const user = {
|
||||
username: 'soup',
|
||||
email: 'hi@strapi.io',
|
||||
password: 'coucou123',
|
||||
};
|
||||
|
||||
return cy.request({ url: `${backendUrl}/users-permissions/init`, method: 'GET' })
|
||||
.then(response => {
|
||||
const { body: { hasAdmin } } = response;
|
||||
|
||||
if (!hasAdmin) {
|
||||
// Create one
|
||||
cy.request({ url: `${backendUrl}/auth/local/register`, method: 'POST', body: user });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('checkModalOpening', () => {
|
||||
return cy.get('.modal').invoke('show');
|
||||
})
|
||||
|
||||
Cypress.Commands.add('deleteUser', (id, jwt) => {
|
||||
cy.request({
|
||||
url: `${backendUrl}/users/${id}`,
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('createProductAndTagApis', (jwt = null) => {
|
||||
return cy
|
||||
.fixture('api/tag.json')
|
||||
.then(body => {
|
||||
return cy.request({
|
||||
url: `${backendUrl}/content-type-builder/models`,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`
|
||||
},
|
||||
body,
|
||||
})
|
||||
.wait(serverRestartDelay)
|
||||
.fixture('api/product.json')
|
||||
.then(body => {
|
||||
return cy.request({
|
||||
url: `${backendUrl}/content-type-builder/models`,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`
|
||||
},
|
||||
body,
|
||||
})
|
||||
.wait(serverRestartDelay);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('createCTMApis', (jwt = null) => {
|
||||
return cy
|
||||
.createProductAndTagApis(jwt)
|
||||
.wait(serverRestartDelay)
|
||||
.fixture('api/category.json')
|
||||
.then(body => {
|
||||
return cy
|
||||
.request({
|
||||
url: `${backendUrl}/content-type-builder/models`,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
},
|
||||
body,
|
||||
})
|
||||
.wait(serverRestartDelay);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('deleteAllModelData', (model, jwt, source = null) => {
|
||||
// GET all data;
|
||||
cy.request({
|
||||
url: `${backendUrl}/content-manager/explorer/${model}`,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
},
|
||||
})
|
||||
.then(data => {
|
||||
const entriesToDelete = data.body.reduce((acc, curr) => {
|
||||
return acc.concat(curr.id);
|
||||
}, []);
|
||||
|
||||
const qs = Object.assign(entriesToDelete, source ? { source } : {});
|
||||
|
||||
return cy.request({
|
||||
url: `${backendUrl}/content-manager/explorer/deleteAll/${model}`,
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
},
|
||||
qs,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('deleteApi', (model, jwt) => {
|
||||
return cy.request({
|
||||
url: `${backendUrl}/content-type-builder/models/${model}`,
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`
|
||||
},
|
||||
})
|
||||
.wait(serverRestartDelay);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('login', () => {
|
||||
cy.createUser()
|
||||
return cy.request({
|
||||
url: `${backendUrl}/auth/local`,
|
||||
method: 'POST',
|
||||
body: {
|
||||
identifier: 'soup',
|
||||
password: 'coucou123',
|
||||
},
|
||||
})
|
||||
.then(response => {
|
||||
window.localStorage.setItem('jwtToken', stringify(response.body.jwt));
|
||||
window.localStorage.setItem('userInfo', stringify(response.body.user));
|
||||
|
||||
return response.body;
|
||||
})
|
||||
});
|
||||
|
||||
Cypress.Commands.add('seedData', (model, jwt, source = null) => {
|
||||
return cy
|
||||
.fixture(`seeds/${model}.json`)
|
||||
.then(seed => {
|
||||
seed.forEach(body => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `${backendUrl}/content-manager/explorer/${model}?source='content-manager`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
},
|
||||
body,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('submitForm', () => {
|
||||
return cy.get('form').submit();
|
||||
});
|
33
cypress/support/index.js
Normal file
33
cypress/support/index.js
Normal file
@ -0,0 +1,33 @@
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
|
||||
// Temporary workaround for fetch see: https://github.com/cypress-io/cypress/issues/95
|
||||
Cypress.on('window:before:load', win => {
|
||||
win.fetch = null;
|
||||
});
|
||||
|
||||
Cypress.on('before:browser:launch', (browser = {}, args) => {
|
||||
if (browser.name === 'chrome') {
|
||||
args.push('--disable-site-isolation-trials');
|
||||
|
||||
return args
|
||||
}
|
||||
})
|
@ -1,7 +1,9 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "3.0.0-alpha.14.5",
|
||||
"dependencies": {},
|
||||
"dependencies": {
|
||||
"cypress": "^3.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"assert": "~1.3.0",
|
||||
"axios": "^0.18.0",
|
||||
|
@ -0,0 +1,443 @@
|
||||
let jwt;
|
||||
let userId;
|
||||
const animDelay = Cypress.config('animDelay');
|
||||
const frontEndUrl = Cypress.config('baseUrl');
|
||||
const frontLoadingDelay = Cypress.config('frontLoadingDelay');
|
||||
const backendUrl = Cypress.config('backendUrl');
|
||||
const pluginUrl = `${frontEndUrl}/admin/plugins/content-manager`;
|
||||
const getCreateRedirectUrl = (model, sort = '_id') => {
|
||||
return `${frontEndUrl}/admin/plugins/content-manager/${model}/create?redirectUrl=/plugins/content-manager/${model}?_limit=10&_page=1&_sort=${sort}&source=content-manager`;
|
||||
};
|
||||
const getRequest = (model, sort = '_id') => {
|
||||
return `${backendUrl}/content-manager/explorer/${model}?_limit=10&_start=0&_sort=${sort}:ASC&source=content-manager`;
|
||||
};
|
||||
|
||||
describe('Testing Content Manager createPages', function() {
|
||||
before(() => {
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
|
||||
return cy
|
||||
.createCTMApis(data.jwt)
|
||||
.then(() => jwt);
|
||||
})
|
||||
.wait(1000);
|
||||
|
||||
Cypress.Commands.add('ctmTagLink', () => {
|
||||
return cy.get('a[href="/admin/plugins/content-manager/tag?source=content-manager"]');
|
||||
});
|
||||
Cypress.Commands.add('ctmProductLink', () => {
|
||||
return cy.get('a[href="/admin/plugins/content-manager/product?source=content-manager"]');
|
||||
});
|
||||
Cypress.Commands.add('ctmCategoryLink', () => {
|
||||
return cy.get('a[href="/admin/plugins/content-manager/category?source=content-manager"]');
|
||||
});
|
||||
Cypress.Commands.add('ctmAddButton', () => {
|
||||
return cy.get('button#addEntry');
|
||||
});
|
||||
Cypress.Commands.add('inputError', (name) => {
|
||||
return cy.get(`#errorOf${name} > span`);
|
||||
});
|
||||
Cypress.Commands.add('getListTagsOrderedByName', () => {
|
||||
return cy.ctmTagLink()
|
||||
.click()
|
||||
.get('tr > th:nth-child(3) > span')
|
||||
.click();
|
||||
});
|
||||
Cypress.Commands.add('fillProductForm', (product) => {
|
||||
Object.keys(product)
|
||||
.forEach(key => {
|
||||
if (key === 'description') {
|
||||
cy.get(`textarea[name="${key}"]`)
|
||||
.type(product[key]);
|
||||
} else {
|
||||
cy.get(`input[name="${key}"]`)
|
||||
.type(product[key]);
|
||||
}
|
||||
})
|
||||
});
|
||||
Cypress.Commands.add('getProduct', (index) => {
|
||||
return cy
|
||||
.ctmProductLink()
|
||||
.click()
|
||||
.wait(1000)
|
||||
.get(`tbody > tr:nth-child(${index})`)
|
||||
.click()
|
||||
.wait(1000)
|
||||
.window()
|
||||
.its('__store__')
|
||||
.its('content-manager')
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.deleteApi('tag', jwt)
|
||||
.deleteApi('category', jwt)
|
||||
.deleteApi('product', jwt)
|
||||
.wait(11000);
|
||||
});
|
||||
|
||||
context('Creating data with no relation', () => {
|
||||
beforeEach(() => {
|
||||
cy.server();
|
||||
cy.route(`${backendUrl}/content-manager/models`).as('initContentManager');
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
userId = data.user._id || data.user.id;
|
||||
})
|
||||
.visit('/admin')
|
||||
.wait(frontLoadingDelay)
|
||||
.wait('@initContentManager');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.deleteAllModelData('tag', jwt)
|
||||
.deleteAllModelData('category', jwt)
|
||||
.deleteAllModelData('product', jwt);
|
||||
});
|
||||
|
||||
it('Should create a tag with no relation', () => {
|
||||
cy.server();
|
||||
cy.route(getRequest('tag')).as('getTags');
|
||||
cy.ctmTagLink()
|
||||
.click()
|
||||
.ctmAddButton()
|
||||
.click();
|
||||
const tagsToCreate = ['tag1', 'tag2', 'tag3', 'superTag', 'badTag', 'I\'m running out of idea tag'];
|
||||
// Check redirect url
|
||||
cy.url()
|
||||
.should('equal', getCreateRedirectUrl('tag'));
|
||||
|
||||
// Try to save empty data
|
||||
cy.submitForm()
|
||||
.get('input#name')
|
||||
.invoke('attr', 'class')
|
||||
.should('include', 'form-control is-invalid');
|
||||
|
||||
tagsToCreate.forEach((tagName, index) => {
|
||||
cy.get('input#name')
|
||||
.type(tagName)
|
||||
.submitForm()
|
||||
.wait('@getTags')
|
||||
.get('tbody')
|
||||
.children()
|
||||
.should('have.length', index + 1);
|
||||
|
||||
if (index < tagsToCreate.length -1) {
|
||||
cy.ctmAddButton()
|
||||
.click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('Should create a category with no relation', () => {
|
||||
cy.server();
|
||||
cy.route(getRequest('category', 'name')).as('getCategories');
|
||||
cy.ctmCategoryLink()
|
||||
.click()
|
||||
.get('tr > th:nth-child(3) > span')
|
||||
.click()
|
||||
.ctmAddButton()
|
||||
.click();
|
||||
const catsToCreate = ['drinks', 'food', 'junk food', 'french food', 'good french food', 'greasy', 'you don\'t want to eat that'];
|
||||
// Check redirect url
|
||||
cy.url()
|
||||
.should('equal', getCreateRedirectUrl('category', 'name'));
|
||||
|
||||
catsToCreate.forEach((catName, index) => {
|
||||
cy.get('input#name')
|
||||
.type(catName)
|
||||
.submitForm()
|
||||
.wait('@getCategories')
|
||||
.get('tbody')
|
||||
.children()
|
||||
.should('have.length', index + 1);
|
||||
|
||||
if (index < catsToCreate.length -1) {
|
||||
cy.ctmAddButton()
|
||||
.click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('Should display an error for unique fields for categories', () => {
|
||||
cy.ctmCategoryLink()
|
||||
.click()
|
||||
.ctmAddButton()
|
||||
.click()
|
||||
.get('input#name')
|
||||
.type('drinks')
|
||||
.submitForm()
|
||||
.get('input#name')
|
||||
.invoke('attr', 'class')
|
||||
.should('includes', 'form-control is-invalid')
|
||||
.get('input#name')
|
||||
.inputError('name')
|
||||
.should('have.text', 'This name is already taken ');
|
||||
});
|
||||
|
||||
it('Should delete all data using the UI', () => {
|
||||
cy.server();
|
||||
cy.route(getRequest('tag')).as('getTags');
|
||||
cy.route(getRequest('category', 'name')).as('getCategories');
|
||||
|
||||
cy.ctmTagLink()
|
||||
.click()
|
||||
.wait('@getTags')
|
||||
.wait(1000)
|
||||
.get('thead > tr > th:first-child')
|
||||
.click()
|
||||
.get('span#deleteAllData')
|
||||
.click()
|
||||
.get('button#ctaConfirm')
|
||||
.click()
|
||||
.wait(2000)
|
||||
.window()
|
||||
.its('__store__')
|
||||
.its('content-manager')
|
||||
.then(pluginStore => {
|
||||
const records = pluginStore
|
||||
.getState()
|
||||
.getIn(['listPage', 'records', 'tag'])
|
||||
.toJS();
|
||||
|
||||
expect(records).to.have.length(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Creating and updating data with relation', () => {
|
||||
before(() => {
|
||||
cy.server();
|
||||
cy.route(`${backendUrl}/content-manager/models`).as('initContentManager');
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
userId = data.user._id || data.user.id;
|
||||
|
||||
return data.jwt;
|
||||
})
|
||||
.then(jwt => {
|
||||
return cy.seedData('tag', jwt)
|
||||
.then(() => jwt);
|
||||
|
||||
})
|
||||
.then(jwt => {
|
||||
return cy.seedData('category', jwt);
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.server();
|
||||
cy.route(`${backendUrl}/content-manager/models`).as('initContentManager');
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
userId = data.user._id || data.user.id;
|
||||
|
||||
return data.jwt;
|
||||
})
|
||||
.visit('/admin')
|
||||
.wait(frontLoadingDelay)
|
||||
.wait('@initContentManager');
|
||||
})
|
||||
|
||||
it('Should create a product and link several tags and 1 category', () => {
|
||||
cy.server();
|
||||
cy.route(`${backendUrl}/content-manager/explorer/tag?_limit=10&_start=0&_sort=name:ASC&source=content-manager`).as('getTags');
|
||||
cy.ctmProductLink()
|
||||
.click()
|
||||
.ctmAddButton()
|
||||
.click();
|
||||
|
||||
// Test default value
|
||||
cy.get('button#__OFF__bool')
|
||||
.invoke('attr', 'class')
|
||||
.should('includes', 'gradientOff')
|
||||
.get('button#__ON__bool1')
|
||||
.invoke('attr', 'class')
|
||||
.should('includes', 'gradientOn');
|
||||
|
||||
// Create a product
|
||||
const product = {
|
||||
name: 'product1',
|
||||
description: 'This is a super description',
|
||||
price: 1337,
|
||||
email: 'hi@strapi.io',
|
||||
};
|
||||
|
||||
Object.keys(product)
|
||||
.forEach(key => {
|
||||
if (key === 'description') {
|
||||
cy.get(`textarea[name="${key}"]`)
|
||||
.type(product[key]);
|
||||
} else {
|
||||
cy.get(`input[name="${key}"]`)
|
||||
.type(product[key]);
|
||||
}
|
||||
});
|
||||
|
||||
cy.get('button#__ON__bool')
|
||||
.click()
|
||||
.get('button#__OFF__bool1')
|
||||
.click();
|
||||
|
||||
cy.get('input#tags')
|
||||
.type('special t', { force: true })
|
||||
.type('{enter}', { force: true })
|
||||
.type('ta', { force: true })
|
||||
.type('{enter}', { force: true })
|
||||
.get('ul#sortableListOftags')
|
||||
.children('li')
|
||||
.should((children) => {
|
||||
expect(children[0].innerText.trim()).to.equal('special tag');
|
||||
expect(children[1].innerText.trim()).to.equal('tag1');
|
||||
})
|
||||
.get('input#category')
|
||||
.type('french food', { force: true })
|
||||
.type('{enter}')
|
||||
.invoke('attr', 'value')
|
||||
.should('equal', 'french food')
|
||||
.submitForm();
|
||||
|
||||
cy.getListTagsOrderedByName()
|
||||
.wait('@getTags')
|
||||
.wait(1000)
|
||||
.get('tbody > tr:first-child')
|
||||
.click()
|
||||
.get('ul#sortableListOfproducts')
|
||||
.children()
|
||||
.should((children) => {
|
||||
expect(children).to.have.length(1);
|
||||
expect(children[0].innerText.trim()).to.equal('product1');
|
||||
});
|
||||
|
||||
cy.getListTagsOrderedByName()
|
||||
.wait('@getTags')
|
||||
.wait(2000)
|
||||
.get('tbody > tr:nth-child(2)')
|
||||
.click()
|
||||
.get('ul#sortableListOfproducts')
|
||||
.children()
|
||||
.should((children) => {
|
||||
expect(children).to.have.length(1);
|
||||
expect(children[0].innerText.trim()).to.equal('product1');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should delete a product in tag1', () => {
|
||||
cy.getListTagsOrderedByName()
|
||||
.wait(frontLoadingDelay)
|
||||
.get('tbody > tr:nth-child(2)')
|
||||
.click()
|
||||
.wait(1000)
|
||||
.get('ul#sortableListOfproducts > li:nth-child(1) > div:nth-child(2)')
|
||||
.click()
|
||||
.submitForm()
|
||||
.ctmProductLink()
|
||||
.click()
|
||||
.wait(1000)
|
||||
.get('tbody > tr:nth-child(1)')
|
||||
.click()
|
||||
.wait(frontLoadingDelay)
|
||||
.get('ul#sortableListOftags')
|
||||
.children()
|
||||
.should((children) => {
|
||||
expect(children).to.have.length(1);
|
||||
expect(children[0].innerText.trim()).to.equal('special tag');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should add several products to category french food', () => {
|
||||
cy.server();
|
||||
cy.route(`${backendUrl}/content-manager/explorer/category?_limit=10&_start=0&_sort=_id:ASC&source=content-manager`).as('getCategories');
|
||||
cy.route(`${backendUrl}/content-manager/explorer/product?_limit=10&_start=0&_sort=_id:ASC&source=content-manager`).as('getProducts');
|
||||
const product = {
|
||||
name: 'MacBook',
|
||||
description: 'A laptop',
|
||||
price: 2000,
|
||||
email: 'john@strapi.io',
|
||||
};
|
||||
const product2 = {
|
||||
name: 'Dell',
|
||||
description: 'Not a mac',
|
||||
price: 4,
|
||||
email: 'bob@strapi.io',
|
||||
};
|
||||
|
||||
cy.ctmProductLink()
|
||||
.click()
|
||||
.ctmAddButton()
|
||||
.click();
|
||||
|
||||
cy.fillProductForm(product)
|
||||
.submitForm()
|
||||
.ctmAddButton()
|
||||
.click()
|
||||
.fillProductForm(product2)
|
||||
.submitForm();
|
||||
|
||||
cy.ctmCategoryLink()
|
||||
.click()
|
||||
.wait('@getCategories')
|
||||
.wait(1000)
|
||||
.get('tbody > tr:nth-child(5)')
|
||||
.click()
|
||||
.get('ul#sortableListOfproducts').as('relations')
|
||||
.children()
|
||||
.should(children => {
|
||||
expect(children).to.have.length(1);
|
||||
expect(children[0].innerText.trim()).to.equal('product1');
|
||||
})
|
||||
.get('ul#sortableListOfproducts > li:nth-child(1) > div:nth-child(2)')
|
||||
.click()
|
||||
.get('input#products')
|
||||
.type('mac', { force: true })
|
||||
.type('{enter}', { force: true })
|
||||
.type('dell', { force: true })
|
||||
.type('{enter}', { force: true })
|
||||
.get('@relations')
|
||||
.children()
|
||||
.should(children => {
|
||||
expect(children).to.have.length(2);
|
||||
expect(children[0].innerText.trim()).to.equal('MacBook');
|
||||
expect(children[1].innerText.trim()).to.equal('Dell');
|
||||
})
|
||||
.submitForm();
|
||||
|
||||
cy.getProduct(1)
|
||||
.then(pluginStore => {
|
||||
const category = pluginStore
|
||||
.getState()
|
||||
.getIn(['editPage', 'record', 'category'])
|
||||
|
||||
expect(category).to.equal(null);
|
||||
});
|
||||
|
||||
cy.getProduct(2)
|
||||
.then(pluginStore => {
|
||||
const category = pluginStore
|
||||
.getState()
|
||||
.getIn(['editPage', 'record', 'category', 'name'])
|
||||
|
||||
expect(category).to.equal('french food');
|
||||
})
|
||||
.getProduct(3)
|
||||
.then(pluginStore => {
|
||||
const category = pluginStore
|
||||
.getState()
|
||||
.getIn(['editPage', 'record', 'category', 'name'])
|
||||
|
||||
expect(category).to.equal('french food');
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.deleteAllModelData('tag', jwt)
|
||||
.deleteAllModelData('category', jwt)
|
||||
.deleteAllModelData('product', jwt);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,104 @@
|
||||
let jwt;
|
||||
let userId;
|
||||
const animDelay = Cypress.config('animDelay');
|
||||
const backendUrl = Cypress.config('backendUrl');
|
||||
const frontEndUrl = Cypress.config('baseUrl');
|
||||
const frontLoadingDelay = Cypress.config('frontLoadingDelay');
|
||||
const links = {
|
||||
Category: '/admin/plugins/content-manager/category?source=content-manager',
|
||||
Product: '/admin/plugins/content-manager/product?source=content-manager',
|
||||
settings: '/admin/plugins/content-manager/ctm-configurations',
|
||||
Tag: '/admin/plugins/content-manager/tag?source=content-manager',
|
||||
User: '/admin/plugins/content-manager/user?source=users-permissions',
|
||||
};
|
||||
const pluginUrl = `${frontEndUrl}/admin/plugins/content-manager`;
|
||||
|
||||
describe('Testing build and schema core_store', () => {
|
||||
before(() => {
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
return cy.createCTMApis(data.jwt);
|
||||
})
|
||||
.wait(1000);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.deleteApi('tag', jwt)
|
||||
.deleteApi('category', jwt)
|
||||
.deleteApi('product', jwt);
|
||||
});
|
||||
|
||||
context('Testing views', () => {
|
||||
beforeEach(() => {
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
userId = data.user._id || data.user.id;
|
||||
})
|
||||
.visit('/admin')
|
||||
.wait(frontLoadingDelay);
|
||||
});
|
||||
|
||||
it('Should visit all list pages without any errors', () => {
|
||||
cy.server();
|
||||
cy.route(`${backendUrl}/content-manager/models`).as('initCTM');
|
||||
cy.get(`a[href="${links.settings}"]`)
|
||||
.click()
|
||||
.wait('@initCTM');
|
||||
|
||||
// Check all list views are rendered without any error
|
||||
for (let i = 0; i < 4; i++) {
|
||||
Object.keys(links).forEach(link => {
|
||||
const name = link === 'settings' ? 'Content Manager' : link;
|
||||
|
||||
cy.get(`a[href="${links[link]}"]`)
|
||||
.click()
|
||||
.get('h1')
|
||||
.should('have', name);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
it('Should visit all views once without any errors', () => {
|
||||
cy.server();
|
||||
cy.route(`${backendUrl}/content-manager/models`).as('initCTM');
|
||||
cy.get(`a[href="${links.settings}"]`)
|
||||
.click()
|
||||
.wait('@initCTM');
|
||||
|
||||
// Testing errors related to reactstrap
|
||||
cy.get('#cancelChanges')
|
||||
.click()
|
||||
.wait(animDelay)
|
||||
.checkModalOpening()
|
||||
.should('be.visible')
|
||||
.type('{esc}');
|
||||
|
||||
|
||||
// Test setting view
|
||||
Object.keys(links).forEach(link => {
|
||||
if (link !== 'settings') {
|
||||
cy.get(`#${link.toLowerCase()}`)
|
||||
.click()
|
||||
.get('h1')
|
||||
.should('have', `Content Manager - ${link}`)
|
||||
.get(`a[href="${links.settings}"]`)
|
||||
.click();
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(links).forEach(link => {
|
||||
if (link !== 'settings') {
|
||||
cy.get(`a[href="${links[link]}"]`)
|
||||
.click()
|
||||
.get('button#addEntry')
|
||||
.click()
|
||||
.get('h1')
|
||||
.should('have', 'New Entry');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,174 @@
|
||||
let jwt;
|
||||
let userId;
|
||||
const animDelay = Cypress.config('animDelay');
|
||||
const frontEndUrl = Cypress.config('baseUrl');
|
||||
const frontLoadingDelay = Cypress.config('frontLoadingDelay');
|
||||
const backendUrl = Cypress.config('backendUrl');
|
||||
const pluginUrl = `${frontEndUrl}/admin/plugins/content-manager`;
|
||||
|
||||
describe('Testing Content Manager ListPages', function() {
|
||||
before(() => {
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
|
||||
return cy
|
||||
.createCTMApis(data.jwt)
|
||||
.then(() => jwt);
|
||||
})
|
||||
.then(jwt => {
|
||||
cy.seedData('product', jwt);
|
||||
})
|
||||
.wait(1000);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.deleteAllModelData('product', jwt);
|
||||
cy.deleteApi('tag', jwt)
|
||||
.deleteApi('category', jwt)
|
||||
.deleteApi('product', jwt);
|
||||
});
|
||||
|
||||
context('Testing sorting options', () => {
|
||||
beforeEach(() => {
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
userId = data.user._id || data.user.id;
|
||||
})
|
||||
.visit('/admin')
|
||||
.wait(frontLoadingDelay);
|
||||
});
|
||||
|
||||
it('Should have the Id default sort', () => {
|
||||
cy.get(`a[href="/admin/plugins/content-manager/product?source=content-manager"]`)
|
||||
.click()
|
||||
.wait(frontLoadingDelay);
|
||||
|
||||
cy.get('tr > th:nth-child(2) > span')
|
||||
.children('i')
|
||||
.should('be.visible')
|
||||
.invoke('attr', 'class')
|
||||
.should('includes', 'fa-sort-asc');
|
||||
});
|
||||
|
||||
it('Should change the default sort of product to name ASC then name DESC', () => {
|
||||
cy.server();
|
||||
cy.route(`${backendUrl}/content-manager/explorer/product?_limit=10&_start=0&_sort=_id:ASC&source=content-manager`).as('getProduct');
|
||||
cy.route(`${backendUrl}/content-manager/explorer/product?_limit=10&_start=0&_sort=name:ASC&source=content-manager`).as('getSortByNameASC');
|
||||
cy.route(`${backendUrl}/content-manager/explorer/product?_limit=10&_start=0&_sort=name:DESC&source=content-manager`).as('getSortByNameDESC');
|
||||
|
||||
cy.get('a[href="/admin/plugins/content-manager/product?source=content-manager"]')
|
||||
.click()
|
||||
.wait('@getProduct')
|
||||
.get('tr > th:nth-child(3) > span').as('getName')
|
||||
.click();
|
||||
|
||||
cy.wait('@getSortByNameASC')
|
||||
.get('@getName')
|
||||
.children('i')
|
||||
.should('be.visible')
|
||||
.invoke('attr', 'class')
|
||||
.should('includes', 'iconAsc')
|
||||
.get('tbody > tr:nth-child(1) > td:nth-child(3)').as('firstResult')
|
||||
.should('have.text', 'name');
|
||||
|
||||
|
||||
cy.get('@getName')
|
||||
.click()
|
||||
.wait('@getSortByNameDESC')
|
||||
.get('@getName')
|
||||
.children('i')
|
||||
.should('be.visible')
|
||||
.invoke('attr', 'class')
|
||||
.should('includes', 'iconDesc')
|
||||
.get('@firstResult')
|
||||
.should('have.text', 'name1');
|
||||
});
|
||||
|
||||
it('Should set the product default sort to name', () => {
|
||||
cy.get('a[href="/admin/plugins/content-manager/ctm-configurations"]')
|
||||
.click()
|
||||
.get('#product')
|
||||
.click()
|
||||
.get('select[name="product\.defaultSort"]').as('defaultSort')
|
||||
.select('name')
|
||||
.should('have.value', 'name')
|
||||
.get('select[name="product\.sort"]').as('sortOption')
|
||||
.select('DESC')
|
||||
.should('have.value', 'DESC')
|
||||
.submitForm()
|
||||
.get('#ctaConfirm')
|
||||
.click()
|
||||
.wait(frontLoadingDelay)
|
||||
.get('a[href="/admin/plugins/content-manager/product?source=content-manager"]')
|
||||
.click()
|
||||
.wait(frontLoadingDelay)
|
||||
.get('tr > th:nth-child(3) > span').as('getName')
|
||||
.children('i')
|
||||
.invoke('attr', 'class')
|
||||
.should('includes', 'iconDesc')
|
||||
.get('tbody > tr:nth-child(1) > td:nth-child(3)')
|
||||
.should('have.text', 'name1');
|
||||
|
||||
// Set it back to normal
|
||||
cy.get('a[href="/admin/plugins/content-manager/ctm-configurations"]')
|
||||
.click()
|
||||
.get('#product')
|
||||
.click()
|
||||
.get('@defaultSort')
|
||||
.select('_id')
|
||||
.should('have.value', '_id')
|
||||
.get('@sortOption')
|
||||
.select('ASC')
|
||||
.should('have.value', 'ASC')
|
||||
.submitForm()
|
||||
.get('#ctaConfirm')
|
||||
.click()
|
||||
.wait(frontLoadingDelay)
|
||||
.get('a[href="/admin/plugins/content-manager/product?source=content-manager"]')
|
||||
.click()
|
||||
.wait(frontLoadingDelay)
|
||||
.get('tr > th:nth-child(2) > span')
|
||||
.children('i')
|
||||
.invoke('attr', 'class')
|
||||
.should('includes', 'iconAsc');
|
||||
});
|
||||
});
|
||||
|
||||
context('Testing filters', () => {
|
||||
beforeEach(() => {
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
userId = data.user._id || data.user.id;
|
||||
})
|
||||
.visit('/admin')
|
||||
.wait(frontLoadingDelay);
|
||||
});
|
||||
|
||||
it('Should apply filters for product data', () => {
|
||||
cy.get(`a[href="/admin/plugins/content-manager/product?source=content-manager"]`)
|
||||
.click()
|
||||
.wait(frontLoadingDelay);
|
||||
cy.get('button#addFilterCTA').as('toggleFilter')
|
||||
.click()
|
||||
.wait(animDelay)
|
||||
.get('div#filterPickWrapper').as('filterWrapper')
|
||||
.children('div')
|
||||
.should('have.length', 1);
|
||||
|
||||
cy.get('input[name="0\.value"]')
|
||||
.type('name')
|
||||
.get('button#newFilter')
|
||||
.click()
|
||||
.get('select[name="1\.attr"]')
|
||||
.select('bool')
|
||||
.get('button[label="content-manager.components.FiltersPickWrapper.PluginHeader.actions.apply"]')
|
||||
.click()
|
||||
.wait(animDelay)
|
||||
.get('tbody > tr')
|
||||
.should('have.length', 1);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,235 @@
|
||||
// import 'whatwg-fetch';
|
||||
|
||||
let jwt;
|
||||
let userId;
|
||||
const animDelay = Cypress.config('animDelay');
|
||||
const frontEndUrl = Cypress.config('baseUrl');
|
||||
const frontLoadingDelay = Cypress.config('frontLoadingDelay');
|
||||
const backendUrl = Cypress.config('backendUrl');
|
||||
const pluginUrl = `${frontEndUrl}/admin/plugins/content-type-builder`;
|
||||
const TAG_API = {
|
||||
name: 'tag',
|
||||
description: 'This is a super tag \nwith multi \nlines description.',
|
||||
};
|
||||
|
||||
describe('Test CTB', () => {
|
||||
context('Check create and update API', () => {
|
||||
beforeEach(() => {
|
||||
cy.server();
|
||||
cy.route(`${backendUrl}/content-type-builder/autoReload`).as('initContentTypeBuilder');
|
||||
cy.login()
|
||||
.then(data => {
|
||||
jwt = data.jwt;
|
||||
userId = data.user._id || data.user.id;
|
||||
});
|
||||
cy.visit('/admin');
|
||||
cy.wait(frontLoadingDelay);
|
||||
cy.wait('@initContentTypeBuilder');
|
||||
});
|
||||
|
||||
it('Should visit the content type builder', () => {
|
||||
cy.get('a[href="/admin/plugins/content-type-builder"')
|
||||
.click();
|
||||
cy.url()
|
||||
.should('equal', pluginUrl);
|
||||
});
|
||||
|
||||
it('Should prevent the user from creating a camelCase api', () => {
|
||||
cy.server();
|
||||
cy.route('GET', `${backendUrl}/content-type-builder/models`).as('models');
|
||||
|
||||
cy.get('a[href="/admin/plugins/content-type-builder"')
|
||||
.click()
|
||||
.wait('@models')
|
||||
.get('#openAddCT')
|
||||
.click()
|
||||
.get('#name')
|
||||
.type('camelCase')
|
||||
.get('#description')
|
||||
.type('\n')
|
||||
.get('#name')
|
||||
.should('have.value', 'camelcase')
|
||||
.get('#name')
|
||||
.type('{selectall}')
|
||||
.type('not camel-case')
|
||||
.get('#description')
|
||||
.type('{backspace}')
|
||||
.get('#name')
|
||||
.should('have.value', 'notcamelcase');
|
||||
});
|
||||
|
||||
it('Should create a TAG API', function() {
|
||||
cy.server();
|
||||
cy.route('GET', `${backendUrl}/content-type-builder/models`).as('models');
|
||||
cy.route('POST', `${backendUrl}/content-type-builder/models`).as('createModel');
|
||||
cy.route('DELETE', `${backendUrl}/content-type-builder/models/tag`).as('deleteTag');
|
||||
|
||||
cy.get('a[href="/admin/plugins/content-type-builder"')
|
||||
.click()
|
||||
.wait('@models');
|
||||
|
||||
// Open modal
|
||||
cy.get('#openAddCT')
|
||||
.click()
|
||||
.wait(animDelay);
|
||||
|
||||
// Check the modal is opened this will tell is if we have a build issue
|
||||
cy.checkModalOpening();
|
||||
cy.get('.modal')
|
||||
.invoke('show');
|
||||
|
||||
// Fill the form
|
||||
Object.keys(TAG_API)
|
||||
.map(key => {
|
||||
cy.log(key);
|
||||
cy.get(`#${key}`)
|
||||
.type(TAG_API[key]);
|
||||
});
|
||||
|
||||
// Submit the form and navigate to product page
|
||||
cy.submitForm()
|
||||
.url()
|
||||
.should('equal', `${pluginUrl}/models/tag`);
|
||||
|
||||
// Open the attributes's modal
|
||||
cy.get('#openAddAttr')
|
||||
.click()
|
||||
.wait(animDelay);
|
||||
|
||||
// Check that we don't have a build error from reacstrap
|
||||
cy.checkModalOpening()
|
||||
.should('be.visible');
|
||||
|
||||
// Ensure the modal is opened to get #attrCardstring
|
||||
cy.wait(1000)
|
||||
.get('button#attrCardstring')
|
||||
.click()
|
||||
.get('input[name="name"]')
|
||||
.type('name')
|
||||
.get('#continue')
|
||||
.click();
|
||||
|
||||
cy.get('button#saveData')
|
||||
.should('contain', 'Save')
|
||||
.click()
|
||||
.wait('@createModel')
|
||||
.wait(frontLoadingDelay);
|
||||
|
||||
cy.get('#attributesList li')
|
||||
.first()
|
||||
.should('contain', 'name');
|
||||
|
||||
// Delete tag API
|
||||
cy.get('a[href="/admin/plugins/content-type-builder"]')
|
||||
.click()
|
||||
.wait(frontLoadingDelay)
|
||||
.wait(frontLoadingDelay)
|
||||
.get('#deletetag')
|
||||
.click()
|
||||
.checkModalOpening()
|
||||
.should('be.visible')
|
||||
.get('#ctaConfirm')
|
||||
.click()
|
||||
.wait('@deleteTag')
|
||||
.wait(frontLoadingDelay)
|
||||
.get('#ctbModelsList li')
|
||||
.should('have.length', 4);
|
||||
});
|
||||
|
||||
it('Should update PRODUCT API field and visit the create product page', () => {
|
||||
cy.server();
|
||||
cy.createProductAndTagApis(jwt);
|
||||
cy.route(`${backendUrl}/content-type-builder/models/product?`).as('getProductModel');
|
||||
cy.route('PUT', `${backendUrl}/content-type-builder/models/product`).as('updateProductModel');
|
||||
|
||||
cy.visit('/admin/plugins/content-type-builder/models/product#editproduct::attributestring::baseSettings::0');
|
||||
cy.wait('@getProductModel');
|
||||
cy.wait(frontLoadingDelay);
|
||||
|
||||
// Open the modal via url
|
||||
cy.checkModalOpening()
|
||||
.should('be.visible')
|
||||
.get('input[name="name"]')
|
||||
.type('{selectall}')
|
||||
.type('updatedName')
|
||||
.get('#continue')
|
||||
.click();
|
||||
|
||||
cy.get('#attributesList li')
|
||||
.first()
|
||||
.should('have.text', 'updatedNameString');
|
||||
|
||||
cy.get('button#saveData')
|
||||
.click()
|
||||
.wait('@updateProductModel')
|
||||
.wait(frontLoadingDelay);
|
||||
|
||||
// Check that we can still go to the create page
|
||||
cy.get('a[href="/admin/plugins/content-manager/product?source=content-manager"')
|
||||
.click()
|
||||
.get('button[label="content-manager.containers.List.addAnEntry"')
|
||||
.click();
|
||||
|
||||
cy.window()
|
||||
.its('__store__')
|
||||
.its('content-manager')
|
||||
.then(pluginStore => {
|
||||
const displayedFields = pluginStore
|
||||
.getState()
|
||||
.getIn(['global', 'schema', 'models', 'product', 'editDisplay', 'fields'])
|
||||
.toJS();
|
||||
|
||||
expect(displayedFields).to.include.members(['description', 'price', 'updatedName', 'bool', 'bool1', 'email']);
|
||||
});
|
||||
});
|
||||
|
||||
it('Should update PRODUCT API name and visit the create product page', () => {
|
||||
cy.server();
|
||||
// cy.createProductAndTagApis(jwt);
|
||||
cy.route(`${backendUrl}/content-type-builder/models/product?`).as('getProductModel');
|
||||
cy.route('PUT', `${backendUrl}/content-type-builder/models/product`).as('updateProductModel');
|
||||
|
||||
cy.visit('/admin/plugins/content-type-builder/models/product#editproduct::contentType::baseSettings');
|
||||
cy.wait('@getProductModel');
|
||||
cy.wait(frontLoadingDelay);
|
||||
|
||||
// Open the modal via url
|
||||
cy.checkModalOpening()
|
||||
.should('be.visible')
|
||||
.get('input[name="name"]')
|
||||
.type('{selectall}')
|
||||
.type('produit')
|
||||
.submitForm()
|
||||
.wait('@updateProductModel')
|
||||
.wait(frontLoadingDelay);
|
||||
|
||||
// Check that we can still go to the create page
|
||||
cy.get('a[href="/admin/plugins/content-manager/produit?source=content-manager"')
|
||||
.click()
|
||||
.wait(frontLoadingDelay)
|
||||
.get('button[label="content-manager.containers.List.addAnEntry"')
|
||||
.click()
|
||||
.get('h1')
|
||||
.should('have', 'New Entry');
|
||||
|
||||
// cy.window()
|
||||
// .its('__store__')
|
||||
// .its('content-manager')
|
||||
// .then(pluginStore => {
|
||||
// const displayedFields = pluginStore
|
||||
// .getState()
|
||||
// .getIn(['global', 'schema', 'models', 'product', 'editDisplay', 'fields'])
|
||||
// .toJS();
|
||||
|
||||
// expect(displayedFields).to.include.members(['description', 'price', 'updatedName', 'bool', 'bool1', 'email']);
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.wait(10000)
|
||||
.deleteApi('tag', jwt)
|
||||
.deleteApi('produit', jwt)
|
||||
.deleteUser(userId, jwt);
|
||||
});
|
||||
});
|
@ -0,0 +1,49 @@
|
||||
const frontLoadingDelay = Cypress.config('frontLoadingDelay');
|
||||
const userData = {
|
||||
identifier: 'soup',
|
||||
password: 'coucou123',
|
||||
};
|
||||
|
||||
describe('Test login', () => {
|
||||
let userId;
|
||||
let jwt;
|
||||
|
||||
// Create a user if there's none
|
||||
before(() => {
|
||||
cy.createUser();
|
||||
});
|
||||
|
||||
// Delete the user to test other features
|
||||
after(() => {
|
||||
if (userId) {
|
||||
cy.deleteUser(userId, jwt);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('Should login the user', () => {
|
||||
cy.visit('/admin/users-permissions/auth/login')
|
||||
.wait(frontLoadingDelay);
|
||||
|
||||
Object
|
||||
.keys(userData)
|
||||
.map(key => {
|
||||
return cy
|
||||
.get(`#${key}`)
|
||||
.type(userData[key]);
|
||||
});
|
||||
|
||||
cy.submitForm()
|
||||
.window()
|
||||
.should(win => {
|
||||
const userInfo = JSON.parse(win.localStorage.getItem('userInfo'));
|
||||
|
||||
jwt = JSON.parse(win.localStorage.getItem('jwtToken'));
|
||||
userId = userInfo._id || userInfo.id;
|
||||
expect(win.localStorage.getItem('jwtToken')).to.be.ok;
|
||||
});
|
||||
|
||||
cy.url()
|
||||
.should('equal', `${Cypress.config('baseUrl')}/admin/`);
|
||||
});
|
||||
});
|
@ -0,0 +1,56 @@
|
||||
const frontLoadingDelay = Cypress.config('frontLoadingDelay');
|
||||
const registerData = {
|
||||
username: 'soup',
|
||||
email: 'hi@strapi.io',
|
||||
password: 'coucou123',
|
||||
confirmPassword: 'coucou123',
|
||||
};
|
||||
let jwt;
|
||||
let userId;
|
||||
const frontEndUrl = Cypress.config('baseUrl');
|
||||
|
||||
describe('Test register page', () => {
|
||||
after(() => {
|
||||
if (userId) {
|
||||
cy.deleteUser(userId, jwt);
|
||||
}
|
||||
})
|
||||
|
||||
it('Visits /admin and should be redirected to register page', () => {
|
||||
cy.visit('/admin')
|
||||
.wait(frontLoadingDelay);
|
||||
|
||||
// Check if the user is being redirected to /register
|
||||
cy.url()
|
||||
.should('include', '/users-permissions/auth/register');
|
||||
});
|
||||
|
||||
it('Should redirect to /register when trying to hit /login', () => {
|
||||
cy.visit('/admin/plugins/users-permissions/auth/login')
|
||||
.wait(frontLoadingDelay);
|
||||
|
||||
cy.url()
|
||||
.should('include', '/users-permissions/auth/register');
|
||||
});
|
||||
|
||||
it('Should register the admin user', () => {
|
||||
Object.keys(registerData).map(key => {
|
||||
return cy
|
||||
.get(`#${key}`)
|
||||
.type(registerData[key]);
|
||||
});
|
||||
|
||||
// Submit form
|
||||
cy.submitForm()
|
||||
.window()
|
||||
.should(win => {
|
||||
const userInfo = JSON.parse(win.sessionStorage.getItem('userInfo'));
|
||||
|
||||
jwt = JSON.parse(win.sessionStorage.getItem('jwtToken'));
|
||||
userId = userInfo._id || userInfo.id;
|
||||
expect(win.sessionStorage.getItem('jwtToken')).to.be.ok;
|
||||
});
|
||||
cy.url()
|
||||
.should('equal', `${frontEndUrl}/admin/`);
|
||||
});
|
||||
});
|
@ -38,6 +38,7 @@ const except = [
|
||||
'strapi-middleware-views',
|
||||
'strapi-plugin-settings-manager',
|
||||
'test',
|
||||
'cypress',
|
||||
];
|
||||
|
||||
const changedDirs = [...changedFiles]
|
||||
|
@ -2,6 +2,7 @@ const spawn = require('child_process').spawn;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const shell = require('shelljs');
|
||||
const cypress = require('cypress')
|
||||
const { deleteApp } = require('./helpers/deleteFolder');
|
||||
|
||||
const strapiBin = path.resolve('./packages/strapi/bin/strapi.js');
|
||||
@ -65,6 +66,7 @@ const main = async () => {
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
if (typeof appStart !== 'undefined') {
|
||||
process.kill(appStart.pid);
|
||||
}
|
||||
@ -73,6 +75,7 @@ const main = async () => {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const test = () => {
|
||||
return new Promise(async (resolve) => {
|
||||
// Run setup tests to generate the app.
|
||||
@ -98,12 +101,18 @@ const main = async () => {
|
||||
});
|
||||
};
|
||||
|
||||
const cypressTest = () => {
|
||||
return cypress
|
||||
.run({ spec: './packages/**/cypress/integration/*' });
|
||||
}
|
||||
|
||||
const testProcess = async (database) => {
|
||||
try {
|
||||
await clean();
|
||||
await generate(database);
|
||||
await start();
|
||||
await test();
|
||||
await cypressTest();
|
||||
// await test();
|
||||
process.kill(appStart.pid);
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
@ -114,7 +123,7 @@ const main = async () => {
|
||||
await testProcess(databases.mongo);
|
||||
// await testProcess(databases.postgres);
|
||||
// await testProcess(databases.mysql);
|
||||
process.exit(testExitCode);
|
||||
// process.exit(testExitCode);
|
||||
};
|
||||
|
||||
main();
|
||||
|
Loading…
x
Reference in New Issue
Block a user