graphdb-workbench-tests 3.0.0-TR6 → 3.0.0-TR7
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.
- package/fixtures/graphql/endpoints/graphql-endpoint-configuration-types.json +46 -0
- package/fixtures/graphql/endpoints/graphql-endpoint-configuration.json +227 -0
- package/integration/graphql/create-graphql-endpoint.spec.js +25 -0
- package/integration/graphql/delete-graphql-endpoint.spec.js +46 -0
- package/integration/graphql/edit-graphql-enpoint.spec.js +196 -0
- package/integration/setup/namespaces.spec.js +19 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/steps/graphql/create-graphql-endpoint-steps.js +12 -0
- package/steps/graphql/edit-graphql-endpoint-steps.js +90 -0
- package/steps/graphql/graphql-endpoint-management-steps.js +30 -0
- package/steps/modal-dialog-steps.js +5 -1
- package/steps/setup/namespace-steps.js +17 -0
- package/stubs/graphql/graphql-stubs.js +17 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"configs": [
|
|
3
|
+
{
|
|
4
|
+
"key": "str",
|
|
5
|
+
"label": "String",
|
|
6
|
+
"type": "string",
|
|
7
|
+
"collection": false,
|
|
8
|
+
"value": "strValue",
|
|
9
|
+
"values": [],
|
|
10
|
+
"regex": "^(?:ALL:?)?(?:(?:-?[\\w]{2}(?:-[\\w]*)?~?|-?NONE|ANY|BROWSER)?(?:,(?:-?[\\w]{2}(?:-[\\w]*)?~?|-?NONE|ANY|BROWSER))*)$"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"key": "bool",
|
|
14
|
+
"label": "Boolean value",
|
|
15
|
+
"type": "boolean",
|
|
16
|
+
"collection": false,
|
|
17
|
+
"value": false,
|
|
18
|
+
"values": []
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"key": "select",
|
|
22
|
+
"label": "Select",
|
|
23
|
+
"type": "string",
|
|
24
|
+
"collection": false,
|
|
25
|
+
"value": "Two",
|
|
26
|
+
"values": ["One", "Two", "Three"]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"key": "multiselect",
|
|
30
|
+
"label": "Multiselect",
|
|
31
|
+
"type": "string",
|
|
32
|
+
"collection": true,
|
|
33
|
+
"value": ["Angular", "JavaScript"],
|
|
34
|
+
"values": ["Angular", "JavaScript", "WebDevelopment"]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"key": "json",
|
|
38
|
+
"label": "JSON",
|
|
39
|
+
"type": "json",
|
|
40
|
+
"collection": false,
|
|
41
|
+
"value": "{\"foo\": \"bar\"}",
|
|
42
|
+
"values": [],
|
|
43
|
+
"required": true
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
{
|
|
2
|
+
"configs": [
|
|
3
|
+
{
|
|
4
|
+
"key": "enable_mutations",
|
|
5
|
+
"label": "enable_mutations",
|
|
6
|
+
"description": "Controls whether the generated GraphQL schema should include object mutations or not.",
|
|
7
|
+
"type": "boolean",
|
|
8
|
+
"collection": false,
|
|
9
|
+
"value": null,
|
|
10
|
+
"values": null,
|
|
11
|
+
"required": false,
|
|
12
|
+
"regex": null
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"key": "lang.fetch",
|
|
16
|
+
"label": "fetch",
|
|
17
|
+
"description": "Default language fetch configuration",
|
|
18
|
+
"type": "string",
|
|
19
|
+
"collection": false,
|
|
20
|
+
"value": null,
|
|
21
|
+
"values": null,
|
|
22
|
+
"required": false,
|
|
23
|
+
"regex": "^(?:ALL:?)?(?:(?:-?[\\w]{2}(?:-[\\w]*)?~?|-?NONE|ANY|BROWSER)?(?:,(?:-?[\\w]{2}(?:-[\\w]*)?~?|-?NONE|ANY|BROWSER))*)$"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"key": "lang.validate",
|
|
27
|
+
"label": "validate",
|
|
28
|
+
"description": "Default language validation configuration",
|
|
29
|
+
"type": "string",
|
|
30
|
+
"collection": false,
|
|
31
|
+
"value": "UNIQ",
|
|
32
|
+
"values": null,
|
|
33
|
+
"required": false,
|
|
34
|
+
"regex": "^(?:[\\w]{2}~?|NONE|ANY|ALL)?(?:,(?:[\\w]{2}~?|NONE|ANY|ALL))*(?:;?UNIQ)?$"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"key": "lang.implicit",
|
|
38
|
+
"label": "implicit",
|
|
39
|
+
"description": "Default language to use when inserting rdf:langString values.",
|
|
40
|
+
"type": "string",
|
|
41
|
+
"collection": false,
|
|
42
|
+
"value": "en",
|
|
43
|
+
"values": null,
|
|
44
|
+
"required": false,
|
|
45
|
+
"regex": "[\\w]{2}(?:-[\\w]*)?"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"key": "lang.defaultNameFetch",
|
|
49
|
+
"label": "defaultNameFetch",
|
|
50
|
+
"description": "Default language spec to apply when loading values for the name property",
|
|
51
|
+
"type": "string",
|
|
52
|
+
"collection": false,
|
|
53
|
+
"value": "ANY",
|
|
54
|
+
"values": null,
|
|
55
|
+
"required": false,
|
|
56
|
+
"regex": "^(?:(?:-?[\\w]{2}(?:-[\\w]*)?~?|-?NONE|ANY|BROWSER)?(?:,(?:-?[\\w]{2}(?:-[\\w]*)?~?|-?NONE|ANY|BROWSER))*)$"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"key": "lang.appendDefaultNameFetch",
|
|
60
|
+
"label": "appendDefaultNameFetch",
|
|
61
|
+
"description": "Specifies whether the default spec, if any, should be appended or not to any user-defined name fetch spec",
|
|
62
|
+
"type": "boolean",
|
|
63
|
+
"collection": false,
|
|
64
|
+
"value": true,
|
|
65
|
+
"values": null,
|
|
66
|
+
"required": false,
|
|
67
|
+
"regex": null
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"key": "queryPfx",
|
|
71
|
+
"label": "queryPfx",
|
|
72
|
+
"description": "Allows setting a prefix that will be put in all queries in the GraphQL schema.",
|
|
73
|
+
"type": "string",
|
|
74
|
+
"collection": false,
|
|
75
|
+
"value": null,
|
|
76
|
+
"values": null,
|
|
77
|
+
"required": false,
|
|
78
|
+
"regex": "[\\w]*"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"key": "mutationPfx",
|
|
82
|
+
"label": "mutationPfx",
|
|
83
|
+
"description": "Allows setting a prefix that will be put in all mutations in the GraphQL schema.",
|
|
84
|
+
"type": "string",
|
|
85
|
+
"collection": false,
|
|
86
|
+
"value": null,
|
|
87
|
+
"values": null,
|
|
88
|
+
"required": false,
|
|
89
|
+
"regex": "[\\w]*"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"key": "search",
|
|
93
|
+
"label": "search",
|
|
94
|
+
"description": "Allows you to define a structure of the searchable data for fields that are not specified in the configuration of the objects and/or properties",
|
|
95
|
+
"type": "dictionary",
|
|
96
|
+
"collection": false,
|
|
97
|
+
"value": null,
|
|
98
|
+
"values": null,
|
|
99
|
+
"required": false,
|
|
100
|
+
"regex": null
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"key": "repository",
|
|
104
|
+
"label": "repository",
|
|
105
|
+
"description": "Changes the default repository used for the entire schema.",
|
|
106
|
+
"type": "string",
|
|
107
|
+
"collection": false,
|
|
108
|
+
"value": null,
|
|
109
|
+
"values": null,
|
|
110
|
+
"required": false,
|
|
111
|
+
"regex": "[\\w]*"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"key": "includeInferred",
|
|
115
|
+
"label": "includeInferred",
|
|
116
|
+
"description": "Controls whether query inference is enabled or disabled by default for all queries and mutations.",
|
|
117
|
+
"type": "boolean",
|
|
118
|
+
"collection": false,
|
|
119
|
+
"value": true,
|
|
120
|
+
"values": null,
|
|
121
|
+
"required": false,
|
|
122
|
+
"regex": null
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"key": "expandOwlSameAs",
|
|
126
|
+
"label": "expandOwlSameAs",
|
|
127
|
+
"description": "Controls whether owl:sameAs expansion is enabled or disabled by default for all queries and mutations.",
|
|
128
|
+
"type": "boolean",
|
|
129
|
+
"collection": false,
|
|
130
|
+
"value": true,
|
|
131
|
+
"values": null,
|
|
132
|
+
"required": false,
|
|
133
|
+
"regex": null
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"key": "disabledChecks",
|
|
137
|
+
"label": "disabledChecks",
|
|
138
|
+
"description": "Specifies which checks could be disabled during the schema validation.",
|
|
139
|
+
"type": "string",
|
|
140
|
+
"collection": true,
|
|
141
|
+
"value": true,
|
|
142
|
+
"values": [
|
|
143
|
+
"regexInheritanceCheck",
|
|
144
|
+
"rangeCheck"
|
|
145
|
+
],
|
|
146
|
+
"required": false,
|
|
147
|
+
"regex": null
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"key": "defaultRole",
|
|
151
|
+
"label": "defaultRole",
|
|
152
|
+
"description": "The default RBAC role the user will receive if no roles are found in the security JWT token or none of the roles match any in the rbac section of the current SOML schema.",
|
|
153
|
+
"type": "string",
|
|
154
|
+
"collection": false,
|
|
155
|
+
"value": "defaultRole",
|
|
156
|
+
"values": null,
|
|
157
|
+
"required": false,
|
|
158
|
+
"regex": "[\\w]*"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"key": "defaultIntegrationRole",
|
|
162
|
+
"label": "defaultIntegrationRole",
|
|
163
|
+
"description": "The default RBAC role that will have read-only access to the data and could be used for system integrations.",
|
|
164
|
+
"type": "string",
|
|
165
|
+
"collection": false,
|
|
166
|
+
"value": "Federation_SystemRole",
|
|
167
|
+
"values": null,
|
|
168
|
+
"required": false,
|
|
169
|
+
"regex": "[\\w]*"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"key": "exposeSomlInGraphQL",
|
|
173
|
+
"label": "exposeSomlInGraphQL",
|
|
174
|
+
"description": "Controls whether GraphQL schema should include directives that expose the effective SOML configurations for each output type and property.",
|
|
175
|
+
"type": "boolean",
|
|
176
|
+
"collection": false,
|
|
177
|
+
"value": false,
|
|
178
|
+
"values": null,
|
|
179
|
+
"required": false,
|
|
180
|
+
"regex": null
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"key": "enableCollectionCount",
|
|
184
|
+
"label": "enableCollectionCount",
|
|
185
|
+
"description": "Controls whether the collections should have a companion property that provides counting of the collection properties.",
|
|
186
|
+
"type": "boolean",
|
|
187
|
+
"collection": false,
|
|
188
|
+
"value": false,
|
|
189
|
+
"values": null,
|
|
190
|
+
"required": false,
|
|
191
|
+
"regex": null
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"key": "enableTypeCount",
|
|
195
|
+
"label": "enableTypeCount",
|
|
196
|
+
"description": "Controls whether new counting queries should be generated for all queryable types.",
|
|
197
|
+
"type": "boolean",
|
|
198
|
+
"collection": false,
|
|
199
|
+
"value": false,
|
|
200
|
+
"values": null,
|
|
201
|
+
"required": false,
|
|
202
|
+
"regex": null
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"key": "compactErrorMessages",
|
|
206
|
+
"label": "compactErrorMessages",
|
|
207
|
+
"description": "Controls the default behavior of the GraphQL Responder how to process the errors that are returned to the client.",
|
|
208
|
+
"type": "boolean",
|
|
209
|
+
"collection": false,
|
|
210
|
+
"value": false,
|
|
211
|
+
"values": null,
|
|
212
|
+
"required": false,
|
|
213
|
+
"regex": null
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"key": "enableGraphQlExplain",
|
|
217
|
+
"label": "enableGraphQlExplain",
|
|
218
|
+
"description": "Controls whether SemanticObjects should provide the generated SPARQL query or its explain plan.",
|
|
219
|
+
"type": "boolean",
|
|
220
|
+
"collection": false,
|
|
221
|
+
"value": true,
|
|
222
|
+
"values": null,
|
|
223
|
+
"required": false,
|
|
224
|
+
"regex": null
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
}
|
|
@@ -228,6 +228,31 @@ describe('Graphql: create endpoint', () => {
|
|
|
228
228
|
CreateGraphqlEndpointSteps.getVocabularyPrefixSelectSelectedOption().should('have.text', 'voc');
|
|
229
229
|
});
|
|
230
230
|
|
|
231
|
+
it('should be able to configure generation settings (the second step)', () => {
|
|
232
|
+
// Given I have a repository with graphql shapes in it
|
|
233
|
+
cy.importServerFile(repositoryId, 'ontology-and-shapes.ttl');
|
|
234
|
+
// And I started the endpoint creation wizard
|
|
235
|
+
GraphqlEndpointManagementSteps.visit();
|
|
236
|
+
cy.wait('@getRepositories');
|
|
237
|
+
GraphqlEndpointManagementSteps.createEndpoint();
|
|
238
|
+
CreateGraphqlEndpointSteps.getView().should('be.visible');
|
|
239
|
+
CreateGraphqlEndpointSteps.getSelectSchemaSourceView().should('be.visible');
|
|
240
|
+
CreateGraphqlEndpointSteps.getAvailableGraphqlShapes().should('have.length', 2);
|
|
241
|
+
// When I select a graphql schema shape
|
|
242
|
+
CreateGraphqlEndpointSteps.selectGraphqlShape(1);
|
|
243
|
+
// Then I should be able to proceed to the next step
|
|
244
|
+
CreateGraphqlEndpointSteps.next();
|
|
245
|
+
CreateGraphqlEndpointSteps.getGenerationSettingsForm().should('be.visible');
|
|
246
|
+
// And the next button should be enabled because all settings fields are available and valid initially
|
|
247
|
+
CreateGraphqlEndpointSteps.getNextStepButton().should('be.enabled');
|
|
248
|
+
// When I click next
|
|
249
|
+
CreateGraphqlEndpointSteps.next();
|
|
250
|
+
// Then I should be on the generate endpoint step
|
|
251
|
+
CreateGraphqlEndpointSteps.getActiveStep().should('contain', 'Create');
|
|
252
|
+
CreateGraphqlEndpointSteps.getGenerateEndpointView().should('be.visible');
|
|
253
|
+
|
|
254
|
+
});
|
|
255
|
+
|
|
231
256
|
it('should be able to cancel the endpoint creation wizard', () => {
|
|
232
257
|
// Given I have a repository with no active GraphQL endpoints
|
|
233
258
|
// When I visit the endpoint management view
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {GraphqlEndpointManagementSteps} from "../../steps/graphql/graphql-endpoint-management-steps";
|
|
2
|
+
import {ModalDialogSteps} from "../../steps/modal-dialog-steps";
|
|
3
|
+
import {ApplicationSteps} from "../../steps/application-steps";
|
|
4
|
+
|
|
5
|
+
describe('Graphql: delete endpoint', () => {
|
|
6
|
+
let repositoryId;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
repositoryId = 'graphql-endpoint-management-' + Date.now();
|
|
10
|
+
cy.createRepository({id: repositoryId});
|
|
11
|
+
cy.presetRepository(repositoryId);
|
|
12
|
+
cy.importServerFile(repositoryId, 'swapi-dataset.ttl');
|
|
13
|
+
cy.uploadGraphqlSchema(repositoryId, 'graphql/soml/swapi-schema.yaml', 'swapi');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
cy.deleteRepository(repositoryId);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should be able to delete graphql endpoint', () => {
|
|
21
|
+
// Given I have a repository with active GraphQL endpoint
|
|
22
|
+
// And I have visited the endpoint management view
|
|
23
|
+
GraphqlEndpointManagementSteps.visit();
|
|
24
|
+
GraphqlEndpointManagementSteps.getView().should('be.visible');
|
|
25
|
+
GraphqlEndpointManagementSteps.getEndpointsInfo().should('have.length', 1);
|
|
26
|
+
// When I click on the delete endpoint button
|
|
27
|
+
GraphqlEndpointManagementSteps.deleteEndpoint(0);
|
|
28
|
+
// Then I should see the confirmation dialog
|
|
29
|
+
ModalDialogSteps.getDialog().should('be.visible');
|
|
30
|
+
// When I reject the confirmation dialog
|
|
31
|
+
ModalDialogSteps.cancel();
|
|
32
|
+
// Then Confirmation dialog should be closed
|
|
33
|
+
ModalDialogSteps.getDialog().should('not.exist');
|
|
34
|
+
// And the endpoint should not be deleted
|
|
35
|
+
GraphqlEndpointManagementSteps.getEndpointsInfo().should('have.length', 1);
|
|
36
|
+
|
|
37
|
+
// When I click on the delete endpoint button again and confirm the deletion
|
|
38
|
+
GraphqlEndpointManagementSteps.deleteEndpoint(0);
|
|
39
|
+
ModalDialogSteps.confirm();
|
|
40
|
+
// Then I should see a success toast
|
|
41
|
+
ApplicationSteps.getSuccessNotifications().should('be.visible');
|
|
42
|
+
// And the endpoint should be deleted and the no results row should be visible
|
|
43
|
+
GraphqlEndpointManagementSteps.getEndpointsInfo().should('have.length', 1);
|
|
44
|
+
GraphqlEndpointManagementSteps.getNoResultsRow().should('be.visible');
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {GraphqlStubs} from "../../stubs/graphql/graphql-stubs";
|
|
2
|
+
import {GraphqlEndpointManagementSteps} from "../../steps/graphql/graphql-endpoint-management-steps";
|
|
3
|
+
import {EditGraphqlEndpointSteps} from "../../steps/graphql/edit-graphql-endpoint-steps";
|
|
4
|
+
import {ApplicationSteps} from "../../steps/application-steps";
|
|
5
|
+
|
|
6
|
+
describe('Graphql: edit endpoint settings', () => {
|
|
7
|
+
let repositoryId;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
repositoryId = 'create-graphql-endpoint-' + Date.now();
|
|
11
|
+
cy.createRepository({id: repositoryId});
|
|
12
|
+
cy.presetRepository(repositoryId);
|
|
13
|
+
// TODO: remove stubs and enable next imports when REST API is ready
|
|
14
|
+
// cy.importServerFile(repositoryId, 'swapi-dataset.ttl');
|
|
15
|
+
// cy.uploadGraphqlSchema(repositoryId, 'graphql/soml/swapi-schema.yaml', 'swapi');
|
|
16
|
+
GraphqlStubs.stubGetEndpointsInfo(repositoryId);
|
|
17
|
+
GraphqlStubs.stubGetEndpoints(repositoryId, 'graphql-swapi-endpoints.json');
|
|
18
|
+
GraphqlStubs.stubGetEndpointConfiguration(repositoryId, 'swapi', undefined, 1000);
|
|
19
|
+
|
|
20
|
+
// Visit the endpoint management view
|
|
21
|
+
GraphqlEndpointManagementSteps.visit();
|
|
22
|
+
// Ensure the endpoints list is loaded
|
|
23
|
+
GraphqlEndpointManagementSteps.getEndpointsInfo().should('have.length.at.least', 1);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
afterEach(() => {
|
|
27
|
+
cy.deleteRepository(repositoryId);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should display and edit different types dynamic form fields', () => {
|
|
31
|
+
GraphqlStubs.stubGetEndpointConfiguration(repositoryId, 'swapi', 'graphql-endpoint-configuration-types.json');
|
|
32
|
+
GraphqlEndpointManagementSteps.editEndpointConfiguration(0);
|
|
33
|
+
EditGraphqlEndpointSteps.getDialog().should('be.visible');
|
|
34
|
+
|
|
35
|
+
EditGraphqlEndpointSteps.getInputField(0).should('have.value', 'strValue');
|
|
36
|
+
EditGraphqlEndpointSteps.fillInputField(0, 'Foo')
|
|
37
|
+
|
|
38
|
+
EditGraphqlEndpointSteps.getBooleanField(0).should('not.be.checked');
|
|
39
|
+
EditGraphqlEndpointSteps.toggleBooleanField(0);
|
|
40
|
+
|
|
41
|
+
EditGraphqlEndpointSteps.getSelectField(0).should('have.value', 'Two');
|
|
42
|
+
EditGraphqlEndpointSteps.selectOption(0, 'One');
|
|
43
|
+
|
|
44
|
+
EditGraphqlEndpointSteps.verifyMultiSelectOptionSelected(0, 'Angular', 'JavaScript');
|
|
45
|
+
EditGraphqlEndpointSteps.toggleMultiSelectOption(0, 'Angular');
|
|
46
|
+
EditGraphqlEndpointSteps.verifyMultiSelectOptionSelected(0, 'JavaScript');
|
|
47
|
+
|
|
48
|
+
EditGraphqlEndpointSteps.getJsonField(0).should('have.value', '{"foo": "bar"}');
|
|
49
|
+
EditGraphqlEndpointSteps.clearJsonField(0);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should allow saving the configuration changes successfully', () => {
|
|
53
|
+
GraphqlStubs.stubSaveEndpointConfiguration(repositoryId, 'swapi', 1000);
|
|
54
|
+
// Open the modal
|
|
55
|
+
GraphqlEndpointManagementSteps.editEndpointConfiguration(0);
|
|
56
|
+
EditGraphqlEndpointSteps.getDialog().should('be.visible');
|
|
57
|
+
|
|
58
|
+
// Then the save button is disabled
|
|
59
|
+
EditGraphqlEndpointSteps.getOKButton().should('be.disabled');
|
|
60
|
+
|
|
61
|
+
// When I change some fields
|
|
62
|
+
EditGraphqlEndpointSteps.fillInputField(0, 'ANY');
|
|
63
|
+
EditGraphqlEndpointSteps.fillInputField(2, 'bg');
|
|
64
|
+
EditGraphqlEndpointSteps.toggleBooleanField(0);
|
|
65
|
+
EditGraphqlEndpointSteps.toggleBooleanField(1);
|
|
66
|
+
|
|
67
|
+
// Then the save button is enabled
|
|
68
|
+
EditGraphqlEndpointSteps.getOKButton().should('be.enabled');
|
|
69
|
+
|
|
70
|
+
// Submit the form
|
|
71
|
+
EditGraphqlEndpointSteps.clickOKButton();
|
|
72
|
+
EditGraphqlEndpointSteps.getSavingLoader().should('be.visible');
|
|
73
|
+
cy.wait('@save-endpoint-configuration').then((interception) => {
|
|
74
|
+
expect(interception.request.body).to.deep.equal([
|
|
75
|
+
{
|
|
76
|
+
"key": "enable_mutations",
|
|
77
|
+
"value": true
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"key": "lang.fetch",
|
|
81
|
+
"value": "ANY"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"key": "lang.validate",
|
|
85
|
+
"value": "UNIQ"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"key": "lang.implicit",
|
|
89
|
+
"value": "bg"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"key": "lang.defaultNameFetch",
|
|
93
|
+
"value": "ANY"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"key": "lang.appendDefaultNameFetch",
|
|
97
|
+
"value": false
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"key": "queryPfx",
|
|
101
|
+
"value": null
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"key": "mutationPfx",
|
|
105
|
+
"value": null
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"key": "search",
|
|
109
|
+
"value": null
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"key": "repository",
|
|
113
|
+
"value": null
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"key": "includeInferred",
|
|
117
|
+
"value": true
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"key": "expandOwlSameAs",
|
|
121
|
+
"value": true
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"key": "disabledChecks",
|
|
125
|
+
"value": []
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"key": "defaultRole",
|
|
129
|
+
"value": "defaultRole"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"key": "defaultIntegrationRole",
|
|
133
|
+
"value": "Federation_SystemRole"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"key": "exposeSomlInGraphQL",
|
|
137
|
+
"value": false
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"key": "enableCollectionCount",
|
|
141
|
+
"value": false
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"key": "enableTypeCount",
|
|
145
|
+
"value": false
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"key": "compactErrorMessages",
|
|
149
|
+
"value": false
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"key": "enableGraphQlExplain",
|
|
153
|
+
"value": true
|
|
154
|
+
}
|
|
155
|
+
]);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Modal should close after successful save
|
|
159
|
+
EditGraphqlEndpointSteps.getDialog().should('not.exist');
|
|
160
|
+
ApplicationSteps.getSuccessNotifications().should('be.visible');
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('should show an error message if saving configuration fails', () => {
|
|
164
|
+
// Force the stub for save configuration to fail
|
|
165
|
+
GraphqlStubs.stubSaveEndpointConfiguration(repositoryId, 'swapi', 1000, true);
|
|
166
|
+
|
|
167
|
+
// Open the modal
|
|
168
|
+
GraphqlEndpointManagementSteps.editEndpointConfiguration(0);
|
|
169
|
+
EditGraphqlEndpointSteps.getDialog().should('be.visible');
|
|
170
|
+
|
|
171
|
+
// Fill in a field to allow form submission
|
|
172
|
+
EditGraphqlEndpointSteps.fillInputField(0, 'ANY');
|
|
173
|
+
|
|
174
|
+
// Submit the form
|
|
175
|
+
EditGraphqlEndpointSteps.clickOKButton();
|
|
176
|
+
EditGraphqlEndpointSteps.getSavingLoader().should('be.visible');
|
|
177
|
+
|
|
178
|
+
// I see a toast error
|
|
179
|
+
ApplicationSteps.getErrorNotifications().should('be.visible');
|
|
180
|
+
|
|
181
|
+
// The modal remains open after failure
|
|
182
|
+
EditGraphqlEndpointSteps.getSavingLoader().should('not.exist');
|
|
183
|
+
EditGraphqlEndpointSteps.getDialog().should('be.visible');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it.only('should close the modal when cancel is clicked', () => {
|
|
187
|
+
GraphqlEndpointManagementSteps.editEndpointConfiguration(0);
|
|
188
|
+
EditGraphqlEndpointSteps.getDialog().should('be.visible');
|
|
189
|
+
|
|
190
|
+
// Click cancel
|
|
191
|
+
EditGraphqlEndpointSteps.cancel();
|
|
192
|
+
|
|
193
|
+
// Verify that the modal is dismissed
|
|
194
|
+
EditGraphqlEndpointSteps.getDialog().should('not.exist');
|
|
195
|
+
});
|
|
196
|
+
});
|
|
@@ -277,4 +277,23 @@ describe('Namespaces', () => {
|
|
|
277
277
|
NamespaceSteps.getNamespacesTable().should('not.be.visible');
|
|
278
278
|
NamespaceSteps.getNoNamespacesAlert().should('be.visible');
|
|
279
279
|
});
|
|
280
|
+
|
|
281
|
+
it('Should got to the second page when click on second page button', () => {
|
|
282
|
+
// Given: I visited the namespaces view, and there is more than one page.
|
|
283
|
+
NamespaceSteps.getNamespacesPageElements()
|
|
284
|
+
// First page + three-page buttons + Last page.
|
|
285
|
+
.should('have.length', 5);
|
|
286
|
+
// The table with namespaces should contain the "geoext" namespace because it is among the first 10 namespaces (the paginator is set to 10 namespaces per page).
|
|
287
|
+
NamespaceSteps.getNamespace('geoext').should('be.visible');
|
|
288
|
+
// The namespace with the prefix "omgeo" should not exist because it is the fourteenth namespace and is only visible on the second page.
|
|
289
|
+
NamespaceSteps.verifyNamespaceNotExist('omgeo');
|
|
290
|
+
|
|
291
|
+
// When I go to the second page.
|
|
292
|
+
NamespaceSteps.getNamespacePageElement(2).click()
|
|
293
|
+
|
|
294
|
+
// Then I expect the "geoext" namespace to no longer be visible, as it is part of the first 10 namespaces.
|
|
295
|
+
NamespaceSteps.verifyNamespaceNotExist('geoext');
|
|
296
|
+
// The namespace with the prefix "omgeo" should now be visible because it appears on the second page.
|
|
297
|
+
NamespaceSteps.getNamespace('omgeo').should('be.visible');
|
|
298
|
+
});
|
|
280
299
|
});
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphdb-workbench-tests",
|
|
3
|
-
"version": "3.0.0-
|
|
3
|
+
"version": "3.0.0-TR7",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "graphdb-workbench-tests",
|
|
9
|
-
"version": "3.0.0-
|
|
9
|
+
"version": "3.0.0-TR7",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"cypress": "^13.3.1",
|
package/package.json
CHANGED
|
@@ -223,6 +223,18 @@ export class CreateGraphqlEndpointSteps {
|
|
|
223
223
|
return this.getView().find('.endpoint-configuration-view');
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
static getGenerationSettingsForm() {
|
|
227
|
+
return this.getConfigureEndpointView().find('.generation-settings-form');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ===================================
|
|
231
|
+
// Generate endpoint view
|
|
232
|
+
// ===================================
|
|
233
|
+
|
|
234
|
+
static getGenerateEndpointView() {
|
|
235
|
+
return this.getView().find('.generate-endpoint-view');
|
|
236
|
+
}
|
|
237
|
+
|
|
226
238
|
// ===================================
|
|
227
239
|
// Wizard actions
|
|
228
240
|
// ===================================
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {ModalDialogSteps} from "../modal-dialog-steps";
|
|
2
|
+
|
|
3
|
+
export class EditGraphqlEndpointSteps extends ModalDialogSteps {
|
|
4
|
+
static getModalTitle() {
|
|
5
|
+
return this.getDialog().find('.modal-title');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
static getDynamicForm() {
|
|
9
|
+
return this.getDialog().find('dynamic-form');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static getFormFields() {
|
|
13
|
+
return this.getDynamicForm().find('.form-field');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static getInputField(index) {
|
|
17
|
+
return this.getFormFields().find('.input-field input').eq(index);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static getBooleanField(index) {
|
|
21
|
+
return this.getFormFields().find('.boolean-field input').eq(index);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static getSelectField(index) {
|
|
25
|
+
return this.getFormFields().find('.select-field select').eq(index);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static getMultiSelectField(index) {
|
|
29
|
+
return this.getFormFields().find('.multiselect-field multiselect-dropdown').eq(index);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static toggleMultiSelectOption(index, optionLabel) {
|
|
33
|
+
this.getMultiSelectField(index)
|
|
34
|
+
.within(() => {
|
|
35
|
+
cy.get('button.dropdown-toggle').click();
|
|
36
|
+
cy.get('ul.dropdown-menu li')
|
|
37
|
+
.contains(optionLabel)
|
|
38
|
+
.click();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static verifyMultiSelectOptionSelected(index, optionLabel) {
|
|
43
|
+
this.getModalTitle().click();
|
|
44
|
+
this.getMultiSelectField(index)
|
|
45
|
+
.within(() => {
|
|
46
|
+
cy.get('button.dropdown-toggle')
|
|
47
|
+
.should('contain.text', optionLabel);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static getJsonField(index) {
|
|
52
|
+
return this.getFormFields().find('.json-field textarea').eq(index);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static clearJsonField(index) {
|
|
56
|
+
return this.getJsonField(index).clear();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static setJsonField(index, value) {
|
|
60
|
+
return this.clearJsonField(index).type(value, {parseSpecialCharSequences:false});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static fillInputField(index, value) {
|
|
64
|
+
return this.getInputField(index).clear().type(value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static checkBooleanField(index) {
|
|
68
|
+
return this.getBooleanField(index).check();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static uncheckBooleanField(index) {
|
|
72
|
+
return this.getBooleanField(index).uncheck();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static toggleBooleanField(index) {
|
|
76
|
+
return this.getBooleanField(index).click();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static selectOption(index, option) {
|
|
80
|
+
this.getSelectField(index).select(option);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static getLoader() {
|
|
84
|
+
return this.getDialog().find('.graphql-endpoint-configuration-loader')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static getSavingLoader() {
|
|
88
|
+
return this.getDialog().find('.saving-endpoint-settings')
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -26,6 +26,10 @@ export class GraphqlEndpointManagementSteps {
|
|
|
26
26
|
return this.getView().find('.endpoints-info-table');
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
static getNoResultsRow() {
|
|
30
|
+
return this.getEndpointTable().find('tbody tr.no-results');
|
|
31
|
+
}
|
|
32
|
+
|
|
29
33
|
static getEndpointsInfo() {
|
|
30
34
|
return this.getEndpointTable().find('tbody tr');
|
|
31
35
|
}
|
|
@@ -42,6 +46,15 @@ export class GraphqlEndpointManagementSteps {
|
|
|
42
46
|
return this.getEndpointsInfo().eq(index).find('.toggle-row a').click();
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
static openActionsMenu(index) {
|
|
50
|
+
this.getEndpointsInfo().eq(index).find('.open-endpoint-actions-btn').click();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static deleteEndpoint(index) {
|
|
54
|
+
this.openActionsMenu(index);
|
|
55
|
+
this.getEndpointsInfo().eq(index).find('.delete-endpoint-btn').click();
|
|
56
|
+
}
|
|
57
|
+
|
|
45
58
|
static filterEndpoints(term) {
|
|
46
59
|
this.getEndpointFilterField().type(term);
|
|
47
60
|
}
|
|
@@ -81,4 +94,21 @@ export class GraphqlEndpointManagementSteps {
|
|
|
81
94
|
this.toggleEndpointRow(index);
|
|
82
95
|
});
|
|
83
96
|
}
|
|
97
|
+
|
|
98
|
+
static getEndpointInfo(index) {
|
|
99
|
+
return this.getEndpointsInfo().eq(index);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static getEndpointActionsButton(index) {
|
|
103
|
+
return this.getEndpointInfo(index).realHover().find('.open-endpoint-actions-btn');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static openEndpointActionMenu(index) {
|
|
107
|
+
return this.getEndpointActionsButton(index).click();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static editEndpointConfiguration(index) {
|
|
111
|
+
this.openEndpointActionMenu(index);
|
|
112
|
+
return cy.get('.configure-endpoint-btn').eq(index).click();
|
|
113
|
+
}
|
|
84
114
|
}
|
|
@@ -39,8 +39,12 @@ export class ModalDialogSteps {
|
|
|
39
39
|
ModalDialogSteps.getConfirmButton().click();
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
static getOKButton() {
|
|
43
|
+
return ModalDialogSteps.getDialogFooter().find('.btn-primary');
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
static clickOKButton() {
|
|
43
|
-
ModalDialogSteps.
|
|
47
|
+
ModalDialogSteps.getOKButton().click();
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
static confirm() {
|
|
@@ -77,6 +77,14 @@ export class NamespaceSteps {
|
|
|
77
77
|
return this.getNamespacesResultHeader().find('.namespaces-header-pagination .pagination');
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
static getNamespacesPageElements() {
|
|
81
|
+
return this.getNamespacesHeaderPagination().find('li ')
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static getNamespacePageElement(index) {
|
|
85
|
+
return this.getNamespacesPageElements().eq(index);
|
|
86
|
+
}
|
|
87
|
+
|
|
80
88
|
static getNamespacesHeaderPaginationInfo() {
|
|
81
89
|
return this.getNamespacesResultHeader().find('.showing-info-namespaces');
|
|
82
90
|
}
|
|
@@ -123,6 +131,15 @@ export class NamespaceSteps {
|
|
|
123
131
|
.last();
|
|
124
132
|
}
|
|
125
133
|
|
|
134
|
+
static verifyNamespaceNotExist(prefix) {
|
|
135
|
+
return this.getNamespacesTable().find('.namespace')
|
|
136
|
+
.should('be.visible')
|
|
137
|
+
.find('.namespace-prefix')
|
|
138
|
+
.should('be.visible')
|
|
139
|
+
.contains(prefix)
|
|
140
|
+
.should('not.exist');
|
|
141
|
+
}
|
|
142
|
+
|
|
126
143
|
static getSelectNamespaceCheckbox(prefix) {
|
|
127
144
|
return this.getNamespace(prefix)
|
|
128
145
|
.should('be.visible')
|
|
@@ -57,6 +57,23 @@ export class GraphqlStubs {
|
|
|
57
57
|
});
|
|
58
58
|
}).as('rickmorty');
|
|
59
59
|
}
|
|
60
|
+
|
|
61
|
+
static stubGetEndpointConfiguration(repositoryId, endpoint, fixture = 'graphql-endpoint-configuration.json', delay = 0) {
|
|
62
|
+
console.log(endpoint)
|
|
63
|
+
console.log(`/rest/repositories/${repositoryId}/manage/graphql/${endpoint}/config`)
|
|
64
|
+
cy.intercept('GET', `/rest/repositories/${repositoryId}/manage/graphql/${endpoint}/config`, {
|
|
65
|
+
fixture: `/graphql/endpoints/${fixture}`,
|
|
66
|
+
statusCode: 200,
|
|
67
|
+
delay: delay
|
|
68
|
+
}).as('get-endpoint-configuration');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static stubSaveEndpointConfiguration(repositoryId, endpoint, delay = 0, shouldFail = false) {
|
|
72
|
+
cy.intercept('PUT', `/rest/repositories//${repositoryId}/manage/graphql/${endpoint}/config`, {
|
|
73
|
+
statusCode: shouldFail ? 400 : 200,
|
|
74
|
+
delay: delay
|
|
75
|
+
}).as('save-endpoint-configuration');
|
|
76
|
+
}
|
|
60
77
|
}
|
|
61
78
|
|
|
62
79
|
const defaultHeaders = {
|