graphdb-workbench-tests 3.3.1 → 3.4.0-dynamic-guides-test

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 (70) hide show
  1. package/cypress-flaky.config.js +2 -0
  2. package/cypress-legacy.config.js +2 -2
  3. package/cypress-security.config.js +3 -14
  4. package/e2e-flaky/import/import-server-files-operations.spec.js +1 -1
  5. package/e2e-flaky/import/import-user-data-batch-operations.spec.js +1 -1
  6. package/e2e-flaky/setup/sparql-template-create.js +3 -18
  7. package/e2e-flaky/sparql-editor/actions/execute-update-query.spec.js +2 -12
  8. package/e2e-flaky/sparql-editor/actions/share-query.spec.js +1 -7
  9. package/e2e-flaky/sparql-editor/yasr/table-plugin.spec.js +1 -6
  10. package/e2e-legacy/explore/visual-graph/visual.graph.spec.js +2 -7
  11. package/e2e-legacy/graphql/graphql-theme.spec.js +73 -0
  12. package/e2e-legacy/guides/execute-sparql-query/execute-sparql-query-guide.spec.js +92 -0
  13. package/e2e-legacy/guides/import-rdf-file/confirm-duplicate-rdf-file.spec.js +63 -0
  14. package/e2e-legacy/guides/import-rdf-file/import-rdf-file.spec.js +105 -0
  15. package/e2e-legacy/guides/main-menu/main-menu-guide.spec.js +302 -0
  16. package/e2e-legacy/guides/rdf-rank/rdf-rank-guide.spec.js +42 -0
  17. package/e2e-legacy/guides/table-graph-explore/table-graph-explore-guide.spec.js +167 -0
  18. package/e2e-legacy/guides/ttyg/conversation/ttyg-conversation-guide.spec.js +6 -2
  19. package/e2e-legacy/guides/ttyg/edit-agent/edit-ttyg-agent-guide.spec.js +87 -0
  20. package/e2e-legacy/guides/visual-graph/visual-graph-guide.spec.js +166 -0
  21. package/e2e-legacy/guides/welcome/welcome-guide.spec.js +36 -0
  22. package/e2e-legacy/help/guides/movies-interactive-guide.spec.js +47 -49
  23. package/e2e-legacy/import/import-server-files.spec.js +3 -1
  24. package/e2e-legacy/repository/repositories.spec.js +5 -2
  25. package/e2e-legacy/repository/url-with-repository-id-parameter.spec.js +26 -0
  26. package/e2e-legacy/resource/resource.spec.js +1 -6
  27. package/e2e-legacy/setup/aclmanagement/create-rule.spec.js +3 -0
  28. package/e2e-legacy/setup/connectors-lucene.spec.js +24 -8
  29. package/e2e-legacy/setup/users-and-access/user-and-access.spec.js +36 -0
  30. package/e2e-legacy/sparql-editor/actions/expand-results-over-sameas.spec.js +1 -1
  31. package/e2e-legacy/sparql-editor/actions/show-saved-queries.spec.js +1 -6
  32. package/e2e-legacy/sparql-editor/yasgui-tabs.spec.js +2 -12
  33. package/e2e-legacy/sparql-editor/yasr/pagination.spec.js +5 -18
  34. package/e2e-legacy/sparql-editor/yasr/table-plugin.spec.js +1 -6
  35. package/e2e-legacy/sparql-editor/yasr/toolbar/visual-graph-button.spec.js +1 -6
  36. package/e2e-legacy/ttyg/chat-list.spec.js +2 -12
  37. package/e2e-legacy/ttyg/create-agent.spec.js +8 -48
  38. package/e2e-legacy/ttyg/edit-agent.spec.js +2 -12
  39. package/e2e-security/repository/url-with-repository-id-parameter.spec.js +57 -0
  40. package/e2e-security/setup/users-and-access/turn-on-security-and-password-change.spec.js +4 -5
  41. package/fixtures/guides/execute-sparql-query/execute-sparql-query-guide.json +54 -0
  42. package/fixtures/guides/import-rdf-file/confirm-duplicate-rdf-file-guide.json +30 -0
  43. package/fixtures/guides/import-rdf-file/import-rdf-file-guide.json +21 -0
  44. package/fixtures/guides/main-menu/main-menu-guide.json +98 -0
  45. package/fixtures/guides/rdf-rank/rdf-rank-guide.json +18 -0
  46. package/fixtures/guides/table-graph-explore/table-graph-explore-guide.json +51 -0
  47. package/fixtures/guides/table-graph-explore/table-graph-explore-without-substeps-guide.json +25 -0
  48. package/fixtures/guides/ttyg/edit-ttyg-agent/edit-ttyg-agent-guide.json +22 -0
  49. package/fixtures/guides/visual-graph/visual-graph-guide.json +85 -0
  50. package/fixtures/guides/welcome/welcome-guide.json +18 -0
  51. package/npm-shrinkwrap.json +317 -263
  52. package/package.json +1 -1
  53. package/steps/base-steps.js +4 -0
  54. package/steps/error-page-steps.js +9 -0
  55. package/steps/graphql/playground-editor-steps.js +46 -0
  56. package/steps/guides/guide-dialog-steps.js +4 -0
  57. package/steps/import/import-resource-message-dialog.js +1 -1
  58. package/steps/login-steps.js +4 -0
  59. package/steps/main-menu-steps.js +12 -0
  60. package/steps/repository-steps.js +2 -2
  61. package/steps/setup/acl-management-steps.js +4 -0
  62. package/steps/setup/user-and-access-steps.js +14 -6
  63. package/steps/sparql-steps.js +13 -1
  64. package/steps/visual-graph-steps.js +17 -1
  65. package/steps/yasgui/yasqe-steps.js +29 -4
  66. package/steps/yasgui/yasr-steps.js +4 -0
  67. package/stubs/guides/guides-stubs.js +41 -1
  68. package/stubs/security-stubs.js +4 -0
  69. package/stubs/ttyg/ttyg-stubs.js +2 -4
  70. package/support/e2e-security.js +9 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "3.3.1",
3
+ "version": "3.4.0-dynamic-guides-test",
4
4
  "description": "Cypress tests for GraphDB workbench",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -22,4 +22,8 @@ export class BaseSteps {
22
22
  static getUrl() {
23
23
  return cy.url();
24
24
  }
25
+
26
+ static validateUrl(url) {
27
+ this.getUrl().should('include', url);
28
+ }
25
29
  }
@@ -0,0 +1,9 @@
1
+ export class ErrorPageSteps {
2
+ static visit404() {
3
+ cy.visit('/404');
4
+ }
5
+
6
+ static get404Page() {
7
+ return cy.get('app-not-found-page');
8
+ }
9
+ }
@@ -0,0 +1,46 @@
1
+ export class PlaygroundEditorSteps {
2
+
3
+ static getResponse() {
4
+ return cy.get('.graphiql-response');
5
+ }
6
+
7
+ static getResponseCodeMirror() {
8
+ return PlaygroundEditorSteps.getResponse().find('.CodeMirror');
9
+ }
10
+
11
+ static getGraphiqlEditors() {
12
+ return cy.get('.graphiql-editors');
13
+ }
14
+
15
+ static getGraphiqlEditorsCodeMirror() {
16
+ return PlaygroundEditorSteps.getGraphiqlEditors().find('.CodeMirror');
17
+ }
18
+
19
+ static getGraphiqlEditorTools() {
20
+ return cy.get('.graphiql-editor-tools');
21
+ }
22
+
23
+ static getGraphiqlEditorTool() {
24
+ return cy.get('.graphiql-editor-tool');
25
+ }
26
+
27
+ static getVariablesBtn() {
28
+ return PlaygroundEditorSteps.getGraphiqlEditorTools().find('button[data-name="variables"]');
29
+ }
30
+
31
+ static openVariables() {
32
+ PlaygroundEditorSteps.getVariablesBtn().click();
33
+ }
34
+
35
+ static getHeadersBtn() {
36
+ return PlaygroundEditorSteps.getGraphiqlEditorTools().find('button[data-name="headers"]');
37
+ }
38
+
39
+ static openHeaders() {
40
+ PlaygroundEditorSteps.getHeadersBtn().click();
41
+ }
42
+
43
+ static getActiveGraphiqlEditorToolCodeMirror() {
44
+ return PlaygroundEditorSteps.getGraphiqlEditorTool().find('.graphiql-editor:not(.hidden) .CodeMirror');
45
+ }
46
+ }
@@ -56,4 +56,8 @@ export class GuideDialogSteps {
56
56
  static assertDialogIsClosed() {
57
57
  GuideDialogSteps.getModalDialog().should('not.exist');
58
58
  }
59
+
60
+ static copyQueryToEditor() {
61
+ GuideDialogSteps.getModalDialog().find('.guide-copy-to-editor-query-button').click();
62
+ }
59
63
  }
@@ -14,7 +14,7 @@ export class ImportResourceMessageDialog extends ModalDialogSteps {
14
14
  }
15
15
 
16
16
  static getMessage() {
17
- return this.getDialogBody().find('.message');
17
+ return this.getDialogBody();
18
18
  }
19
19
 
20
20
  static getCopyToClipboard() {
@@ -18,6 +18,10 @@ export class LoginSteps {
18
18
  cy.visit(`/login?r=${returnURLEncoded}`);
19
19
  }
20
20
 
21
+ static getLoginPage() {
22
+ return cy.get('app-login');
23
+ }
24
+
21
25
  static navigateToLoginPage() {
22
26
  cy.get('onto-user-login').click();
23
27
  }
@@ -95,6 +95,10 @@ export class MainMenuSteps {
95
95
 
96
96
  static clickOnVisualGraph() {
97
97
  this.clickOnExplore();
98
+ this.clickOnSubmenuVisualGraph();
99
+ }
100
+
101
+ static clickOnSubmenuVisualGraph() {
98
102
  this.getSubMenuButton('sub-menu-visual-graph').click();
99
103
  }
100
104
 
@@ -190,11 +194,19 @@ export class MainMenuSteps {
190
194
 
191
195
  static clickOnRDFRank() {
192
196
  this.clickOnMenuSetup();
197
+ this.clickOnSubmenuRDFRank();
198
+ }
199
+
200
+ static clickOnSubmenuRDFRank() {
193
201
  this.getSubMenuButton('sub-menu-rdf-rank').click();
194
202
  }
195
203
 
196
204
  static clickOnConnectors() {
197
205
  this.clickOnMenuSetup();
206
+ this.clickOnSubmenuConnectors();
207
+ }
208
+
209
+ static clickOnSubmenuConnectors() {
198
210
  this.getSubMenuButton('sub-menu-connectors').click();
199
211
  }
200
212
 
@@ -76,7 +76,7 @@ export class RepositorySteps extends BaseSteps {
76
76
  }
77
77
 
78
78
  static getRepositoryConnectionOffBtn(id) {
79
- return RepositorySteps.getRepositoryFromList(id).find('.ri-link-unlink');
79
+ return RepositorySteps.getRepositoryFromList(id).find('.icon-connection-off');
80
80
  }
81
81
 
82
82
  static activateRepository(id) {
@@ -84,7 +84,7 @@ export class RepositorySteps extends BaseSteps {
84
84
  }
85
85
 
86
86
  static getRepositoryConnectionOnBtn(id) {
87
- return RepositorySteps.getRepositoryFromList(id).find('.ri-link');
87
+ return RepositorySteps.getRepositoryFromList(id).find('.icon-connection-on');
88
88
  }
89
89
 
90
90
  static clickRepositoryIcon(repositoryId, selector) {
@@ -165,6 +165,10 @@ export class AclManagementSteps {
165
165
  this.getRoleField(index).clear().type(value);
166
166
  }
167
167
 
168
+ static blurRole(index) {
169
+ this.getRoleField(index).blur();
170
+ }
171
+
168
172
  static getFieldError() {
169
173
  return cy.get('div.small');
170
174
  }
@@ -13,6 +13,10 @@ export class UserAndAccessSteps {
13
13
  });
14
14
  }
15
15
 
16
+ static getUsersCatalogContainer() {
17
+ return cy.get('#wb-users');
18
+ }
19
+
16
20
  static getUrl() {
17
21
  return cy.url();
18
22
  }
@@ -105,6 +109,10 @@ export class UserAndAccessSteps {
105
109
  .closest('tr').as('user');
106
110
  }
107
111
 
112
+ static getUserCustomRoles(userRow) {
113
+ return cy.get(userRow).getByTestId('custom-roles').getByTestId('custom-role');
114
+ }
115
+
108
116
  static getUsernameField() {
109
117
  return cy.get('#wb-user-username');
110
118
  }
@@ -359,15 +367,15 @@ export class UserAndAccessSteps {
359
367
  }
360
368
 
361
369
  static clickFreeWriteAccessRepo(repoName) {
362
- const repoRow = cy.get('.repo-fields').contains(repoName).parent('.row');
363
- repoRow.scrollIntoView();
364
- repoRow.find('.write').realClick();
370
+ cy.get('.repo-fields').contains(repoName).parent('.row').as('row');
371
+ cy.get('@row').scrollIntoView();
372
+ cy.get('@row').find('.write').realClick();
365
373
  }
366
374
 
367
375
  static clickFreeGraphqlAccessRepo(repoName) {
368
- const repoRow = cy.get('.repo-fields').contains(repoName).parent('.row');
369
- repoRow.scrollIntoView();
370
- repoRow.find('.graphql').realClick();
376
+ cy.get('.repo-fields').contains(repoName).parent('.row').as('row');
377
+ cy.get('@row').scrollIntoView();
378
+ cy.get('@row').find('.graphql').realClick();
371
379
  }
372
380
 
373
381
  }
@@ -63,8 +63,12 @@ class SparqlSteps {
63
63
  this.getLoader().should('not.exist');
64
64
  }
65
65
 
66
+ static getActiveTabPanel() {
67
+ return cy.get('.tabPanel.active');
68
+ }
69
+
66
70
  static getRunQueryButton() {
67
- return cy.get('#wb-sparql-runQuery');
71
+ return this.getActiveTabPanel().find('.yasqe_queryButton');
68
72
  }
69
73
 
70
74
  static getNoQueryRunInfo() {
@@ -124,6 +128,14 @@ class SparqlSteps {
124
128
  return cy.get('#saveAsBtn');
125
129
  }
126
130
 
131
+ static getVisualBtn() {
132
+ return this.getActiveTabPanel().find('.explore-visual-graph-button');
133
+ }
134
+
135
+ static visualizeConstructQuery() {
136
+ this.getVisualBtn().click();
137
+ }
138
+
127
139
  static getEditorAndResultsBtn() {
128
140
  return cy.get('.editor-and-results-btn');
129
141
  }
@@ -148,6 +148,14 @@ export class VisualGraphSteps extends BaseSteps {
148
148
  return cy.get(`[id="${nodeId}"] circle`);
149
149
  }
150
150
 
151
+ static clickOnNode(nodeId) {
152
+ this.getCircleOfNodeByNodeId(nodeId).click();
153
+ }
154
+
155
+ static dblclickOnNode(nodeId) {
156
+ this.getCircleOfNodeByNodeId(nodeId).dblclick();
157
+ }
158
+
151
159
  static getLineBetweenNodesById(narrowId) {
152
160
  return cy.get(`[id="${narrowId}"] line`);
153
161
  }
@@ -157,13 +165,17 @@ export class VisualGraphSteps extends BaseSteps {
157
165
  }
158
166
 
159
167
  static getSidePanelCloseButton() {
160
- return cy.get('');
168
+ return this.getSidePanelContent().find('.close');
161
169
  }
162
170
 
163
171
  static getSidePanelContent() {
164
172
  return cy.get('.rdf-side-panel-content');
165
173
  }
166
174
 
175
+ static closeSidePanel() {
176
+ this.getSidePanelCloseButton().click();
177
+ }
178
+
167
179
  // Visual graph settings form field access
168
180
 
169
181
  static openPredicatesTab() {
@@ -429,6 +441,10 @@ export class VisualGraphSteps extends BaseSteps {
429
441
  .find('#auto-complete-results-wrapper .result-item').eq(index).click();
430
442
  }
431
443
 
444
+ static clickOnAutocompleteElement(elementText) {
445
+ cy.get('.result-item').contains(elementText).click();
446
+ }
447
+
432
448
  static getSelectedStartNodeUri() {
433
449
  return this.getStartNodeSelectorComponent().find('.selected-node code');
434
450
  }
@@ -35,8 +35,29 @@ export class YasqeSteps {
35
35
  return YasqeSteps.getYasqe().find('.yasqe_queryButton');
36
36
  }
37
37
 
38
+ /**
39
+ * Clicks on the execute query button and hides the tooltip, which is sometimes overlapping the button and prevents
40
+ * it from being clicked.
41
+ * @param force - whether to force the click and mouseleave events. This is needed when testing a guide, because the
42
+ * shepherd's overlay is overlapping the button and prevents it from being clicked. In other scenarios, it is better
43
+ * not to force the click, because we want to make sure that the button is actually clickable by the user.
44
+ */
45
+ static clickExecuteQueryButtonAndHideTooltip(force = false) {
46
+ this.getExecuteQueryButton().click({force});
47
+ this.getExecuteQueryButton().trigger('mouseleave', {force: true});
48
+ }
49
+
38
50
  static executeQuery() {
39
- this.getExecuteQueryButton().click();
51
+ this.clickExecuteQueryButtonAndHideTooltip();
52
+ YasrSteps.getResponseInfo()
53
+ .should('not.have.class', 'hidden')
54
+ .should('not.have.class', 'empty')
55
+ .should('be.visible');
56
+ }
57
+
58
+ // This step is needed when testing a guide. The shepherd's overlay is overlapping somehow the button.
59
+ static forceExecuteQuery() {
60
+ this.clickExecuteQueryButtonAndHideTooltip(true);
40
61
  YasrSteps.getResponseInfo()
41
62
  .should('not.have.class', 'hidden')
42
63
  .should('not.have.class', 'empty')
@@ -44,11 +65,11 @@ export class YasqeSteps {
44
65
  }
45
66
 
46
67
  static executeQueryWithoutWaiteResult() {
47
- this.getExecuteQueryButton().click();
68
+ this.clickExecuteQueryButtonAndHideTooltip();
48
69
  }
49
70
 
50
71
  static executeErrorQuery() {
51
- this.getExecuteQueryButton().click();
72
+ this.clickExecuteQueryButtonAndHideTooltip();
52
73
  // Wait a wile for the response information to be present.
53
74
  cy.get('.error-response-plugin').should('be.visible');
54
75
  }
@@ -95,7 +116,11 @@ export class YasqeSteps {
95
116
  return cy.waitUntil(() =>
96
117
  this.getEditor().find('.CodeMirror')
97
118
  .then((codeMirrorEl) => {
98
- return codeMirrorEl && codeMirrorEl[0].CodeMirror.getValue().indexOf(query) !== -1;
119
+ if (codeMirrorEl && codeMirrorEl[0].CodeMirror.getValue().indexOf(query) !== -1) {
120
+ return true;
121
+ } else {
122
+ cy.fail('Query in editor is not as expected. Expected query:\n' + query + '\nActual query:\n' + codeMirrorEl[0].CodeMirror.getValue());
123
+ }
99
124
  }));
100
125
  }
101
126
 
@@ -63,6 +63,10 @@ export class YasrSteps {
63
63
  this.getResultCell(rowNumber, cellNumber).realHover();
64
64
  }
65
65
 
66
+ static clickOnResource(rowNumber, cellNumber) {
67
+ this.getResultCell(rowNumber, cellNumber).find('.uri-link').click({force: true});
68
+ }
69
+
66
70
  static getCopyResourceLink(rowNumber, cellNumber) {
67
71
  return this.getResultCell(rowNumber, cellNumber)
68
72
  .realHover()
@@ -15,6 +15,10 @@ export class GuidesStubs {
15
15
  GuidesStubs.stubWithFixture('../fixtures/guides/ttyg/conversation/ttyg-conversation-guide.json');
16
16
  }
17
17
 
18
+ static stubTTYGEditAgentGuide() {
19
+ GuidesStubs.stubWithFixture('../fixtures/guides/ttyg/edit-ttyg-agent/edit-ttyg-agent-guide.json');
20
+ }
21
+
18
22
  static stubClassHierarchyGuide() {
19
23
  GuidesStubs.stubWithFixture('../fixtures/guides/class-hierarchy/class-hierarchy-guide.json');
20
24
  }
@@ -39,10 +43,46 @@ export class GuidesStubs {
39
43
  GuidesStubs.stubWithFixture('../fixtures/guides/download-guide-resource/download-guide-resource-guide.json');
40
44
  }
41
45
 
46
+ static stubMainMenuGuide() {
47
+ GuidesStubs.stubWithFixture('../fixtures/guides/main-menu/main-menu-guide.json');
48
+ }
49
+
50
+ static stubExecuteSparqlQueryGuide() {
51
+ GuidesStubs.stubWithFixture('../fixtures/guides/execute-sparql-query/execute-sparql-query-guide.json');
52
+ }
53
+
42
54
  static stubDownloadResource(resourcePath, resourceFile) {
43
55
  cy.intercept('GET', `/rest/guides/download/${resourcePath}/${resourceFile}`, {
44
56
  fixture: `guides/download-resource.ttl`,
45
- }).as('resource-download');;
57
+ }).as('resource-download');
58
+ }
59
+
60
+ static stubImportRDFFileGuide() {
61
+ GuidesStubs.stubWithFixture('../fixtures/guides/import-rdf-file/import-rdf-file-guide.json');
62
+ }
63
+
64
+ static stubConfirmDuplicatedRDFFileGuide() {
65
+ GuidesStubs.stubWithFixture('../fixtures/guides/import-rdf-file/confirm-duplicate-rdf-file-guide.json');
66
+ }
67
+
68
+ static stubRDFRankGuide() {
69
+ GuidesStubs.stubWithFixture('../fixtures/guides/rdf-rank/rdf-rank-guide.json');
70
+ }
71
+
72
+ static stubTableGraphExploreWithoutSubstepsGuide() {
73
+ GuidesStubs.stubWithFixture('../fixtures/guides/table-graph-explore/table-graph-explore-without-substeps-guide.json');
74
+ }
75
+
76
+ static stubTableGraphExploreGuide() {
77
+ GuidesStubs.stubWithFixture('../fixtures/guides/table-graph-explore/table-graph-explore-guide.json');
78
+ }
79
+ static stubWelcomGuide() {
80
+ GuidesStubs.stubWithFixture('../fixtures/guides/welcome/welcome-guide.json');
81
+ }
82
+
83
+
84
+ static stubVisualGraphGuide() {
85
+ GuidesStubs.stubWithFixture('../fixtures/guides/visual-graph/visual-graph-guide.json');
46
86
  }
47
87
 
48
88
  static stubWithFixture(fixturePath) {
@@ -10,6 +10,10 @@ export class SecurityStubs {
10
10
  }).as('security-get-admin');
11
11
  }
12
12
 
13
+ static spyOnUserCreate() {
14
+ cy.intercept('POST', 'rest/security/users/*').as('create-user');
15
+ }
16
+
13
17
  static stubInferAndSameAsDefaults() {
14
18
  cy.intercept('rest/security/all', (req) => {
15
19
  req.reply(SecurityStubs.getResponseSecurityEnabled());
@@ -106,12 +106,10 @@ export class TTYGStubs extends Stubs {
106
106
  }).as('get-agent');
107
107
  }
108
108
 
109
- static stubAgentListGetError() {
109
+ static stubAgentListGetError(error = 'Internal Server Error') {
110
110
  cy.intercept('GET', '/rest/chat/agents', {
111
111
  statusCode: 500,
112
- response: {
113
- error: 'Internal Server Error'
114
- }
112
+ body: error
115
113
  }).as('get-agent-list-error');
116
114
  }
117
115
 
@@ -0,0 +1,9 @@
1
+ import './e2e';
2
+
3
+ afterEach(() => {
4
+ cy.loginAsAdmin();
5
+ // Switch off security after each test to ensure that tests are independent and don't affect each other.
6
+ // For example, if security is enabled in one test, it can cause other tests that don't expect security to fail.
7
+ cy.switchOffSecurity(true);
8
+ cy.switchOffFreeAccess(true);
9
+ });