graphdb-workbench-tests 3.5.1-TR3 → 4.0.0-SPARQL12

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.
Files changed (50) hide show
  1. package/cypress-guides.config.js +45 -0
  2. package/e2e-flaky/import/import-server-files-operations.spec.js +8 -30
  3. package/e2e-flaky/import/import-user-data-batch-operations.spec.js +7 -7
  4. package/e2e-flaky/import/import-user-data-url.spec.js +1 -1
  5. package/e2e-legacy/cluster/cluster-configuration/cluster-configuration-multi-region.spec.js +7 -0
  6. package/e2e-legacy/cluster/edit-cluster-nodes-modal.spec.js +1 -1
  7. package/e2e-legacy/explore/visual-graph/visual.graph.spec.js +45 -9
  8. package/e2e-legacy/guides/import-rdf-file/confirm-duplicate-rdf-file.spec.js +1 -1
  9. package/e2e-legacy/guides/main-menu/main-menu-guide.spec.js +6 -14
  10. package/e2e-legacy/guides/ttyg/configure-agent/configure-agent-guide.spec.js +27 -32
  11. package/e2e-legacy/guides/ttyg/edit-agent/edit-ttyg-agent-guide.spec.js +12 -20
  12. package/e2e-legacy/import/import-server-files-batch-operations.spec.js +5 -5
  13. package/e2e-legacy/import/import-server-files.spec.js +20 -22
  14. package/e2e-legacy/import/import-user-data-file-upload.spec.js +21 -22
  15. package/e2e-legacy/import/import-user-data-text-snippet.spec.js +6 -45
  16. package/e2e-legacy/import/import-user-data-url.spec.js +9 -6
  17. package/e2e-legacy/import/import-view.spec.js +2 -2
  18. package/e2e-legacy/repository/ontop-repository.spec.js +2 -1
  19. package/e2e-legacy/repository/rename-repository-restrictions.spec.js +129 -0
  20. package/e2e-legacy/repository/repositories.spec.js +3 -3
  21. package/e2e-legacy/resource/resource.spec.js +160 -35
  22. package/e2e-legacy/setup/aclmanagement/create-rule.spec.js +14 -25
  23. package/e2e-legacy/setup/aclmanagement/delete-rule.spec.js +6 -6
  24. package/e2e-legacy/setup/aclmanagement/edit-rule.spec.js +15 -15
  25. package/e2e-legacy/setup/aclmanagement/render-rules.spec.js +1 -1
  26. package/e2e-legacy/setup/aclmanagement/reorder-rules.spec.js +2 -2
  27. package/e2e-legacy/setup/aclmanagement/revert-rules.spec.js +2 -2
  28. package/e2e-legacy/setup/aclmanagement/update-rules.spec.js +3 -3
  29. package/e2e-legacy/setup/aclmanagement/validate-uri.spec.js +152 -0
  30. package/e2e-legacy/setup/users-and-access/user-and-access.spec.js +21 -20
  31. package/e2e-legacy/sparql-editor/yasr/download-as.spec.js +4 -7
  32. package/e2e-legacy/ttyg/edit-agent.spec.js +8 -0
  33. package/e2e-legacy/ttyg/ttyg-initial-state-with-configured-api-key.spec.js +1 -1
  34. package/e2e-legacy/ttyg/ttyg-initial-state-with-selected-repository.spec.js +1 -1
  35. package/e2e-legacy/ttyg/ttyg-initial-state-without-repositories.spec.js +1 -1
  36. package/eslint.config.js +5 -0
  37. package/fixtures/cluster/cluster-config-with-tag.json +17 -0
  38. package/fixtures/graphdb-import/wine.rdf +279 -285
  39. package/npm-shrinkwrap.json +138 -497
  40. package/package.json +3 -2
  41. package/steps/import/import-steps.js +26 -6
  42. package/steps/import/import-test-constants.js +1 -1
  43. package/steps/main-menu-steps.js +5 -14
  44. package/steps/resource/resource-steps.js +64 -5
  45. package/steps/setup/acl-management-steps.js +3 -23
  46. package/stubs/cluster/cluster-stubs.js +7 -0
  47. package/stubs/repositories/repositories-stubs.js +4 -0
  48. package/fixtures/graphdb-import/test-trigstar.trigs +0 -32
  49. package/fixtures/graphdb-import/test_turtlestar.ttls +0 -6
  50. package/fixtures/graphdb-import/turtlestar-data.ttls +0 -77
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "3.5.1-TR3",
3
+ "version": "4.0.0-SPARQL12",
4
4
  "description": "Cypress tests for GraphDB workbench",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -10,7 +10,8 @@
10
10
  "cy:open-legacy": "cypress open --config-file cypress-legacy.config.js",
11
11
  "cy:open-security": "cypress open --config-file cypress-security.config.js",
12
12
  "cy:open-flaky": "cypress open --config-file cypress-flaky.config.js",
13
- "cy:guides": "cypress run --config-file cypress-legacy.config.js --spec \"e2e-legacy/guides/**/*.spec.js\" --browser chrome",
13
+ "cy:open-guides": "cypress open --config-file cypress-guides.config.js",
14
+ "cy:run-guides": "cypress run --config-file cypress-guides.config.js",
14
15
  "cy:run": "npm run cy:run-legacy && cypress run",
15
16
  "cy:run:partial": "cypress run --config-file cypress-legacy.config.js --spec \"e2e-legacy/ttyg/**/*.spec.js\" --browser chrome",
16
17
  "cy:run-legacy": "cypress run --config-file cypress-legacy.config.js --browser chrome",
@@ -161,17 +161,29 @@ class ImportSteps {
161
161
  return this.getSelectedResources().eq(index).closest('.title-row');
162
162
  }
163
163
 
164
- static getResource(index) {
164
+ static getResourceTitleRow(index) {
165
165
  return this.getResources().eq(index);
166
166
  }
167
167
 
168
+ static getResourceByIndex(index) {
169
+ return this.getResourcesTable().find(`[data-test="resource-${index}"]`);
170
+ }
171
+
172
+ static getResourceNameByIndex(index) {
173
+ return this.getResourceByIndex(index).find('.cell-title').invoke('text');
174
+ }
175
+
176
+ static getResourceStatusByIndex(index) {
177
+ return this.getResourceByIndex(index).find('.import-resource-message');
178
+ }
179
+
168
180
  static getResourceByName(name) {
169
181
  return this.getResources().find('.cell-title').contains(name)
170
182
  .closest('.row.title-row');
171
183
  }
172
184
 
173
185
  static selectFileByIndex(index) {
174
- this.getResource(index).find('.select-checkbox').click();
186
+ this.getResourceTitleRow(index).find('.select-checkbox').click();
175
187
  }
176
188
 
177
189
  static selectFileByName(name) {
@@ -194,8 +206,16 @@ class ImportSteps {
194
206
  return this.getResources().find('.import-resource-message');
195
207
  }
196
208
 
197
- static checkImportedResource(index, resourceName, expectedStatus) {
209
+ static checkImportedResourceByIndex(index, resourceName, expectedStatus) {
198
210
  const status = expectedStatus || 'Imported successfully';
211
+
212
+ this.getResourceNameByIndex(index).should('contain', resourceName);
213
+ this.getResourceStatusByIndex(index).should('contain', status);
214
+ }
215
+
216
+ static checkImportedResourceByName(resourceName, expectedStatus) {
217
+ const status = expectedStatus || 'Imported successfully';
218
+
199
219
  this.getResourceByName(resourceName).should('contain', resourceName);
200
220
  this.getResourceStatus(resourceName).should('contain', status);
201
221
  }
@@ -263,11 +283,11 @@ class ImportSteps {
263
283
  }
264
284
 
265
285
  static deleteUploadedFile(index) {
266
- this.getResource(index).find('.import-resource-action-remove-btn').invoke('show').trigger('click');
286
+ this.getResourceTitleRow(index).find('.import-resource-action-remove-btn').invoke('show').trigger('click');
267
287
  }
268
288
 
269
289
  static importFile(index) {
270
- this.getResource(index).find('.import-resource-action-import-btn').invoke('show').trigger('click');
290
+ this.getResourceTitleRow(index).find('.import-resource-action-import-btn').invoke('show').trigger('click');
271
291
  }
272
292
 
273
293
  static importResourceByName(name) {
@@ -275,7 +295,7 @@ class ImportSteps {
275
295
  }
276
296
 
277
297
  static resetFileStatus(index) {
278
- this.getResource(index).find('.import-resource-action-reset-btn').click();
298
+ this.getResourceTitleRow(index).find('.import-resource-action-reset-btn').click();
279
299
  }
280
300
 
281
301
  static resetResourceStatusByName(name) {
@@ -1 +1 @@
1
- export const SERVER_FILES_COUNT = 20;
1
+ export const SERVER_FILES_COUNT = 17;
@@ -272,23 +272,14 @@ export class MainMenuSteps {
272
272
  }
273
273
 
274
274
  // --------------------------
275
- // -- Lab menu --
275
+ // -- TTYG menu --
276
276
  // --------------------------
277
- static getMenuLab() {
278
- return this.getMainMenu().getByTestId('menu-lab');
277
+ static getMenuTTYG() {
278
+ return this.getMainMenu().getByTestId('menu-ttyg');
279
279
  }
280
280
 
281
- static clickOnMenuLab() {
282
- return this.getMenuLab().click();
283
- }
284
-
285
- static clickOnTTYG() {
286
- this.clickOnMenuLab();
287
- this.clickOnTTYGSubmenu()
288
- }
289
-
290
- static clickOnTTYGSubmenu() {
291
- this.getSubMenuButton('sub-menu-ttyg').click();
281
+ static clickOnMenuTTYG() {
282
+ return this.getMenuTTYG().click();
292
283
  }
293
284
 
294
285
  // --------------------------
@@ -1,5 +1,11 @@
1
1
  const VIEW_URL = '/resource';
2
2
 
3
+ /**
4
+ * The label of the "triple term" role tab. It differs from the role itself, which is "triple-term".
5
+ * @type {string}
6
+ */
7
+ export const TRIPLE_TERM_ROLE_LABEL = 'triple term';
8
+
3
9
  export class ResourceSteps {
4
10
 
5
11
  static visit(parameters) {
@@ -89,8 +95,12 @@ export class ResourceSteps {
89
95
  return cy.get('#selection');
90
96
  }
91
97
 
98
+ static getRoleTabs() {
99
+ return ResourceSteps.getRoleSelectionElement().find('.nav-link');
100
+ }
101
+
92
102
  static getRoleTab(role = 'subject') {
93
- return ResourceSteps.getRoleSelectionElement().find('.nav-link').contains(role);
103
+ return ResourceSteps.getRoleTabs().contains(role);
94
104
  }
95
105
 
96
106
  static selectRole(role) {
@@ -121,21 +131,59 @@ export class ResourceSteps {
121
131
  ResourceSteps.getAllRoleTab().click();
122
132
  }
123
133
 
134
+ /**
135
+ * Verifies that the tab of the given role is the only active one. Only the rendered tabs are checked,
136
+ * because the "triple term" tab is rendered for triple terms only.
137
+ *
138
+ * @param {string} activeRole the label of the role tab which is expected to be active
139
+ */
124
140
  static verifyActiveRoleTab(activeRole = 'subject') {
125
- ResourceSteps.getAllRoles().forEach((role) => {
126
- const chainer = activeRole === role ? 'have.class' : 'not.have.class';
127
- ResourceSteps.getRoleTab(role).should(chainer, 'active');
141
+ // Assert that the expected tab is rendered at all, otherwise the check below passes vacuously.
142
+ ResourceSteps.getRoleTab(activeRole).should('have.class', 'active');
143
+ ResourceSteps.getRoleTabs().each(($tab) => {
144
+ const chainer = $tab.text().trim() === activeRole ? 'have.class' : 'not.have.class';
145
+ cy.wrap($tab).should(chainer, 'active');
128
146
  });
129
147
  }
130
148
 
131
- static getAllRoles() {
149
+ static verifyRoleTabDisabled(role) {
150
+ ResourceSteps.getRoleTab(role)
151
+ .should('have.class', 'disabled')
152
+ .and('have.attr', 'tabindex', '-1');
153
+ }
154
+
155
+ static verifyRoleTabEnabled(role) {
156
+ ResourceSteps.getRoleTab(role)
157
+ .should('not.have.class', 'disabled')
158
+ .and('have.attr', 'tabindex', '0');
159
+ }
160
+
161
+ static verifyRoleTabMissing(role) {
162
+ ResourceSteps.getRoleTabs().contains(role).should('not.exist');
163
+ }
164
+
165
+ /**
166
+ * @return {string[]} the roles which can be selected for a resource which is not a triple term.
167
+ */
168
+ static getPlainResourceRoles() {
132
169
  return ['subject', 'predicate', 'object', 'context', 'all'];
133
170
  }
134
171
 
172
+ /**
173
+ * @return {string[]} the labels of all role tabs, including the "triple term" one.
174
+ */
175
+ static getAllRoles() {
176
+ return [TRIPLE_TERM_ROLE_LABEL, ...ResourceSteps.getPlainResourceRoles()];
177
+ }
178
+
135
179
  static getTargetLink() {
136
180
  return cy.get('.target-link');
137
181
  }
138
182
 
183
+ static clickOnTargetLink() {
184
+ ResourceSteps.getTargetLink().click();
185
+ }
186
+
139
187
  static getTripleResourceLink() {
140
188
  return cy.get('.triple-resource-link');
141
189
  }
@@ -144,6 +192,17 @@ export class ResourceSteps {
144
192
  ResourceSteps.getTripleResourceLink().click();
145
193
  }
146
194
 
195
+ /**
196
+ * Verifies the text of an element after trimming it. The templates surround the interpolated
197
+ * values with whitespace, which makes a plain "have.text" assertion unusable.
198
+ *
199
+ * @param {Cypress.Chainable} element the element whose text has to be verified
200
+ * @param {string} expectedText the expected text without any surrounding whitespace
201
+ */
202
+ static verifyTrimmedText(element, expectedText) {
203
+ element.invoke('text').invoke('trim').should('eq', expectedText);
204
+ }
205
+
147
206
  static getDataTable() {
148
207
  return cy.get('.dataTable');
149
208
  }
@@ -357,7 +357,7 @@ export class AclManagementSteps {
357
357
  }
358
358
 
359
359
  static checkIfRuleSavingIsForbidden(index) {
360
- AclManagementSteps.getSaveRuleButton(index).should('not.exist');
360
+ AclManagementSteps.getSaveRuleButton(index).should('be.visible');
361
361
  AclManagementSteps.getSaveRuleDisabledButton(index).should('be.disabled');
362
362
  }
363
363
 
@@ -388,16 +388,6 @@ export const ACL_VIEW = [
388
388
  "object": "*",
389
389
  "context": "*"
390
390
  },
391
- {
392
- "scope": "statement",
393
- "policy": "deny",
394
- "role": "ROLE3",
395
- "operation": "read",
396
- "subject": "<<<http://example.com/test> <http://www.w3.org/2000/01/rdf-schema#label> \"test aber auf Deutsch\"@de>>",
397
- "predicate": "*",
398
- "object": "\"test aber auf Deutsch\"@en",
399
- "context": "<http://example.com/graph1>"
400
- },
401
391
  {
402
392
  "scope": "statement",
403
393
  "policy": "allow",
@@ -415,7 +405,7 @@ export const ACL_VIEW = [
415
405
  "operation": "write",
416
406
  "subject": "<urn:Cat>",
417
407
  "predicate": "*",
418
- "object": "<<<http://example.com/test> <http://www.w3.org/2000/01/rdf-schema#label> \"test aber auf Deutsch\"@de>>",
408
+ "object": "<<( <http://example.com/test> <http://www.w3.org/2000/01/rdf-schema#label> \"test aber auf Deutsch\"@de )>>",
419
409
  "context": "*"
420
410
  }
421
411
  ];
@@ -440,16 +430,6 @@ export const ACL = [
440
430
  "object": "*",
441
431
  "context": "*"
442
432
  },
443
- {
444
- "scope": "statement",
445
- "policy": "deny",
446
- "role": "CUSTOM_ROLE3",
447
- "operation": "read",
448
- "subject": "<<<http://example.com/test> <http://www.w3.org/2000/01/rdf-schema#label> \"test aber auf Deutsch\"@de>>",
449
- "predicate": "*",
450
- "object": "\"test aber auf Deutsch\"@en",
451
- "context": "<http://example.com/graph1>"
452
- },
453
433
  {
454
434
  "scope": "statement",
455
435
  "policy": "allow",
@@ -467,7 +447,7 @@ export const ACL = [
467
447
  "operation": "write",
468
448
  "subject": "<urn:Cat>",
469
449
  "predicate": "*",
470
- "object": "<<<http://example.com/test> <http://www.w3.org/2000/01/rdf-schema#label> \"test aber auf Deutsch\"@de>>",
450
+ "object": "<<( <http://example.com/test> <http://www.w3.org/2000/01/rdf-schema#label> \"test aber auf Deutsch\"@de )>>",
471
451
  "context": "*"
472
452
  }
473
453
  ];
@@ -77,6 +77,13 @@ export class ClusterStubs extends Stubs {
77
77
  }).as('cluster-config');
78
78
  }
79
79
 
80
+ static stubClusterConfigWithTag() {
81
+ cy.intercept('/rest/cluster/config', {
82
+ fixture: '/cluster/cluster-config-with-tag.json',
83
+ statusCode: 200
84
+ }).as('cluster-config-with-tag');
85
+ }
86
+
80
87
  static stubDeleteCluster() {
81
88
  cy.intercept('/rest/cluster/config?force=false', {
82
89
  fixture: '/cluster/delete-cluster.json',
@@ -20,6 +20,10 @@ export class RepositoriesStubs extends Stubs {
20
20
  cy.intercept('GET', '/rest/locations/active').as('getActiveLocations');
21
21
  }
22
22
 
23
+ static spyGetRepository(id) {
24
+ cy.intercept(`GET`, `${REPOSITORIES_URL}/${id}?location=`).as('getRepository');
25
+ }
26
+
23
27
  static stubLocations(withDelay = 0) {
24
28
  RepositoriesStubs.stubQueryResponse('/rest/locations', '/repositories/get-locations.json', 'get-locations', withDelay);
25
29
  }
@@ -1,32 +0,0 @@
1
- @prefix ex: <http://example.com/> .
2
- @prefix dct: <http://purl.org/dc/terms/> .
3
- @prefix foaf: <http://xmlns.com/foaf/0.1/> .
4
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
5
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
6
-
7
-
8
- graph ex:rdfstar {
9
- ex:bob foaf:knows << ex:alice foaf:knows<<ex:bob dct:created ex:book>> >> .
10
-
11
- <<<< ex:bob dct:created ex:book >> foaf:knows ex:alice >> dct:source ex:otherbook .
12
-
13
- ex:bobshomepage dct:source<< ex:book dct:creator ex:alice >> .
14
-
15
- << ex:book dct:creator ex:alice >> dct:source ex:bobshomepage .
16
-
17
- << ex:book dct:creator ex:alice >> dct:requires << ex:alice dct:created ex:book >> .
18
-
19
- <<<http://example.org/a>ex:b ex:c>>ex:valid "1999-08-16"^^xsd:date .
20
-
21
- << # Start of triple
22
- ex:bob # triple subject
23
- foaf:birthday # triple predicate
24
- "1908-03-18"^^xsd:date # triple object
25
- >> # end of triple
26
- dct:source ex:bobshomepage .
27
-
28
- << ex:book dct:title "Example book"@en >> dct:source ex:bobshomepage .
29
- << ex:book dct:title "Beispielbuch"@de>> dct:source ex:bobshomepage.
30
- << ex:book dct:title "Example Book"@en-US>> dct:source ex:bobshomepage.
31
-
32
- }
@@ -1,6 +0,0 @@
1
- @prefix ex:<http:/base.org/> .
2
-
3
- ex:foo ex:pred ex:obj .
4
- <<ex:foo rdfs:label "label">> ex:author "guest" .
5
- ex:obj ex:quote <<ex:meta ex:data ex:foo>> .
6
- <<<<ex:foo rdfs:label "label">> ex:data ex:foo>> ex:recursive true .
@@ -1,77 +0,0 @@
1
- @prefix foaf: <http://xmlns.com/foaf/0.1/> .
2
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
3
- @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
4
- @prefix dc: <http://purl.org/dc/terms/> .
5
- @prefix re: <http://reasoner.example.com/engines#> .
6
- @prefix rr: <http://reasoner.example.com/rules#> .
7
- @prefix rv: <http://reasoner.example.com/vocabulary#> .
8
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
9
- @prefix bd: <http://bigdata.com/RDF#> .
10
-
11
- bd:alice
12
- rdf:type foaf:Person ;
13
- foaf:name "Alice" ;
14
- foaf:mbox <mailto:alice@work> ;
15
- foaf:knows bd:bob.
16
-
17
- # The terse syntax:
18
- <<bd:alice foaf:mbox <mailto:alice@work>>>
19
- dc:source <http://hr.example.com/employees#bob> ;
20
- dc:created "2012-02-05T12:34:00Z"^^xsd:dateTime .
21
- # The expanded syntax.
22
- #_:s1 rdf:subject bd:alice .
23
- #_:s1 rdf:predicate foaf:mbox .
24
- #_:s1 rdf:object <mailto:alice@work> .
25
- #_:s1 rdf:type rdf:Statement .
26
- #_:s1 dc:source <http://hr.example.com/employees#bob> ;
27
- # dc:created "2012-02-05T12:34:00Z"^^xsd:dateTime .
28
-
29
- # Terse
30
- <<bd:alice foaf:knows bd:bob>>
31
- dc:source re:engine_1;
32
- rv:rule rr:rule524 ;
33
- rv:confidence 0.9835 .
34
- # Expanded
35
- #_:s2 rdf:subject bd:alice .
36
- #_:s2 rdf:predicate foaf:knows .
37
- #_:s2 rdf:object bd:bob .
38
- #_:s2 rdf:type rdf:Statement .
39
- #_:s2
40
- # dc:source re:engine_1;
41
- # rv:rule rr:rule524 ;
42
- # rv:confidence 0.9835 .
43
-
44
- bd:bob
45
- rdf:type foaf:Person ;
46
- foaf:name "Bob" ;
47
- foaf:knows bd:alice ;
48
- foaf:mbox <mailto:bob@work> ;
49
- foaf:mbox <mailto:bob@home> .
50
-
51
- # Terse
52
- <<bd:bob foaf:mbox <mailto:bob@home>>>
53
- dc:creator <http://hr.example.com/infra/crawlers#we1> ;
54
- dc:created "2012-02-05T12:34:00Z"^^xsd:dateTime ;
55
- dc:source <http://whatever.nu/profile/bob1975> .
56
- # Expanded
57
- #_:s3 rdf:subject bd:bob .
58
- #_:s3 rdf:predicate foaf:mbox .
59
- #_:s3 rdf:object <mailto:bob@home> .
60
- #_:s3 rdf:type rdf:Statement .
61
- #_:s3
62
- # dc:creator <http://hr.example.com/infra/crawlers#we1> ;
63
- # dc:created "2011-04-05T12:00:00Z"^^xsd:dateTime ;
64
- # dc:source <http://whatever.nu/profile/bob1975> .
65
-
66
- # Terse
67
- <<bd:bob foaf:mbox <mailto:bob@home>>>
68
- dc:source <http://hr.example.com/employees/bob> ;
69
- dc:created "2012-02-05T12:34:00Z"^^xsd:dateTime .
70
- # Expanded
71
- #_:s4 rdf:subject bd:bob .
72
- #_:s4 rdf:predicate foaf:mbox .
73
- #_:s4 rdf:object <mailto:bob@home> .
74
- #_:s4 rdf:type rdf:Statement .
75
- #_:s4
76
- # dc:source <http://hr.example.com/employees/bob> ;
77
- # dc:created "2012-02-05T12:34:00Z"^^xsd:dateTime .