graphdb-workbench-tests 4.0.0-TR7 → 4.0.0-TR8

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.
@@ -0,0 +1,200 @@
1
+ import {ReactodiaSteps} from '../../steps/reactodia-steps.js';
2
+ import {PageRestrictionsSteps} from '../../steps/page-restrictions-steps.js';
3
+ import {RepositoryPickerListSteps} from '../../steps/repository-picker-list-steps.js';
4
+ import {LicenseStubs} from '../../stubs/license-stubs.js';
5
+ import {RepositorySteps} from '../../steps/repository-steps.js';
6
+
7
+ const NO_REPOSITORY_MESSAGE = 'you are not connected to any repository';
8
+ const INVALID_LICENSE_MESSAGE = 'your license is not valid';
9
+ const SELECT_OR_CREATE_REPOSITORY_MESSAGE = 'Select a repository below or create a new one.';
10
+ const SELECT_REPOSITORY_MESSAGE = 'Select a repository below.';
11
+
12
+ describe('Reactodia view restrictions', () => {
13
+ let repositoryId;
14
+
15
+ beforeEach(() => {
16
+ repositoryId = 'reactodia-view-restrictions-' + Date.now();
17
+ cy.createRepository({id: repositoryId});
18
+ });
19
+
20
+ afterEach(() => {
21
+ cy.deleteRepository(repositoryId);
22
+ });
23
+
24
+ it('should show the repository picker when no repository is selected', () => {
25
+ // GIVEN no repository is selected
26
+
27
+ // WHEN I open the Reactodia view
28
+ ReactodiaSteps.visit();
29
+ // THEN I expect the repository restriction is shown
30
+ PageRestrictionsSteps.getMessages().should('have.length', 1);
31
+ PageRestrictionsSteps.getMessage(NO_REPOSITORY_MESSAGE).should('be.visible');
32
+ // AND the existing repository is available in the picker
33
+ RepositoryPickerListSteps.getRepositoryRow(repositoryId).should('be.visible');
34
+ // AND the graph is not rendered
35
+ ReactodiaSteps.getComponent().should('not.exist');
36
+ });
37
+
38
+ it('should render the graph when a repository is selected from the picker', () => {
39
+ // GIVEN the Reactodia view is open with no repository selected
40
+ ReactodiaSteps.visit();
41
+
42
+ // WHEN I select a repository
43
+ RepositoryPickerListSteps.selectRepository(repositoryId);
44
+ // THEN I expect the restriction is removed and the graph is rendered
45
+ PageRestrictionsSteps.getRestrictions().should('not.exist');
46
+ ReactodiaSteps.getWorkspace().should('exist');
47
+ });
48
+
49
+ it('should not restrict the view when the license is valid and a repository is selected', () => {
50
+ // GIVEN a valid license and a selected repository
51
+ cy.presetRepository(repositoryId);
52
+
53
+ // WHEN I open the Reactodia view
54
+ ReactodiaSteps.visit();
55
+ // THEN I expect the view is not restricted
56
+ ReactodiaSteps.getWorkspace().should('exist');
57
+ PageRestrictionsSteps.getRestrictions().should('not.exist');
58
+ });
59
+
60
+ context('when the license is invalid', () => {
61
+ beforeEach(() => {
62
+ LicenseStubs.stubNoValidLicense();
63
+ });
64
+
65
+ it('should show the license restriction when a repository is selected', () => {
66
+ // GIVEN an invalid license and a selected repository
67
+ cy.presetRepository(repositoryId);
68
+
69
+ // WHEN I open the Reactodia view
70
+ ReactodiaSteps.visit();
71
+ // THEN I expect the license restriction is shown
72
+ PageRestrictionsSteps.getMessages().should('have.length', 1);
73
+ PageRestrictionsSteps.getMessage(INVALID_LICENSE_MESSAGE).should('be.visible');
74
+ // AND the "Set a new license" link is displayed
75
+ PageRestrictionsSteps.getInternalLink()
76
+ .should('contain.text', 'Set a new license')
77
+ .and('have.attr', 'href')
78
+ .and('include', '/license');
79
+ // AND the repository picker and graph are not rendered
80
+ RepositoryPickerListSteps.getRepositoryPickerList().should('not.exist');
81
+ ReactodiaSteps.getComponent().should('not.exist');
82
+ });
83
+
84
+ it('should show both restrictions when no repository is selected', () => {
85
+ // GIVEN an invalid license and no repository selected
86
+
87
+ // WHEN I open the Reactodia view
88
+ ReactodiaSteps.visit();
89
+ // THEN both restrictions are shown
90
+ PageRestrictionsSteps.getMessages().should('have.length', 2);
91
+ PageRestrictionsSteps.getMessage(INVALID_LICENSE_MESSAGE).should('be.visible');
92
+ PageRestrictionsSteps.getMessage(NO_REPOSITORY_MESSAGE)
93
+ .should('be.visible')
94
+ .and('not.contain.text', 'create a new one');
95
+ // AND the existing repository is available, but repository creation is not
96
+ RepositoryPickerListSteps.getRepositoryRow(repositoryId).should('be.visible');
97
+ RepositoryPickerListSteps.getCreateRepositoryButton().should('not.exist');
98
+ // AND the graph is not rendered
99
+ ReactodiaSteps.getComponent().should('not.exist');
100
+ });
101
+ });
102
+
103
+ context('with security enabled', () => {
104
+ const readOnlyUser = 'reactodia-reader-' + Date.now();
105
+ const repoManagerUser = 'reactodia-repo-manager-' + Date.now();
106
+ const repoMaintainerUser = 'reactodia-repo-maintainer-' + Date.now();
107
+ const password = 'root';
108
+
109
+ beforeEach(() => {
110
+ cy.createUser({
111
+ username: readOnlyUser,
112
+ password,
113
+ grantedAuthorities: ['ROLE_USER', `READ_REPO_${repositoryId}`]
114
+ });
115
+ cy.createUser({
116
+ username: repoManagerUser,
117
+ password,
118
+ grantedAuthorities: ['ROLE_USER', 'ROLE_REPO_MANAGER']
119
+ });
120
+ cy.createUser({
121
+ username: repoMaintainerUser,
122
+ password,
123
+ grantedAuthorities: [
124
+ 'ROLE_USER',
125
+ `READ_REPO_${repositoryId}`,
126
+ `WRITE_REPO_${repositoryId}`,
127
+ `MAINTAIN_REPO_${repositoryId}`
128
+ ]
129
+ });
130
+ cy.switchOnSecurity();
131
+ });
132
+
133
+ afterEach(() => {
134
+ cy.loginAsAdmin().then(() => {
135
+ cy.deleteUser(readOnlyUser, true);
136
+ cy.deleteUser(repoManagerUser, true);
137
+ cy.deleteUser(repoMaintainerUser, true);
138
+ cy.switchOffSecurity(true);
139
+ });
140
+ });
141
+
142
+ it('should not restrict the view for a user without write permission', () => {
143
+ // GIVEN a user with read-only access to the selected repository
144
+ cy.loginAs(readOnlyUser, password);
145
+ cy.presetRepository(repositoryId);
146
+
147
+ // WHEN I open the Reactodia view
148
+ ReactodiaSteps.visit();
149
+ // THEN I expect the view is not restricted
150
+ ReactodiaSteps.getWorkspace().should('exist');
151
+ PageRestrictionsSteps.getRestrictions().should('not.exist');
152
+ });
153
+
154
+ it('should offer repository creation to the administrator', () => {
155
+ // GIVEN the administrator is logged in with no repository selected
156
+ cy.loginAs('admin', password);
157
+
158
+ // WHEN I open the Reactodia view
159
+ ReactodiaSteps.visit();
160
+ // THEN I expect the option to select or create a repository is displayed
161
+ PageRestrictionsSteps.getMessage(SELECT_OR_CREATE_REPOSITORY_MESSAGE).should('be.visible');
162
+ RepositoryPickerListSteps.getRepositoryRow(repositoryId).should('be.visible');
163
+ RepositoryPickerListSteps.getCreateRepositoryButton().should('be.visible');
164
+ });
165
+
166
+ it('should offer repository creation to a repository manager', () => {
167
+ // GIVEN a repository manager is logged in with no repository selected
168
+ cy.loginAs(repoManagerUser, password);
169
+
170
+ // WHEN I open the Reactodia view
171
+ ReactodiaSteps.visit();
172
+ // THEN the option to select or create a repository is displayed
173
+ PageRestrictionsSteps.getMessage(SELECT_OR_CREATE_REPOSITORY_MESSAGE).should('be.visible');
174
+ RepositoryPickerListSteps.getRepositoryRow(repositoryId).should('be.visible');
175
+
176
+ // WHEN I click the create repository button
177
+ RepositoryPickerListSteps.clickCreateRepositoryButton();
178
+ // THEN the create repository view is opened
179
+ RepositorySteps.verifyRepositoryCreateViewUrl().and('include', 'previous=%2Freactodia');
180
+ });
181
+
182
+ [
183
+ {role: 'a read-only user', username: readOnlyUser},
184
+ {role: 'a repository maintainer', username: repoMaintainerUser},
185
+ ].forEach(({role, username}) => {
186
+ it(`should not offer repository creation to ${role}`, () => {
187
+ // GIVEN a user without repository management rights is logged in with no repository selected
188
+ cy.loginAs(username, password);
189
+
190
+ // WHEN I open the Reactodia view
191
+ ReactodiaSteps.visit();
192
+ // THEN only the option to select a repository is displayed
193
+ PageRestrictionsSteps.getMessage(SELECT_REPOSITORY_MESSAGE).should('be.visible');
194
+ PageRestrictionsSteps.getMessages().should('not.contain.text', 'create a new one');
195
+ RepositoryPickerListSteps.getRepositoryRow(repositoryId).should('be.visible');
196
+ RepositoryPickerListSteps.getCreateRepositoryButton().should('not.exist');
197
+ });
198
+ });
199
+ });
200
+ });
@@ -2,6 +2,7 @@ import {ReactodiaSteps} from '../../steps/reactodia-steps.js';
2
2
  import {LanguageSelectorSteps} from '../../steps/language-selector-steps.js';
3
3
  import {RepositorySelectorSteps} from '../../steps/repository-selector-steps.js';
4
4
  import {MainMenuSteps} from '../../steps/main-menu-steps.js';
5
+ import {YasqeSteps} from '../../steps/yasgui/yasqe-steps.js';
5
6
 
6
7
  const FILE_TO_IMPORT = 'resource-test-data.ttl';
7
8
  const SEED_RESOURCE_ENCODED = 'http:%2F%2Fexample.com%2Fontology%23CustomerLoyalty';
@@ -86,6 +87,12 @@ describe('Reactodia graph explorer', () => {
86
87
  MainMenuSteps.clickOnSparqlMenu();
87
88
  ReactodiaSteps.getComponent().should('not.exist');
88
89
 
90
+ // Wait for the SPARQL Query & Update view to be loaded before continuing.
91
+ // Without this wait, Cypress may try to click the Reactodia menu item before the page is fully loaded,
92
+ // causing the test to fail intermittently with the error:
93
+ // "This element `<li.sub-menu-item>` is not visible because it has CSS property: `display: none`"
94
+ // when trying to click the Reactodia submenu.
95
+ YasqeSteps.getEditor().should('be.visible');
89
96
  // And I return to the reactodia view via the navigation bar.
90
97
  MainMenuSteps.clickOnReactodia();
91
98
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "4.0.0-TR7",
3
+ "version": "4.0.0-TR8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "graphdb-workbench-tests",
9
- "version": "4.0.0-TR7",
9
+ "version": "4.0.0-TR8",
10
10
  "license": "Apache-2.0",
11
11
  "devDependencies": {
12
12
  "@bahmutov/cypress-code-coverage": "^2.7.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "4.0.0-TR7",
3
+ "version": "4.0.0-TR8",
4
4
  "description": "Cypress tests for GraphDB workbench",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -26,4 +26,8 @@ export class BaseSteps {
26
26
  static validateUrl(url) {
27
27
  this.getUrl().should('include', url);
28
28
  }
29
+
30
+ static buildTestIdAttr(testId) {
31
+ return `[data-test="${testId}"]`;
32
+ }
29
33
  }
@@ -0,0 +1,24 @@
1
+ import {BaseSteps} from "./base-steps.js";
2
+
3
+ /**
4
+ * Steps for the restriction block (`app-page-restrictions`) that the new workbench shows instead of a
5
+ * page's content when the page is restricted. For its repository picker see {@link RepositoryPickerListSteps}.
6
+ */
7
+ export class PageRestrictionsSteps extends BaseSteps {
8
+
9
+ static getRestrictions() {
10
+ return this.getByTestId('page-restrictions');
11
+ }
12
+
13
+ static getMessages() {
14
+ return this.getRestrictions().find(this.buildTestIdAttr('page-restriction-message'));
15
+ }
16
+
17
+ static getInternalLink() {
18
+ return this.getMessages().find(this.buildTestIdAttr('restriction-internal-link'));
19
+ }
20
+
21
+ static getMessage(text) {
22
+ return this.getMessages().contains(text);
23
+ }
24
+ }
@@ -0,0 +1,40 @@
1
+ import {BaseSteps} from "./base-steps.js";
2
+
3
+ /**
4
+ * Steps for the repository picker list (`app-repository-picker-list`) of the new workbench, which lists the
5
+ * repositories the user can select and, when allowed, offers the creation of a new one.
6
+ */
7
+ export class RepositoryPickerListSteps extends BaseSteps {
8
+
9
+ static getRepositoryPickerList() {
10
+ return this.getByTestId('repository-picker-list');
11
+ }
12
+
13
+ static getRepositoryRows() {
14
+ return this.getRepositoryPickerList().find(this.buildTestIdAttr('repository-picker-row'));
15
+ }
16
+
17
+ static getRepositoryRow(repositoryId) {
18
+ return this.getRepositoryRows()
19
+ .contains(this.buildTestIdAttr('repository-picker-repository-id'), repositoryId)
20
+ .parents(this.buildTestIdAttr('repository-picker-row'));
21
+ }
22
+
23
+ static getRepositorySelectButton(repositoryId) {
24
+ return this.getRepositoryRow(repositoryId).find(this.buildTestIdAttr('repository-picker-select-btn'));
25
+ }
26
+
27
+ static selectRepository(repositoryId) {
28
+ // The select button is shown only while the row is hovered.
29
+ this.getRepositoryRow(repositoryId).realHover();
30
+ this.getRepositorySelectButton(repositoryId).click();
31
+ }
32
+
33
+ static getCreateRepositoryButton() {
34
+ return this.getRepositoryPickerList().find(this.buildTestIdAttr('repository-picker-create-btn'));
35
+ }
36
+
37
+ static clickCreateRepositoryButton() {
38
+ this.getCreateRepositoryButton().click();
39
+ }
40
+ }
@@ -20,6 +20,10 @@ export class RepositorySteps extends BaseSteps {
20
20
  cy.visit(`repository/edit/${repositoryId}?location=`);
21
21
  }
22
22
 
23
+ static verifyRepositoryCreateViewUrl() {
24
+ return cy.url().should('include', '/repository/create');
25
+ }
26
+
23
27
  static getRepositoryPage() {
24
28
  return cy.get('#wb-repository');
25
29
  }