@jahia/cypress 4.0.0 → 4.2.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.
package/README.md CHANGED
@@ -102,4 +102,9 @@ module.exports = (on, config) => {
102
102
  ```
103
103
  ## Open-Source
104
104
 
105
- This is an Open-Source codebase, you can find more details about Open-Source @ Jahia [in this repository](https://github.com/Jahia/open-source)
105
+ This is an Open-Source codebase, you can find more details about Open-Source @ Jahia [in this repository](https://github.com/Jahia/open-source)
106
+
107
+ ## How to release
108
+ Ensure and eventually change the version in [package.json](package.json) to match the version to release.
109
+
110
+ From Github release panel, draft a new release with a tag named `vX.Y.Z` and a title `vX.Y.Z`. The release will be published to NPM automatically.
@@ -5,9 +5,11 @@ export declare class Menu extends BaseComponent {
5
5
  static overlaySelector: string;
6
6
  submenu(item: string, menu: string): Menu;
7
7
  shouldHaveItem(item: string): void;
8
+ shouldHaveRoleItem(role: string): void;
8
9
  shouldNotHaveItem(item: string): void;
10
+ shouldNotHaveRoleItem(role: string): void;
9
11
  select(item: string): Menu;
10
- selectByRole(item: string): Menu;
12
+ selectByRole(role: string): Menu;
11
13
  /** Can be used for choicelist dropdown menu */
12
14
  selectByValue(value: string): Menu;
13
15
  close(): Chainable<unknown>;
@@ -24,29 +24,38 @@ var Menu = /** @class */ (function (_super) {
24
24
  return _super !== null && _super.apply(this, arguments) || this;
25
25
  }
26
26
  Menu.prototype.submenu = function (item, menu) {
27
- this.get().find('.moonstone-menuItem').contains(item).scrollIntoView().should('be.visible');
27
+ this.shouldHaveItem(item);
28
28
  this.get().find('.moonstone-menuItem').contains(item).realHover();
29
29
  return utils_1.getComponentByRole(Menu, menu);
30
30
  };
31
31
  Menu.prototype.shouldHaveItem = function (item) {
32
- this.get().find('.moonstone-menuItem').contains(item).scrollIntoView().should('be.visible');
32
+ this.get().find('.moonstone-menuItem').contains(item).scrollIntoView();
33
+ this.get().find('.moonstone-menuItem').contains(item).should('be.visible');
34
+ };
35
+ Menu.prototype.shouldHaveRoleItem = function (role) {
36
+ this.get().find(".moonstone-menuItem[data-sel-role=" + role + "]").scrollIntoView();
37
+ this.get().find(".moonstone-menuItem[data-sel-role=" + role + "]").should('be.visible');
33
38
  };
34
39
  Menu.prototype.shouldNotHaveItem = function (item) {
35
40
  this.get().find('.moonstone-menuItem').contains(item).should('not.exist');
36
41
  };
42
+ Menu.prototype.shouldNotHaveRoleItem = function (role) {
43
+ this.get().find(".moonstone-menuItem[data-sel-role=\"" + role + "\"]").should('not.exist');
44
+ };
37
45
  Menu.prototype.select = function (item) {
38
- this.get().find('.moonstone-menuItem').contains(item).scrollIntoView().should('be.visible');
46
+ this.shouldHaveItem(item);
39
47
  this.get().find('.moonstone-menuItem').contains(item).trigger('click');
40
48
  return this;
41
49
  };
42
- Menu.prototype.selectByRole = function (item) {
43
- this.get().find(".moonstone-menuItem[data-sel-role=\"" + item + "\"]").scrollIntoView().should('be.visible');
44
- this.get().find(".moonstone-menuItem[data-sel-role=\"" + item + "\"]").trigger('click');
50
+ Menu.prototype.selectByRole = function (role) {
51
+ this.shouldHaveRoleItem(role);
52
+ this.get().find(".moonstone-menuItem[data-sel-role=\"" + role + "\"]").trigger('click');
45
53
  return this;
46
54
  };
47
55
  /** Can be used for choicelist dropdown menu */
48
56
  Menu.prototype.selectByValue = function (value) {
49
- this.get().find(".moonstone-menuItem[data-value=\"" + value + "\"]").scrollIntoView().should('be.visible');
57
+ this.get().find(".moonstone-menuItem[data-value=\"" + value + "\"]").scrollIntoView();
58
+ this.get().find(".moonstone-menuItem[data-value=\"" + value + "\"]").should('be.visible');
50
59
  this.get().find(".moonstone-menuItem[data-value=\"" + value + "\"]").trigger('click');
51
60
  return this;
52
61
  };
@@ -0,0 +1,27 @@
1
+ import { JahiaServer } from '../support';
2
+ export declare type ExportParameters = {
3
+ viewContent?: boolean;
4
+ viewVersion?: boolean;
5
+ viewAcl?: boolean;
6
+ viewLinks?: boolean;
7
+ viewMetadata?: boolean;
8
+ viewWorkflow?: boolean;
9
+ exportPath?: string;
10
+ exportformat: 'all' | 'site' | 'xml' | 'zip';
11
+ root?: string;
12
+ live?: boolean;
13
+ users?: boolean;
14
+ sitebox?: string[];
15
+ paths?: string[];
16
+ cleanup?: 'template' | 'simple';
17
+ filesToZip?: string;
18
+ };
19
+ declare type ExportContentParams = {
20
+ workspace?: string;
21
+ nodePath?: string;
22
+ exportFormat?: string;
23
+ params?: ExportParameters;
24
+ jahiaServer?: JahiaServer;
25
+ };
26
+ export declare const exportContent: ({ workspace, nodePath, exportFormat, params, jahiaServer }: ExportContentParams) => void;
27
+ export {};
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ // Utility methods to call import/export Jahia API
3
+ var __spreadArray = (this && this.__spreadArray) || function (to, from) {
4
+ for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
5
+ to[j] = from[i];
6
+ return to;
7
+ };
8
+ exports.__esModule = true;
9
+ exports.exportContent = void 0;
10
+ var API_NAME = '/cms/export';
11
+ var serverDefaults = {
12
+ url: Cypress.config().baseUrl,
13
+ username: 'root',
14
+ password: Cypress.env('SUPER_USER_PASSWORD')
15
+ };
16
+ var exportContent = function (_a) {
17
+ var _b, _c;
18
+ var _d = _a.workspace, workspace = _d === void 0 ? 'default' : _d, _e = _a.nodePath, nodePath = _e === void 0 ? '/export' : _e, _f = _a.exportFormat, exportFormat = _f === void 0 ? 'zip' : _f, _g = _a.params, params = _g === void 0 ? {
19
+ exportformat: 'site',
20
+ live: true,
21
+ users: true
22
+ } : _g, _h = _a.jahiaServer, jahiaServer = _h === void 0 ? serverDefaults : _h;
23
+ var queryStringParams = Object.keys(params)
24
+ .filter(function (key) { return !['paths', 'sitebox'].includes(key); })
25
+ .map(function (key) { return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]); }) || [];
26
+ var sitebox = ((_b = params.sitebox) === null || _b === void 0 ? void 0 : _b.map(function (sb) { return "sitebox=" + encodeURIComponent(sb); })) || [];
27
+ var paths = ((_c = params.paths) === null || _c === void 0 ? void 0 : _c.map(function (path) { return "path=" + encodeURIComponent(path); })) || [];
28
+ var qs = __spreadArray(__spreadArray(__spreadArray([], queryStringParams), sitebox), paths).join('&');
29
+ // It is not possible to use the "qs" field of RequestOptions for querystring as it does not support multiple parameters with the same name (path or sitebox)
30
+ cy.request({
31
+ url: "" + jahiaServer.url + API_NAME + "/" + workspace + nodePath + "." + exportFormat + "?" + qs,
32
+ method: 'GET',
33
+ auth: {
34
+ user: jahiaServer.username,
35
+ pass: jahiaServer.password,
36
+ sendImmediately: true
37
+ }
38
+ });
39
+ };
40
+ exports.exportContent = exportContent;
@@ -6,13 +6,15 @@ export declare const addNode: (variables: {
6
6
  parentPathOrId: string;
7
7
  primaryNodeType: string;
8
8
  name: string;
9
- properties?: any[];
10
- children?: any[];
11
- mixins?: any[];
9
+ properties?: [];
10
+ children?: [];
11
+ mixins?: [];
12
12
  }) => Cypress.Chainable;
13
+ export declare const addMixins: (pathOrId: string, mixins: string[]) => Cypress.Chainable;
13
14
  export declare const getNodeByPath: (path: string, properties?: string[], language?: string, childrenTypes?: string[], workspace?: Workspace) => Cypress.Chainable;
14
15
  export declare const getNodeAcl: (path: string) => Cypress.Chainable;
15
16
  export declare const moveNode: (pathOrId: string, destParentPathOrId: string, destName?: string) => Cypress.Chainable;
16
17
  export declare const getNodeTypes: (filter?: {}) => Cypress.Chainable;
18
+ export declare const markForDeletion: (pathOrId: string) => Cypress.Chainable;
17
19
  export declare const uploadFile: (fixturePath: string, parentPathOrId: string, name: string, mimeType: string) => Cypress.Chainable;
18
20
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  exports.__esModule = true;
3
- exports.uploadFile = exports.getNodeTypes = exports.moveNode = exports.getNodeAcl = exports.getNodeByPath = exports.addNode = exports.deleteNodeProperty = exports.deleteNode = exports.setNodeProperty = void 0;
3
+ exports.uploadFile = exports.markForDeletion = exports.getNodeTypes = exports.moveNode = exports.getNodeAcl = exports.getNodeByPath = exports.addMixins = exports.addNode = exports.deleteNodeProperty = exports.deleteNode = exports.setNodeProperty = void 0;
4
4
  var setNodeProperty = function (pathOrId, property, value, language) {
5
5
  var mutationFile = 'graphql/jcr/mutation/setProperty.graphql';
6
6
  if (value instanceof Array) {
@@ -39,7 +39,6 @@ var deleteNodeProperty = function (pathOrId, property, language) {
39
39
  });
40
40
  };
41
41
  exports.deleteNodeProperty = deleteNodeProperty;
42
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
42
  var addNode = function (variables) {
44
43
  return cy.apollo({
45
44
  variables: variables,
@@ -47,6 +46,14 @@ var addNode = function (variables) {
47
46
  });
48
47
  };
49
48
  exports.addNode = addNode;
49
+ var addMixins = function (pathOrId, mixins) {
50
+ return cy.apollo({
51
+ variables: { pathOrId: pathOrId, mixins: mixins },
52
+ mutationFile: 'graphql/jcr/mutation/addMixins.graphql'
53
+ });
54
+ };
55
+ exports.addMixins = addMixins;
56
+ // eslint-disable-next-line max-params
50
57
  var getNodeByPath = function (path, properties, language, childrenTypes, workspace) {
51
58
  if (childrenTypes === void 0) { childrenTypes = []; }
52
59
  if (workspace === void 0) { workspace = 'EDIT'; }
@@ -92,6 +99,15 @@ var getNodeTypes = function (filter) {
92
99
  });
93
100
  };
94
101
  exports.getNodeTypes = getNodeTypes;
102
+ var markForDeletion = function (pathOrId) {
103
+ return cy.apollo({
104
+ variables: {
105
+ pathOrId: pathOrId
106
+ },
107
+ mutationFile: 'graphql/jcr/mutation/markForDeletion.graphql'
108
+ });
109
+ };
110
+ exports.markForDeletion = markForDeletion;
95
111
  var uploadFile = function (fixturePath, parentPathOrId, name, mimeType) {
96
112
  return cy.fixture(fixturePath, 'binary')
97
113
  .then(function (image) {
@@ -6,6 +6,15 @@ import Chainable = Cypress.Chainable;
6
6
  * @param probeNamesFilter return and calculate health status only for the probes with the given names, default is null
7
7
  */
8
8
  export declare const healthCheck: (severity?: string, probeHealthFilter?: any, probeNamesFilter?: string[]) => Chainable<any>;
9
+ declare type WaitUntilSAMStatusParams = {
10
+ expectedHealth: string;
11
+ severity?: string;
12
+ probeHealthFilter?: any;
13
+ probeNamesFilter?: string[] | null;
14
+ timeout?: number;
15
+ interval?: number;
16
+ statusMatchCount?: number;
17
+ };
9
18
  /**
10
19
  * Wait until the health check returns the expected health
11
20
  * @param expectedHealth the expected health status
@@ -16,15 +25,7 @@ export declare const healthCheck: (severity?: string, probeHealthFilter?: any, p
16
25
  * @param interval the interval in milliseconds, default is 500
17
26
  * @param statusMatchCount the number of consecutive status matches before the waitUntil resolves, default is 3
18
27
  */
19
- export declare const waitUntilSAMStatus: ({ expectedHealth, severity, probeHealthFilter, probeNamesFilter, timeout, interval, statusMatchCount }: {
20
- expectedHealth: any;
21
- severity?: string;
22
- probeHealthFilter?: any;
23
- probeNamesFilter?: any;
24
- timeout?: number;
25
- interval?: number;
26
- statusMatchCount?: number;
27
- }) => void;
28
+ export declare const waitUntilSAMStatus: ({ expectedHealth, severity, probeHealthFilter, probeNamesFilter, timeout, interval, statusMatchCount }: WaitUntilSAMStatusParams) => void;
28
29
  /**
29
30
  When Jahia is starting or performing provisioning operations
30
31
  it is expected for the SAM probe to alternate beween GREEN, YELLOW and RED statuses.
@@ -36,3 +37,4 @@ export declare const waitUntilSAMStatus: ({ expectedHealth, severity, probeHealt
36
37
  GREEN status was returned a number of consecutive times (greenMatchCount).
37
38
  */
38
39
  export declare const waitUntilSAMStatusGreen: (severity?: string, timeout?: number, interval?: number, greenMatchCount?: number) => void;
40
+ export {};
@@ -4,5 +4,8 @@ export declare const createUser: (userName: string, password: string, properties
4
4
  name: string;
5
5
  value: string;
6
6
  }[]) => void;
7
+ export declare const getUserPath: (username: string, siteKey?: string) => Cypress.Chainable;
7
8
  export declare const deleteUser: (userName: string) => void;
9
+ export declare const createGroup: (groupName: string, hidden?: boolean, siteKey?: string) => void;
10
+ export declare const deleteGroup: (groupName: string, siteKey?: string) => void;
8
11
  export declare const addUserToGroup: (userName: string, groupName: string, siteKey?: string) => void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  exports.__esModule = true;
3
- exports.addUserToGroup = exports.deleteUser = exports.createUser = exports.revokeRoles = exports.grantRoles = void 0;
3
+ exports.addUserToGroup = exports.deleteGroup = exports.createGroup = exports.deleteUser = exports.getUserPath = exports.createUser = exports.revokeRoles = exports.grantRoles = void 0;
4
4
  var grantRoles = function (pathOrId, roleNames, principalName, principalType) {
5
5
  cy.log('Grant role(s) ' + roleNames + ' with principal type ' + principalType + ' to ' + principalName + ' on node ' + pathOrId);
6
6
  return cy.apollo({
@@ -39,12 +39,42 @@ var createUser = function (userName, password, properties) {
39
39
  });
40
40
  };
41
41
  exports.createUser = createUser;
42
+ var getUserPath = function (username, siteKey) {
43
+ if (siteKey === void 0) { siteKey = ''; }
44
+ return cy.apollo({
45
+ variables: {
46
+ siteKey: siteKey,
47
+ username: username
48
+ },
49
+ queryFile: 'graphql/jcr/query/getUserPath.graphql'
50
+ });
51
+ };
52
+ exports.getUserPath = getUserPath;
42
53
  var deleteUser = function (userName) {
43
54
  cy.executeGroovy('groovy/admin/deleteUser.groovy', {
44
55
  USER_NAME: userName
45
56
  });
46
57
  };
47
58
  exports.deleteUser = deleteUser;
59
+ var createGroup = function (groupName, hidden, siteKey) {
60
+ if (siteKey === void 0) { siteKey = ''; }
61
+ cy.executeGroovy('groovy/admin/userGroupHelper.groovy', {
62
+ OPERATION: 'create',
63
+ GROUPNAME: groupName,
64
+ HIDDEN: hidden ? 'true' : 'false',
65
+ SITEKEY: siteKey
66
+ });
67
+ };
68
+ exports.createGroup = createGroup;
69
+ var deleteGroup = function (groupName, siteKey) {
70
+ if (siteKey === void 0) { siteKey = ''; }
71
+ cy.executeGroovy('groovy/admin/userGroupHelper.groovy', {
72
+ OPERATION: 'delete',
73
+ GROUPNAME: groupName,
74
+ SITEKEY: siteKey
75
+ });
76
+ };
77
+ exports.deleteGroup = deleteGroup;
48
78
  var addUserToGroup = function (userName, groupName, siteKey) {
49
79
  cy.executeGroovy('groovy/admin/addUserToGroup.groovy', {
50
80
  USER_NAME: userName,
@@ -7,3 +7,4 @@ export * from './ClusterHelper';
7
7
  export * from './JahiaPlatformHelper';
8
8
  export * from './GraphQLHelper';
9
9
  export * from './SAMHelper';
10
+ export * from './ExportHelper';
@@ -19,3 +19,4 @@ __exportStar(require("./ClusterHelper"), exports);
19
19
  __exportStar(require("./JahiaPlatformHelper"), exports);
20
20
  __exportStar(require("./GraphQLHelper"), exports);
21
21
  __exportStar(require("./SAMHelper"), exports);
22
+ __exportStar(require("./ExportHelper"), exports);
package/env.debug.sh CHANGED
@@ -2,14 +2,6 @@
2
2
  # This script can be used to warmup the environment and execute the tests
3
3
  # It is used by the docker image at startup
4
4
 
5
- BASEDIR=$(dirname $(readlink -f $0))
5
+ echo "$(date +'%d %B %Y - %k:%M') == env.debug.sh == Run Cypress in interactive mode"
6
6
 
7
- bash $BASEDIR/env.provision.sh
8
-
9
- source $BASEDIR/set-env.sh
10
-
11
- if [[ -z "${CYPRESS_CONFIGURATION_FILE}" ]]; then
12
- CYPRESS_CONFIGURATION_FILE=cypress.config.ts
13
- fi
14
-
15
- yarn e2e:debug --config-file "${CYPRESS_CONFIGURATION_FILE}"
7
+ MODE=debug ./env.run.sh
package/env.provision.sh CHANGED
@@ -9,7 +9,7 @@ source $BASEDIR/set-env.sh
9
9
  #!/usr/bin/env bash
10
10
  START_TIME=$SECONDS
11
11
 
12
- echo "$(date +'%d %B %Y - %k:%M') == Printing the most important environment variables"
12
+ echo "$(date +'%d %B %Y - %k:%M') == env.provision.sh == Printing the most important environment variables"
13
13
  echo " MANIFEST: ${MANIFEST}"
14
14
  echo " NEXUS_USERNAME: ${NEXUS_USERNAME:0:3}***${NEXUS_USERNAME:(-6)}"
15
15
  echo " TESTS_IMAGE: ${TESTS_IMAGE}"
package/env.run.sh CHANGED
@@ -8,9 +8,12 @@ bash $BASEDIR/env.provision.sh
8
8
 
9
9
  source $BASEDIR/set-env.sh
10
10
 
11
+ MODE=${MODE:-ci}
12
+
11
13
  echo "$(date +'%d %B %Y - %k:%M') == env.run.sh == Printing the most important environment variables"
12
14
  echo "$(date +'%d %B %Y - %k:%M') == NEXUS_USERNAME: ${NEXUS_USERNAME:0:3}***${NEXUS_USERNAME:(-6)}"
13
15
  echo "$(date +'%d %B %Y - %k:%M') == DEBUG: ${DEBUG}"
16
+ echo "$(date +'%d %B %Y - %k:%M') == CYPRESS MODE: ${MODE}"
14
17
 
15
18
  if [[ "${DEBUG}" == "true" ]]; then
16
19
  touch /tmp/debug
@@ -48,7 +51,7 @@ fi
48
51
 
49
52
  echo "$(date +'%d %B %Y - %k:%M') == Running Cypress with configuration file ${CYPRESS_CONFIGURATION_FILE} =="
50
53
 
51
- NO_COLOR=1 yarn e2e:ci --config-file "${CYPRESS_CONFIGURATION_FILE}"
54
+ NO_COLOR=1 yarn e2e:${MODE} --config-file "${CYPRESS_CONFIGURATION_FILE}"
52
55
 
53
56
  if [[ $? -eq 0 ]]; then
54
57
  echo "$(date +'%d %B %Y - %k:%M') == Full execution successful =="
@@ -0,0 +1,8 @@
1
+ mutation addMixins($pathOrId: String!, $mixins: [String]! = []) {
2
+ jcr(workspace: EDIT) {
3
+ mutateNode(pathOrId: $pathOrId) {
4
+ addMixins(mixins: $mixins)
5
+ uuid
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,7 @@
1
+ mutation startWorkflow($pathOrId: String!) {
2
+ jcr {
3
+ mutateNode(pathOrId:$pathOrId) {
4
+ markForDeletion
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,11 @@
1
+ query($username: String!, $siteKey: String) {
2
+ admin {
3
+ userAdmin {
4
+ user(username: $username, site: $siteKey) {
5
+ node {
6
+ path
7
+ }
8
+ }
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,29 @@
1
+ import org.jahia.services.content.JCRCallback
2
+ import org.jahia.services.content.JCRSessionWrapper
3
+ import org.jahia.services.content.JCRTemplate
4
+ import org.jahia.services.usermanager.JahiaGroupManagerService
5
+ import org.jahia.services.usermanager.JahiaUserManagerService
6
+ import javax.jcr.RepositoryException
7
+
8
+ JahiaGroupManagerService groupManagerService = JahiaGroupManagerService.getInstance();
9
+
10
+ JCRTemplate.getInstance().doExecuteWithSystemSession(session -> {
11
+ String operation = "OPERATION";
12
+ String groupName = "GROUPNAME"
13
+ String siteKey = "SITEKEY".equals("") ? null : "SITEKEY";
14
+ boolean hidden = Boolean.parseBoolean("HIDDEN")
15
+ log.info("{} : {}", operation, groupName)
16
+ switch (operation) {
17
+ case "create":
18
+ groupManagerService.createGroup(siteKey, groupName, null, hidden, session)
19
+ break;
20
+ case "delete":
21
+ def group = groupManagerService.lookupGroup(siteKey, groupName);
22
+ if (group != null) {
23
+ groupManagerService.deleteGroup(group.getPath(), session)
24
+ }
25
+ break;
26
+ }
27
+ session.save()
28
+ return null
29
+ })
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@jahia/cypress",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "scripts": {
5
5
  "build": "tsc",
6
- "lint": "eslint src -c .eslintrc.json --ext .ts"
6
+ "lint": "eslint src -c .eslintrc.json --ext .ts --max-warnings=0"
7
7
  },
8
8
  "bin": {
9
9
  "ci.build": "./ci.build.sh",
@@ -7,34 +7,45 @@ export class Menu extends BaseComponent {
7
7
  static overlaySelector = '.moonstone-menu_overlay';
8
8
 
9
9
  submenu(item: string, menu: string): Menu {
10
- this.get().find('.moonstone-menuItem').contains(item).scrollIntoView().should('be.visible');
10
+ this.shouldHaveItem(item);
11
11
  this.get().find('.moonstone-menuItem').contains(item).realHover();
12
12
  return getComponentByRole(Menu, menu);
13
13
  }
14
14
 
15
15
  shouldHaveItem(item: string):void {
16
- this.get().find('.moonstone-menuItem').contains(item).scrollIntoView().should('be.visible');
16
+ this.get().find('.moonstone-menuItem').contains(item).scrollIntoView();
17
+ this.get().find('.moonstone-menuItem').contains(item).should('be.visible');
18
+ }
19
+
20
+ shouldHaveRoleItem(role: string):void {
21
+ this.get().find(`.moonstone-menuItem[data-sel-role=${role}]`).scrollIntoView();
22
+ this.get().find(`.moonstone-menuItem[data-sel-role=${role}]`).should('be.visible');
17
23
  }
18
24
 
19
25
  shouldNotHaveItem(item: string):void {
20
26
  this.get().find('.moonstone-menuItem').contains(item).should('not.exist');
21
27
  }
22
28
 
29
+ shouldNotHaveRoleItem(role: string):void {
30
+ this.get().find(`.moonstone-menuItem[data-sel-role="${role}"]`).should('not.exist');
31
+ }
32
+
23
33
  select(item: string): Menu {
24
- this.get().find('.moonstone-menuItem').contains(item).scrollIntoView().should('be.visible');
34
+ this.shouldHaveItem(item);
25
35
  this.get().find('.moonstone-menuItem').contains(item).trigger('click');
26
36
  return this;
27
37
  }
28
38
 
29
- selectByRole(item: string): Menu {
30
- this.get().find(`.moonstone-menuItem[data-sel-role="${item}"]`).scrollIntoView().should('be.visible');
31
- this.get().find(`.moonstone-menuItem[data-sel-role="${item}"]`).trigger('click');
39
+ selectByRole(role: string): Menu {
40
+ this.shouldHaveRoleItem(role);
41
+ this.get().find(`.moonstone-menuItem[data-sel-role="${role}"]`).trigger('click');
32
42
  return this;
33
43
  }
34
44
 
35
45
  /** Can be used for choicelist dropdown menu */
36
46
  selectByValue(value: string): Menu {
37
- this.get().find(`.moonstone-menuItem[data-value="${value}"]`).scrollIntoView().should('be.visible');
47
+ this.get().find(`.moonstone-menuItem[data-value="${value}"]`).scrollIntoView();
48
+ this.get().find(`.moonstone-menuItem[data-value="${value}"]`).should('be.visible');
38
49
  this.get().find(`.moonstone-menuItem[data-value="${value}"]`).trigger('click');
39
50
  return this;
40
51
  }
@@ -1,4 +1,4 @@
1
- export const waitUntilJournalSync = (predicate?: (cluster: any) => boolean, timeout = 60000,
1
+ export const waitUntilJournalSync = (predicate?: (cluster) => boolean, timeout = 60000,
2
2
  interval = 1000) : void => {
3
3
  cy.waitUntil(() =>
4
4
  cy.apollo({
@@ -0,0 +1,72 @@
1
+ // Utility methods to call import/export Jahia API
2
+
3
+ // http://localhost:8080/cms/export/default/export.zip?exportformat=site&live=true&users=true&path=/groups&path=/settings/mail-server-1&sitebox=digitall&exportPath=abc
4
+ // Export
5
+
6
+ import {JahiaServer} from '../support';
7
+
8
+ const API_NAME = '/cms/export';
9
+
10
+ export type ExportParameters = {
11
+ viewContent?: boolean;
12
+ viewVersion?: boolean;
13
+ viewAcl?: boolean;
14
+ viewLinks?: boolean;
15
+ viewMetadata?: boolean;
16
+ viewWorkflow?: boolean;
17
+ exportPath?: string;
18
+ exportformat: 'all' | 'site' | 'xml' | 'zip';
19
+ root?: string;
20
+ live?: boolean;
21
+ users?: boolean;
22
+ sitebox?: string[];
23
+ paths?: string[];
24
+ cleanup?: 'template' | 'simple';
25
+ filesToZip?: string;
26
+ }
27
+
28
+ const serverDefaults: JahiaServer = {
29
+ url: Cypress.config().baseUrl,
30
+ username: 'root',
31
+ password: Cypress.env('SUPER_USER_PASSWORD')
32
+ };
33
+
34
+ type ExportContentParams = {
35
+ workspace?: string;
36
+ nodePath?: string;
37
+ exportFormat?: string;
38
+ params?: ExportParameters;
39
+ jahiaServer?: JahiaServer;
40
+ }
41
+
42
+ export const exportContent = (
43
+ {
44
+ workspace = 'default',
45
+ nodePath = '/export',
46
+ exportFormat = 'zip',
47
+ params = {
48
+ exportformat: 'site',
49
+ live: true,
50
+ users: true
51
+ },
52
+ jahiaServer = serverDefaults
53
+ }: ExportContentParams): void => {
54
+ const queryStringParams = Object.keys(params)
55
+ .filter(key => !['paths', 'sitebox'].includes(key))
56
+ .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`) || [];
57
+
58
+ const sitebox: string[] = params.sitebox?.map(sb => `sitebox=${encodeURIComponent(sb)}`) || [];
59
+ const paths: string[] = params.paths?.map(path => `path=${encodeURIComponent(path)}`) || [];
60
+ const qs = [...queryStringParams, ...sitebox, ...paths].join('&');
61
+ // It is not possible to use the "qs" field of RequestOptions for querystring as it does not support multiple parameters with the same name (path or sitebox)
62
+ cy.request({
63
+ url: `${jahiaServer.url}${API_NAME}/${workspace}${nodePath}.${exportFormat}?${qs}`,
64
+ method: 'GET',
65
+ auth: {
66
+ user: jahiaServer.username,
67
+ pass: jahiaServer.password,
68
+ sendImmediately: true
69
+ }
70
+ });
71
+ };
72
+
@@ -38,14 +38,28 @@ export const deleteNodeProperty = (pathOrId: string, property: string, language:
38
38
  });
39
39
  };
40
40
 
41
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
- export const addNode = (variables: { parentPathOrId: string, primaryNodeType: string, name: string, properties?: any[], children?: any[], mixins?: any[] }): Cypress.Chainable => {
41
+ export const addNode = (variables: {
42
+ parentPathOrId: string,
43
+ primaryNodeType: string,
44
+ name: string,
45
+ properties?: [],
46
+ children?: [],
47
+ mixins?: []
48
+ }): Cypress.Chainable => {
43
49
  return cy.apollo({
44
50
  variables: variables,
45
51
  mutationFile: 'graphql/jcr/mutation/addNode.graphql'
46
52
  });
47
53
  };
48
54
 
55
+ export const addMixins = (pathOrId: string, mixins: string[]): Cypress.Chainable => {
56
+ return cy.apollo({
57
+ variables: {pathOrId: pathOrId, mixins: mixins},
58
+ mutationFile: 'graphql/jcr/mutation/addMixins.graphql'
59
+ });
60
+ };
61
+
62
+ // eslint-disable-next-line max-params
49
63
  export const getNodeByPath = (path: string, properties?: string[], language?: string, childrenTypes: string[] = [], workspace: Workspace = 'EDIT'): Cypress.Chainable => {
50
64
  return cy.apollo({
51
65
  variables: {
@@ -88,6 +102,17 @@ export const getNodeTypes = (filter = {}): Cypress.Chainable => {
88
102
  });
89
103
  };
90
104
 
105
+ export const markForDeletion = (pathOrId: string): Cypress.Chainable => {
106
+ return cy.apollo(
107
+ {
108
+ variables: {
109
+ pathOrId: pathOrId
110
+ },
111
+ mutationFile: 'graphql/jcr/mutation/markForDeletion.graphql'
112
+ }
113
+ );
114
+ };
115
+
91
116
  export const uploadFile = (fixturePath: string, parentPathOrId: string, name: string, mimeType: string): Cypress.Chainable => {
92
117
  return cy.fixture(fixturePath, 'binary')
93
118
  .then(image => {
@@ -23,6 +23,16 @@ export const healthCheck = (severity = 'MEDIUM', probeHealthFilter = null, probe
23
23
  });
24
24
  };
25
25
 
26
+ type WaitUntilSAMStatusParams = {
27
+ expectedHealth: string;
28
+ severity?: string;
29
+ probeHealthFilter?: any;
30
+ probeNamesFilter?: string[] | null;
31
+ timeout?: number;
32
+ interval?: number;
33
+ statusMatchCount?: number;
34
+ };
35
+
26
36
  /**
27
37
  * Wait until the health check returns the expected health
28
38
  * @param expectedHealth the expected health status
@@ -33,7 +43,7 @@ export const healthCheck = (severity = 'MEDIUM', probeHealthFilter = null, probe
33
43
  * @param interval the interval in milliseconds, default is 500
34
44
  * @param statusMatchCount the number of consecutive status matches before the waitUntil resolves, default is 3
35
45
  */
36
- export const waitUntilSAMStatus = ({expectedHealth, severity = 'MEDIUM', probeHealthFilter = null, probeNamesFilter = null, timeout = 60000, interval = 500, statusMatchCount = 3}) : void => {
46
+ export const waitUntilSAMStatus = ({expectedHealth, severity = 'MEDIUM', probeHealthFilter = null, probeNamesFilter = null, timeout = 60000, interval = 500, statusMatchCount = 3}: WaitUntilSAMStatusParams) : void => {
37
47
  let statusCount = 0;
38
48
  let lastGraphqlResponse = {};
39
49
  cy.waitUntil(() =>
@@ -1,4 +1,3 @@
1
-
2
1
  export const grantRoles = (pathOrId: string, roleNames: Array<string>, principalName: string, principalType: string): Cypress.Chainable => {
3
2
  cy.log('Grant role(s) ' + roleNames + ' with principal type ' + principalType + ' to ' + principalName + ' on node ' + pathOrId);
4
3
  return cy.apollo({
@@ -25,7 +24,10 @@ export const revokeRoles = (pathOrId: string, roleNames: Array<string>, principa
25
24
  });
26
25
  };
27
26
 
28
- export const createUser = (userName: string, password: string, properties: { name: string, value: string }[] = []): void => {
27
+ export const createUser = (userName: string, password: string, properties: {
28
+ name: string,
29
+ value: string
30
+ }[] = []): void => {
29
31
  const userProperties = properties.map(property => {
30
32
  return 'properties.setProperty("' + property.name + '", "' + property.value + '")';
31
33
  });
@@ -36,12 +38,40 @@ export const createUser = (userName: string, password: string, properties: { nam
36
38
  });
37
39
  };
38
40
 
41
+ export const getUserPath = (username: string, siteKey = ''): Cypress.Chainable => {
42
+ return cy.apollo({
43
+ variables: {
44
+ siteKey,
45
+ username
46
+ },
47
+ queryFile: 'graphql/jcr/query/getUserPath.graphql'
48
+ }
49
+ );
50
+ };
51
+
39
52
  export const deleteUser = (userName: string): void => {
40
53
  cy.executeGroovy('groovy/admin/deleteUser.groovy', {
41
54
  USER_NAME: userName
42
55
  });
43
56
  };
44
57
 
58
+ export const createGroup = (groupName: string, hidden?: boolean, siteKey = ''): void => {
59
+ cy.executeGroovy('groovy/admin/userGroupHelper.groovy', {
60
+ OPERATION: 'create',
61
+ GROUPNAME: groupName,
62
+ HIDDEN: hidden ? 'true' : 'false',
63
+ SITEKEY: siteKey
64
+ });
65
+ };
66
+
67
+ export const deleteGroup = (groupName: string, siteKey = ''): void => {
68
+ cy.executeGroovy('groovy/admin/userGroupHelper.groovy', {
69
+ OPERATION: 'delete',
70
+ GROUPNAME: groupName,
71
+ SITEKEY: siteKey
72
+ });
73
+ };
74
+
45
75
  export const addUserToGroup = (userName: string, groupName: string, siteKey?: string): void => {
46
76
  cy.executeGroovy('groovy/admin/addUserToGroup.groovy', {
47
77
  USER_NAME: userName,
@@ -7,3 +7,4 @@ export * from './ClusterHelper';
7
7
  export * from './JahiaPlatformHelper';
8
8
  export * from './GraphQLHelper';
9
9
  export * from './SAMHelper';
10
+ export * from './ExportHelper';