graphdb-workbench-tests 2.7.0-TR14 → 2.7.0-TR16
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/locale-en.json +17 -10
- package/integration/import/import-server-files.spec.js +5 -5
- package/integration/import/import-user-data.spec.js +3 -1
- package/integration/import/import-view.spec.js +63 -0
- package/integration/setup/aclmanagement/create-rule.spec.js +15 -0
- package/integration/setup/user-and-access.spec.js +98 -138
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/steps/import/import-steps.js +5 -0
- package/steps/setup/acl-management-steps.js +4 -0
- package/steps/setup/user-and-access-steps.js +189 -0
package/fixtures/locale-en.json
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"link_state_in_sync": "In sync",
|
|
33
33
|
"link_state_syncing": "Syncing",
|
|
34
34
|
"link_state_out_of_sync": "Out of sync",
|
|
35
|
+
"link_state_receiving_snapshot": "Receiving a snapshot",
|
|
35
36
|
"link_state_recovering": "Recovering",
|
|
36
37
|
"recovery_state": {
|
|
37
38
|
"searching_for_node": "Searching for node",
|
|
@@ -202,7 +203,8 @@
|
|
|
202
203
|
"errors": {
|
|
203
204
|
"loading_rules": "Error during ACL rules",
|
|
204
205
|
"updating_rules": "Error during ACL rules update",
|
|
205
|
-
"duplicated_rules": "Every ACL rule should be unique."
|
|
206
|
+
"duplicated_rules": "Every ACL rule should be unique.",
|
|
207
|
+
"role_length_too_short": "Too short"
|
|
206
208
|
},
|
|
207
209
|
"defaults": {
|
|
208
210
|
"asterisk": "* - Any RDF value",
|
|
@@ -482,6 +484,7 @@
|
|
|
482
484
|
"security.count.all.results": "Count all SPARQL results",
|
|
483
485
|
"security.read.write.access": "Repositories read/write access",
|
|
484
486
|
"security.user.rights": "Users should have rights to at least one repository!",
|
|
487
|
+
"security.user.role.too.short": "Must be at least 2 symbols long",
|
|
485
488
|
"security.no.active.location": "There is no active location.",
|
|
486
489
|
"security.repository.title": "Repository",
|
|
487
490
|
"security.tooltip.read": "Read",
|
|
@@ -986,26 +989,30 @@
|
|
|
986
989
|
"copied_to_clipboard": "Copied to clipboard"
|
|
987
990
|
},
|
|
988
991
|
"on_upload": {
|
|
989
|
-
"import_user_data": "Import
|
|
990
|
-
"
|
|
991
|
-
"file_size_limit_can_be_changed": "The file size limit can be changed by setting the",
|
|
992
|
+
"import_user_data": "Import RDF files from your computer, from a URL, or type or paste RDF data",
|
|
993
|
+
"file_size_limit_can_be_changed": "The file size limit for uploads can be changed by setting the",
|
|
992
994
|
"the_property": " property",
|
|
993
995
|
"execution": "Import execution",
|
|
994
996
|
"work_in_background": "Imports are executed in the background while you continue working on other things.",
|
|
997
|
+
"to_reimport_again": "To reimport a file, URL or text snippet click the Import button again.",
|
|
995
998
|
"interrupt_support": "Interrupt is supported only when the location is local.",
|
|
996
999
|
"parser_config": "Parser config options are not available for remote locations."
|
|
997
1000
|
},
|
|
998
1001
|
"on_server_import": {
|
|
999
|
-
"import_from_server": "
|
|
1000
|
-
"open_directory": "
|
|
1001
|
-
"put_files_into": "
|
|
1002
|
+
"import_from_server": "Import files from the server where GraphDB is running",
|
|
1003
|
+
"open_directory": "Put files or directories you want to import into the",
|
|
1004
|
+
"put_files_into": "directory on the GraphDB server. Create the directory if necessary.",
|
|
1002
1005
|
"directory_can_be_changed": "The directory can be changed by setting the",
|
|
1003
|
-
"the_property": "property"
|
|
1006
|
+
"the_property": "property",
|
|
1007
|
+
"execution": "Import execution",
|
|
1008
|
+
"work_in_background": "Imports are executed in the background while you continue working on other things.",
|
|
1009
|
+
"to_reimport_again": "To reimport a file, URL or text snippet click the Import button again.",
|
|
1010
|
+
"interrupt_support": "Interrupt is supported only when the location is local."
|
|
1004
1011
|
},
|
|
1005
1012
|
"on_file_size_limit": {
|
|
1006
|
-
"
|
|
1013
|
+
"file_import_options_info_1": "Explore other file import options - ",
|
|
1014
|
+
"file_import_options_info_2": "import (opens Server files tab) or ",
|
|
1007
1015
|
"server_files_link": "Server files",
|
|
1008
|
-
"import_or_use": "import or use the",
|
|
1009
1016
|
"api_link": "API"
|
|
1010
1017
|
}
|
|
1011
1018
|
},
|
|
@@ -41,12 +41,12 @@ describe('Import server files', () => {
|
|
|
41
41
|
|
|
42
42
|
it('Should be able to toggle the server file import help', () => {
|
|
43
43
|
// When the page is loaded
|
|
44
|
-
// Then I should see the server files import help
|
|
45
|
-
ImportServerFilesSteps.getHelpMessage().should('be.visible');
|
|
46
|
-
// When I close the help
|
|
47
|
-
ImportServerFilesSteps.closeHelpMessage();
|
|
48
|
-
// Then the help should disappear
|
|
44
|
+
// Then I should not see the server files import help
|
|
49
45
|
ImportServerFilesSteps.getHelpMessage().should('not.exist');
|
|
46
|
+
// When I open the help
|
|
47
|
+
ImportServerFilesSteps.toggleHelpMessage();
|
|
48
|
+
// Then the help should disappear
|
|
49
|
+
ImportServerFilesSteps.getHelpMessage().should('be.visible');
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
it('Should be able to filter the files', () => {
|
|
@@ -78,7 +78,7 @@ describe('Import user data', () => {
|
|
|
78
78
|
ImportUserDataSteps.visit();
|
|
79
79
|
// When the page is loaded and no uploaded files are present
|
|
80
80
|
ImportUserDataSteps.getResources().should('have.length', 0);
|
|
81
|
-
// Then I should see the user data import help
|
|
81
|
+
// Then I should not see the user data import help
|
|
82
82
|
ImportUserDataSteps.getHelpMessage().should('be.visible');
|
|
83
83
|
// When I have uploaded a text snippet
|
|
84
84
|
ImportUserDataSteps.openImportTextSnippetDialog();
|
|
@@ -86,6 +86,8 @@ describe('Import user data', () => {
|
|
|
86
86
|
ImportUserDataSteps.clickImportTextSnippetButton();
|
|
87
87
|
ImportSettingsDialogSteps.import();
|
|
88
88
|
ImportUserDataSteps.getResources().should('have.length', 1);
|
|
89
|
+
ImportUserDataSteps.getHelpMessage().should('not.exist');
|
|
90
|
+
ImportUserDataSteps.toggleHelpMessage();
|
|
89
91
|
// And I close the help
|
|
90
92
|
ImportUserDataSteps.closeHelpMessage();
|
|
91
93
|
// And I visit another page and return
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {ImportSettingsDialogSteps} from "../../steps/import/import-settings-dialog-steps";
|
|
2
2
|
import {ImportUserDataSteps} from "../../steps/import/import-user-data-steps";
|
|
3
3
|
import {ImportServerFilesSteps} from "../../steps/import/import-server-files-steps";
|
|
4
|
+
import ImportSteps from "../../steps/import/import-steps";
|
|
5
|
+
import HomeSteps from "../../steps/home-steps";
|
|
4
6
|
|
|
5
7
|
const bnodes = `_:node0 <http://purl.org/dc/elements/1.1/title> "A new book" ;
|
|
6
8
|
\t<http://purl.org/dc/elements/1.1/creator> "A.N.Other" .`;
|
|
@@ -42,4 +44,65 @@ describe('Import view', () => {
|
|
|
42
44
|
ImportUserDataSteps.getResources().should('have.length', 1);
|
|
43
45
|
ImportUserDataSteps.getResourceByName('bnodes.ttl').should('be.visible');
|
|
44
46
|
});
|
|
47
|
+
|
|
48
|
+
it('Should display/hide help message depends on resource result', () => {
|
|
49
|
+
// Given I am on import page
|
|
50
|
+
|
|
51
|
+
// Then help message has to be displayed, because the result of imported files are empty.
|
|
52
|
+
ImportUserDataSteps.getHelpMessage().should('exist');
|
|
53
|
+
|
|
54
|
+
// When I toggle the help
|
|
55
|
+
ImportUserDataSteps.toggleHelpMessage();
|
|
56
|
+
|
|
57
|
+
// Then help message mustn't be displayed because the user has hidden it, regardless resources are empty.
|
|
58
|
+
ImportUserDataSteps.getHelpMessage().should('not.exist');
|
|
59
|
+
|
|
60
|
+
// When I go to server tab
|
|
61
|
+
ImportSteps.openServerFilesTab();
|
|
62
|
+
|
|
63
|
+
// Then help message mustn't be displayed because the resources are not empty.
|
|
64
|
+
ImportServerFilesSteps.getHelpMessage().should('not.exist');
|
|
65
|
+
|
|
66
|
+
// When I toggle the server help
|
|
67
|
+
ImportServerFilesSteps.toggleHelpMessage();
|
|
68
|
+
|
|
69
|
+
// Then I expect the help message be displayed.
|
|
70
|
+
ImportServerFilesSteps.getHelpMessage().should('exist');
|
|
71
|
+
|
|
72
|
+
// When I return to the user tab
|
|
73
|
+
ImportSteps.openUserDataTab();
|
|
74
|
+
|
|
75
|
+
// Then help message mustn't be displayed because the user has hidden it, regardless resources are empty.
|
|
76
|
+
ImportUserDataSteps.getHelpMessage().should('not.exist');
|
|
77
|
+
|
|
78
|
+
// When I go to server tab
|
|
79
|
+
ImportSteps.openServerFilesTab();
|
|
80
|
+
|
|
81
|
+
// Then I expect the help message be displayed.
|
|
82
|
+
ImportServerFilesSteps.getHelpMessage().should('exist');
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
// When I go to other view
|
|
86
|
+
HomeSteps.visit();
|
|
87
|
+
// And return to import user data
|
|
88
|
+
ImportUserDataSteps.visit();
|
|
89
|
+
|
|
90
|
+
// Then I expect the help message to be displayed, because there are no results, regardless of whether the user had previously hidden the help message.
|
|
91
|
+
ImportUserDataSteps.getHelpMessage().should('exist');
|
|
92
|
+
|
|
93
|
+
// When I go to server tab
|
|
94
|
+
ImportSteps.openServerFilesTab()
|
|
95
|
+
|
|
96
|
+
// Then help message mustn't be displayed because the resources are not empty.
|
|
97
|
+
ImportServerFilesSteps.getHelpMessage().should('not.exist');
|
|
98
|
+
|
|
99
|
+
// When I go to user tab and upload a file
|
|
100
|
+
ImportSteps.openUserDataTab();
|
|
101
|
+
ImportUserDataSteps.selectFile(ImportUserDataSteps.createFile(testFiles[0], bnodes));
|
|
102
|
+
ImportSettingsDialogSteps.import();
|
|
103
|
+
ImportUserDataSteps.getResources().should('have.length', 1);
|
|
104
|
+
|
|
105
|
+
// Then I expect the help message not exist, because user because there are resource displayed
|
|
106
|
+
ImportUserDataSteps.getHelpMessage().should('not.exist');
|
|
107
|
+
});
|
|
45
108
|
});
|
|
@@ -199,5 +199,20 @@ describe('ACL Management: create rule', () => {
|
|
|
199
199
|
// Then I expect an error notification to be displayed that describe me that ACL have to be unique.
|
|
200
200
|
ApplicationSteps.getErrorNotifications().contains('Every ACL rule should be unique.');
|
|
201
201
|
});
|
|
202
|
+
|
|
203
|
+
it('should not allow creating a new rule if CUSTOM ROLE is less than 2 symbols', () => {
|
|
204
|
+
// When I am on "ACL Management" page and create a new rule with a CUSTOM ROLE of 1 symbol
|
|
205
|
+
AclManagementSteps.addRuleInBeginning();
|
|
206
|
+
AclManagementSteps.selectPolicy(0, 'allow');
|
|
207
|
+
AclManagementSteps.fillRole(0, 'A');
|
|
208
|
+
AclManagementSteps.selectOperation(0, 'write');
|
|
209
|
+
AclManagementSteps.fillSubject(0, '<urn:Mary>');
|
|
210
|
+
AclManagementSteps.fillPredicate(0, '*');
|
|
211
|
+
AclManagementSteps.fillObject(0, '*');
|
|
212
|
+
AclManagementSteps.fillContext(0, '*');
|
|
213
|
+
|
|
214
|
+
// Then I expect an error notification to be displayed that tells me this ROLE length is not allowed
|
|
215
|
+
AclManagementSteps.getFieldError().contains('Too short');
|
|
216
|
+
});
|
|
202
217
|
});
|
|
203
218
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {UserAndAccessSteps} from "../../steps/setup/user-and-access-steps";
|
|
2
|
+
|
|
1
3
|
describe('User and Access', () => {
|
|
2
4
|
|
|
3
5
|
const PASSWORD = "password";
|
|
@@ -7,21 +9,21 @@ describe('User and Access', () => {
|
|
|
7
9
|
const DEFAULT_ADMIN_PASSWORD = "root";
|
|
8
10
|
|
|
9
11
|
beforeEach(() => {
|
|
10
|
-
|
|
12
|
+
UserAndAccessSteps.visit();
|
|
11
13
|
cy.window();
|
|
12
14
|
// Users table should be visible
|
|
13
|
-
getUsersTable().should('be.visible');
|
|
15
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
14
16
|
});
|
|
15
17
|
|
|
16
18
|
after(() => {
|
|
17
|
-
|
|
18
|
-
getUsersTable().should('be.visible');
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
getUsersTable().should('be.visible');
|
|
19
|
+
UserAndAccessSteps.visit();
|
|
20
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
21
|
+
UserAndAccessSteps.getUsersTableRow().then((table) => {
|
|
22
|
+
UserAndAccessSteps.getTableRow().each(($el, index, $list) => {
|
|
23
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
22
24
|
const username = $el.find('.username').text();
|
|
23
25
|
if (username !=='admin') {
|
|
24
|
-
deleteUser(username);
|
|
26
|
+
UserAndAccessSteps.deleteUser(username);
|
|
25
27
|
}
|
|
26
28
|
});
|
|
27
29
|
});
|
|
@@ -29,26 +31,22 @@ describe('User and Access', () => {
|
|
|
29
31
|
|
|
30
32
|
it('Initial state', () => {
|
|
31
33
|
// Create new user button should be visible
|
|
32
|
-
getCreateNewUserButton().should('be.visible');
|
|
34
|
+
UserAndAccessSteps.getCreateNewUserButton().should('be.visible');
|
|
33
35
|
// Security should be disabled
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
cy.get('#toggle-security').find('.switch:checkbox').should('not.be.checked');
|
|
36
|
+
UserAndAccessSteps.getSecuritySwitchLabel().should('be.visible').and('contain', 'Security is OFF');
|
|
37
|
+
UserAndAccessSteps.getSecurityCheckbox().should('not.be.checked');
|
|
37
38
|
// Only admin user should be created by default
|
|
38
|
-
|
|
39
|
-
findUserInTable('admin');
|
|
40
|
-
|
|
41
|
-
.and('contain', 'Administrator');
|
|
39
|
+
UserAndAccessSteps.getTableRow().should('have.length', 1);
|
|
40
|
+
UserAndAccessSteps.findUserInTable('admin');
|
|
41
|
+
UserAndAccessSteps.getUserType().should('be.visible').and('contain', 'Administrator');
|
|
42
42
|
// The admin should have unrestricted rights
|
|
43
|
-
|
|
44
|
-
.and('contain', 'Unrestricted');
|
|
43
|
+
UserAndAccessSteps.getRepositoryRights().should('be.visible').and('contain', 'Unrestricted');
|
|
45
44
|
// And can be edited
|
|
46
|
-
|
|
47
|
-
.and('not.be.disabled');
|
|
45
|
+
UserAndAccessSteps.getEditUserButton().should('be.visible').and('not.be.disabled');
|
|
48
46
|
// And cannot be deleted
|
|
49
|
-
|
|
47
|
+
UserAndAccessSteps.getDeleteUserButton().should('not.exist');
|
|
50
48
|
// Date created should be visible
|
|
51
|
-
|
|
49
|
+
UserAndAccessSteps.getDateCreated().should('be.visible');
|
|
52
50
|
});
|
|
53
51
|
|
|
54
52
|
it('Create user', () => {
|
|
@@ -72,140 +70,102 @@ describe('User and Access', () => {
|
|
|
72
70
|
testForUser(name, true);
|
|
73
71
|
});
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
73
|
+
it('Create user with custom role', () => {
|
|
74
|
+
const name = "user";
|
|
75
|
+
// When I create a read/write user
|
|
76
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
77
|
+
UserAndAccessSteps.typeUsername(name);
|
|
78
|
+
UserAndAccessSteps.typePassword(PASSWORD);
|
|
79
|
+
UserAndAccessSteps.typeConfirmPasswordField(PASSWORD);
|
|
80
|
+
UserAndAccessSteps.selectRoleRadioButton(ROLE_USER);
|
|
81
|
+
// And add a custom role of 1 letter
|
|
82
|
+
UserAndAccessSteps.addTextToCustomRoleField('A');
|
|
83
|
+
UserAndAccessSteps.getRepositoryRightsList().contains('Any data repository').nextUntil('.write').eq(1).within(() => {
|
|
84
|
+
UserAndAccessSteps.clickWriteAccess();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Then the 'create' button should be disabled
|
|
88
|
+
UserAndAccessSteps.getConfirmUserCreateButton().should('be.disabled');
|
|
89
|
+
// And the field should show an error
|
|
90
|
+
UserAndAccessSteps.getFieldError().should('contain.text', 'Must be at least 2 symbols long');
|
|
91
|
+
// When I add more text to the custom role tag
|
|
92
|
+
UserAndAccessSteps.addTextToCustomRoleField('A{enter}');
|
|
93
|
+
// Then the 'create' button should be enabled
|
|
94
|
+
UserAndAccessSteps.getConfirmUserCreateButton().should('be.enabled');
|
|
95
|
+
// And the field error should not exist
|
|
96
|
+
UserAndAccessSteps.getFieldError().should('not.be.visible');
|
|
97
|
+
|
|
98
|
+
// When I type an invalid tag
|
|
99
|
+
UserAndAccessSteps.addTextToCustomRoleField('B{enter}');
|
|
100
|
+
// And the field shows an error
|
|
101
|
+
UserAndAccessSteps.getFieldError().should('contain.text', 'Must be at least 2 symbols long');
|
|
102
|
+
// When I delete the invalid text
|
|
103
|
+
UserAndAccessSteps.addTextToCustomRoleField('{backspace}');
|
|
104
|
+
// Then the error should not be visible
|
|
105
|
+
UserAndAccessSteps.getFieldError().should('not.be.visible');
|
|
106
|
+
});
|
|
101
107
|
|
|
102
108
|
it('Warn users when setting no password when creating new user admin', () => {
|
|
103
|
-
getUsersTable().should('be.visible');
|
|
109
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
104
110
|
createUser("adminWithNoPassword", PASSWORD, ROLE_CUSTOM_ADMIN);
|
|
105
|
-
getUsersTable().should('be.visible');
|
|
106
|
-
|
|
107
|
-
deleteUser("adminWithNoPassword");
|
|
111
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
112
|
+
UserAndAccessSteps.getSplashLoader().should('not.be.visible');
|
|
113
|
+
UserAndAccessSteps.deleteUser("adminWithNoPassword");
|
|
108
114
|
});
|
|
109
115
|
|
|
110
|
-
function getCreateNewUserButton() {
|
|
111
|
-
return cy.get('#wb-users-userCreateLink');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function getToggleSecuritySwitch() {
|
|
115
|
-
return cy.get('#toggle-security span.switch');
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function getUsersTable() {
|
|
119
|
-
return cy.get('#wb-users-userInUsers');
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function findUserInTable(username) {
|
|
123
|
-
return getUsersTable().find(`tbody .username:contains(${username})`)
|
|
124
|
-
.closest('tr').as('user');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function getUsernameField() {
|
|
128
|
-
return cy.get('#wb-user-username');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function getPasswordField() {
|
|
132
|
-
return cy.get('#wb-user-password');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function getConfirmPasswordField() {
|
|
136
|
-
return cy.get('#wb-user-confirmpassword');
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function getConfirmUserCreateButton() {
|
|
140
|
-
return cy.get('#wb-user-submit');
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function getRoleRadioButton(userRole) {
|
|
144
|
-
return cy.get(userRole);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function getRepoitoryRightsList() {
|
|
148
|
-
return cy.get('#user-repos');
|
|
149
|
-
}
|
|
150
|
-
|
|
151
116
|
function createUser(username, password, role) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
117
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
118
|
+
UserAndAccessSteps.typeUsername(username);
|
|
119
|
+
UserAndAccessSteps.typePassword(password);
|
|
120
|
+
UserAndAccessSteps.typeConfirmPasswordField(password);
|
|
121
|
+
UserAndAccessSteps.selectRoleRadioButton(role);
|
|
157
122
|
if (role === "#roleUser") {
|
|
158
|
-
|
|
159
|
-
|
|
123
|
+
UserAndAccessSteps.getRepositoryRightsList().contains('Any data repository').nextUntil('.write').eq(1).within(() => {
|
|
124
|
+
UserAndAccessSteps.clickWriteAccess();
|
|
160
125
|
});
|
|
161
|
-
|
|
126
|
+
UserAndAccessSteps.confirmUserCreate();
|
|
162
127
|
} else if (role === "#roleAdmin" && username === "adminWithNoPassword") {
|
|
163
|
-
|
|
128
|
+
UserAndAccessSteps.getNoPasswordCheckbox().check()
|
|
164
129
|
.then(() => {
|
|
165
|
-
|
|
130
|
+
UserAndAccessSteps.getNoPasswordCheckbox()
|
|
166
131
|
.should('be.checked');
|
|
167
132
|
});
|
|
168
|
-
getConfirmUserCreateButton().click()
|
|
133
|
+
UserAndAccessSteps.getConfirmUserCreateButton().click()
|
|
169
134
|
.then(() => {
|
|
170
|
-
|
|
135
|
+
UserAndAccessSteps.getDialogText().contains('If the password is unset and security is enabled, this administrator will not be ' +
|
|
171
136
|
'able to log into GraphDB through the workbench. Are you sure that you want to continue?');
|
|
172
|
-
|
|
137
|
+
UserAndAccessSteps.confirmInDialog();
|
|
173
138
|
});
|
|
174
139
|
} else {
|
|
175
|
-
|
|
140
|
+
UserAndAccessSteps.confirmUserCreate();
|
|
176
141
|
}
|
|
177
|
-
|
|
178
|
-
getUsersTable().should('contain', username);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function deleteUser(username) {
|
|
182
|
-
findUserInTable(username);
|
|
183
|
-
cy.get('@user')
|
|
184
|
-
.should('have.length', 1)
|
|
185
|
-
.within(() => {
|
|
186
|
-
cy.get('.delete-user-btn')
|
|
187
|
-
.as('deleteBtn');
|
|
188
|
-
});
|
|
189
|
-
return cy.waitUntil(() =>
|
|
190
|
-
cy.get('@deleteBtn')
|
|
191
|
-
.then((deleteBtn) => deleteBtn && Cypress.dom.isAttached(deleteBtn) && deleteBtn.trigger('click')))
|
|
192
|
-
.then(() => {
|
|
193
|
-
cy.get('.confirm-btn').click();
|
|
194
|
-
});
|
|
142
|
+
UserAndAccessSteps.getSplashLoader().should('not.be.visible');
|
|
143
|
+
UserAndAccessSteps.getUsersTable().should('contain', username);
|
|
195
144
|
}
|
|
196
145
|
|
|
197
|
-
function
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
.
|
|
208
|
-
|
|
209
|
-
|
|
146
|
+
function testForUser(name, isAdmin) {
|
|
147
|
+
//enable security
|
|
148
|
+
UserAndAccessSteps.toggleSecurity();
|
|
149
|
+
//login new user
|
|
150
|
+
UserAndAccessSteps.loginWithUser(name, PASSWORD);
|
|
151
|
+
//verify permissions
|
|
152
|
+
UserAndAccessSteps.getUrl().should('include', '/users');
|
|
153
|
+
if (isAdmin) {
|
|
154
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
155
|
+
} else {
|
|
156
|
+
UserAndAccessSteps.getError().should('contain',
|
|
157
|
+
'You have no permission to access this functionality with your current credentials.');
|
|
158
|
+
}
|
|
159
|
+
UserAndAccessSteps.logout();
|
|
160
|
+
//login with the admin
|
|
161
|
+
UserAndAccessSteps.loginWithUser("admin", DEFAULT_ADMIN_PASSWORD);
|
|
162
|
+
UserAndAccessSteps.getSplashLoader().should('not.be.visible');
|
|
163
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
164
|
+
//delete new-user
|
|
165
|
+
UserAndAccessSteps.deleteUser(name);
|
|
166
|
+
//disable security
|
|
167
|
+
UserAndAccessSteps.toggleSecurity();//.click({force: true});
|
|
168
|
+
UserAndAccessSteps.getSecuritySwitchLabel().should('be.visible').and('contain', 'Security is OFF');
|
|
169
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
210
170
|
}
|
|
211
171
|
});
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphdb-workbench-tests",
|
|
3
|
-
"version": "2.7.0-
|
|
3
|
+
"version": "2.7.0-TR16",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "graphdb-workbench-tests",
|
|
9
|
-
"version": "2.7.0-
|
|
9
|
+
"version": "2.7.0-TR16",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"cypress": "^13.3.1",
|
package/package.json
CHANGED
|
@@ -143,6 +143,11 @@ class ImportSteps {
|
|
|
143
143
|
return cy.window().its('navigator.clipboard').invoke('readText').then((text) => text);
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
static toggleHelpMessage() {
|
|
147
|
+
// For some reason the page info box opens unexpectedly and covers the help info icon.
|
|
148
|
+
this.getView().find('.toggle-help-btn').click({force: true});
|
|
149
|
+
}
|
|
150
|
+
|
|
146
151
|
static closeHelpMessage() {
|
|
147
152
|
return this.getHelpMessage().find('button.close').click();
|
|
148
153
|
}
|
|
@@ -161,6 +161,10 @@ export class AclManagementSteps {
|
|
|
161
161
|
this.getRoleField(index).clear().type(value);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
static getFieldError() {
|
|
165
|
+
return cy.get('div.small');
|
|
166
|
+
}
|
|
167
|
+
|
|
164
168
|
static getPluginField(index) {
|
|
165
169
|
return this.getRule(index).find('.plugin-cell textarea');
|
|
166
170
|
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
export class UserAndAccessSteps {
|
|
2
|
+
static visit() {
|
|
3
|
+
cy.visit('/users');
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
static getUrl() {
|
|
7
|
+
return cy.url();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static getSplashLoader() {
|
|
11
|
+
return cy.get('.ot-splash');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static getCreateNewUserButton() {
|
|
15
|
+
return cy.get('#wb-users-userCreateLink');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static clickCreateNewUserButton() {
|
|
19
|
+
this.getCreateNewUserButton().click();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getToggleSecuritySwitch() {
|
|
23
|
+
return cy.get('#toggle-security span.switch');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static toggleSecurity() {
|
|
27
|
+
this.getToggleSecuritySwitch().click();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static getSecuritySwitchLabel() {
|
|
31
|
+
return cy.get('#toggle-security').find('.security-switch-label');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static getSecurityCheckbox() {
|
|
35
|
+
return cy.get('#toggle-security').find('.switch:checkbox');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static getUser() {
|
|
39
|
+
return cy.get('@user');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static getUserType() {
|
|
43
|
+
return this.getUser().find('.user-type');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static getRepositoryRights() {
|
|
47
|
+
return this.getUser().find('.repository-rights');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static getEditUserButton() {
|
|
51
|
+
return this.getUser().find('.edit-user-btn');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static getDeleteUserButton() {
|
|
55
|
+
return this.getUser().find('.delete-user-btn');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static getDateCreated() {
|
|
59
|
+
return this.getUser().find('.date-created');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static getUsersTable() {
|
|
63
|
+
return cy.get('#wb-users-userInUsers');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static getTableRow() {
|
|
67
|
+
return this.getUsersTable().find('tbody tr');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static getUsersTableRow() {
|
|
71
|
+
return cy.get('#wb-users-userInUsers tr');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static findUserInTable(username) {
|
|
75
|
+
return this.getUsersTable().find(`tbody .username:contains(${username})`)
|
|
76
|
+
.closest('tr').as('user');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static getUsernameField() {
|
|
80
|
+
return cy.get('#wb-user-username');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static typeUsername(text) {
|
|
84
|
+
this.getUsernameField().type(text);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static getPasswordField() {
|
|
88
|
+
return cy.get('#wb-user-password');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static typePassword(text) {
|
|
92
|
+
this.getPasswordField().type(text);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static getConfirmPasswordField() {
|
|
96
|
+
return cy.get('#wb-user-confirmpassword');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static typeConfirmPasswordField(text) {
|
|
100
|
+
this.getConfirmPasswordField().type(text);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static getNoPasswordCheckbox() {
|
|
104
|
+
return cy.get('#noPassword:checkbox');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static getCustomRoleField() {
|
|
108
|
+
return cy.get('tags-input');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static addTextToCustomRoleField(text) {
|
|
112
|
+
this.getCustomRoleField().type(text);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static getConfirmUserCreateButton() {
|
|
116
|
+
return cy.get('#wb-user-submit');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static confirmUserCreate() {
|
|
120
|
+
cy.get('#wb-user-submit').click();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static getRoleRadioButton(userRole) {
|
|
124
|
+
return cy.get(userRole);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static selectRoleRadioButton(role) {
|
|
128
|
+
this.getRoleRadioButton(role).click();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static getRepositoryRightsList() {
|
|
132
|
+
return cy.get('#user-repos');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static clickWriteAccess() {
|
|
136
|
+
cy.get('.write').click();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static getFieldError() {
|
|
140
|
+
return cy.get('div.small');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static getError() {
|
|
144
|
+
return cy.get('.alert-danger');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static getModal() {
|
|
148
|
+
return cy.get('.modal-dialog');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static getDialogText() {
|
|
152
|
+
return this.getModal().find('.lead');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
static confirmInDialog() {
|
|
156
|
+
this.getModal().find('.confirm-btn').click();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static deleteUser(username) {
|
|
160
|
+
this.findUserInTable(username);
|
|
161
|
+
cy.get('@user')
|
|
162
|
+
.should('have.length', 1)
|
|
163
|
+
.within(() => {
|
|
164
|
+
cy.get('.delete-user-btn')
|
|
165
|
+
.as('deleteBtn');
|
|
166
|
+
});
|
|
167
|
+
return cy.waitUntil(() =>
|
|
168
|
+
cy.get('@deleteBtn')
|
|
169
|
+
.then((deleteBtn) => deleteBtn && Cypress.dom.isAttached(deleteBtn) && deleteBtn.trigger('click')))
|
|
170
|
+
.then(() => {
|
|
171
|
+
cy.get('.confirm-btn').click();
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
static loginWithUser(username, password) {
|
|
176
|
+
cy.get('#wb-login-username').type(username);
|
|
177
|
+
cy.get('#wb-login-password').type(password);
|
|
178
|
+
cy.get('#wb-login-submitLogin').click();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static logout() {
|
|
182
|
+
cy.get('#btnGroupDrop2').click();
|
|
183
|
+
cy.get('.dropdown-item')
|
|
184
|
+
.contains('Logout')
|
|
185
|
+
.closest('a')
|
|
186
|
+
// Force the click because Cypress sometimes determines that the item has 0x0 dimensions
|
|
187
|
+
.click({force: true});
|
|
188
|
+
}
|
|
189
|
+
}
|