@eeacms/volto-tableau 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ const defaultBabel = require('@plone/volto/babel');
2
2
 
3
3
  function applyDefault(api) {
4
4
  const voltoBabel = defaultBabel(api);
5
- voltoBabel.plugins.push('@babel/plugin-transform-modules-commonjs', 'transform-class-properties', 'istanbul');
5
+ voltoBabel.plugins.push('istanbul');
6
6
  return voltoBabel;
7
7
  }
8
8
 
@@ -0,0 +1 @@
1
+ module.exports = require('@plone/volto/babel');
package/CHANGELOG.md CHANGED
@@ -4,11 +4,24 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ ### [2.0.0](https://github.com/eea/volto-tableau/compare/1.3.0...2.0.0) - 31 October 2022
8
+
9
+ #### :bug: Bug Fixes
10
+
11
+ - fix(cypress): fix silly test [Nilesh - [`d53131a`](https://github.com/eea/volto-tableau/commit/d53131adc4a38252727a6202860e258fbc4d899c)]
12
+
13
+ #### :hammer_and_wrench: Others
14
+
15
+ - Update block-basics.cy.js [Nilesh - [`e4f7ca4`](https://github.com/eea/volto-tableau/commit/e4f7ca45969d379fa373bb4b88a1680945b5ca7e)]
16
+ - prepare 2.0 [Nilesh - [`e60db00`](https://github.com/eea/volto-tableau/commit/e60db002471ca193a446edbbfc3d015ad88bbc8c)]
17
+ - Update block-basics.cy.js [Nilesh - [`65b6419`](https://github.com/eea/volto-tableau/commit/65b64190af746d24e87276d397db2ad6473e9883)]
18
+ - Update commands.js [Nilesh - [`7c48437`](https://github.com/eea/volto-tableau/commit/7c4843780efb9b85a4728de73c00d831c1d8fdcf)]
19
+ - Update e2e.js [Nilesh - [`f67b45c`](https://github.com/eea/volto-tableau/commit/f67b45c170f58f8d0301192994226f173e4cb00a)]
20
+ - latest volto compatibility refs #154757 [nileshgulia1 - [`881ba48`](https://github.com/eea/volto-tableau/commit/881ba482dc9b82e7fdac16549d41e80a6d26b3de)]
7
21
  ### [1.3.0](https://github.com/eea/volto-tableau/compare/1.2.5...1.3.0) - 28 September 2022
8
22
 
9
23
  #### :hammer_and_wrench: Others
10
24
 
11
- - refactor script set tableau [andreiggr - [`d78328e`](https://github.com/eea/volto-tableau/commit/d78328e74d67d685390ca0671a44a1bfe9b21e97)]
12
25
  - Bump version [Miu Razvan - [`837f8a7`](https://github.com/eea/volto-tableau/commit/837f8a70257660253b70b818977693101d6576e9)]
13
26
  - clear lint [andreiggr - [`69d83b8`](https://github.com/eea/volto-tableau/commit/69d83b806aa48a6a696e01b6e026de07e6a34dfe)]
14
27
  ### [1.2.5](https://github.com/eea/volto-tableau/compare/1.2.4...1.2.5) - 2 September 2022
package/Jenkinsfile CHANGED
@@ -4,9 +4,9 @@ pipeline {
4
4
  environment {
5
5
  GIT_NAME = "volto-tableau"
6
6
  NAMESPACE = "@eeacms"
7
- SONARQUBE_TAGS = "volto.eea.europa.eu,climate-energy.eea.europa.eu,forest.eea.europa.eu,biodiversity.europa.eu,water.europa.eu-freshwater"
7
+ SONARQUBE_TAGS = "volto.eea.europa.eu,climate-energy.eea.europa.eu,forest.eea.europa.eu,biodiversity.europa.eu,water.europa.eu-freshwater,water.europa.eu-marine"
8
8
  DEPENDENCIES = ""
9
- VOLTO = "16.0.0-alpha.14"
9
+ VOLTO = "alpha"
10
10
  }
11
11
 
12
12
  stages {
@@ -41,19 +41,19 @@ pipeline {
41
41
 
42
42
  "ES lint": {
43
43
  node(label: 'docker') {
44
- sh '''docker run -i --rm --name="$BUILD_TAG-eslint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci eslint'''
44
+ sh '''docker run -i --rm --name="$BUILD_TAG-eslint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha eslint'''
45
45
  }
46
46
  },
47
47
 
48
48
  "Style lint": {
49
49
  node(label: 'docker') {
50
- sh '''docker run -i --rm --name="$BUILD_TAG-stylelint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci stylelint'''
50
+ sh '''docker run -i --rm --name="$BUILD_TAG-stylelint" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha stylelint'''
51
51
  }
52
52
  },
53
53
 
54
54
  "Prettier": {
55
55
  node(label: 'docker') {
56
- sh '''docker run -i --rm --name="$BUILD_TAG-prettier" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci prettier'''
56
+ sh '''docker run -i --rm --name="$BUILD_TAG-prettier" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha prettier'''
57
57
  }
58
58
  }
59
59
  )
@@ -77,8 +77,8 @@ pipeline {
77
77
  node(label: 'docker') {
78
78
  script {
79
79
  try {
80
- sh '''docker pull plone/volto-addon-ci'''
81
- sh '''docker run -i --name="$BUILD_TAG-volto" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci'''
80
+ sh '''docker pull plone/volto-addon-ci:alpha'''
81
+ sh '''docker run -i --name="$BUILD_TAG-volto" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci:alpha'''
82
82
  sh '''rm -rf xunit-reports'''
83
83
  sh '''mkdir -p xunit-reports'''
84
84
  sh '''docker cp $BUILD_TAG-volto:/opt/frontend/my-volto-project/coverage xunit-reports/'''
@@ -125,8 +125,8 @@ pipeline {
125
125
  node(label: 'docker') {
126
126
  script {
127
127
  try {
128
- sh '''docker pull eeacms/plone-backend; docker run -d --rm --name="$BUILD_TAG-plone" -e SITE="Plone" -e PROFILES="eea.kitkat:testing" eeacms/plone-backend'''
129
- sh '''docker pull plone/volto-addon-ci; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e NODE_ENV=development -e VOLTO="$VOLTO" plone/volto-addon-ci cypress'''
128
+ sh '''docker pull eeacms/plone-backend; docker run --rm -d --name="$BUILD_TAG-plone" -e SITE="Plone" -e PROFILES="eea.kitkat:testing" eeacms/plone-backend'''
129
+ sh '''docker pull plone/volto-addon-ci:alpha; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e NODE_ENV=development -e VOLTO=$VOLTO plone/volto-addon-ci:alpha cypress'''
130
130
  } finally {
131
131
  try {
132
132
  sh '''rm -rf cypress-reports cypress-results cypress-coverage'''
@@ -239,4 +239,4 @@ pipeline {
239
239
  }
240
240
  }
241
241
  }
242
- }
242
+ }
@@ -0,0 +1,17 @@
1
+ module.exports = function (api) {
2
+ api.cache(true);
3
+ const presets = ['razzle'];
4
+ const plugins = [
5
+ [
6
+ 'react-intl', // React Intl extractor, required for the whole i18n infrastructure to work
7
+ {
8
+ messagesDir: './build/messages/',
9
+ },
10
+ ],
11
+ ];
12
+
13
+ return {
14
+ plugins,
15
+ presets,
16
+ };
17
+ };
@@ -1,20 +1,17 @@
1
- import { setupBeforeEach, tearDownAfterEach } from '../support';
1
+ import { slateBeforeEach, slateAfterEach } from '../support/e2e';
2
2
 
3
3
  describe('Blocks Tests', () => {
4
- beforeEach(setupBeforeEach);
5
- afterEach(tearDownAfterEach);
4
+ beforeEach(slateBeforeEach);
5
+ afterEach(slateAfterEach);
6
6
 
7
7
  it('Add Block: Empty', () => {
8
8
  // Change page title
9
- cy.get('.documentFirstHeading > .public-DraftStyleDefault-block')
10
- .clear()
11
- .type('My Add-on Page')
12
- .get('.documentFirstHeading span[data-text]')
13
- .contains('My Add-on Page');
9
+ cy.clearSlateTitle();
10
+ cy.getSlateTitle().type('My Add-on Page');
14
11
 
15
- cy.get('.documentFirstHeading > .public-DraftStyleDefault-block').type(
16
- '{enter}',
17
- );
12
+ cy.get('.documentFirstHeading').contains('My Add-on Page');
13
+
14
+ cy.getSlate().click();
18
15
 
19
16
  // Add block
20
17
  cy.get('.ui.basic.icon.button.block-add-button').first().click();
@@ -1,5 +1,8 @@
1
1
  /* eslint no-console: ["error", { allow: ["log"] }] */
2
2
 
3
+ const SLATE_SELECTOR = '.content-area .slate-editor [contenteditable=true]';
4
+ const SLATE_TITLE_SELECTOR = '.block.inner.title [contenteditable="true"]';
5
+
3
6
  // --- AUTOLOGIN -------------------------------------------------------------
4
7
  Cypress.Commands.add('autologin', () => {
5
8
  let api_url, user, password;
@@ -68,8 +71,7 @@ Cypress.Commands.add(
68
71
  id: contentId,
69
72
  title: contentTitle,
70
73
  image: {
71
- data:
72
- 'iVBORw0KGgoAAAANSUhEUgAAANcAAAA4CAMAAABZsZ3QAAAAM1BMVEX29fK42OU+oMvn7u9drtIPisHI4OhstdWZyt4fkcXX5+sAg74umMhNp86p0eJ7vNiKw9v/UV4wAAAAAXRSTlMAQObYZgAABBxJREFUeF7tmuty4yAMhZG4X2zn/Z92J5tsBJwWXG/i3XR6frW2Y/SBLIRAfaQUDNt8E5tLUt9BycfcKfq3R6Mlfyimtx4rzp+K3dtibXkor99zsEqLYZltblTecciogoh+TXfY1Ve4dn07rCDGG9dHSEEOg/GmXl0U1XDxTKxNK5De7BxsyyBr6gGm2/vPxKJ8F6f7BXKfRMp1xIWK9A+5ks25alSb353dWnDJN1k35EL5f8dVGifTf/4tjUuuFq7u4srmXC60yAmldLXIWbg65RKU87lcGxJCFqUPv0IacW0PmSivOZFLE908inPToMmii/roG+MRV/O8FU88i8tFsxV3a06MFUw0Qu7RmAtdV5/HVVaOVMTWNOWSwMljLhzhcB6XIS7OK5V6AvRDNN7t5VJWQs1J40UmalbK56usBG/CuCHSYuc+rkUGeMCViNRARPrzW52N3oQLe6WifNliSuuGaH3czbVNudI9s7ZLUCLHVwWlyES522o1t14uvmbblmVTKqFjaZYJFSTPP4dLL1kU1z7p0lzdbRulmEWLxoQX+z9ce7A8GqEEucllLxePuZwdJl1Lezu0hoswvTPt61DrFcRuujV/2cmlxaGBC7Aw6cpovGANwRiSdOAWJ5AGy4gLL64dl0QhUEAuEUNws+XxV+OKGPdw/hESGYF9XEGaFC7sNLMSXWJjHsnanYi87VK428N2uxpOjOFANcagLM5l+7mSycM8KknZpKLcGi6jmzWGr/vLurZ/0g4u9AZuAoeb5r1ceQhyiTPY1E4wUR6u/F3H2ojSpXMMriBPT9cezTto8Cx+MsglHL4fv1Rxrb1LVw9yvyQpJ3AhFnLZfuRLH2QsOG3FGGD20X/th/u5bFAt16Bt308KjF+MNOXgl/SquIEySX3GhaZvc67KZbDxcCDORz2N8yCWPaY5lyQZO7lQ29fnZbt3Xu6qoge4+DjXl/MocySPOp9rlvdyznahRyHEYd77v3LhugOXDv4J65QXfl803BDAdaWBEDhfVx7nKofjoVCgxnUAqw/UAUDPn788BDvQuG4TDtdtUPvzjSlXAB8DvaDOhhrmhwbywylXAm8CvaouikJTL93gs3y7Yy4VYbIxOHrcMizPqWOjqO9l3Uz52kibQy4xxOgqhJvD+w5rvokOcAlGvNCfeqCv1ste1stzLm0f71Iq3ZfTrPfuE5nhPtF+LvQE2lffQC7pYtQy3tdzdrKvd5TLVVzDetScS3nEKmmwDyt1Cev1kX3YfbvzNK4fzrlw+cB6vm+uiUgf2zdXI62241LawCb7Pi5FXFPF8KpzDoF/Sw2lg+GrHNbno1mhPu+VCF/vfMnw06PnUl6j48dVHD3jHNHPua+fc3o/5yp/zsGi0vYtzi3Pz5mHd4T6BWMIlewacd63AAAAAElFTkSuQmCC',
74
+ data: 'iVBORw0KGgoAAAANSUhEUgAAANcAAAA4CAMAAABZsZ3QAAAAM1BMVEX29fK42OU+oMvn7u9drtIPisHI4OhstdWZyt4fkcXX5+sAg74umMhNp86p0eJ7vNiKw9v/UV4wAAAAAXRSTlMAQObYZgAABBxJREFUeF7tmuty4yAMhZG4X2zn/Z92J5tsBJwWXG/i3XR6frW2Y/SBLIRAfaQUDNt8E5tLUt9BycfcKfq3R6Mlfyimtx4rzp+K3dtibXkor99zsEqLYZltblTecciogoh+TXfY1Ve4dn07rCDGG9dHSEEOg/GmXl0U1XDxTKxNK5De7BxsyyBr6gGm2/vPxKJ8F6f7BXKfRMp1xIWK9A+5ks25alSb353dWnDJN1k35EL5f8dVGifTf/4tjUuuFq7u4srmXC60yAmldLXIWbg65RKU87lcGxJCFqUPv0IacW0PmSivOZFLE908inPToMmii/roG+MRV/O8FU88i8tFsxV3a06MFUw0Qu7RmAtdV5/HVVaOVMTWNOWSwMljLhzhcB6XIS7OK5V6AvRDNN7t5VJWQs1J40UmalbK56usBG/CuCHSYuc+rkUGeMCViNRARPrzW52N3oQLe6WifNliSuuGaH3czbVNudI9s7ZLUCLHVwWlyES522o1t14uvmbblmVTKqFjaZYJFSTPP4dLL1kU1z7p0lzdbRulmEWLxoQX+z9ce7A8GqEEucllLxePuZwdJl1Lezu0hoswvTPt61DrFcRuujV/2cmlxaGBC7Aw6cpovGANwRiSdOAWJ5AGy4gLL64dl0QhUEAuEUNws+XxV+OKGPdw/hESGYF9XEGaFC7sNLMSXWJjHsnanYi87VK428N2uxpOjOFANcagLM5l+7mSycM8KknZpKLcGi6jmzWGr/vLurZ/0g4u9AZuAoeb5r1ceQhyiTPY1E4wUR6u/F3H2ojSpXMMriBPT9cezTto8Cx+MsglHL4fv1Rxrb1LVw9yvyQpJ3AhFnLZfuRLH2QsOG3FGGD20X/th/u5bFAt16Bt308KjF+MNOXgl/SquIEySX3GhaZvc67KZbDxcCDORz2N8yCWPaY5lyQZO7lQ29fnZbt3Xu6qoge4+DjXl/MocySPOp9rlvdyznahRyHEYd77v3LhugOXDv4J65QXfl803BDAdaWBEDhfVx7nKofjoVCgxnUAqw/UAUDPn788BDvQuG4TDtdtUPvzjSlXAB8DvaDOhhrmhwbywylXAm8CvaouikJTL93gs3y7Yy4VYbIxOHrcMizPqWOjqO9l3Uz52kibQy4xxOgqhJvD+w5rvokOcAlGvNCfeqCv1ste1stzLm0f71Iq3ZfTrPfuE5nhPtF+LvQE2lffQC7pYtQy3tdzdrKvd5TLVVzDetScS3nEKmmwDyt1Cev1kX3YfbvzNK4fzrlw+cB6vm+uiUgf2zdXI62241LawCb7Pi5FXFPF8KpzDoF/Sw2lg+GrHNbno1mhPu+VCF/vfMnw06PnUl6j48dVHD3jHNHPua+fc3o/5yp/zsGi0vYtzi3Pz5mHd4T6BWMIlewacd63AAAAAElFTkSuQmCC',
73
75
  encoding: 'base64',
74
76
  filename: 'image.png',
75
77
  'content-type': 'image/png',
@@ -92,7 +94,7 @@ Cypress.Commands.add(
92
94
  title: contentTitle,
93
95
  blocks: {
94
96
  'd3f1c443-583f-4e8e-a682-3bf25752a300': { '@type': 'title' },
95
- '7624cf59-05d0-4055-8f55-5fd6597d84b0': { '@type': 'text' },
97
+ '7624cf59-05d0-4055-8f55-5fd6597d84b0': { '@type': 'slate' },
96
98
  },
97
99
  blocks_layout: {
98
100
  items: [
@@ -122,9 +124,103 @@ Cypress.Commands.add(
122
124
  })
123
125
  .then(() => console.log(`${contentType} created`));
124
126
  }
125
- },
127
+ }
126
128
  );
127
129
 
130
+ // --- Add DX Content-Type ----------------------------------------------------------
131
+ Cypress.Commands.add('addContentType', (name) => {
132
+ let api_url, auth;
133
+ api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
134
+ auth = {
135
+ user: 'admin',
136
+ pass: 'admin',
137
+ };
138
+ return cy
139
+ .request({
140
+ method: 'POST',
141
+ url: `${api_url}/@controlpanels/dexterity-types/${name}`,
142
+ headers: {
143
+ Accept: 'application/json',
144
+ },
145
+ auth: auth,
146
+ body: {
147
+ title: name,
148
+ },
149
+ })
150
+ .then(() => console.log(`${name} content-type added.`));
151
+ });
152
+
153
+ // --- Remove DX behavior ----------------------------------------------------------
154
+ Cypress.Commands.add('removeContentType', (name) => {
155
+ let api_url, auth;
156
+ api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
157
+ auth = {
158
+ user: 'admin',
159
+ pass: 'admin',
160
+ };
161
+ return cy
162
+ .request({
163
+ method: 'DELETE',
164
+ url: `${api_url}/@controlpanels/dexterity-types/${name}`,
165
+ headers: {
166
+ Accept: 'application/json',
167
+ },
168
+ auth: auth,
169
+ body: {},
170
+ })
171
+ .then(() => console.log(`${name} content-type removed.`));
172
+ });
173
+
174
+ // --- Add DX field ----------------------------------------------------------
175
+ Cypress.Commands.add('addSlateJSONField', (type, name) => {
176
+ let api_url, auth;
177
+ api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
178
+ auth = {
179
+ user: 'admin',
180
+ pass: 'admin',
181
+ };
182
+ return cy
183
+ .request({
184
+ method: 'POST',
185
+ url: `${api_url}/@types/${type}`,
186
+ headers: {
187
+ Accept: 'application/json',
188
+ },
189
+ auth: auth,
190
+ body: {
191
+ id: name,
192
+ title: name,
193
+ description: 'Slate JSON Field',
194
+ factory: 'SlateJSONField',
195
+ required: false,
196
+ },
197
+ })
198
+ .then(() => console.log(`${name} SlateJSONField field added to ${type}`));
199
+ });
200
+
201
+ // --- Remove DX field ----------------------------------------------------------
202
+ Cypress.Commands.add('removeSlateJSONField', (type, name) => {
203
+ let api_url, auth;
204
+ api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
205
+ auth = {
206
+ user: 'admin',
207
+ pass: 'admin',
208
+ };
209
+ return cy
210
+ .request({
211
+ method: 'DELETE',
212
+ url: `${api_url}/@types/${type}/${name}`,
213
+ headers: {
214
+ Accept: 'application/json',
215
+ },
216
+ auth: auth,
217
+ body: {},
218
+ })
219
+ .then(() =>
220
+ console.log(`${name} SlateJSONField field removed from ${type}`)
221
+ );
222
+ });
223
+
128
224
  // --- REMOVE CONTENT --------------------------------------------------------
129
225
  Cypress.Commands.add('removeContent', (path) => {
130
226
  let api_url, auth;
@@ -146,6 +242,41 @@ Cypress.Commands.add('removeContent', (path) => {
146
242
  .then(() => console.log(`${path} removed`));
147
243
  });
148
244
 
245
+ Cypress.Commands.add('typeInSlate', { prevSubject: true }, (subject, text) => {
246
+ return (
247
+ cy
248
+ .wrap(subject)
249
+ .then((subject) => {
250
+ subject[0].dispatchEvent(
251
+ new InputEvent('beforeinput', {
252
+ inputType: 'insertText',
253
+ data: text,
254
+ })
255
+ );
256
+ return subject;
257
+ })
258
+ // TODO: do this only for Electron-based browser which does not understand instantaneously
259
+ // that the user inserted some text in the block
260
+ .wait(1000)
261
+ );
262
+ });
263
+
264
+ Cypress.Commands.add('lineBreakInSlate', { prevSubject: true }, (subject) => {
265
+ return (
266
+ cy
267
+ .wrap(subject)
268
+ .then((subject) => {
269
+ subject[0].dispatchEvent(
270
+ new InputEvent('beforeinput', { inputType: 'insertLineBreak' })
271
+ );
272
+ return subject;
273
+ })
274
+ // TODO: do this only for Electron-based browser which does not understand instantaneously
275
+ // that the block was split
276
+ .wait(1000)
277
+ );
278
+ });
279
+
149
280
  // --- SET WORKFLOW ----------------------------------------------------------
150
281
  Cypress.Commands.add(
151
282
  'setWorkflow',
@@ -184,7 +315,7 @@ Cypress.Commands.add(
184
315
  include_children: include_children,
185
316
  },
186
317
  });
187
- },
318
+ }
188
319
  );
189
320
 
190
321
  // --- waitForResourceToLoad ----------------------------------------------------------
@@ -244,9 +375,86 @@ Cypress.Commands.add(
244
375
  setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
245
376
  }
246
377
  });
247
- },
378
+ }
248
379
  );
249
380
 
381
+ Cypress.Commands.add('getSlate', ({ createNewSlate = true } = {}) => {
382
+ let slate;
383
+ cy.getIfExists(
384
+ SLATE_SELECTOR,
385
+ () => {
386
+ slate = cy.get(SLATE_SELECTOR).last();
387
+ },
388
+ () => {
389
+ if (createNewSlate) {
390
+ cy.get('.block.inner').last().type('{moveToEnd}{enter}');
391
+ }
392
+ slate = cy.get(SLATE_SELECTOR, { timeout: 10000 }).last();
393
+ }
394
+ );
395
+ return slate;
396
+ });
397
+
398
+ Cypress.Commands.add('clearSlate', (selector) => {
399
+ return cy
400
+ .get(selector)
401
+ .focus()
402
+ .click()
403
+ .wait(1000)
404
+ .type('{selectAll}')
405
+ .wait(1000)
406
+ .type('{backspace}');
407
+ });
408
+
409
+ Cypress.Commands.add('getSlateTitle', () => {
410
+ return cy.get(SLATE_TITLE_SELECTOR, {
411
+ timeout: 10000,
412
+ });
413
+ });
414
+
415
+ Cypress.Commands.add('clearSlateTitle', () => {
416
+ return cy.clearSlate(SLATE_TITLE_SELECTOR);
417
+ });
418
+
419
+ Cypress.Commands.add('setSlateSelection', (subject, query, endQuery) => {
420
+ cy.get('.slate-editor.selected [contenteditable=true]')
421
+ .focus()
422
+ .click()
423
+ .setSelection(subject, query, endQuery)
424
+ .wait(1000); // this wait is needed for the selection change to be detected after
425
+ });
426
+
427
+ Cypress.Commands.add('getSlateEditorAndType', (type) => {
428
+ cy.getSlate().focus().click().type(type);
429
+ });
430
+
431
+ Cypress.Commands.add('setSlateCursor', (subject, query, endQuery) => {
432
+ cy.get('.slate-editor.selected [contenteditable=true]')
433
+ .focus()
434
+ .click()
435
+ .setCursor(subject, query, endQuery)
436
+ .wait(1000);
437
+ });
438
+
439
+ Cypress.Commands.add('clickSlateButton', (button) => {
440
+ cy.get(`.slate-inline-toolbar .button-wrapper a[title="${button}"]`, {
441
+ timeout: 10000,
442
+ }).click({ force: true }); //force click is needed to ensure the button in visible in view.
443
+ });
444
+
445
+ Cypress.Commands.add('toolbarSave', () => {
446
+ cy.wait(1000);
447
+
448
+ // Save
449
+ cy.get('#toolbar-save').click();
450
+ cy.waitForResourceToLoad('@navigation');
451
+ cy.waitForResourceToLoad('@breadcrumbs');
452
+ cy.waitForResourceToLoad('@actions');
453
+ cy.waitForResourceToLoad('@types');
454
+ cy.waitForResourceToLoad('my-page');
455
+ cy.url().should('eq', Cypress.config().baseUrl + '/cypress/my-page');
456
+ });
457
+
250
458
  // Low level command reused by `setCursorBefore` and `setCursorAfter`, equal to `setCursorAfter`
251
459
  Cypress.Commands.add(
252
460
  'setCursor',
@@ -262,7 +470,7 @@ Cypress.Commands.add(
262
470
  });
263
471
  // Depending on what you're testing, you may need to chain a `.click()` here to ensure
264
472
  // further commands are picked up by whatever you're testing (this was required for Slate, for example).
265
- },
473
+ }
266
474
  );
267
475
 
268
476
  Cypress.Commands.add(
@@ -270,7 +478,7 @@ Cypress.Commands.add(
270
478
  { prevSubject: true },
271
479
  (subject, query) => {
272
480
  cy.wrap(subject).setCursor(query, true);
273
- },
481
+ }
274
482
  );
275
483
 
276
484
  Cypress.Commands.add(
@@ -278,7 +486,7 @@ Cypress.Commands.add(
278
486
  { prevSubject: true },
279
487
  (subject, query) => {
280
488
  cy.wrap(subject).setCursor(query);
281
- },
489
+ }
282
490
  );
283
491
 
284
492
  // Helper functions
@@ -313,3 +521,16 @@ Cypress.Commands.add('store', () => {
313
521
  Cypress.Commands.add('settings', (key, value) => {
314
522
  return cy.window().its('settings');
315
523
  });
524
+
525
+ Cypress.Commands.add(
526
+ 'getIfExists',
527
+ (selector, successAction = () => {}, failAction = () => {}) => {
528
+ cy.get('body').then((body) => {
529
+ if (body.find(selector).length > 0 && successAction) {
530
+ successAction();
531
+ } else if (failAction) {
532
+ failAction();
533
+ }
534
+ });
535
+ }
536
+ );
@@ -0,0 +1,125 @@
1
+ // ***********************************************************
2
+ // This example support/index.js is processed and
3
+ // loaded automatically before your test files.
4
+ //
5
+ // This is a great place to put global configuration and
6
+ // behavior that modifies Cypress.
7
+ //
8
+ // You can change the location of this file or turn off
9
+ // automatically serving support files with the
10
+ // 'supportFile' configuration option.
11
+ //
12
+ // You can read more here:
13
+ // https://on.cypress.io/configuration
14
+ // ***********************************************************
15
+
16
+ // Import commands.js using ES2015 syntax:
17
+ import './commands';
18
+ // Alternatively you can use CommonJS syntax:
19
+ // require('./commands')
20
+
21
+ //Generate code-coverage
22
+ import '@cypress/code-coverage/support';
23
+
24
+ export const slateBeforeEach = (contentType = 'Document') => {
25
+ cy.autologin();
26
+ cy.createContent({
27
+ contentType: 'Document',
28
+ contentId: 'cypress',
29
+ contentTitle: 'Cypress',
30
+ });
31
+ cy.createContent({
32
+ contentType: contentType,
33
+ contentId: 'my-page',
34
+ contentTitle: 'My Page',
35
+ path: 'cypress',
36
+ });
37
+ cy.visit('/cypress/my-page');
38
+ cy.waitForResourceToLoad('@navigation');
39
+ cy.waitForResourceToLoad('@breadcrumbs');
40
+ cy.waitForResourceToLoad('@actions');
41
+ cy.waitForResourceToLoad('@types');
42
+ cy.waitForResourceToLoad('my-page');
43
+ cy.navigate('/cypress/my-page/edit');
44
+ };
45
+
46
+ export const slateAfterEach = () => {
47
+ cy.autologin();
48
+ cy.removeContent('cypress');
49
+ };
50
+
51
+ export const slateJsonBeforeEach = (contentType = 'slate') => {
52
+ cy.autologin();
53
+ cy.addContentType(contentType);
54
+ cy.addSlateJSONField(contentType, 'slate');
55
+ slateBeforeEach(contentType);
56
+ };
57
+
58
+ export const slateJsonAfterEach = (contentType = 'slate') => {
59
+ cy.autologin();
60
+ cy.removeContentType(contentType);
61
+ slateAfterEach();
62
+ };
63
+
64
+ export const getSelectedSlateEditor = () => {
65
+ return cy.get('.slate-editor.selected [contenteditable=true]').click();
66
+ };
67
+
68
+ export const createSlateBlock = () => {
69
+ cy.get('.ui.basic.icon.button.block-add-button').first().click();
70
+ cy.get('.blocks-chooser .title').contains('Text').click();
71
+ cy.get('.ui.basic.icon.button.slate').contains('Text').click();
72
+ return getSelectedSlateEditor();
73
+ };
74
+
75
+ export const getSlateBlockValue = (sb) => {
76
+ return sb.invoke('attr', 'data-slate-value').then((str) => {
77
+ return typeof str === 'undefined' ? [] : JSON.parse(str);
78
+ });
79
+ };
80
+
81
+ export const createSlateBlockWithList = ({
82
+ numbered,
83
+ firstItemText,
84
+ secondItemText,
85
+ }) => {
86
+ let s1 = createSlateBlock();
87
+
88
+ s1.typeInSlate(firstItemText + secondItemText);
89
+
90
+ // select all contents of slate block
91
+ // - this opens hovering toolbar
92
+ cy.contains(firstItemText + secondItemText).then((el) => {
93
+ selectSlateNodeOfWord(el);
94
+ });
95
+
96
+ // TODO: do not hardcode these selectors:
97
+ if (numbered) {
98
+ // this is the numbered list option in the hovering toolbar
99
+ cy.get('.slate-inline-toolbar > :nth-child(9)').click();
100
+ } else {
101
+ // this is the bulleted list option in the hovering toolbar
102
+ cy.get('.slate-inline-toolbar > :nth-child(10)').click();
103
+ }
104
+
105
+ // move the text cursor
106
+ const sse = getSelectedSlateEditor();
107
+ sse.type('{leftarrow}');
108
+ for (let i = 0; i < firstItemText.length; ++i) {
109
+ sse.type('{rightarrow}');
110
+ }
111
+
112
+ // simulate pressing Enter
113
+ getSelectedSlateEditor().lineBreakInSlate();
114
+
115
+ return s1;
116
+ };
117
+
118
+ export const selectSlateNodeOfWord = (el) => {
119
+ return cy.window().then((win) => {
120
+ var event = new CustomEvent('Test_SelectWord', {
121
+ detail: el[0],
122
+ });
123
+ win.document.dispatchEvent(event);
124
+ });
125
+ };
@@ -0,0 +1,26 @@
1
+ const { defineConfig } = require('cypress');
2
+
3
+ module.exports = defineConfig({
4
+ viewportWidth: 1280,
5
+ defaultCommandTimeout: 8888,
6
+ chromeWebSecurity: false,
7
+ reporter: 'junit',
8
+ video: true,
9
+ retries: {
10
+ runMode: 8,
11
+ openMode: 0,
12
+ },
13
+ reporterOptions: {
14
+ mochaFile: 'cypress/reports/cypress-[hash].xml',
15
+ jenkinsMode: true,
16
+ toConsole: true,
17
+ },
18
+ e2e: {
19
+ setupNodeEvents(on, config) {
20
+ // e2e testing node events setup code
21
+ require('@cypress/code-coverage/task')(on, config);
22
+ return config;
23
+ },
24
+ baseUrl: 'http://localhost:3000',
25
+ },
26
+ });
@@ -11,16 +11,15 @@ module.exports = {
11
11
  '@package/(.*)$': '<rootDir>/src/$1',
12
12
  '@plone/volto-quanta/(.*)$': '<rootDir>/src/addons/volto-quanta/src/$1',
13
13
  '@eeacms/(.*?)/(.*)$': '<rootDir>/src/addons/$1/src/$2',
14
- 'volto-slate/(.*)$': '<rootDir>/src/addons/volto-slate/src/$1',
14
+ '@plone/volto-slate':
15
+ '<rootDir>/node_modules/@plone/volto/packages/volto-slate/src',
15
16
  '~/(.*)$': '<rootDir>/src/$1',
16
17
  'load-volto-addons':
17
18
  '<rootDir>/node_modules/@plone/volto/jest-addons-loader.js',
19
+ '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
18
20
  },
19
21
  transform: {
20
22
  '^.+\\.js(x)?$': 'babel-jest',
21
- '^.+\\.css$': 'jest-css-modules',
22
- '^.+\\.less$': 'jest-css-modules',
23
- '^.+\\.scss$': 'jest-css-modules',
24
23
  '^.+\\.(png)$': 'jest-file',
25
24
  '^.+\\.(jpg)$': 'jest-file',
26
25
  '^.+\\.(svg)$': './node_modules/@plone/volto/jest-svgsystem-transform.js',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-tableau",
3
- "version": "1.3.0",
3
+ "version": "2.0.0",
4
4
  "description": "@eeacms/volto-tableau: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -24,7 +24,9 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "@cypress/code-coverage": "^3.9.5",
27
- "babel-plugin-transform-class-properties": "^6.24.1"
27
+ "@plone/scripts": "*",
28
+ "babel-plugin-transform-class-properties": "^6.24.1",
29
+ "md5": "^2.3.0"
28
30
  },
29
31
  "scripts": {
30
32
  "release": "release-it",
@@ -1,26 +0,0 @@
1
- /// <reference types="cypress" />
2
- // ***********************************************************
3
- // This example plugins/index.js can be used to load plugins
4
- //
5
- // You can change the location of this file or turn off loading
6
- // the plugins file with the 'pluginsFile' configuration option.
7
- //
8
- // You can read more here:
9
- // https://on.cypress.io/plugins-guide
10
- // ***********************************************************
11
-
12
- // This function is called when a project is opened or re-opened (e.g. due to
13
- // the project's config changing)
14
-
15
- /**
16
- * @type {Cypress.PluginConfig}
17
- */
18
- module.exports = (on, config) => {
19
- // `on` is used to hook into various events Cypress emits
20
- // `config` is the resolved Cypress config
21
- /* coverage-start
22
- require('@cypress/code-coverage/task')(on, config)
23
- on('file:preprocessor', require('@cypress/code-coverage/use-babelrc'))
24
- return config
25
- coverage-end */
26
- };
@@ -1,53 +0,0 @@
1
- // ***********************************************************
2
- // This example support/index.js is processed and
3
- // loaded automatically before your test files.
4
- //
5
- // This is a great place to put global configuration and
6
- // behavior that modifies Cypress.
7
- //
8
- // You can change the location of this file or turn off
9
- // automatically serving support files with the
10
- // 'supportFile' configuration option.
11
- //
12
- // You can read more here:
13
- // https://on.cypress.io/configuration
14
- // ***********************************************************
15
-
16
- // Import commands.js using ES2015 syntax:
17
- import './commands';
18
-
19
- // Alternatively you can use CommonJS syntax:
20
- // require('./commands')
21
-
22
- /* coverage-start
23
- //Generate code-coverage
24
- import '@cypress/code-coverage/support';
25
- coverage-end */
26
-
27
- export const setupBeforeEach = () => {
28
- cy.autologin();
29
- cy.createContent({
30
- contentType: 'Document',
31
- contentId: 'cypress',
32
- contentTitle: 'Cypress',
33
- });
34
- cy.createContent({
35
- contentType: 'Document',
36
- contentId: 'my-page',
37
- contentTitle: 'My Page',
38
- path: 'cypress',
39
- });
40
- cy.visit('/cypress/my-page');
41
- cy.waitForResourceToLoad('@navigation');
42
- cy.waitForResourceToLoad('@breadcrumbs');
43
- cy.waitForResourceToLoad('@actions');
44
- cy.waitForResourceToLoad('@types');
45
- cy.waitForResourceToLoad('my-page');
46
- cy.navigate('/cypress/my-page/edit');
47
- cy.get(`.block.title [data-contents]`);
48
- };
49
-
50
- export const tearDownAfterEach = () => {
51
- cy.autologin();
52
- cy.removeContent('cypress');
53
- };
package/cypress.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "baseUrl": "http://localhost:3000",
3
- "viewportWidth": 1280,
4
- "defaultCommandTimeout": 8888,
5
- "reporter": "junit",
6
- "video": true,
7
- "reporterOptions": {
8
- "mochaFile": "cypress/reports/cypress-[hash].xml",
9
- "jenkinsMode": true,
10
- "toConsole": true
11
- },
12
- "chromeWebSecurity": false,
13
- "retries": {
14
- "runMode": 8,
15
- "openMode": 0
16
- }
17
- }