graphdb-workbench-tests 2.7.3 → 2.7.4-GA1

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.
@@ -176,6 +176,9 @@
176
176
  "role": "ROLE1",
177
177
  "plugin": "Plugin"
178
178
  },
179
+ "prefix_warning": {
180
+ "text": "Custom roles should be entered without the \"CUSTOM_\" prefix in Workbench"
181
+ },
179
182
  "actions": {
180
183
  "move_up": "Move the rule up",
181
184
  "move_down": "Move the rule down",
@@ -935,6 +938,7 @@
935
938
  "could.not.send.data": "Could not send data for import; {{data}}",
936
939
  "could.not.send.url": "Could not send url for import; {{data}}",
937
940
  "could.not.upload.file": "Could not upload file; {{data}}",
941
+ "upload.file.failure": "File upload failed.",
938
942
  "could.not.update.text": "Could not update text import; {{data}}",
939
943
  "text.snippet.not.imported": "Text snippet was edited but has not been imported again.",
940
944
  "graph.already.in.list": "This graph is already in the list.",
@@ -1003,7 +1007,7 @@
1003
1007
  "execution": "Import execution",
1004
1008
  "work_in_background": "Imports are executed in the background while you continue working on other things.",
1005
1009
  "to_reimport_again": "To reimport a file, URL or text snippet click the Import button again.",
1006
- "interrupt_support": "Interrupt is supported only when the location is local.",
1010
+ "interrupt_support": "Interrupt is supported only when the repository is local.",
1007
1011
  "parser_config": "Parser config options are not available for remote locations."
1008
1012
  },
1009
1013
  "on_server_import": {
@@ -1015,7 +1019,7 @@
1015
1019
  "execution": "Import execution",
1016
1020
  "work_in_background": "Imports are executed in the background while you continue working on other things.",
1017
1021
  "to_reimport_again": "To reimport a file, URL or text snippet click the Import button again.",
1018
- "interrupt_support": "Interrupt is supported only when the location is local."
1022
+ "interrupt_support": "Interrupt is supported only when the repository is local."
1019
1023
  },
1020
1024
  "on_file_size_limit": {
1021
1025
  "file_import_options_info_1": "Explore other file import options - ",
@@ -0,0 +1,72 @@
1
+ [
2
+ {
3
+ "uri": "http://local",
4
+ "label": "Remote Ontopic Instance (http://local)",
5
+ "username": "username",
6
+ "password": "password",
7
+ "authType": "basic",
8
+ "locationType": "ONTOPIC",
9
+ "active": false,
10
+ "local": false,
11
+ "system": false,
12
+ "errorMsg": null,
13
+ "defaultRepository": null,
14
+ "isInCluster": false
15
+ },
16
+ {
17
+ "uri": "http://localhost:7212",
18
+ "label": "Remote (http://localhost:7212)",
19
+ "username": null,
20
+ "password": null,
21
+ "authType": "none",
22
+ "locationType": "GDB",
23
+ "active": false,
24
+ "local": false,
25
+ "system": false,
26
+ "errorMsg": "Cannot connect to location Connect to localhost:7212 [localhost/127.0.0.1] failed: Connection refused (Connection refused) (Connect to localhost:7212 [localhost/127.0.0.1] failed: Connection refused (Connection refused)).",
27
+ "defaultRepository": null,
28
+ "isInCluster": false
29
+ },
30
+ {
31
+ "uri": "",
32
+ "label": "Local",
33
+ "username": null,
34
+ "password": null,
35
+ "authType": "none",
36
+ "locationType": null,
37
+ "active": true,
38
+ "local": true,
39
+ "system": true,
40
+ "errorMsg": null,
41
+ "defaultRepository": null,
42
+ "isInCluster": false
43
+ },
44
+ {
45
+ "uri": "http://localhost:7201",
46
+ "label": "Remote (http://localhost:7201)",
47
+ "username": null,
48
+ "password": null,
49
+ "authType": "none",
50
+ "locationType": "GDB",
51
+ "active": false,
52
+ "local": false,
53
+ "system": false,
54
+ "errorMsg": null,
55
+ "defaultRepository": null,
56
+ "isInCluster": false
57
+ },
58
+ {
59
+ "uri": "http://localhost:7202",
60
+ "label": "Remote (http://localhost:7202)",
61
+ "username": null,
62
+ "password": null,
63
+ "authType": "none",
64
+ "locationType": "GDB",
65
+ "active": false,
66
+ "local": false,
67
+ "system": false,
68
+ "errorMsg": null,
69
+ "defaultRepository": null,
70
+ "isInCluster": false
71
+ }
72
+ ]
@@ -0,0 +1,106 @@
1
+ {
2
+ "": [
3
+ {
4
+ "id": "test",
5
+ "title": "",
6
+ "uri": "http://localhost:8080/graphdb/repositories/test",
7
+ "externalUrl": "http://boyantonchev:9000/repositories/test",
8
+ "local": true,
9
+ "type": "graphdb",
10
+ "sesameType": "graphdb:SailRepository",
11
+ "location": "",
12
+ "readable": true,
13
+ "writable": true,
14
+ "unsupported": false,
15
+ "state": "RUNNING"
16
+ }
17
+ ],
18
+ "http://ghh": [],
19
+ "http://localhost:7201": [],
20
+ "http://localhost:7202": [
21
+ {
22
+ "id": "movies",
23
+ "title": "",
24
+ "uri": "http://localhost:7202/repositories/movies",
25
+ "externalUrl": "http://localhost:7202/repositories/movies",
26
+ "local": false,
27
+ "type": "graphdb",
28
+ "sesameType": "graphdb:SailRepository",
29
+ "location": "http://localhost:7202",
30
+ "readable": true,
31
+ "writable": true,
32
+ "unsupported": false,
33
+ "state": "RUNNING"
34
+ },
35
+ {
36
+ "id": "configurations",
37
+ "title": "",
38
+ "uri": "http://localhost:7202/repositories/configurations",
39
+ "externalUrl": "http://localhost:7202/repositories/configurations",
40
+ "local": false,
41
+ "type": "graphdb",
42
+ "sesameType": "graphdb:SailRepository",
43
+ "location": "http://localhost:7202",
44
+ "readable": true,
45
+ "writable": true,
46
+ "unsupported": false,
47
+ "state": "RUNNING"
48
+ },
49
+ {
50
+ "id": "schedules",
51
+ "title": "",
52
+ "uri": "http://localhost:7202/repositories/schedules",
53
+ "externalUrl": "http://localhost:7202/repositories/schedules",
54
+ "local": false,
55
+ "type": "graphdb",
56
+ "sesameType": "graphdb:SailRepository",
57
+ "location": "http://localhost:7202",
58
+ "readable": true,
59
+ "writable": true,
60
+ "unsupported": false,
61
+ "state": "RUNNING"
62
+ },
63
+ {
64
+ "id": "statuses",
65
+ "title": "",
66
+ "uri": "http://localhost:7202/repositories/statuses",
67
+ "externalUrl": "http://localhost:7202/repositories/statuses",
68
+ "local": false,
69
+ "type": "graphdb",
70
+ "sesameType": "graphdb:SailRepository",
71
+ "location": "http://localhost:7202",
72
+ "readable": true,
73
+ "writable": true,
74
+ "unsupported": false,
75
+ "state": "RUNNING"
76
+ },
77
+ {
78
+ "id": "home-repository-1716184222365",
79
+ "title": "",
80
+ "uri": "http://localhost:7202/repositories/home-repository-1716184222365",
81
+ "externalUrl": "http://localhost:7202/repositories/home-repository-1716184222365",
82
+ "local": false,
83
+ "type": "graphdb",
84
+ "sesameType": "graphdb:SailRepository",
85
+ "location": "http://localhost:7202",
86
+ "readable": true,
87
+ "writable": true,
88
+ "unsupported": false,
89
+ "state": "RUNNING"
90
+ },
91
+ {
92
+ "id": "repository-1716184200859",
93
+ "title": "",
94
+ "uri": "http://localhost:7202/repositories/repository-1716184200859",
95
+ "externalUrl": "http://localhost:7202/repositories/repository-1716184200859",
96
+ "local": false,
97
+ "type": "graphdb",
98
+ "sesameType": "graphdb:SailRepository",
99
+ "location": "http://localhost:7202",
100
+ "readable": true,
101
+ "writable": true,
102
+ "unsupported": false,
103
+ "state": "RUNNING"
104
+ }
105
+ ]
106
+ }
@@ -0,0 +1,47 @@
1
+ [
2
+ {
3
+ "conversationId": "thread_jdQBvbkaU6JPoO48oFbC54dA",
4
+ "conversationName": "Very long chat name which does not fit in the sidebar",
5
+ "timestamp": 1697408400
6
+ },
7
+ {
8
+ "conversationId": "thread_jdQBvbkaU6JPoO48oQaL76dB",
9
+ "conversationName": "Test chat 2",
10
+ "timestamp": 1697428200
11
+ },
12
+ {
13
+ "conversationId": "thread_jdQBvbkaU6JPoO48oQaL76dC",
14
+ "conversationName": "Test chat 3",
15
+ "timestamp": 1697448900
16
+ },
17
+ {
18
+ "conversationId": "thread_jdQBvbkaU6JPoO48oFbC54dD",
19
+ "conversationName": "Test chat 4",
20
+ "timestamp": 1697331600
21
+ },
22
+ {
23
+ "conversationId": "thread_jdQBvbkaU6JPoO48oQaL76dE",
24
+ "conversationName": "Test chat 5",
25
+ "timestamp": 1697252400
26
+ },
27
+ {
28
+ "conversationId": "thread_jdQBvbkaU6JPoO48oQaL76dF",
29
+ "conversationName": "Test chat 6",
30
+ "timestamp": 1697154000
31
+ },
32
+ {
33
+ "conversationId": "thread_jdQBvbkaU6JPoO48oFbC54dE",
34
+ "conversationName": "Test chat 7",
35
+ "timestamp": 1697073000
36
+ },
37
+ {
38
+ "conversationId": "thread_jdQBvbkaU6JPoO48oQaL76dG",
39
+ "conversationName": "Test chat 8",
40
+ "timestamp": 1696980300
41
+ },
42
+ {
43
+ "conversationId": "thread_jdQBvbkaU6JPoO48oQaL76dH",
44
+ "conversationName": "Test chat 9",
45
+ "timestamp": 1696899300
46
+ }
47
+ ]
@@ -144,4 +144,44 @@ describe('Import server files', () => {
144
144
  // Then I expect the dialog closed
145
145
  ImportResourceMessageDialog.getDialog().should('not.exist');
146
146
  });
147
+
148
+ it('Should order by size', () => {
149
+ // When I sort the listed files by their size.
150
+ ImportServerFilesSteps.orderBySize();
151
+
152
+ // Then I expect the directories to be sorted in ascending order,
153
+ ImportServerFilesSteps.getResource(0).should('contain', "more-files");
154
+ ImportServerFilesSteps.getResource(3).should('contain', "more-files-with-error");
155
+
156
+ // and inner files to be sorted ascending as well.
157
+ // checks first folder files
158
+ ImportServerFilesSteps.getResource(1).should('contain', "jsonld-file.jsonld");
159
+ ImportServerFilesSteps.getResource(2).should('contain', "rdfxml.rdf");
160
+ // checks second folder files
161
+ ImportServerFilesSteps.getResource(4).should('contain', "import-resource-with-correct-data.jsonld");
162
+ ImportServerFilesSteps.getResource(5).should('contain', "import-resource-with-incorrect-data.rdf");
163
+ ImportServerFilesSteps.getResource(6).should('contain', "import-resource-with-long-error.rdf");
164
+ // checks files in root
165
+ ImportServerFilesSteps.getResource(7).should('contain', "bnodes.ttl");
166
+ ImportServerFilesSteps.getResource(8).should('contain', "test_turtlestar.ttls");
167
+ ImportServerFilesSteps.getResource(9).should('contain', "0007-import-file.jsonld");
168
+
169
+ // When I change the order by size.
170
+ ImportServerFilesSteps.orderBySize();
171
+
172
+ // Then I expect the directories to be sorted in descending order,
173
+ ImportServerFilesSteps.getResource(0).should('contain', "more-files-with-error");
174
+ ImportServerFilesSteps.getResource(4).should('contain', "more-files");
175
+ // checks first folder files
176
+ ImportServerFilesSteps.getResource(1).should('contain', "import-resource-with-long-error.rdf");
177
+ ImportServerFilesSteps.getResource(2).should('contain', "import-resource-with-incorrect-data.rdf");
178
+ ImportServerFilesSteps.getResource(3).should('contain', "import-resource-with-correct-data.jsonld");
179
+ // checks second folder files
180
+ ImportServerFilesSteps.getResource(5).should('contain', "rdfxml.rdf");
181
+ ImportServerFilesSteps.getResource(6).should('contain', "jsonld-file.jsonld");
182
+ // checks files in root
183
+ ImportServerFilesSteps.getResource(15).should('contain', "0007-import-file.jsonld");
184
+ ImportServerFilesSteps.getResource(16).should('contain', "test_turtlestar.ttls");
185
+ ImportServerFilesSteps.getResource(17).should('contain', "bnodes.ttl");
186
+ });
147
187
  });
@@ -0,0 +1,154 @@
1
+ import {RepositorySteps} from "../../steps/repository-steps";
2
+ import {AttachRepositorySteps} from "../../steps/repositories/attach-repository-steps";
3
+ import {ModalDialogSteps} from "../../steps/modal-dialog-steps";
4
+ import {RepositoriesStubs} from "../../stubs/repositories/repositories-stubs";
5
+
6
+ /**
7
+ * Skipped for now until the backend is ready
8
+ */
9
+ describe.skip('Attach remote location', () => {
10
+
11
+ beforeEach(() => {
12
+ RepositorySteps.visit();
13
+ });
14
+
15
+ it('Should create and delete remote instance', () => {
16
+ // When I open the "Attach a remote instance" dialog.
17
+ AttachRepositorySteps.openAttachRemoteLocationDialog();
18
+
19
+ // Then I expect the "Attach" button to be disabled (not clickable), because location URL is mandatory
20
+ AttachRepositorySteps.getAttachBtn().should('be.disabled');
21
+ // and authentication type to be "None". This is default location type.
22
+ AttachRepositorySteps.getRemoteLocationDialog().should('contain', 'No authentication will be used with this location.');
23
+ // I expect GraphDB type be selected
24
+ AttachRepositorySteps.getGraphDBRadioBtn().should('be.checked');
25
+
26
+ // When I fill wrong location URL
27
+ AttachRepositorySteps.getLocationURLInput().type("Wrong URL");
28
+
29
+ // Then I expect to see error message
30
+ AttachRepositorySteps.getRemoteLocationDialog().should('contain', 'Note that the location should be a URL that points to a remote GraphDB installation,');
31
+
32
+ // When I clear the wrong URL
33
+ AttachRepositorySteps.getLocationURLInput().clear();
34
+
35
+ // Then I expect to see an error message that states the location is required.
36
+ AttachRepositorySteps.getRemoteLocationDialog().should('contain', 'Location URL is required.');
37
+
38
+ // When I fill correct URL
39
+ AttachRepositorySteps.getLocationURLInput().type("http://loc");
40
+
41
+ // Then I expect the "Attach" button to be enabled
42
+ AttachRepositorySteps.getAttachBtn().should('be.enabled');
43
+
44
+ // When I switch to basic authentication
45
+ AttachRepositorySteps.selectBasicRadioBtn();
46
+
47
+ // Then I expect the "Attach" button to be disabled (not clickable), because Username and Password are mandatory
48
+ AttachRepositorySteps.getAttachBtn().should('be.disabled');
49
+
50
+ // When I fill Username
51
+ AttachRepositorySteps.getUsernameInput().type('username');
52
+
53
+ // Then I expect the "Attach" button to be disabled (not clickable), because Password is mandatory
54
+ AttachRepositorySteps.getAttachBtn().should('be.disabled');
55
+
56
+ // When I fill password
57
+ AttachRepositorySteps.getPasswordInput().type('password');
58
+ // Then I expect the "Attach" button to be enabled
59
+ AttachRepositorySteps.getAttachBtn().should('be.enabled');
60
+
61
+ // When I remove the Username and Password and
62
+ AttachRepositorySteps.getUsernameInput().clear();
63
+ AttachRepositorySteps.getPasswordInput().clear();
64
+ // switch to Signature authentication type
65
+ AttachRepositorySteps.selectSignatureRadioBtn();
66
+
67
+ // Then I expect the "Attach" button to be enabled, because only location URL is mandatory
68
+ AttachRepositorySteps.getAttachBtn().should('be.enabled');
69
+
70
+ // When I clear the location URL
71
+ AttachRepositorySteps.getLocationURLInput().clear();
72
+
73
+ // Then I expect the "Attach" button to be disabled (not clickable), because Location URL is mandatory
74
+ AttachRepositorySteps.getAttachBtn().should('be.disabled');
75
+
76
+ // When I switch to Ontopic instance
77
+ AttachRepositorySteps.selectOntopicRadioBtn();
78
+ // Then I expect the "Attach" button to be disabled (not clickable), because Location URL, ClienatId and Secret are mandatory
79
+ AttachRepositorySteps.getAttachBtn().should('be.disabled');
80
+
81
+ // When I fill wrong location URL
82
+ AttachRepositorySteps.getLocationURLInput().type("Wrong URL");
83
+
84
+ // Then I expect to see error message
85
+ AttachRepositorySteps.getRemoteLocationDialog().should('contain', 'Note that the location should be a URL that points to a remote Ontopic installation,');
86
+
87
+ // When I clear the wrong URL
88
+ AttachRepositorySteps.getLocationURLInput().clear();
89
+
90
+ // Then I expect to see an error message that states the location is required.
91
+ AttachRepositorySteps.getRemoteLocationDialog().should('contain', 'Location URL is required.');
92
+
93
+ // When I fill all mandatory fields
94
+ AttachRepositorySteps.getLocationURLInput().type('http://local');
95
+ AttachRepositorySteps.getUsernameInput().type("username");
96
+ AttachRepositorySteps.getPasswordInput().type('password');
97
+
98
+ // Then I expect the "Attach" button to be enabled
99
+ AttachRepositorySteps.getAttachBtn().should('be.enabled');
100
+
101
+ // When I click the "Attach" button
102
+ AttachRepositorySteps.attachRemoteLocation();
103
+
104
+ // Then I expect location with URL "http://local" to be created
105
+ RepositorySteps.getOntopicTable().should('contain', 'http://local');
106
+
107
+ // When delete the created location
108
+ RepositorySteps.deleteOntopicInstance('http://local');
109
+
110
+ // I expect to see deleting confirmation dialog.
111
+ ModalDialogSteps.getDialogBody().should('contain', 'Are you sure you want to detach the location \'http://local\'?');
112
+
113
+ // When I confirm
114
+ ModalDialogSteps.getConfirmButton().click();
115
+
116
+ // Then I expect the location to be deleted.
117
+ RepositorySteps.getOntopicTable().should('not.exist');
118
+ });
119
+
120
+ it('Should information be present for all location possible scenarios: error, location with and without repositories', () => {
121
+ // When I open the Repositories view that contains all possible kind of locations.
122
+ RepositoriesStubs.stubRepositories();
123
+ RepositoriesStubs.stubLocations();
124
+
125
+ // Then I expect to see the repositories from location GraphDb instance
126
+ RepositorySteps.getLocalGraphDBTable().contains('test · RUNNING');
127
+ // and a remote GraphDB instance with no repositories in it
128
+ RepositorySteps.getRemoteGraphDBTable().contains('There are no repositories in the current location');
129
+ // and a remote GrapDB instance with repositories
130
+ RepositorySteps.getRemoteGraphDBTable().contains('repository-1716184200859 · RUNNI');
131
+ // and a remote GraphDB instance with error in it
132
+ RepositorySteps.getRemoteGraphDBTable().contains('Cannot connect to location Connect to localhost:7212 [localhost/127.0.0.1] fa');
133
+ // and a remote Ontopic instance
134
+ RepositorySteps.getOntopicTable().contains('http://local');
135
+ });
136
+
137
+ it('Should open edit remote location dialog', () => {
138
+ // When I open the Repositories view that contains all possible kind of locations.
139
+ RepositoriesStubs.stubRepositories();
140
+ RepositoriesStubs.stubLocations();
141
+
142
+ // When I click on edit ontopic istance
143
+ RepositorySteps.editOntopicInstance('http://local');
144
+
145
+ // Then I expect to see that Ontopic instance is set
146
+ AttachRepositorySteps.getOntopicRadioBtn().should('be.checked');
147
+ // And be disabled
148
+ AttachRepositorySteps.getOntopicRadioBtn().should('be.disabled');
149
+ // The location url be set
150
+ AttachRepositorySteps.getLocationURLInput().should('have.value', 'http://local');
151
+ // And be disabled
152
+ AttachRepositorySteps.getLocationURLInput().should('be.disabled');
153
+ });
154
+ });
@@ -214,5 +214,25 @@ describe('ACL Management: create rule', () => {
214
214
  // Then I expect an error notification to be displayed that tells me this ROLE length is not allowed
215
215
  AclManagementSteps.getFieldError().contains('Too short');
216
216
  });
217
+
218
+ it('should show message if role prefix is CUSTOM_', () => {
219
+ // When I am on "ACL Management" page and create a new rule with a CUSTOM_ prefix
220
+ AclManagementSteps.addRuleInBeginning();
221
+ AclManagementSteps.selectPolicy(0, 'allow');
222
+ AclManagementSteps.fillRole(0, 'CUSTOM_ROLE_FOO');
223
+
224
+ // Then I expect the prefix warning to appear
225
+ AclManagementSteps.getPrefixWarning().should('be.visible');
226
+ AclManagementSteps.getPrefixWarning().should('contain.text', 'Custom roles should be entered without the "CUSTOM_" prefix in Workbench');
227
+ // When I save the rule
228
+ AclManagementSteps.saveRule(0);
229
+ // Then the text should be how the user typed it
230
+ AclManagementSteps.getSavedRoleField(0).should('contain', 'CUSTOM_ROLE_FOO');
231
+ // And I expect a warning icon to appear
232
+ AclManagementSteps.getWarningIcon().should('be.visible');
233
+ AclManagementSteps.mouseoverWarningIcon();
234
+ // And the icon should have the same tooltip text as the warning
235
+ AclManagementSteps.getWarningIconTooltipText().should('be.visible').and('contain.text', 'Custom roles should be entered without the "CUSTOM_" prefix in Workbench');
236
+ });
217
237
  });
218
238
 
@@ -105,6 +105,15 @@ describe('User and Access', () => {
105
105
  UserAndAccessSteps.getFieldError().should('not.be.visible');
106
106
  });
107
107
 
108
+ it('Adding a role with a CUSTOM_ prefix shows a warning message', () => {
109
+ // When I create a user
110
+ UserAndAccessSteps.clickCreateNewUserButton();
111
+ // And I add a custom role tag with prefix CUSTOM_
112
+ UserAndAccessSteps.addTextToCustomRoleField('CUSTOM_USER');
113
+ // There should be a warning text
114
+ UserAndAccessSteps.getPrefixWarning().should('contain', 'Custom roles should be entered without the "CUSTOM_" prefix in Workbench');
115
+ });
116
+
108
117
  it('Warn users when setting no password when creating new user admin', () => {
109
118
  UserAndAccessSteps.getUsersTable().should('be.visible');
110
119
  createUser("adminWithNoPassword", PASSWORD, ROLE_CUSTOM_ADMIN);
@@ -0,0 +1,90 @@
1
+ import {TTYGViewSteps} from "../../steps/ttyg/ttyg-view-steps";
2
+ import {TTYGStubs} from "../../stubs/ttyg/ttyg-stubs";
3
+
4
+ describe('TTYG view', () => {
5
+ let repositoryId;
6
+
7
+ beforeEach(() => {
8
+ repositoryId = 'ttyg-repo-' + Date.now();
9
+ cy.createRepository({id: repositoryId});
10
+ cy.presetRepository(repositoryId);
11
+ });
12
+
13
+ it('Should load ttyg page and render main components', () => {
14
+ TTYGStubs.stubChatsListGet();
15
+ // Given I have opened the ttyg page
16
+ TTYGViewSteps.visit();
17
+ // When the ttyg page is loaded
18
+ // Then I should see the ttyg view
19
+ TTYGViewSteps.getTtygView().should('exist');
20
+ TTYGViewSteps.getTtygViewTitle().should('contain', 'Talk to Your Graph');
21
+ // Verify the chats sidebar
22
+ TTYGViewSteps.getChatsPanel().should('be.visible');
23
+ TTYGViewSteps.getToggleChatsSidebarButton().should('be.visible');
24
+ TTYGViewSteps.getCreateChatButton().should('be.visible');
25
+ // Verify the agents sidebar
26
+ TTYGViewSteps.getAgentsPanel().should('be.visible');
27
+ TTYGViewSteps.getHelpButton().should('be.visible');
28
+ TTYGViewSteps.getCreateAgentButton().should('be.visible');
29
+ TTYGViewSteps.getToggleAgentsSidebarButton().should('be.visible');
30
+ // Verify the chat panel
31
+ TTYGViewSteps.getChat().should('be.visible');
32
+ TTYGViewSteps.getChatPanelToolbar().should('be.visible');
33
+ TTYGViewSteps.getEditCurrentAgentButton().should('be.visible');
34
+ TTYGViewSteps.getExportCurrentChatButton().should('be.visible');
35
+ });
36
+
37
+ it.skip('Should render chat list', () => {
38
+ TTYGStubs.stubChatsListGet();
39
+ // Given I have opened the ttyg page
40
+ TTYGViewSteps.visit();
41
+ // When the ttyg page is loaded
42
+ // Then I should see the chat list
43
+ // TODO: Temporary removed because it fails on CI.
44
+ // TTYGViewSteps.getChatListLoadingIndicator().should('be.visible');
45
+ TTYGViewSteps.getChatsPanel().should('be.visible');
46
+ // And I should see 7 chat groups by day
47
+ TTYGViewSteps.getChatByDayGroups().should('have.length', 7);
48
+ // And the first chat group should have 3 chats
49
+ verifyChatList([
50
+ [
51
+ {name: 'Very long chat name which does not fit in the sidebar'},
52
+ {name: 'Test chat 2'},
53
+ {name: 'Test chat 3'}
54
+ ],
55
+ [{name: 'Test chat 4'}],
56
+ [{name: 'Test chat 5'}],
57
+ [{name: 'Test chat 6'}],
58
+ [{name: 'Test chat 7'}],
59
+ [{name: 'Test chat 8'}],
60
+ [{name: 'Test chat 9'}]
61
+ ]);
62
+ });
63
+
64
+ it('Should render no results when there are no chats', () => {
65
+ TTYGStubs.stubChatsListGetNoResults();
66
+ // Given I have opened the ttyg page
67
+ TTYGViewSteps.visit();
68
+ // When the ttyg page is loaded
69
+ // And there are no chats
70
+ // Then I expect chat list panel to be hidden
71
+ TTYGViewSteps.getChatsPanel().should('be.hidden');
72
+ // When I open the chat list
73
+ TTYGViewSteps.expandChatsSidebar();
74
+ // Then I should see no chats
75
+ TTYGViewSteps.getChatByDayGroups().should('have.length', 0);
76
+ });
77
+ });
78
+
79
+ /**
80
+ * @param {*[]} data
81
+ */
82
+ function verifyChatList(data) {
83
+ TTYGViewSteps.getChatByDayGroups().should('have.length', data.length);
84
+ data.forEach((group, index) => {
85
+ TTYGViewSteps.getChatsFromGroup(index).should('have.length', group.length);
86
+ group.forEach((chat, chatIndex) => {
87
+ TTYGViewSteps.getChatFromGroup(index, chatIndex).should('contain', chat.name);
88
+ });
89
+ });
90
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "2.7.3",
3
+ "version": "2.7.4-GA1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "graphdb-workbench-tests",
9
- "version": "2.7.3",
9
+ "version": "2.7.4-GA1",
10
10
  "license": "Apache-2.0",
11
11
  "devDependencies": {
12
12
  "cypress": "^13.3.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "2.7.3",
3
+ "version": "2.7.4-GA1",
4
4
  "description": "Cypress tests for GraphDB workbench",
5
5
  "scripts": {
6
6
  "prepack": "npm shrinkwrap",
@@ -205,7 +205,7 @@ class ImportSteps {
205
205
  }
206
206
 
207
207
  static checkImportedStatusIsEmpty(resourceName) {
208
- this.getResourceStatus(resourceName).find('.import-resource-message').children().should('have.length', 0);
208
+ this.getResourceStatus(resourceName).find('.import-resource-message .success-messages').should('have.length', 0);
209
209
  }
210
210
 
211
211
  static checkUserDataUploadedResource(index, resourceName) {
@@ -458,6 +458,14 @@ class ImportSteps {
458
458
  .and('not.have.class', 'ng-animate')
459
459
  .and('have.class', 'in');
460
460
  }
461
+
462
+ static getSizeCell() {
463
+ return cy.get('th.cell-size');
464
+ }
465
+
466
+ static orderBySize() {
467
+ ImportSteps.getSizeCell().click();
468
+ }
461
469
  }
462
470
 
463
471
  export default ImportSteps;
@@ -0,0 +1,85 @@
1
+ export class AttachRepositorySteps {
2
+
3
+ static getAttachRemoteLocationBtn() {
4
+ return cy.get('#addAttachRemoteLocation');
5
+ }
6
+
7
+ static openAttachRemoteLocationDialog() {
8
+ AttachRepositorySteps.getAttachRemoteLocationBtn().click();
9
+ }
10
+
11
+ static getAttachBtn() {
12
+ return cy.get('.attach-location');
13
+ }
14
+
15
+ static attachRemoteLocation() {
16
+ AttachRepositorySteps.getAttachBtn().click();
17
+ }
18
+
19
+ static getCancelBtn() {
20
+ return cy.get('.cancel-attaching-location');
21
+ }
22
+
23
+ static cancelAttaching() {
24
+ AttachRepositorySteps.getCancelBtn().click();
25
+ }
26
+
27
+ static saveRemoteLocation() {
28
+ AttachRepositorySteps.getAttachBtn().click();
29
+ }
30
+
31
+ static getRemoteLocationDialog() {
32
+ return cy.get('#remoteLocationForm');
33
+ }
34
+
35
+ static getAuthenticationRadioBtn() {
36
+ return AttachRepositorySteps.getRemoteLocationDialog().find('.none-authentication');
37
+ }
38
+
39
+ static selectAuthenticationRadioBtn() {
40
+ AttachRepositorySteps.getAuthenticationRadioBtn().check();
41
+ }
42
+
43
+ static getBasicRadioBtn() {
44
+ return AttachRepositorySteps.getRemoteLocationDialog().find('.basic-authentication');
45
+ }
46
+
47
+ static selectBasicRadioBtn() {
48
+ AttachRepositorySteps.getBasicRadioBtn().check();
49
+ }
50
+
51
+ static getSignatureRadioBtn() {
52
+ return AttachRepositorySteps.getRemoteLocationDialog().find('.signature-authentication');
53
+ }
54
+
55
+ static selectSignatureRadioBtn() {
56
+ AttachRepositorySteps.getSignatureRadioBtn().check();
57
+ }
58
+
59
+ static getGraphDBRadioBtn() {
60
+ return AttachRepositorySteps.getRemoteLocationDialog().find('.graph-db-instance');
61
+ }
62
+
63
+ static selectGraphDBRadioBtn() {
64
+ AttachRepositorySteps.getGraphDBRadioBtn().check();
65
+ }
66
+ static getOntopicRadioBtn() {
67
+ return AttachRepositorySteps.getRemoteLocationDialog().find('.ontopic-instance');
68
+ }
69
+
70
+ static selectOntopicRadioBtn() {
71
+ AttachRepositorySteps.getOntopicRadioBtn().check();
72
+ }
73
+
74
+ static getLocationURLInput() {
75
+ return AttachRepositorySteps.getRemoteLocationDialog().get('#location');
76
+ }
77
+
78
+ static getUsernameInput() {
79
+ return AttachRepositorySteps.getRemoteLocationDialog().get('#username');
80
+ }
81
+
82
+ static getPasswordInput() {
83
+ return AttachRepositorySteps.getRemoteLocationDialog().get('#password');
84
+ }
85
+ }
@@ -206,4 +206,32 @@ export class RepositorySteps {
206
206
  .and('contain', 'Repositories from: ')
207
207
  .and('contain', 'Local');
208
208
  }
209
+
210
+ static getOntopicTable() {
211
+ return cy.get('#wb-repositories-ontopic-repositoryInGetRepositories');
212
+ }
213
+
214
+ static getDeleteOntopicInstanceBtn(url) {
215
+ return RepositorySteps.getOntopicTable().find('tr').contains(url).parent().find('.delete-ontopic-location');
216
+ }
217
+
218
+ static deleteOntopicInstance(url) {
219
+ RepositorySteps.getDeleteOntopicInstanceBtn(url).click();
220
+ }
221
+
222
+ static getEditOntopicInstanceBtn(url) {
223
+ return RepositorySteps.getOntopicTable().find('tr').contains(url).parent().find('.edit-ontopic-location');
224
+ }
225
+
226
+ static editOntopicInstance(url) {
227
+ RepositorySteps.getEditOntopicInstanceBtn(url).click();
228
+ }
229
+
230
+ static getRemoteGraphDBTable() {
231
+ return cy.get('#wb-locations-locationInGetRemoteLocations');
232
+ }
233
+
234
+ static getLocalGraphDBTable() {
235
+ return cy.get('#wb-locations-locationInGetLocations');
236
+ }
209
237
  }
@@ -157,6 +157,10 @@ export class AclManagementSteps {
157
157
  return this.getRule(index).find('.role-cell textarea');
158
158
  }
159
159
 
160
+ static getSavedRoleField(index) {
161
+ return this.getRule(index).find('.role-cell');
162
+ }
163
+
160
164
  static fillRole(index, value) {
161
165
  this.getRoleField(index).clear().type(value);
162
166
  }
@@ -165,6 +169,22 @@ export class AclManagementSteps {
165
169
  return cy.get('div.small');
166
170
  }
167
171
 
172
+ static getPrefixWarning() {
173
+ return cy.get('.prefix-warning-text');
174
+ }
175
+
176
+ static getWarningIcon() {
177
+ return cy.get('.icon-warning');
178
+ }
179
+
180
+ static getWarningIconTooltipText() {
181
+ return cy.get('.angular-tooltip');
182
+ }
183
+
184
+ static mouseoverWarningIcon() {
185
+ cy.get('.icon-warning').first().trigger('mouseover');
186
+ }
187
+
168
188
  static getPluginField(index) {
169
189
  return this.getRule(index).find('.plugin-cell textarea');
170
190
  }
@@ -148,6 +148,10 @@ export class UserAndAccessSteps {
148
148
  return cy.get('.modal-dialog');
149
149
  }
150
150
 
151
+ static getPrefixWarning() {
152
+ return cy.get('.prefix-warning');
153
+ }
154
+
151
155
  static getDialogText() {
152
156
  return this.getModal().find('.lead');
153
157
  }
@@ -0,0 +1,121 @@
1
+ export class TTYGViewSteps {
2
+ static visit() {
3
+ cy.visit('/chatgpt');
4
+ }
5
+
6
+ static getTtygView() {
7
+ return cy.get('.ttyg-view');
8
+ }
9
+
10
+ static getTtygViewTitle() {
11
+ return cy.get('#ttyg-view-title');
12
+ }
13
+
14
+ static getTtygViewContent() {
15
+ return cy.get('.ttyg-view-content');
16
+ }
17
+
18
+ static getChatsSidebar() {
19
+ return cy.get('.left-sidebar');
20
+ }
21
+
22
+ static getChatListLoadingIndicator() {
23
+ return this.getChatsSidebar().find('[onto-loader-fancy]');
24
+ }
25
+
26
+ static getChatsPanel() {
27
+ return this.getChatsSidebar().find('.chat-list-panel');
28
+ }
29
+
30
+ static getChatListComponent() {
31
+ return this.getChatsPanel().find('.chat-list-component');
32
+ }
33
+
34
+ static getChatByDayGroups() {
35
+ return this.getChatListComponent().find('.chat-group');
36
+ }
37
+
38
+ static getChatGroup(index) {
39
+ return this.getChatByDayGroups().eq(index);
40
+ }
41
+
42
+ static getChatsFromGroup(index) {
43
+ return this.getChatGroup(index).find('.chat-item');
44
+ }
45
+
46
+ static getChatFromGroup(groupIndex, chatIndex) {
47
+ return this.getChatGroup(groupIndex).find('.chat-item').eq(chatIndex);
48
+ }
49
+
50
+ static getToggleChatsSidebarButton() {
51
+ return this.getChatsSidebar().find('.toggle-chats-sidebar-btn');
52
+ }
53
+
54
+ static collapseChatsSidebar() {
55
+ return this.getToggleChatsSidebarButton().click();
56
+ }
57
+
58
+ static expandChatsSidebar() {
59
+ return this.getToggleChatsSidebarButton().click();
60
+ }
61
+
62
+ static getCreateChatButton() {
63
+ return this.getChatsSidebar().find('.create-chat-btn');
64
+ }
65
+
66
+ static getAgentsSidebar() {
67
+ return cy.get('.right-sidebar');
68
+ }
69
+
70
+ static getAgentsPanel() {
71
+ return this.getAgentsSidebar().find('.agents-list-panel');
72
+ }
73
+
74
+ static getHelpButton() {
75
+ return this.getAgentsSidebar().find('.help-btn');
76
+ }
77
+
78
+ static getCreateAgentButton() {
79
+ return this.getAgentsSidebar().find('.create-agent-btn');
80
+ }
81
+
82
+ static getToggleAgentsSidebarButton() {
83
+ return this.getAgentsSidebar().find('.toggle-agents-sidebar-btn');
84
+ }
85
+
86
+ static collapseAgentsSidebar() {
87
+ return this.getToggleAgentsSidebarButton().click();
88
+ }
89
+
90
+ static expandAgentsSidebar() {
91
+ return this.getToggleAgentsSidebarButton().click();
92
+ }
93
+
94
+ static getChatPanel() {
95
+ return this.getTtygView().find('.chat-content');
96
+ }
97
+
98
+ static getChatPanelToolbar() {
99
+ return this.getChatPanel().find('.toolbar');
100
+ }
101
+
102
+ static getEditCurrentAgentButton() {
103
+ return this.getChatPanelToolbar().find('.edit-current-agent-btn');
104
+ }
105
+
106
+ static editCurrentAgent() {
107
+ return this.getEditCurrentAgentButton().click();
108
+ }
109
+
110
+ static getExportCurrentChatButton() {
111
+ return this.getChatPanelToolbar().find('.export-current-chat-btn');
112
+ }
113
+
114
+ static exportCurrentChat() {
115
+ return this.getExportCurrentChatButton().click();
116
+ }
117
+
118
+ static getChat() {
119
+ return this.getChatPanel().find('.chat');
120
+ }
121
+ }
@@ -0,0 +1,11 @@
1
+ import {Stubs} from "../stubs";
2
+
3
+ export class RepositoriesStubs extends Stubs {
4
+ static stubRepositories(withDelay = 0) {
5
+ RepositoriesStubs.stubQueryResponse('/rest/repositories/all', '/repositories/get-repositories.json', 'backup-and-restore-response', withDelay);
6
+ }
7
+
8
+ static stubLocations(withDelay = 0) {
9
+ RepositoriesStubs.stubQueryResponse('/rest/locations?filterClusterLocations=true', '/repositories/get-locations.json', 'backup-and-restore-response', withDelay);
10
+ }
11
+ }
@@ -0,0 +1,34 @@
1
+ export class TTYGStubs {
2
+ static stubChatsListGet(delay = 0) {
3
+ cy.intercept('/rest/chat/conversations', {
4
+ method: 'GET',
5
+ fixture: '/ttyg/chats/get-chat-list.json',
6
+ statusCode: 200,
7
+ delay: delay
8
+ }).as('get-chat-list');
9
+ }
10
+
11
+ static stubChatsListGetNoResults() {
12
+ cy.intercept('/rest/chat/conversations', {
13
+ method: 'GET',
14
+ fixture: '/ttyg/chats/get-chat-list-0.json',
15
+ statusCode: 200
16
+ }).as('get-chat-list');
17
+ }
18
+
19
+ static stubChatCreate() {
20
+
21
+ }
22
+
23
+ static stubChatGet() {
24
+
25
+ }
26
+
27
+ static stubChatUpdate() {
28
+
29
+ }
30
+
31
+ static stubChatDelete() {
32
+
33
+ }
34
+ }