graphdb-workbench-tests 2.8.0-Test → 2.8.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.
Files changed (117) hide show
  1. package/cypress.config.js +3 -0
  2. package/fixtures/cluster/2-nodes-cluster-group-status-deleted.json +30 -0
  3. package/fixtures/cluster/2-nodes-cluster-group-status.json +30 -0
  4. package/fixtures/cluster/3-nodes-cluster-group-status-after-replace.json +44 -0
  5. package/fixtures/cluster/3-nodes-cluster-group-status-building-snapshot.json +4 -1
  6. package/fixtures/cluster/3-nodes-cluster-group-status-receiving-snapshot.json +4 -1
  7. package/fixtures/cluster/3-nodes-cluster-group-status-sending-snapshot.json +4 -1
  8. package/fixtures/cluster/3-nodes-cluster-group-status-waiting-for-snapshot.json +4 -1
  9. package/fixtures/cluster/3-nodes-cluster-group-status-with-tag.json +47 -0
  10. package/fixtures/cluster/3-nodes-cluster-group-status.json +12 -3
  11. package/fixtures/cluster/4-nodes-cluster-group-status.json +58 -0
  12. package/fixtures/cluster/cluster-config.json +1 -0
  13. package/fixtures/cluster/cluster-node-status.json +4 -1
  14. package/fixtures/cluster/no-cluster-group-status.json +2 -1
  15. package/fixtures/cluster/no-cluster-node-status.json +2 -1
  16. package/fixtures/cluster/save-cluster-configuration-response.json +10 -0
  17. package/fixtures/connectors/get-retrieval-connector.json +1 -1
  18. package/fixtures/connectors/get-ttyg-chatgpt-connectors.json +188 -0
  19. package/fixtures/locale-en.json +382 -101
  20. package/fixtures/remote-location/get-0-remote-locations.json +1 -2
  21. package/fixtures/remote-location/get-1-remote-locations.json +2 -4
  22. package/fixtures/remote-location/get-2-remote-locations.json +3 -6
  23. package/fixtures/remote-location/get-3-remote-locations.json +4 -8
  24. package/fixtures/remote-location/get-4-remote-locations.json +54 -0
  25. package/fixtures/remote-location/remote-location-status-in-cluster.json +1 -2
  26. package/fixtures/remote-location/remote-location-status-not-in-cluster.json +1 -2
  27. package/fixtures/remote-location/remote-locations-filter.json +1 -2
  28. package/fixtures/repositories/get-locations.json +5 -10
  29. package/fixtures/repositories/get-ttyg-repositories.json +28 -0
  30. package/fixtures/security/get-admin-user.json +22 -0
  31. package/fixtures/similarity/get-ttyg-similarity-connectors.json +46 -0
  32. package/fixtures/ttyg/agent/create-agent.json +2 -1
  33. package/fixtures/ttyg/agent/get-agent-defaults.json +42 -0
  34. package/fixtures/ttyg/agent/get-agent-list-after-deleted.json +1 -1
  35. package/fixtures/ttyg/agent/get-agent-list-new-agent.json +2 -73
  36. package/fixtures/ttyg/agent/get-agent-list.json +1 -1
  37. package/fixtures/ttyg/agent/get-agent.json +25 -0
  38. package/fixtures/ttyg/chats/ask-question.json +25 -0
  39. package/fixtures/ttyg/chats/create/create-chat-response.json +16 -0
  40. package/fixtures/ttyg/chats/create/get-chats-after-create.json +12 -0
  41. package/fixtures/ttyg/chats/create/get-chats-before-create.json +7 -0
  42. package/fixtures/ttyg/chats/explain-response-1.json +59 -0
  43. package/fixtures/ttyg/chats/explain-response-2.json +59 -0
  44. package/fixtures/ttyg/chats/get-chat.json +199 -0
  45. package/integration/cluster/cluster-configuration/cluster-configuration-multi-region.spec.js +97 -0
  46. package/integration/cluster/cluster-configuration/cluster-configuration-nodes.spec.js +70 -0
  47. package/integration/cluster/cluster-configuration/cluster-configuration-properties.spec.js +95 -0
  48. package/integration/cluster/cluster-configuration/cluster-configuration.spec.js +38 -0
  49. package/integration/cluster/cluster-legend.spec.js +1 -0
  50. package/integration/cluster/edit-cluster-nodes-modal.spec.js +425 -0
  51. package/integration/explore/graphs.overview.spec.js +4 -0
  52. package/integration/explore/similariti-index-create.spec.js +1 -1
  53. package/integration/explore/similarity-index.spec.js +1 -1
  54. package/integration/explore/visual-graph/visual.graph.spec.js +31 -35
  55. package/integration/home/cookie-policy.spec.js +83 -0
  56. package/integration/home/create-repository.spec.js +35 -0
  57. package/integration/home/documentation-link.spec.js +60 -0
  58. package/integration/home/google-analytics.spec.js +60 -0
  59. package/integration/home/language-selector.spec.js +19 -0
  60. package/integration/home/rdf-resource-search.spec.js +192 -0
  61. package/integration/home/view-resource-autocomplete.spec.js +52 -0
  62. package/integration/home/workbench.home.spec.js +1 -277
  63. package/integration/import/import-user-data-file-upload.spec.js +13 -0
  64. package/integration/import/import-user-data.spec.js +6 -1
  65. package/integration/import/import-view.spec.js +6 -1
  66. package/integration/license/license.spec.js +26 -0
  67. package/integration/repository/attach-remote-location.spec.js +94 -40
  68. package/integration/repository/repositories.spec.js +1 -7
  69. package/integration/setup/my-settings.spec.js +13 -21
  70. package/integration/ttyg/agent-list.spec.js +27 -25
  71. package/integration/ttyg/agent-select-menu.spec.js +18 -16
  72. package/integration/ttyg/chat-list.spec.js +72 -9
  73. package/integration/ttyg/chat-panel.spec.js +106 -10
  74. package/integration/ttyg/clone-agent.spec.js +8 -4
  75. package/integration/ttyg/create-agent.spec.js +303 -51
  76. package/integration/ttyg/create-chat.spec.js +68 -0
  77. package/integration/ttyg/delete-agent.spec.js +6 -5
  78. package/integration/ttyg/edit-agent.spec.js +16 -5
  79. package/integration/ttyg/ttyg-permission.spec.js +66 -0
  80. package/integration/ttyg/ttyg-view.spec.js +8 -4
  81. package/npm-shrinkwrap.json +215 -220
  82. package/package.json +5 -6
  83. package/steps/alert-dialog-steps.js +25 -0
  84. package/steps/cluster/cluster-configuration-steps.js +173 -5
  85. package/steps/cluster/cluster-page-steps.js +8 -0
  86. package/steps/cluster/custer-nodes-configuration-steps.js +107 -0
  87. package/steps/home-steps.js +48 -5
  88. package/steps/import/import-steps.js +11 -7
  89. package/steps/license-steps.js +25 -0
  90. package/steps/repositories/attach-repository-steps.js +33 -0
  91. package/steps/repository-steps.js +26 -11
  92. package/steps/setup/settings-steps.js +17 -0
  93. package/steps/ttyg/chat-panel-steps.js +31 -6
  94. package/steps/ttyg/ttyg-agent-settings-modal.steps.js +82 -4
  95. package/steps/ttyg/ttyg-view-steps.js +77 -3
  96. package/steps/visual-graph-steps.js +29 -1
  97. package/stubs/cluster/cluster-stubs.js +162 -7
  98. package/stubs/cluster/remote-location-stubs.js +46 -0
  99. package/stubs/connector-stubs.js +24 -0
  100. package/stubs/environment-stubs.js +27 -0
  101. package/stubs/license-stubs.js +108 -0
  102. package/stubs/repositories/repositories-stubs.js +11 -8
  103. package/stubs/repositories-stub.js +15 -0
  104. package/stubs/security-stubs.js +29 -0
  105. package/stubs/similarity-index-stubs.js +25 -0
  106. package/stubs/stubs.js +4 -0
  107. package/stubs/ttyg/ttyg-stubs.js +79 -40
  108. package/support/commands.js +2 -0
  109. package/support/index.js +18 -0
  110. package/support/security-command.js +25 -0
  111. package/support/settings-commands.js +4 -5
  112. package/support/user-commands.js +31 -0
  113. package/fixtures/ttyg/chats/get-chat-1.json +0 -43
  114. package/integration/cluster/cluster-management.spec.js +0 -220
  115. package/steps/cluster/add-remote-location-dialog-steps.js +0 -11
  116. package/steps/cluster/create-cluster-dialog-steps.js +0 -39
  117. package/steps/cluster/replace-nodes-dialog-steps.js +0 -39
@@ -0,0 +1,59 @@
1
+ {
2
+ "conversationId": "thread_jdQBvbkaU6JPoO48oFbC54dA",
3
+ "answerId": "msg_YbtWCL64HPu9Kf7SbsssseRlrwCc2",
4
+ "queryMethods": [
5
+ {
6
+ "name": "sparql_query",
7
+ "rawQuery": "SELECT ?character ?name ?height WHERE {\n ?character a voc:Character;\n rdfs:label ?name;\n voc:height ?height.\n FILTER(?name = \"Luke Skywalker\" || ?name = \"Leia Organa\")\n}",
8
+ "query": "SELECT ?character ?name ?height WHERE {\n ?character a voc:Character;\n rdfs:label ?name;\n voc:height ?height.\n FILTER(?name = \"Luke Skywalker\" || ?name = \"Leia Organa\")\n}",
9
+ "queryType": "sparql",
10
+ "errorOutput": "Error: org.eclipse.rdf4j.query.MalformedQueryException: org.eclipse.rdf4j.query.parser.sparql.ast.VisitorException: QName 'voc:Character' uses an undefined prefix"
11
+ }, {
12
+ "name": "retrieval_search",
13
+ "rawQuery": "{\"queries\":[{\"query\":\"pilots that work with Luke Skywalker\",\"filter\":{\"document_id\":\"https://swapi.co/resource/human/1\"},\"top_k\":3}]}",
14
+ "query": "{\n \"queries\" : [ {\n \"query\" : \"pilots that work with Luke Skywalker\",\n \"filter\" : {\n \"document_id\" : \"https://swapi.co/resource/human/1\"\n },\n \"top_k\" : 3\n } ]\n}",
15
+ "queryType": "json",
16
+ "errorOutput": null
17
+ },
18
+ {
19
+ "name": "iri_discovery",
20
+ "rawQuery": "Luke Skywalker",
21
+ "query": "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\nPREFIX skos: <http://www.w3.org/2004/02/skos/core#>\nPREFIX onto: <http://www.ontotext.com/>\nSELECT ?label ?iri {\n ?label onto:fts ('''Luke~ Skywalker~''' '*') .\n ?iri rdfs:label|skos:prefLabel ?label .\n}",
22
+ "queryType": "sparql",
23
+ "errorOutput": null
24
+ },
25
+ {
26
+ "name": "sparql_query",
27
+ "rawQuery": "SELECT ?height WHERE {\n <https://swapi.co/resource/human/1> voc:height ?height.\n}",
28
+ "query": "SELECT ?height WHERE {\n <https://swapi.co/resource/human/1> voc:height ?height.\n}",
29
+ "queryType": "sparql",
30
+ "errorOutput": "Error: org.eclipse.rdf4j.query.MalformedQueryException: org.eclipse.rdf4j.query.parser.sparql.ast.VisitorException: QName 'voc:height' uses an undefined prefix"
31
+ },
32
+ {
33
+ "name": "sparql_query",
34
+ "rawQuery": "PREFIX voc: <https://swapi.co/vocabulary/>\nSELECT ?name ?height WHERE {\n ?character voc:height ?height;\n rdfs:label ?name.\n FILTER(?name = \"Luke Skywalker\" || ?name = \"Leia Organa\")\n}",
35
+ "query": "PREFIX voc: <https://swapi.co/vocabulary/>\nSELECT ?name ?height WHERE {\n ?character voc:height ?height;\n rdfs:label ?name.\n FILTER(?name = \"Luke Skywalker\" || ?name = \"Leia Organa\")\n}",
36
+ "queryType": "sparql",
37
+ "errorOutput": null
38
+ },
39
+ {
40
+ "name": "fts_search",
41
+ "rawQuery": "Second Luke",
42
+ "query": "PREFIX onto: <http://www.ontotext.com/>\nDESCRIBE ?iri {\n\t?x onto:fts \\'\\'\\'Second Luke\\'\\'\\' .\n\t{\n\t\t?x ?p ?iri .\n\t} union {\n\t\t?iri ?p ?x .\n\t}\n}",
43
+ "queryType": "sparql",
44
+ "errorOutput": null
45
+ }, {
46
+ "name": "similarity_search",
47
+ "rawQuery": "Second Luke",
48
+ "query": "PREFIX onto: <http://www.ontotext.com/>\nDESCRIBE ?iri {\n\t?x onto:fts \\'\\'\\'Second Luke\\'\\'\\' .\n\t{\n\t\t?x ?p ?iri .\n\t} union {\n\t\t?iri ?p ?x .\n\t}\n}",
49
+ "queryType": "sparql",
50
+ "errorOutput": null
51
+ }, {
52
+ "name": "iri_discovery",
53
+ "rawQuery": "Luke Skywalker",
54
+ "query": "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\nPREFIX skos: <http://www.w3.org/2004/02/skos/core#>\nPREFIX onto: <http://www.ontotext.com/>\nSELECT ?label ?iri {\n ?label onto:fts ('''Luke~ Skywalker~''' '*') .\n ?iri rdfs:label|skos:prefLabel ?label .\n}",
55
+ "queryType": "sparql",
56
+ "errorOutput": null
57
+ }
58
+ ]
59
+ }
@@ -0,0 +1,199 @@
1
+ {
2
+ "thread_jdQBvbkaU6JPoO48oQaL76dC": {
3
+ "id": "thread_jdQBvbkaU6JPoO48oQaL76dC",
4
+ "name": "Han Solo is a fictional character in the...",
5
+ "messages": [
6
+ {
7
+ "id": "msg_A9UeOFT9SF3pKzJzar1HwM7d",
8
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
9
+ "agentId": null,
10
+ "role": "user",
11
+ "message": "Who is Han Solo?",
12
+ "timestamp": "1725875323",
13
+ "name": null
14
+ },
15
+ {
16
+ "id": "msg_YbtWCL64HPu9Kf7SbsssseRlrwCc1",
17
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
18
+ "agentId": "asst_gAPcrHQQ9ZIxD5eXWH2BNFfo",
19
+ "role": "assistant",
20
+ "message": "Han Solo is a fictional character in the Star Wars franchise.",
21
+ "timestamp": "1725875332",
22
+ "name": null
23
+ },
24
+ {
25
+ "id": "msg_1niL7yYidTfiGZynCiryiMMd",
26
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
27
+ "agentId": null,
28
+ "role": "user",
29
+ "message": "Who are the Han Solo's children?",
30
+ "timestamp": "1725875483",
31
+ "name": null
32
+ },
33
+ {
34
+ "id": "msg_YbtWCL64HPu9Kf7SbsssseRlrwCc2",
35
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
36
+ "agentId": "asst_gAPcrHQQ9ZIxD5eXWH2BNFfo",
37
+ "role": "assistant",
38
+ "message": "Han Solo is a fictional character in the Star ",
39
+ "timestamp": "1725875332",
40
+ "name": null
41
+ }
42
+ ],
43
+ "timestamp": "1725875483"
44
+ },
45
+ "thread_jdQBvbkaU6JPoO48oFbC54dA": {
46
+ "id": "thread_jdQBvbkaU6JPoO48oFbC54dA",
47
+ "name": "Han Solo is a fictional character in the...",
48
+ "messages": [
49
+ {
50
+ "id": "msg_A9UeOFT9SF3pKzJzar1HwM7d",
51
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
52
+ "agentId": null,
53
+ "role": "user",
54
+ "message": "Who is Han Solo?",
55
+ "timestamp": "1725875323",
56
+ "name": null
57
+ },
58
+ {
59
+ "id": "msg_YbtWCL64HPu9Kf7SbeRlrwCc",
60
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
61
+ "agentId": "asst_gAPcrHQQ9ZIxD5eXWH2BNFfos",
62
+ "role": "assistant",
63
+ "message": "Han Solo is a fictional character in the Star Wars franchise.",
64
+ "timestamp": "1725875332",
65
+ "name": null
66
+ },
67
+ {
68
+ "id": "msg_1niL7yYidTfiGZynCiryiMMd",
69
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
70
+ "agentId": null,
71
+ "role": "user",
72
+ "message": "Who are the Han Solo's children?",
73
+ "timestamp": "1725875483",
74
+ "name": null
75
+ },
76
+ {
77
+ "id": "msg_YbtWCL64HPu9Kf7SbsssseRlrwCc2",
78
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
79
+ "agentId": "asst_gAPcrHQQ9ZIxD5eXWH2BNFfos",
80
+ "role": "assistant",
81
+ "message": "Han Solo is a fictional character in the Star ",
82
+ "timestamp": "1725875332",
83
+ "name": null
84
+ }
85
+ ],
86
+ "timestamp": "1725875483"
87
+ },
88
+ "thread_jdQBvbkaU6JPoO48oFbC54dD": {
89
+ "id": "thread_jdQBvbkaU6JPoO48oFbC54dD",
90
+ "name": "Han Solo is a fictional character in the...",
91
+ "messages": [
92
+ {
93
+ "id": "msg_1niL7yYidTfiGZynCiryiMMd",
94
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
95
+ "agentId": null,
96
+ "role": "user",
97
+ "message": "Who are the Han Solo's children?",
98
+ "timestamp": "1725875483",
99
+ "name": null
100
+ },
101
+ {
102
+ "id": "msg_YbtWCL64HPu9Kf7SbsssseRlrwCc3",
103
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
104
+ "agentId": "asst_gAPcrHQQ9ZIxD5eXWH2BNFfo",
105
+ "role": "assistant",
106
+ "message": "Certainly! Here's a random example that incorporates code, JSON, and a SPARQL query:\n\n### Code (Python)\n\n```python\ndef greet(name):\n return f\"Hello, {name}!\"\n\nprint(greet(\"World\"))\n```\n\n### JSON\n\n```json\n{\n \"greeting\": \"Hello\",\n \"target\": \"World\",\n \"language\": \"English\"\n}\n```\n\n### SPARQL Query\n\n```sparql\nSELECT ?person ?name\nWHERE {\n ?person a ex:Person .\n ?person ex:hasName ?name .\n}\nLIMIT 10\n```\n\nThis example demonstrates a simple Python function for greeting, a JSON object representing a greeting structure, and a SPARQL query to retrieve names of persons from a dataset.",
107
+ "timestamp": "1725875332",
108
+ "name": null
109
+ }
110
+ ],
111
+ "timestamp": "1725875483"
112
+ },
113
+ "thread_jdQBvbkaU6JPoO48oQaL76dB": {
114
+ "id": "thread_jdQBvbkaU6JPoO48oQaL76dB",
115
+ "name": "Han Solo is a fictional character in the...",
116
+ "messages": [
117
+ {
118
+ "id": "msg_A9UeOFT9SF3pKzJzar1HwM7d",
119
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
120
+ "agentId": null,
121
+ "role": "user",
122
+ "message": "Who is Han Solo?",
123
+ "timestamp": "1725875323",
124
+ "name": null
125
+ },
126
+ {
127
+ "id": "msg_YbtWCL64HPu9Kf7SbeRlrwCc",
128
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
129
+ "agentId": "asst_Cr0RxobrY07WpOvvyQilEWMI",
130
+ "role": "assistant",
131
+ "message": "Han Solo is a fictional character in the Star Wars franchise.",
132
+ "timestamp": "1725875332",
133
+ "name": null
134
+ },
135
+ {
136
+ "id": "msg_1niL7yYidTfiGZynCiryiMMd",
137
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
138
+ "agentId": null,
139
+ "role": "user",
140
+ "message": "Who are the Han Solo's children?",
141
+ "timestamp": "1725875483",
142
+ "name": null
143
+ },
144
+ {
145
+ "id": "msg_YbtWCL64HPu9Kf7SbsssseRlrwCc4",
146
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
147
+ "agentId": "asst_Cr0RxobrY07WpOvvyQilEWMI",
148
+ "role": "assistant",
149
+ "message": "Han Solo is a fictional character in the Star ",
150
+ "timestamp": "1725875332",
151
+ "name": null
152
+ },
153
+ {
154
+ "id": "msg_A9UeOFT9SF3pKzJzar1HwM7d",
155
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
156
+ "agentId": null,
157
+ "role": "user",
158
+ "message": "Who is Han Solo?",
159
+ "timestamp": "1725875323",
160
+ "name": null
161
+ },
162
+ {
163
+ "id": "msg_YbtWCL64HPu9Kf7SbeRlrwCc",
164
+ "conversationId": "thread_gy2K7D3efStfchq2v5VvpEvn",
165
+ "agentId": "asst_qMyCpCBmqxV9I2B8UoMfFzc5",
166
+ "role": "assistant",
167
+ "message": "Han Solo is a fictional character in the Star Wars franchise.",
168
+ "timestamp": "1725875332",
169
+ "name": null
170
+ }
171
+ ],
172
+ "timestamp": "1725875483"
173
+ },
174
+ "thread_new_created_chat": {
175
+ "id": "thread_new_created_chat",
176
+ "name": "Han Solo is a character",
177
+ "messages": [
178
+ {
179
+ "id": "msg_A9UeOFT9SF3pKzJzar1HwM7d",
180
+ "conversationId": "thread_new_created_chat",
181
+ "agentId": "asst_gAPcrHQQ9ZIxD5eXWH2BNFfo",
182
+ "role": "user",
183
+ "message": "Who is Han Solo?",
184
+ "timestamp": 1725875323,
185
+ "name": null
186
+ },
187
+ {
188
+ "id": "msg_Bn07kVDCYT1qmgu1G7Zw0KNeс_",
189
+ "conversationId": "thread_new_created_chat",
190
+ "role": "assistant",
191
+ "agentId": "asst_gAPcrHQQ9ZIxD5eXWH2BNFfo",
192
+ "message": "Han Solo is a character ...",
193
+ "timestamp": 1725875323,
194
+ "name": null
195
+ }
196
+ ],
197
+ "timestamp": "1725875483"
198
+ }
199
+ }
@@ -0,0 +1,97 @@
1
+ import {ClusterPageSteps} from "../../../steps/cluster/cluster-page-steps";
2
+ import {GlobalOperationsStatusesStub} from "../../../stubs/global-operations-statuses-stub";
3
+ import {ClusterStubs} from "../../../stubs/cluster/cluster-stubs";
4
+ import {RemoteLocationStubs} from "../../../stubs/cluster/remote-location-stubs";
5
+ import {ClusterConfigurationSteps} from "../../../steps/cluster/cluster-configuration-steps";
6
+ import {ModalDialogSteps} from "../../../steps/modal-dialog-steps";
7
+ import {ApplicationSteps} from "../../../steps/application-steps";
8
+
9
+ describe('Cluster configuration', () => {
10
+ let repositoryId;
11
+
12
+ beforeEach(() => {
13
+ repositoryId = 'cluster-repo' + Date.now();
14
+ GlobalOperationsStatusesStub.stubNoOperationsResponse(repositoryId);
15
+ // Given there is an existing cluster created
16
+ ClusterStubs.stubClusterConfig();
17
+ ClusterStubs.stubClusterGroupStatus();
18
+ ClusterStubs.stubClusterNodeStatus();
19
+ RemoteLocationStubs.stubRemoteLocationFilter();
20
+ RemoteLocationStubs.stubRemoteLocationStatusInCluster();
21
+ });
22
+
23
+ it('should be able to add and delete tags', () => {
24
+ const tagName = 'test';
25
+ // Given I have opened the cluster management page
26
+ ClusterPageSteps.visit();
27
+ // When I click on edit properties and open Multi-region tab
28
+ ClusterPageSteps.previewClusterConfig();
29
+ ClusterConfigurationSteps.selectMultiRegionConfigTab();
30
+ // I expect to see
31
+ ClusterConfigurationSteps.getMultiRegionHeader().should('contain.text', 'Primary cluster');
32
+ ClusterConfigurationSteps.getAddTagButton().should('be.visible').and('not.be.disabled');
33
+ ClusterConfigurationSteps.getEnableSecondaryModeButton().should('be.visible').and('be.enabled');
34
+ ClusterConfigurationSteps.getTagsTable().should('not.exist');
35
+
36
+ ClusterStubs.stubAddTag(tagName);
37
+ ClusterConfigurationSteps.clickAddTagButton();
38
+ ClusterConfigurationSteps.typeTag(tagName);
39
+ ClusterConfigurationSteps.clickSubmitTagButton();
40
+ cy.wait('@add-tag').then((interception) => {
41
+ expect(interception.request.body).to.deep.equal({tag: tagName});
42
+ });
43
+
44
+ ClusterStubs.stubClusterGroupStatusWithTag();
45
+ cy.wait('@3-nodes-cluster-group-status-tag');
46
+ // Assert the tags table contains the expected tag
47
+ ClusterConfigurationSteps.getTagsTable().should('be.visible');
48
+ ClusterConfigurationSteps.getTagsTableRows().should('contain.text', tagName);
49
+
50
+ // And expect success message to be displayed.
51
+ ApplicationSteps.getSuccessNotifications().contains(`Successfully added to cluster primary identifier tag: ${tagName}`);
52
+
53
+ //When I delete the tag
54
+ ClusterConfigurationSteps.clickDeleteTagButton();
55
+ // I expect to see deleting confirmation dialog.
56
+ ModalDialogSteps.getDialogHeader().should('contain', `Delete identifier tag ${tagName}`);
57
+ ModalDialogSteps.getDialogBody().should('contain', 'Deleting identifier tag would stop any secondary cluster identified with it from pulling updates.');
58
+
59
+ // When I confirm
60
+ ClusterStubs.stubDeleteTag(tagName);
61
+ ModalDialogSteps.clickOnConfirmButton();
62
+ cy.wait('@delete-tag').then((interception) => {
63
+ expect(interception.request.body).to.deep.equal({tag: tagName});
64
+ });
65
+ });
66
+
67
+ it('should be able to switch modes', () => {
68
+ ClusterStubs.stubEnableSecondaryMode();
69
+ const rpcAddress = 'node-name:7300';
70
+ const tag = 'us-central';
71
+
72
+ // Given I have opened the cluster management page
73
+ ClusterPageSteps.visit();
74
+ // When I click on edit properties and open Nodes tab
75
+ ClusterPageSteps.previewClusterConfig();
76
+ ClusterConfigurationSteps.selectMultiRegionConfigTab();
77
+ // I click enable secondary mode btn
78
+ ClusterConfigurationSteps.clickEnableSecondaryModeButton();
79
+ // I expect to see enable secondary mode confirmation dialog.
80
+ ModalDialogSteps.getDialogHeader().should('contain', `Enable secondary mode`);
81
+ ModalDialogSteps.getDialogBody().should('contain', 'By enabling secondary mode this cluster would become a read-only replica of the specified primary cluster.');
82
+ // When I confirm I expect to see configuration modal
83
+ ModalDialogSteps.getConfirmButton().click();
84
+ ModalDialogSteps.getDialogHeader().should('contain', `Secondary cluster settings`);
85
+ ClusterConfigurationSteps.getEnableButton().should('be.disabled');
86
+ ClusterConfigurationSteps.typeRpcAddress(rpcAddress);
87
+ ClusterConfigurationSteps.getEnableButton().should('be.disabled');
88
+ ClusterConfigurationSteps.typePrimaryTag(tag);
89
+ ClusterConfigurationSteps.getEnableButton().should('not.be.disabled');
90
+ ClusterConfigurationSteps.clickEnableButton();
91
+ cy.wait('@enable-secondary-mode').then((interception) => {
92
+ expect(interception.request.body).to.deep.equal({primaryNode: rpcAddress, tag});
93
+ });
94
+ // And expect success message to be displayed.
95
+ ApplicationSteps.getSuccessNotifications().contains(`Successfully enabled secondary mode`);
96
+ });
97
+ });
@@ -0,0 +1,70 @@
1
+ import {ClusterPageSteps} from "../../../steps/cluster/cluster-page-steps";
2
+ import {GlobalOperationsStatusesStub} from "../../../stubs/global-operations-statuses-stub";
3
+ import {ClusterStubs} from "../../../stubs/cluster/cluster-stubs";
4
+ import {RemoteLocationStubs} from "../../../stubs/cluster/remote-location-stubs";
5
+ import {ClusterConfigurationSteps} from "../../../steps/cluster/cluster-configuration-steps";
6
+
7
+ describe('Cluster configuration', () => {
8
+ let repositoryId;
9
+
10
+ beforeEach(() => {
11
+ repositoryId = 'cluster-repo' + Date.now();
12
+ GlobalOperationsStatusesStub.stubNoOperationsResponse(repositoryId);
13
+ // Given there is an existing cluster created
14
+ ClusterStubs.stubClusterConfig();
15
+ ClusterStubs.stubClusterGroupStatus();
16
+ ClusterStubs.stubClusterNodeStatus();
17
+ RemoteLocationStubs.stubRemoteLocationFilter();
18
+ RemoteLocationStubs.stubRemoteLocationStatusInCluster();
19
+ });
20
+
21
+ it('should display the nodes list with correct node information in the modal', () => {
22
+ // Given I have opened the cluster management page
23
+ ClusterPageSteps.visit();
24
+ // When I click on edit properties and open Nodes tab
25
+ ClusterPageSteps.previewClusterConfig();
26
+ ClusterConfigurationSteps.selectNodesTab();
27
+ // I expect to see
28
+ ClusterConfigurationSteps.getNodesListHeader().should('contain.text', 'Nodes list');
29
+ ClusterConfigurationSteps.assertNodesCount(3);
30
+
31
+ const nodeData = [
32
+ {
33
+ url: 'http://pc-desktop:7200',
34
+ rpcAddress: 'pc-desktop:7300',
35
+ state: 'FOLLOWER',
36
+ local: true
37
+ },
38
+ {
39
+ url: 'http://pc-desktop:7201',
40
+ rpcAddress: 'pc-desktop:7301',
41
+ state: 'LEADER',
42
+ local: false
43
+ },
44
+ {
45
+ url: 'http://pc-desktop:7202',
46
+ rpcAddress: 'pc-desktop:7302',
47
+ state: 'FOLLOWER',
48
+ local: false
49
+ }
50
+ ];
51
+
52
+ nodeData.forEach((data, index) => {
53
+ ClusterConfigurationSteps.getNodeLink(index)
54
+ .should('have.attr', 'href', data.url)
55
+ .and('contain.text', data.url);
56
+
57
+ ClusterConfigurationSteps.getNodeRPCAddress(index)
58
+ .should('contain.text', data.rpcAddress);
59
+
60
+ ClusterConfigurationSteps.getNodeState(index)
61
+ .should('contain.text', data.state);
62
+
63
+ if (data.local) {
64
+ ClusterConfigurationSteps.isNodeLocal(index).should('exist');
65
+ } else {
66
+ ClusterConfigurationSteps.isNodeLocal(index).should('not.exist');
67
+ }
68
+ });
69
+ });
70
+ });
@@ -0,0 +1,95 @@
1
+ import {ClusterPageSteps} from "../../../steps/cluster/cluster-page-steps";
2
+ import {GlobalOperationsStatusesStub} from "../../../stubs/global-operations-statuses-stub";
3
+ import {ClusterStubs} from "../../../stubs/cluster/cluster-stubs";
4
+ import {RemoteLocationStubs} from "../../../stubs/cluster/remote-location-stubs";
5
+ import {DeleteClusterDialogSteps} from "../../../steps/cluster/delete-cluster-dialog-steps";
6
+ import {ClusterConfigurationSteps} from "../../../steps/cluster/cluster-configuration-steps";
7
+
8
+ describe('Cluster configuration', () => {
9
+ let repositoryId;
10
+
11
+ beforeEach(() => {
12
+ repositoryId = 'cluster-repo' + Date.now();
13
+ GlobalOperationsStatusesStub.stubNoOperationsResponse(repositoryId);
14
+ // Given there is an existing cluster created
15
+ ClusterStubs.stubClusterConfig();
16
+ ClusterStubs.stubClusterGroupStatus();
17
+ ClusterStubs.stubClusterNodeStatus();
18
+ RemoteLocationStubs.stubRemoteLocationFilter();
19
+ RemoteLocationStubs.stubRemoteLocationStatusInCluster();
20
+ });
21
+
22
+ it('Should be able to delete cluster', () => {
23
+ // Given I have opened the cluster management page
24
+ ClusterPageSteps.visit();
25
+
26
+ ClusterPageSteps.getClusterPage().should('be.visible');
27
+ ClusterPageSteps.getCreateClusterButton().should('not.have.class', 'no-cluster');
28
+ // When I click on delete cluster
29
+ ClusterPageSteps.previewClusterConfig();
30
+ ClusterConfigurationSteps.getClusterConfig().should('be.visible');
31
+ ClusterConfigurationSteps.deleteCluster();
32
+ // Then I expect a confirmation dialog to appear
33
+ DeleteClusterDialogSteps.getDialog().should('be.visible');
34
+ // When I confirm
35
+ ClusterStubs.stubDeleteCluster();
36
+ ClusterStubs.stubNoClusterGroupStatus();
37
+ ClusterStubs.stubNoClusterNodeStatus();
38
+ DeleteClusterDialogSteps.confirmDeleteCluster();
39
+ // Then Cluster should be deleted
40
+ ClusterStubs.stubNoClusterConfig();
41
+ RemoteLocationStubs.stubRemoteLocationStatusNotCluster();
42
+ DeleteClusterDialogSteps.getDialog().should('not.exist');
43
+ ClusterPageSteps.getRemoveNodesButton().should('not.exist');
44
+ ClusterPageSteps.getAddNodesButton().should('not.exist');
45
+ ClusterPageSteps.getReplaceNodesButton().should('not.exist');
46
+ ClusterPageSteps.getPreviewClusterConfigButton().should('not.exist');
47
+ ClusterPageSteps.getCreateClusterButton().should('have.class', 'no-cluster');
48
+ });
49
+
50
+ it('Should be able to edit cluster properties', () => {
51
+ // Given I have opened the cluster management page
52
+ ClusterPageSteps.visit();
53
+ // When I click on edit properties
54
+ ClusterPageSteps.previewClusterConfig();
55
+ ClusterConfigurationSteps.getClusterConfig().should('be.visible');
56
+ // When I press edit properties
57
+ ClusterConfigurationSteps.editProperties();
58
+ // Then I expect a modal to be shown
59
+ ClusterConfigurationSteps.getModal().should('be.visible');
60
+ // I can set values in form fields
61
+ ClusterConfigurationSteps.setFieldValue('electionMinTimeout', '5000');
62
+ ClusterConfigurationSteps.setFieldValue('electionRangeTimeout', '3000');
63
+ // Verify a field validation error appears if left empty
64
+ ClusterConfigurationSteps.getFieldByName('heartbeatInterval').clear();
65
+ ClusterConfigurationSteps.verifyFieldError('heartbeatInterval', 'This field is required');
66
+ // And Save button is disabled
67
+ ClusterConfigurationSteps.getSaveButton().should('be.disabled');
68
+ // Set value for required field to enable Save button
69
+ ClusterConfigurationSteps.setFieldValue('heartbeatInterval', '1500');
70
+ // And Save button is disabled
71
+ ClusterConfigurationSteps.getSaveButton().should('be.enabled');
72
+ ClusterConfigurationSteps.setFieldValue('messageSizeKB', '64');
73
+ ClusterConfigurationSteps.setFieldValue('verificationTimeout', '1200');
74
+ ClusterConfigurationSteps.setFieldValue('transactionLogMaximumSizeGB', '50');
75
+ ClusterConfigurationSteps.setFieldValue('batchUpdateInterval', '2000');
76
+
77
+ // Click Save button to submit
78
+ ClusterStubs.stubSaveClusterConfiguration();
79
+ ClusterConfigurationSteps.save();
80
+ const expectedRequestBody = {
81
+ electionMinTimeout: 5000,
82
+ electionRangeTimeout: 3000,
83
+ heartbeatInterval: 1500,
84
+ messageSizeKB: 64,
85
+ verificationTimeout: 1200,
86
+ transactionLogMaximumSizeGB: 50,
87
+ batchUpdateInterval: 2000
88
+ };
89
+ cy.wait('@save-cluster-properties').then((interception) => {
90
+ expect(interception.request.body).to.deep.equal(expectedRequestBody);
91
+ });
92
+ // And the modal is closed
93
+ ClusterConfigurationSteps.getModal().should('not.exist');
94
+ });
95
+ });
@@ -0,0 +1,38 @@
1
+ import {ClusterPageSteps} from "../../../steps/cluster/cluster-page-steps";
2
+ import {GlobalOperationsStatusesStub} from "../../../stubs/global-operations-statuses-stub";
3
+ import {ClusterStubs} from "../../../stubs/cluster/cluster-stubs";
4
+ import {RemoteLocationStubs} from "../../../stubs/cluster/remote-location-stubs";
5
+ import {ClusterConfigurationSteps} from "../../../steps/cluster/cluster-configuration-steps";
6
+
7
+ describe('Cluster configuration', () => {
8
+
9
+ let repositoryId;
10
+ beforeEach(() => {
11
+ repositoryId = 'cluster-repo' + Date.now();
12
+ GlobalOperationsStatusesStub.stubNoOperationsResponse(repositoryId);
13
+ });
14
+
15
+ it('Should display cluster configuration', () => {
16
+ // Given there is an existing cluster created
17
+ ClusterStubs.stubClusterConfig();
18
+ ClusterStubs.stubClusterGroupStatus();
19
+ ClusterStubs.stubClusterNodeStatus();
20
+ RemoteLocationStubs.stubRemoteLocationFilter();
21
+ RemoteLocationStubs.stubRemoteLocationStatusInCluster();
22
+ // Given I have opened the cluster management page
23
+ ClusterPageSteps.visit();
24
+ // When I click on edit properties
25
+ ClusterPageSteps.previewClusterConfig();
26
+ // Then I should see cluster configuration with 3 tabs
27
+ ClusterConfigurationSteps.getClusterConfig().should('be.visible');
28
+ ClusterConfigurationSteps.getTabs().should('have.length', 3);
29
+ ClusterConfigurationSteps.getActiveTab().should('have.text', 'Properties');
30
+ ClusterConfigurationSteps.getClusterPropertiesTabContent().should('be.visible');
31
+ ClusterConfigurationSteps.selectTab(1);
32
+ ClusterConfigurationSteps.getActiveTab().should('have.text', 'Nodes');
33
+ ClusterConfigurationSteps.getClusterNodesTabContent().should('be.visible');
34
+ ClusterConfigurationSteps.selectTab(2);
35
+ ClusterConfigurationSteps.getActiveTab().should('have.text', 'Multi-region');
36
+ ClusterConfigurationSteps.getMultiRegionTabContent().should('be.visible');
37
+ });
38
+ });
@@ -9,6 +9,7 @@ describe('Cluster legend', () => {
9
9
 
10
10
  beforeEach(() => {
11
11
  repositoryId = 'cluster-repo' + Date.now();
12
+ cy.setDefaultUserData();
12
13
  GlobalOperationsStatusesStub.stubNoOperationsResponse(repositoryId);
13
14
  });
14
15