graphdb-workbench-tests 4.0.0-TR12 → 4.0.0-TR13

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.
@@ -8,10 +8,24 @@ const NO_REPOSITORY_MESSAGE = 'you are not connected to any repository';
8
8
  const INVALID_LICENSE_MESSAGE = 'your license is not valid';
9
9
  const SELECT_OR_CREATE_REPOSITORY_MESSAGE = 'Select a repository below or create a new one.';
10
10
  const SELECT_REPOSITORY_MESSAGE = 'Select a repository below.';
11
+ // TODO: Remove once GraphDB creates the system repository itself.
12
+ // The graph-navigator settings endpoint requires this repository.
13
+ const SYSTEM_REPOSITORY_ID = 'SystemRepository';
11
14
 
12
15
  describe('Graph Navigator view restrictions', () => {
13
16
  let repositoryId;
14
17
 
18
+ // TODO: Remove once GraphDB creates the system repository itself.
19
+ before(() => {
20
+ cy.deleteRepository(SYSTEM_REPOSITORY_ID);
21
+ cy.createRepository({id: SYSTEM_REPOSITORY_ID});
22
+ });
23
+
24
+ // TODO: Remove once GraphDB creates the system repository itself.
25
+ after(() => {
26
+ cy.deleteRepository(SYSTEM_REPOSITORY_ID);
27
+ });
28
+
15
29
  beforeEach(() => {
16
30
  repositoryId = 'graph-navigator-view-restrictions-' + Date.now();
17
31
  cy.createRepository({id: repositoryId});
@@ -9,13 +9,29 @@ import {ToasterSteps} from '../../steps/toaster-steps.js';
9
9
  const FILE_TO_IMPORT = 'resource-test-data.ttl';
10
10
  const SEED_RESOURCE_ENCODED = 'http:%2F%2Fexample.com%2Fontology%23CustomerLoyalty';
11
11
  const SEED_RESOURCE_LABEL = 'CustomerLoyalty';
12
+ const SETTINGS_FILE_NAME = 'graph-navigator-settings.ttl';
13
+ const SETTINGS_FILE = `fixtures/graph-navigator/${SETTINGS_FILE_NAME}`;
12
14
 
13
15
  const CONSTRUCT_QUERY = 'CONSTRUCT { <http://example.com/ontology#CustomerLoyalty> ?p ?o } WHERE { <http://example.com/ontology#CustomerLoyalty> ?p ?o }';
14
16
  const CONSTRUCT_TARGET_LABEL = 'Metric';
17
+ // TODO: Remove once GraphDB creates the system repository itself.
18
+ // The graph-navigator settings endpoint requires this repository.
19
+ const SYSTEM_REPOSITORY_ID = 'SystemRepository';
15
20
 
16
21
  describe('Graph Navigator', () => {
17
22
  let repositoryId;
18
23
 
24
+ // TODO: Remove once GraphDB creates the system repository itself.
25
+ before(() => {
26
+ cy.deleteRepository(SYSTEM_REPOSITORY_ID);
27
+ cy.createRepository({id: SYSTEM_REPOSITORY_ID});
28
+ });
29
+
30
+ // TODO: Remove once GraphDB creates the system repository itself.
31
+ after(() => {
32
+ cy.deleteRepository(SYSTEM_REPOSITORY_ID);
33
+ });
34
+
19
35
  beforeEach(() => {
20
36
  repositoryId = 'repository-' + Date.now();
21
37
  cy.createRepository({id: repositoryId});
@@ -124,7 +140,6 @@ describe('Graph Navigator', () => {
124
140
  GraphNavigatorSteps.getElements().should('not.exist');
125
141
  });
126
142
 
127
- // These run against the in-code REST stub. TODO: GDB-15242 switch to intercepts when the endpoints are available.
128
143
  describe('Settings', () => {
129
144
  it('should open the settings popover', () => {
130
145
  // Given I open the Graph Navigator view.
@@ -152,14 +167,14 @@ describe('Graph Navigator', () => {
152
167
  // Given I have selected a settings file.
153
168
  GraphNavigatorSteps.visit();
154
169
  GraphNavigatorSteps.openSettings();
155
- GraphNavigatorSteps.selectSettingsFile();
156
- GraphNavigatorSteps.getSelectedSettingsFile().should('exist');
170
+ GraphNavigatorSteps.selectSettingsFile(SETTINGS_FILE);
171
+ GraphNavigatorSteps.getSelectedSettingsFile(SETTINGS_FILE_NAME).should('exist');
157
172
 
158
173
  // When I cancel it.
159
174
  GraphNavigatorSteps.clickCancelFile();
160
175
 
161
176
  // Then I expect the file to be removed.
162
- GraphNavigatorSteps.getSettingsPopover().should('not.contain', 'settings.ttl');
177
+ GraphNavigatorSteps.getSettingsPopover().should('not.contain', SETTINGS_FILE_NAME);
163
178
  GraphNavigatorSteps.getUploadButton().should('be.disabled');
164
179
  });
165
180
 
@@ -167,7 +182,7 @@ describe('Graph Navigator', () => {
167
182
  // Given I have selected a settings file.
168
183
  GraphNavigatorSteps.visit();
169
184
  GraphNavigatorSteps.openSettings();
170
- GraphNavigatorSteps.selectSettingsFile();
185
+ GraphNavigatorSteps.selectSettingsFile(SETTINGS_FILE);
171
186
 
172
187
  // When I upload it.
173
188
  GraphNavigatorSteps.clickUpload();
@@ -181,7 +196,7 @@ describe('Graph Navigator', () => {
181
196
 
182
197
  // Then I expect the popover to stay open with the file still selected.
183
198
  GraphNavigatorSteps.getSettingsPopover().should('be.visible');
184
- GraphNavigatorSteps.getSelectedSettingsFile().should('exist');
199
+ GraphNavigatorSteps.getSelectedSettingsFile(SETTINGS_FILE_NAME).should('exist');
185
200
 
186
201
  // When I upload and confirm.
187
202
  GraphNavigatorSteps.clickUpload();
@@ -196,7 +211,7 @@ describe('Graph Navigator', () => {
196
211
  // Given the repository has uploaded settings.
197
212
  GraphNavigatorSteps.visit();
198
213
  GraphNavigatorSteps.openSettings();
199
- GraphNavigatorSteps.selectSettingsFile();
214
+ GraphNavigatorSteps.selectSettingsFile(SETTINGS_FILE);
200
215
  GraphNavigatorSteps.clickUpload();
201
216
  GraphNavigatorSteps.confirmDialog();
202
217
  ToasterSteps.verifySuccess('The settings were uploaded');
@@ -87,6 +87,39 @@ describe('Import server files - Batch operations', () => {
87
87
  ImportServerFilesSteps.getSelectedResources().should('have.length', 0);
88
88
  });
89
89
 
90
+ it('Should select all displayed resources with the select all checkbox', () => {
91
+ // When I check the select all checkbox
92
+ ImportServerFilesSteps.toggleSelectAllResources();
93
+ // Then I should see all files selected
94
+ ImportServerFilesSteps.getSelectedResources().should('have.length', SERVER_FILES_COUNT);
95
+ ImportServerFilesSteps.getSelectAllCheckbox().should('be.checked');
96
+ // When I uncheck the select all checkbox
97
+ ImportServerFilesSteps.toggleSelectAllResources();
98
+ // Then I should see no files selected
99
+ ImportServerFilesSteps.getSelectedResources().should('have.length', 0);
100
+ ImportServerFilesSteps.getSelectAllCheckbox().should('not.be.checked');
101
+ // When I select a directory via the checkbox on the row
102
+ ImportServerFilesSteps.selectFileByName('more-files');
103
+ // Then the select all checkbox should be partially selected
104
+ ImportServerFilesSteps.getSelectAllCheckbox().should('have.prop', 'indeterminate', true);
105
+ // When I check the select all checkbox
106
+ ImportServerFilesSteps.toggleSelectAllResources();
107
+ // Then I should see all files selected
108
+ ImportServerFilesSteps.getSelectedResources().should('have.length', SERVER_FILES_COUNT);
109
+ ImportServerFilesSteps.getSelectAllCheckbox().should('be.checked').and('have.prop', 'indeterminate', false);
110
+ // When I deselect all and filter the files by name
111
+ ImportServerFilesSteps.toggleSelectAllResources();
112
+ ImportServerFilesSteps.typeInFilterField('bnodes');
113
+ ImportServerFilesSteps.getResources().should('have.length', 1);
114
+ // and check the select all checkbox
115
+ ImportServerFilesSteps.toggleSelectAllResources();
116
+ // Then only the displayed file should be selected
117
+ ImportServerFilesSteps.clearFilterField();
118
+ ImportServerFilesSteps.getResources().should('have.length', SERVER_FILES_COUNT);
119
+ ImportServerFilesSteps.getSelectedResources().should('have.length', 1);
120
+ ImportServerFilesSteps.getSelectedResourceName(0).should('contain', 'bnodes.ttl');
121
+ });
122
+
90
123
  it('Should perform batch import and reset of selected server files with changing settings', () => {
91
124
  // Given I have opened the server files tab
92
125
  // When I select couple of files for import
@@ -206,4 +206,22 @@ describe('Import server files', () => {
206
206
  // Then: I expect the import button be enabled, because the "JSON-LD Context" is not mandatory field.
207
207
  ImportSettingsDialogSteps.getImportButton().should('be.enabled');
208
208
  });
209
+
210
+ it('should send the DOCTYPE declarations option with the import settings', () => {
211
+ // Given: The server files tab is loaded and the import requests are intercepted
212
+ ImportServerFilesSteps.interceptServerFilesImport(repositoryId);
213
+
214
+ // When: I open the import dialog for a file,
215
+ ImportServerFilesSteps.importResourceByName('bnodes.ttl');
216
+ ImportSettingsDialogSteps.expandAdvancedSettings();
217
+ // Then: I expect DOCTYPE declarations to be disallowed by default.
218
+ ImportSettingsDialogSteps.getDisallowDoctypeDeclCheckbox().should('be.checked');
219
+
220
+ // When: I allow DOCTYPE declarations and start the import
221
+ ImportSettingsDialogSteps.allowDoctypeDeclarations();
222
+ ImportSettingsDialogSteps.import();
223
+ // Then: I expect DOCTYPE declarations to be allowed in the request.
224
+ ImportServerFilesSteps.waitForServerFilesImportSettings()
225
+ .its('parserSettings.disallowDoctypeDecl').should('equal', false);
226
+ });
209
227
  });
@@ -1,15 +1,14 @@
1
1
  import {ImportUserDataSteps} from "../../steps/import/import-user-data-steps";
2
+ import {ImportSettingsDialogSteps} from "../../steps/import/import-settings-dialog-steps";
2
3
 
3
- const bnodes = `_:node0 <http://purl.org/dc/elements/1.1/title> "A new book" ;
4
- \t<http://purl.org/dc/elements/1.1/creator> "A.N.Other" .`;
5
- const jsonld = JSON.stringify({
6
- "@context": {
7
- "ab": "http://learningsparql.com/ns/addressbook#"
8
- },
9
- "@id": "ab:richard",
10
- "ab:homeTel": "(229)276-5135",
11
- "ab:email": "richard491@hotmail.com"
12
- });
4
+ const RDF_TEXT_SNIPPET = '<urn:s1> <urn:p1> <urn:o1>.';
5
+ const RDF_XML_WITH_DOCTYPE_SNIPPET = '<?xml version="1.0"?>\n' +
6
+ '<!DOCTYPE rdf:RDF [<!ENTITY ex "http://example.com/">]>\n' +
7
+ '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ex="http://example.com/">\n' +
8
+ ' <rdf:Description rdf:about="&ex;subject"><ex:predicate>object</ex:predicate></rdf:Description>\n' +
9
+ '</rdf:RDF>';
10
+ const RDF_XML_FORMAT = 'RDF/XML';
11
+ const TEXT_SNIPPET = 'Text snippet';
13
12
 
14
13
  describe('Import user data: Import settings dialog', () => {
15
14
 
@@ -31,6 +30,78 @@ describe('Import user data: Import settings dialog', () => {
31
30
  cy.deleteRepository(repositoryId);
32
31
  });
33
32
 
33
+ it('Should disallow DOCTYPE declarations by default', () => {
34
+ // Given I have opened the import settings dialog for a text snippet
35
+ ImportUserDataSteps.interceptTextSnippetImport(repositoryId);
36
+ ImportUserDataSteps.openTextSnippetImportSettings(RDF_TEXT_SNIPPET);
37
+ // When I expand the advanced settings
38
+ ImportSettingsDialogSteps.expandAdvancedSettings();
39
+ // Then the DOCTYPE declarations option should be checked
40
+ ImportSettingsDialogSteps.getDisallowDoctypeDeclCheckbox().should('be.checked');
41
+ // When I start the import
42
+ ImportSettingsDialogSteps.import();
43
+ // Then DOCTYPE declarations should be disallowed in the request
44
+ ImportUserDataSteps.waitForTextSnippetImportSettings()
45
+ .its('parserSettings.disallowDoctypeDecl').should('equal', true);
46
+ });
47
+
48
+ it('Should allow DOCTYPE declarations when the option is unchecked', () => {
49
+ // Given I have opened the import settings dialog for a text snippet
50
+ ImportUserDataSteps.interceptTextSnippetImport(repositoryId);
51
+ ImportUserDataSteps.openTextSnippetImportSettings(RDF_TEXT_SNIPPET);
52
+ ImportSettingsDialogSteps.expandAdvancedSettings();
53
+ // When I uncheck the DOCTYPE declarations option and start the import
54
+ ImportSettingsDialogSteps.allowDoctypeDeclarations();
55
+ ImportSettingsDialogSteps.import();
56
+ // Then DOCTYPE declarations should be allowed in the request
57
+ ImportUserDataSteps.waitForTextSnippetImportSettings()
58
+ .its('parserSettings.disallowDoctypeDecl').should('equal', false);
59
+ });
60
+
61
+ it('Should restore the DOCTYPE declarations option to its default', () => {
62
+ // Given I have opened the import settings dialog for a text snippet
63
+ ImportUserDataSteps.openTextSnippetImportSettings(RDF_TEXT_SNIPPET);
64
+ ImportSettingsDialogSteps.expandAdvancedSettings();
65
+ // And I have unchecked the DOCTYPE declarations option
66
+ ImportSettingsDialogSteps.allowDoctypeDeclarations();
67
+ ImportSettingsDialogSteps.getDisallowDoctypeDeclCheckbox().should('not.be.checked');
68
+ // When I restore the default settings
69
+ ImportSettingsDialogSteps.restoreDefaults();
70
+ // Then the DOCTYPE declarations option should be checked again
71
+ ImportSettingsDialogSteps.getDisallowDoctypeDeclCheckbox().should('be.checked');
72
+ });
73
+
74
+ it('Should reject RDF/XML with a DOCTYPE declaration by default', () => {
75
+ // Given I have opened the import settings dialog for an RDF/XML snippet with a DOCTYPE declaration
76
+ ImportUserDataSteps.openTextSnippetImportSettings(RDF_XML_WITH_DOCTYPE_SNIPPET, RDF_XML_FORMAT);
77
+ // When I start the import with the default settings
78
+ ImportSettingsDialogSteps.import();
79
+ // Then the import should fail, because DOCTYPE declarations are disallowed
80
+ ImportUserDataSteps.checkImportedResourceByIndex(0, TEXT_SNIPPET, 'DOCTYPE is disallowed');
81
+ });
82
+
83
+ it('Should import RDF/XML with a DOCTYPE declaration when DOCTYPE declarations are allowed', () => {
84
+ // Given I have opened the import settings dialog for an RDF/XML snippet with a DOCTYPE declaration
85
+ ImportUserDataSteps.openTextSnippetImportSettings(RDF_XML_WITH_DOCTYPE_SNIPPET, RDF_XML_FORMAT);
86
+ ImportSettingsDialogSteps.expandAdvancedSettings();
87
+ // When I allow DOCTYPE declarations and start the import
88
+ ImportSettingsDialogSteps.allowDoctypeDeclarations();
89
+ ImportSettingsDialogSteps.import();
90
+ // Then the import should succeed
91
+ ImportUserDataSteps.checkImportedResourceByIndex(0, TEXT_SNIPPET);
92
+
93
+ // When I open the import settings dialog for the same snippet again
94
+ ImportUserDataSteps.importFile(0);
95
+ ImportSettingsDialogSteps.expandAdvancedSettings();
96
+ // Then the saved DOCTYPE declarations option should be restored
97
+ ImportSettingsDialogSteps.getDisallowDoctypeDeclCheckbox().should('not.be.checked');
98
+
99
+ // When I restore the default settings
100
+ ImportSettingsDialogSteps.restoreDefaults();
101
+ // Then the DOCTYPE declarations option should be reset to the backend default, not to the saved value
102
+ ImportSettingsDialogSteps.getDisallowDoctypeDeclCheckbox().should('be.checked');
103
+ });
104
+
34
105
  it.skip('Should prevent import when there are missing or invalid settings', () => {
35
106
  // Given I have uploaded a file
36
107
 
@@ -9,7 +9,6 @@ describe('Import user data: URL import', () => {
9
9
  const JSONLD_FORMAT = 'JSON-LD';
10
10
  const VALID_URL_RDF_FORMAT = 'RDF/XML';
11
11
  const RDF_ERROR_MESSAGE = 'RDF Parse Error:';
12
- const IMPORT_JSONLD_URL = 'https://example.com/0007-context.jsonld';
13
12
 
14
13
  beforeEach(() => {
15
14
  repositoryId = 'user-import-' + Date.now();
@@ -54,17 +53,17 @@ describe('Import user data: URL import', () => {
54
53
  });
55
54
 
56
55
 
57
- // FIXME: wine.rdf contains DOCTYPE which is forbidden in the TR for GDB 12
58
- it.skip('Test import file via URL successfully with Auto format selected', () => {
56
+ it('Test import file via URL successfully with Auto format selected', () => {
59
57
  ImportUserDataSteps.openImportURLDialog(IMPORT_URL);
60
58
  ImportUserDataSteps.clickImportUrlButton();
61
- // Without changing settings
59
+ // wine.rdf contains a DOCTYPE declaration, which is disallowed by default
60
+ ImportSettingsDialogSteps.expandAdvancedSettings();
61
+ ImportSettingsDialogSteps.allowDoctypeDeclarations();
62
62
  ImportSettingsDialogSteps.import();
63
63
  ImportUserDataSteps.checkImportedResourceByIndex(0, IMPORT_URL);
64
64
  });
65
65
 
66
- // FIXME: wine.rdf contains DOCTYPE which is forbidden in the TR for GDB 12. Expected error message is different.
67
- it.skip('Test import file via URL with invalid RDF format selected', () => {
66
+ it('Test import file via URL with invalid RDF format selected', () => {
68
67
  ImportUserDataSteps.openImportURLDialog(IMPORT_URL);
69
68
  ImportUserDataSteps.selectRDFFormat(JSONLD_FORMAT);
70
69
  ImportUserDataSteps.clickImportUrlButton();
@@ -72,11 +71,13 @@ describe('Import user data: URL import', () => {
72
71
  ImportUserDataSteps.checkImportedResourceByIndex(0, IMPORT_URL, RDF_ERROR_MESSAGE);
73
72
  });
74
73
 
75
- // FIXME: wine.rdf contains DOCTYPE which is forbidden in the TR for GDB 12
76
- it.skip('Test import file via URL successfully with valid RDF format selected', () => {
74
+ it('Test import file via URL successfully with valid RDF format selected', () => {
77
75
  ImportUserDataSteps.openImportURLDialog(IMPORT_URL);
78
76
  ImportUserDataSteps.selectRDFFormat(VALID_URL_RDF_FORMAT);
79
77
  ImportUserDataSteps.clickImportUrlButton();
78
+ // wine.rdf contains a DOCTYPE declaration, which is disallowed by default
79
+ ImportSettingsDialogSteps.expandAdvancedSettings();
80
+ ImportSettingsDialogSteps.allowDoctypeDeclarations();
80
81
  ImportSettingsDialogSteps.import();
81
82
  ImportUserDataSteps.checkImportedResourceByIndex(0, IMPORT_URL);
82
83
  });
@@ -690,6 +690,8 @@ describe('User and Access', () => {
690
690
  // 2. Read permission for one repository.
691
691
  UserAndAccessSteps.openEditUserPage(maintainerUser);
692
692
  cy.wait('@get-user');
693
+ // Wait until the loaded user is bound to the form, otherwise toggling a right fails.
694
+ UserAndAccessSteps.getUsernameField().should('have.value', maintainerUser);
693
695
  setUserAuths({repo: readRepositoryId, read: true});
694
696
  // 3. Write permission for one repository.
695
697
  setUserAuths({repo: writeRepositoryId, write: true});
@@ -700,6 +702,8 @@ describe('User and Access', () => {
700
702
  // When I log in as a user with repository maintain permission.
701
703
  UserAndAccessSteps.toggleSecurity();
702
704
  LoginSteps.loginWithUser(maintainerUser, PASSWORD);
705
+ // Wait for the login to complete, otherwise visiting another page aborts it.
706
+ cy.url().should('not.include', '/login');
703
707
  // And navigate to the repository list view.
704
708
  RepositorySteps.visit(false);
705
709
 
@@ -760,6 +764,8 @@ describe('User and Access', () => {
760
764
  createUser(maintainerUser, PASSWORD, ROLE_USER, {maintain: true, repoName: maintainedRepositoryId});
761
765
  UserAndAccessSteps.toggleSecurity();
762
766
  LoginSteps.loginWithUser(maintainerUser, PASSWORD);
767
+ // Wait for the login to complete, otherwise visiting another page aborts it.
768
+ cy.url().should('not.include', '/login');
763
769
  RepositorySteps.visit(false);
764
770
 
765
771
  // When the user opens the edit page of the repository they can maintain.
@@ -0,0 +1,148 @@
1
+ @prefix gn: <http://www.ontotext.com/graph-navigator#> .
2
+
3
+ gn:settings gn:defaultPrefix """PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
4
+ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
5
+ PREFIX owl: <http://www.w3.org/2002/07/owl#>
6
+ """;
7
+ gn:schemaLabelProperty "rdfs:label";
8
+ gn:dataLabelProperty "rdfs:label";
9
+ gn:classTreeQuery """
10
+ SELECT ?class ?label ?parent
11
+ WHERE {
12
+ {
13
+ ?class a rdfs:Class
14
+ } UNION {
15
+ ?class a owl:Class
16
+ }
17
+ FILTER ISIRI(?class)
18
+ OPTIONAL {
19
+ ?class rdfs:label ?label
20
+ ${labelLanguageFilter}
21
+ }
22
+ OPTIONAL {?class rdfs:subClassOf ?parent. FILTER ISIRI(?parent)}
23
+ }
24
+ """;
25
+ gn:classInfoQuery """SELECT ?class ?label ?instcount WHERE {
26
+ VALUES(?class) {${ids}}
27
+ OPTIONAL {
28
+ ?class ${schemaLabelProperty} ?label
29
+ ${labelLanguageFilter}
30
+ }
31
+ BIND(\"\" as ?instcount)
32
+ }""";
33
+ gn:linkTypesQuery """SELECT DISTINCT ?link ?instcount ?label WHERE {
34
+ ${linkTypesPattern}
35
+ OPTIONAL {
36
+ ?link ${schemaLabelProperty} ?label
37
+ ${labelLanguageFilter}
38
+ }
39
+ }""";
40
+ gn:linkTypesPattern """
41
+ { ?link a rdf:Property }
42
+ UNION
43
+ { ?link a owl:ObjectProperty }
44
+ BIND('' as ?instcount)
45
+ """;
46
+ gn:linkTypesInfoQuery """SELECT ?link ?label WHERE {
47
+ VALUES(?link) {${ids}}
48
+ OPTIONAL {
49
+ ?link ${schemaLabelProperty} ?label
50
+ ${labelLanguageFilter}
51
+ }
52
+ }""";
53
+ gn:propertyInfoQuery """SELECT ?property ?label WHERE {
54
+ VALUES(?property) {${ids}}
55
+ OPTIONAL {
56
+ ?property ${schemaLabelProperty} ?label
57
+ ${labelLanguageFilter}
58
+ }
59
+ }""";
60
+ gn:elementInfoQuery """
61
+ CONSTRUCT {
62
+ ?inst <urn:reactodia:sparql:type> ?class .
63
+ ?inst <urn:reactodia:sparql:label> ?label .
64
+ ?inst ?propType ?propValue.
65
+ } WHERE {
66
+ VALUES (?inst) {${ids}}
67
+ OPTIONAL { ?inst a ?class }
68
+ OPTIONAL {
69
+ ?inst ${dataLabelProperty} ?label
70
+ ${labelLanguageFilter}
71
+ }
72
+ OPTIONAL {
73
+ ${propertyConfigurations}
74
+ FILTER (isLiteral(?propValue))
75
+ ${valueLanguageFilter}
76
+ }
77
+ }
78
+ """;
79
+ gn:linksInfoQuery """SELECT ?source ?type ?target
80
+ WHERE {
81
+ ${linkConfigurations}
82
+ VALUES (?source) {${sourceIris}}
83
+ VALUES (?target) {${targetIris}}
84
+ }""";
85
+ gn:imageQueryPattern "{ ?inst ?linkType ?image } UNION { [] ?linkType ?inst. BIND(?inst as ?image) }";
86
+ gn:linkTypesOfQuery """
87
+ SELECT DISTINCT ?link ?direction
88
+ WHERE {
89
+ ${linkConfigurations}
90
+ }
91
+ """;
92
+ gn:linkTypesStatisticsQuery """
93
+ SELECT ?link ?outCount ?inCount
94
+ WHERE {
95
+ {
96
+ SELECT (${linkId} as ?link) (count(?outObject) as ?outCount) WHERE {
97
+ ${linkConfigurationOut}
98
+ ${navigateElementFilterOut}
99
+ } LIMIT 101
100
+ } {
101
+ SELECT (${linkId} as ?link) (count(?inObject) as ?inCount) WHERE {
102
+ ${linkConfigurationIn}
103
+ ${navigateElementFilterIn}
104
+ } LIMIT 101
105
+ }
106
+ }
107
+ """;
108
+ gn:lookupQuery """SELECT ${outerProjection} WHERE {
109
+ ${filterInnerPrelude}
110
+ {
111
+ SELECT DISTINCT ${innerProjection} WHERE {
112
+ ${filterByType}
113
+ ${filterByRefElementLink}
114
+ ${filterByText}
115
+ ${filterAdditionalRestriction}
116
+ } ${orderBy} ${limit}
117
+ }
118
+ ${queryTypes}
119
+ ${queryElementInfo}
120
+ } ${orderBy}""";
121
+ gn:filterInnerPrelude "";
122
+ gn:filterRefElementLinkPattern "";
123
+ gn:filterTypePattern "?inst a ?instType. ?instType rdfs:subClassOf* ?class";
124
+ gn:filterElementInfoPattern """
125
+ OPTIONAL {?inst rdf:type ?foundClass}
126
+ BIND (coalesce(?foundClass, owl:Thing) as ?class)
127
+ OPTIONAL {
128
+ ?inst ${dataLabelProperty} ?label
129
+ ${labelLanguageFilter}
130
+ }
131
+ """;
132
+ gn:filterAdditionalRestriction "";
133
+ gn:openWorldLinks false;
134
+ gn:openWorldProperties false;
135
+ gn:acceptBlankNodes false;
136
+ gn:blankNodeStatementLimit "20"^^<http://www.w3.org/2001/XMLSchema#int>;
137
+ gn:filterOnlyLanguages [ a <http://www.w3.org/1999/02/22-rdf-syntax-ns#List>;
138
+ <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "en";
139
+ <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil>
140
+ ];
141
+ gn:fullTextSearch [
142
+ gn:prefix "";
143
+ gn:queryPattern """?inst ${dataLabelProperty} ?search1
144
+ FILTER regex(COALESCE(str(?search1)), \"${text}\", \"i\")
145
+ BIND(0 as ?score)
146
+ """;
147
+ gn:extractLabel true
148
+ ] .
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "4.0.0-TR12",
3
+ "version": "4.0.0-TR13",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "graphdb-workbench-tests",
9
- "version": "4.0.0-TR12",
9
+ "version": "4.0.0-TR13",
10
10
  "license": "Apache-2.0",
11
11
  "devDependencies": {
12
12
  "@bahmutov/cypress-code-coverage": "^2.7.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "4.0.0-TR12",
3
+ "version": "4.0.0-TR13",
4
4
  "description": "Cypress tests for GraphDB workbench",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -64,13 +64,12 @@ export class GraphNavigatorSteps extends BaseSteps {
64
64
  return this.getByTestId('graph-navigator-settings-upload').find('.p-fileupload-choose-button input[type=file]');
65
65
  }
66
66
 
67
- static selectSettingsFile(fileName = 'settings.ttl', contents = '@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .') {
67
+ static selectSettingsFile(file) {
68
68
  // PrimeNG hides the file input (display: none), so force is needed to select a file on it.
69
- this.getSettingsFileInput()
70
- .selectFile({contents: Cypress.Buffer.from(contents), fileName, mimeType: 'text/turtle'}, {force: true});
69
+ this.getSettingsFileInput().selectFile(file, {force: true});
71
70
  }
72
71
 
73
- static getSelectedSettingsFile(fileName = 'settings.ttl') {
72
+ static getSelectedSettingsFile(fileName) {
74
73
  return GraphNavigatorSteps.getSettingsPopover().contains(fileName);
75
74
  }
76
75
 
@@ -10,6 +10,14 @@ export class ImportServerFilesSteps extends ImportSteps {
10
10
  return this.getView().find('.server-files-import-help');
11
11
  }
12
12
 
13
+ static interceptServerFilesImport(repositoryId) {
14
+ cy.intercept('POST', `/rest/repositories/${repositoryId}/import/server`).as('importServerFiles');
15
+ }
16
+
17
+ static waitForServerFilesImportSettings() {
18
+ return cy.wait('@importServerFiles').its('request.body.importSettings');
19
+ }
20
+
13
21
  static getSelectedTypeFilterButton() {
14
22
  return this.getResourcesTable().find('.import-resource-type-filter .active');
15
23
  }
@@ -64,6 +64,22 @@ export class ImportSettingsDialogSteps extends ModalDialogSteps {
64
64
  this.getSettingsForm().find('input[name="preserveBNodeIDs"]').check();
65
65
  }
66
66
 
67
+ static getDisallowDoctypeDeclCheckbox() {
68
+ return this.getSettingsForm().find('input[name="disallowDoctypeDecl"]');
69
+ }
70
+
71
+ static allowDoctypeDeclarations() {
72
+ this.getDisallowDoctypeDeclCheckbox().uncheck();
73
+ }
74
+
75
+ static getRestoreDefaultsButton() {
76
+ return this.getDialog().find('.restore-defaults-btn');
77
+ }
78
+
79
+ static restoreDefaults() {
80
+ this.getRestoreDefaultsButton().click();
81
+ }
82
+
67
83
  static fillContextLink(contextLink) {
68
84
  this.getSettingsForm().find('input[name="contextLink"]').type(contextLink).should('have.value', contextLink);
69
85
  }
@@ -92,6 +92,10 @@ class ImportSteps {
92
92
  return this.getFilterField().type(query);
93
93
  }
94
94
 
95
+ static clearFilterField() {
96
+ return this.getFilterField().clear();
97
+ }
98
+
95
99
  static getTabs() {
96
100
  return this.getView().find('.nav-tabs .nav-item');
97
101
  }
@@ -266,7 +270,16 @@ class ImportSteps {
266
270
  }
267
271
 
268
272
  static openStatusSelectMenu() {
269
- return this.getStatusSelectMenu().click().find('.dropdown-menu .dropdown-item');
273
+ this.getStatusSelectMenuToggle().click();
274
+ return this.getStatusSelectMenu().find('.dropdown-menu .dropdown-item');
275
+ }
276
+
277
+ static getSelectAllCheckbox() {
278
+ return this.getStatusSelectMenu().find('.select-all-checkbox');
279
+ }
280
+
281
+ static toggleSelectAllResources() {
282
+ this.getSelectAllCheckbox().click();
270
283
  }
271
284
 
272
285
  static selectAllResources() {
@@ -339,7 +352,7 @@ class ImportSteps {
339
352
  }
340
353
 
341
354
  static openFileUploadDialog() {
342
- this.getUploadRdfFilesButton().find('#wb-import-uploadFile').click();
355
+ this.getUploadRdfFilesButton().click();
343
356
  }
344
357
 
345
358
  static selectFile(files) {
@@ -518,7 +531,7 @@ class ImportSteps {
518
531
  }
519
532
 
520
533
  static orderBySize() {
521
- ImportSteps.getSizeCell().click();
534
+ ImportSteps.getSizeCell().find('button').click();
522
535
  }
523
536
  }
524
537
 
@@ -15,9 +15,9 @@ export class ImportUserDataSteps extends ImportSteps {
15
15
  }
16
16
 
17
17
  static openImportTextSnippetDialog() {
18
- cy.get('#import-user .import-rdf-snippet-btn').click()
19
- // Forces the popover to disappear as it covers the modal and Cypress refuses to continue
20
- .trigger('mouseleave', {force: true});
18
+ cy.get('#import-user .import-rdf-snippet-btn').click();
19
+ // Forces the popover to disappear as it covers the modal and Cypress refuses to continue
20
+ cy.get('#import-user .import-rdf-snippet-btn').trigger('mouseleave', {force: true});
21
21
  this.getModal().find('#wb-import-textarea').should('be.visible');
22
22
  return this;
23
23
  }
@@ -34,7 +34,8 @@ export class ImportUserDataSteps extends ImportSteps {
34
34
  static selectRDFFormat(rdfFormat) {
35
35
  cy.get('.modal-footer .import-format-dropdown').within(() => {
36
36
  cy.get('.import-format-dropdown-btn').click();
37
- cy.get('.dropdown-item').contains(rdfFormat).click().should('not.be.visible');
37
+ cy.get('.dropdown-item').contains(rdfFormat).click();
38
+ cy.get('.dropdown-item').contains(rdfFormat).should('not.be.visible');
38
39
  });
39
40
  return this;
40
41
  }
@@ -48,6 +49,24 @@ export class ImportUserDataSteps extends ImportSteps {
48
49
  cy.intercept('POST', `/rest/repositories/${repositoryId}/import/upload/url`).as('postJsonldUrl');
49
50
  }
50
51
 
52
+ static openTextSnippetImportSettings(snippet, rdfFormat) {
53
+ this.openImportTextSnippetDialog();
54
+ this.pasteRDFTextSnippet(snippet);
55
+ if (rdfFormat) {
56
+ this.selectRDFFormat(rdfFormat);
57
+ }
58
+ this.clickImportTextSnippetButton();
59
+ return this;
60
+ }
61
+
62
+ static interceptTextSnippetImport(repositoryId) {
63
+ cy.intercept('POST', `/rest/repositories/${repositoryId}/import/upload/text`).as('importTextSnippet');
64
+ }
65
+
66
+ static waitForTextSnippetImportSettings() {
67
+ return cy.wait('@importTextSnippet').its('request.body');
68
+ }
69
+
51
70
  static getErrors() {
52
71
  return cy.get('.text-danger');
53
72
  }
@@ -64,30 +83,11 @@ export class ImportUserDataSteps extends ImportSteps {
64
83
  return this.getModal().find('#wb-import-textarea');
65
84
  }
66
85
 
67
- static getImportFromDataRadioButton() {
68
- return this.getModal().find('#wb-import-from-data');
69
- }
70
-
71
- static getImportInDefaultGraphRadioButton() {
72
- return this.getModal().find('#wb-import-in-default-graph');
73
- }
74
-
75
- static getExistingDataReplacementCheckbox() {
76
- return this.getModal().find('#wb-import-existing-data-replacement');
77
- }
78
-
79
- static getReplacedGraphsInputField() {
80
- return this.getModal().find('#wb-import-replaced-graphs');
81
- }
82
-
83
- static getAddGraphToReplaceButton() {
84
- return this.getModal().find('#wb-import-add-graph-to-replace');
85
- }
86
-
87
86
  //verifies that the data has been inserted in the given graph and that the new data has replaced the old one.
88
87
  static verifyGraphData(graphName, s, p, o, c, checkForReplacedData, oldData) {
89
88
  cy.visit('/graphs');
90
89
  // wait a bit to give chance page loaded.
90
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
91
91
  cy.wait(1000);
92
92
  cy.get(`#export-graphs td a:contains(${graphName})`).click();
93
93
  cy.get(`.uri-cell:contains(${s})`).should('be.visible');