Skip to content

Commit 03537ca

Browse files
nirajacharya2anon-pradip
authored andcommitted
test: convert groups.feature test to playwright
1 parent faa23f6 commit 03537ca

11 files changed

Lines changed: 385 additions & 21 deletions

File tree

.drone.star

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ config = {
102102
"cucumber/features/admin-settings/users.feature:106",
103103
"cucumber/features/admin-settings/users.feature:131",
104104
"cucumber/features/admin-settings/users.feature:185",
105-
"cucumber/features/keycloak",
106105
],
107106
"extraServerEnvironment": {
108107
"PROXY_AUTOPROVISION_ACCOUNTS": "true",
@@ -220,8 +219,8 @@ config = {
220219
"keycloak": {
221220
"earlyFail": True,
222221
"skip": False,
223-
"features": [
224-
"specs/admin-settings/spaces.spec.ts",
222+
"suites": [
223+
"keycloak",
225224
],
226225
"extraServerEnvironment": {
227226
"PROXY_AUTOPROVISION_ACCOUNTS": "true",

tests/e2e-playwright/specs/admin-settings/groups.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ test.describe('groups management', () => {
1919
stepUser: 'Admin',
2020
groupIds: ['sales', 'security']
2121
})
22-
await ui.userShouldSeeGroupIds({
22+
await ui.checkGroupsPresenceById({
2323
world,
2424
stepUser: 'Admin',
2525
expectedGroupIds: ['sales', 'security']
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import { expect } from '@playwright/test'
2+
import { test } from '../../support/test'
3+
import { config } from '../../../e2e/config.js'
4+
import { ActorsEnvironment, UsersEnvironment } from '../../../e2e/support/environment/index.js'
5+
import { setAccessAndRefreshToken } from '../../helpers/setAccessAndRefreshToken.js'
6+
import * as api from '../../steps/api/api.js'
7+
import * as ui from '../../steps/ui/index'
8+
9+
// For synchronization-related details, see https://owncloud.dev/services/proxy/#claim-updates
10+
test.describe('groups management', () => {
11+
let actorsEnvironment
12+
const usersEnvironment = new UsersEnvironment()
13+
14+
test.beforeEach(async ({ browser }) => {
15+
actorsEnvironment = new ActorsEnvironment({
16+
context: {
17+
acceptDownloads: config.acceptDownloads,
18+
reportDir: config.reportDir,
19+
tracingReportDir: config.tracingReportDir,
20+
reportHar: config.reportHar,
21+
reportTracing: config.reportTracing,
22+
reportVideo: config.reportVideo,
23+
failOnUncaughtConsoleError: config.failOnUncaughtConsoleError
24+
},
25+
browser: browser
26+
})
27+
28+
await setAccessAndRefreshToken(usersEnvironment)
29+
})
30+
31+
test('keycloak group sync with oCIS', async ({ world }) => {
32+
// Given "Admin" creates following user using API
33+
// | id |
34+
// | Alice |
35+
// | Brian |
36+
await api.usersHaveBeenCreated({
37+
world,
38+
stepUser: 'Admin',
39+
users: ['Alice', 'Brian']
40+
})
41+
42+
// And "Alice" creates the following files into personal space using API
43+
// | pathToFile | content |
44+
// | shareToSales.txt | Keycloak group share |
45+
// | shareToSecurity.txt | Keycloak group share |
46+
await api.userHasCreatedFiles({
47+
world,
48+
stepUser: 'Alice',
49+
files: [
50+
{ pathToFile: 'shareToSales.txt', content: 'Keycloak group share' },
51+
{ pathToFile: 'shareToSecurity.txt', content: 'Keycloak group share' }
52+
]
53+
})
54+
55+
// When "Admin" logs in
56+
await ui.userLogsIn({ world, stepUser: 'Admin' })
57+
58+
// And "Admin" opens the "admin-settings" app
59+
await ui.userOpensApplication({ world, stepUser: 'Admin', name: 'admin-settings' })
60+
61+
// And "Admin" navigates to the groups management page
62+
await ui.userNavigatesToGroupsManagementPage({ world, stepUser: 'Admin' })
63+
64+
// When "Admin" creates the following groups
65+
// | id |
66+
// | security |
67+
// | sales |
68+
await ui.userCreatesGroups({
69+
world,
70+
stepUser: 'Admin',
71+
groupIds: ['security', 'sales']
72+
})
73+
74+
// Then "Admin" should see the following group
75+
// | group |
76+
// | security |
77+
// | keycloak sales |
78+
// | keycloak finance |
79+
expect(
80+
await ui.checkGroupsPresenceById({
81+
world,
82+
stepUser: 'Admin',
83+
expectedGroupIds: ['security', 'keycloak sales', 'keycloak finance']
84+
})
85+
).toBeTruthy()
86+
87+
// When "Admin" navigates to the users management page
88+
await ui.userNavigatesToUserManagementPage({ world, stepUser: 'Admin' })
89+
// And "Admin" adds the user "Brian" to the groups "security,keycloak sales" using the sidebar panel
90+
await ui.userAddsUserToGroup({
91+
world,
92+
stepUser: 'Admin',
93+
action: 'adds',
94+
groups: ['security', 'keycloak sales'],
95+
user: 'Brian'
96+
})
97+
98+
// And "Admin" logs out
99+
await ui.userLogsOut({ world, stepUser: 'Admin' })
100+
// And "Alice" logs in
101+
await ui.userLogsIn({ world, stepUser: 'Alice' })
102+
103+
// And "Alice" shares the following resource using the sidebar panel
104+
// | resource | recipient | type | role | resourceType |
105+
// | shareToSales.txt | keycloak sales | group | Can edit without versions | file |
106+
// | shareToSecurity.txt | security | group | Can edit without versions | file |
107+
await ui.userSharesResources({
108+
world,
109+
stepUser: 'Alice',
110+
actionType: 'SIDEBAR_PANEL',
111+
shares: [
112+
{
113+
resource: 'shareToSales.txt',
114+
recipient: 'keycloak sales',
115+
type: 'group',
116+
role: 'Can edit without versions',
117+
resourceType: 'file'
118+
},
119+
{
120+
resource: 'shareToSecurity.txt',
121+
recipient: 'security',
122+
type: 'group',
123+
role: 'Can edit without versions',
124+
resourceType: 'file'
125+
}
126+
]
127+
})
128+
129+
// And "Alice" logs out
130+
await ui.userLogsOut({ world, stepUser: 'Alice' })
131+
132+
// And "Brian" logs in
133+
await ui.userLogsIn({ world, stepUser: 'Brian' })
134+
// And "Brian" navigates to the shared with me page
135+
await ui.userNavigatesToSharedWithMePage({ world, stepUser: 'Brian' })
136+
137+
// user should have access to unsynced shares
138+
// When "Brian" opens the following file in texteditor
139+
// | resource |
140+
// | shareToSales.txt |
141+
await ui.userOpensFileInViewer({
142+
world,
143+
stepUser: 'Brian',
144+
resource: 'shareToSales.txt',
145+
actionType: 'texteditor'
146+
})
147+
// And "Brian" closes the file viewer
148+
await ui.userClosesFileViewer({ world, stepUser: 'Brian' })
149+
// And "Brian" edits the following resources
150+
// | resource | content |
151+
// | shareToSecurity.txt | new content |
152+
await ui.userEditsFile({
153+
world,
154+
stepUser: 'Brian',
155+
resource: 'shareToSecurity.txt',
156+
content: 'new content'
157+
})
158+
// And "Brian" logs out
159+
await ui.userLogsOut({ world, stepUser: 'Brian' })
160+
161+
// When "Admin" logs in
162+
await ui.userLogsIn({ world, stepUser: 'Admin' })
163+
164+
// And "Admin" opens the "admin-settings" app
165+
await ui.userOpensApplication({ world, stepUser: 'Admin', name: 'admin-settings' })
166+
167+
// And "Admin" navigates to the groups management page
168+
await ui.userNavigatesToGroupsManagementPage({ world, stepUser: 'Admin' })
169+
170+
// Renaming a Keycloak group results in the creation of a new group on the oCIS server (see https://github.com/owncloud/ocis/issues/10445).
171+
// After renaming a group, it may take up to 5 minutes for the changes to sync, so avoid using the renamed group in the subsequent steps.
172+
// And "Admin" changes displayName to "a renamed group" for group "keycloak finance" using the sidebar panel
173+
await ui.userRenamesGroup({
174+
world,
175+
stepUser: 'Admin',
176+
attribute: 'displayName',
177+
value: 'a renamed group',
178+
user: 'keycloak finance'
179+
})
180+
181+
// When "Admin" deletes the following group using the context menu
182+
// | group |
183+
// | sales |
184+
await ui.userDeletesGroup({
185+
world,
186+
stepUser: 'Admin',
187+
actionType: 'context menu',
188+
group: 'sales'
189+
})
190+
// Then "Admin" should not see the following group
191+
// | group |
192+
// | sales |
193+
expect(
194+
await ui.checkGroupsPresenceById({
195+
world,
196+
stepUser: 'Admin',
197+
expectedGroupIds: ['sales']
198+
})
199+
).toBeFalsy()
200+
// And "Admin" logs out
201+
await ui.userLogsOut({ world, stepUser: 'Admin' })
202+
})
203+
})
File renamed without changes.

tests/e2e-playwright/steps/ui/adminSettings.ts

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { expect } from '@playwright/test'
21
import { objects } from '../../../e2e/support'
32
import { World } from '../../support/world'
3+
import { expect } from '@playwright/test'
44

55
export async function userNavigatesToGeneralManagementPage({
66
world,
@@ -69,21 +69,24 @@ export async function userCreatesGroups({
6969
}
7070
}
7171

72-
export async function userShouldSeeGroupIds({
72+
export async function checkGroupsPresenceById({
7373
world,
7474
stepUser,
7575
expectedGroupIds
7676
}: {
7777
world: World
7878
stepUser: string
7979
expectedGroupIds: string[]
80-
}): Promise<void> {
80+
}): Promise<boolean> {
8181
const { page } = world.actorsEnvironment.getActor({ key: stepUser })
8282
const groupsObject = new objects.applicationAdminSettings.Groups({ page })
8383
const actualGroupsIds = await groupsObject.getDisplayedGroupsIds()
8484
for (const group of expectedGroupIds) {
85-
expect(actualGroupsIds).toContain(groupsObject.getUUID({ key: group }))
85+
if (!actualGroupsIds.includes(groupsObject.getUUID({ key: group }))) {
86+
return false
87+
}
8688
}
89+
return true
8790
}
8891

8992
export async function userShouldNotSeeGroupIds({
@@ -202,3 +205,91 @@ export async function userChangesUserQuota({
202205
const usersObject = new objects.applicationAdminSettings.Users({ page })
203206
await usersObject.changeQuota({ key, value, action: 'context-menu' })
204207
}
208+
209+
export async function userDeletesGroup({
210+
world,
211+
stepUser,
212+
actionType,
213+
group
214+
}: {
215+
world: World
216+
stepUser: string
217+
actionType: 'batch actions' | 'context menu'
218+
group: string
219+
}): Promise<void> {
220+
const { page } = world.actorsEnvironment.getActor({ key: stepUser })
221+
const groupsObject = new objects.applicationAdminSettings.Groups({ page })
222+
const groupIds = []
223+
224+
switch (actionType) {
225+
case 'batch actions':
226+
groupIds.push(groupsObject.getUUID({ key: group }))
227+
await groupsObject.selectGroup({ key: group })
228+
await groupsObject.deleteGroupUsingBatchAction({ groupIds })
229+
break
230+
case 'context menu':
231+
await groupsObject.deleteGroupUsingContextMenu({ key: group })
232+
break
233+
default:
234+
throw new Error(`'${actionType}' not implemented`)
235+
}
236+
}
237+
238+
export async function userRenamesGroup({
239+
world,
240+
stepUser,
241+
attribute,
242+
value,
243+
user
244+
}: {
245+
world: World
246+
stepUser: string
247+
attribute: string
248+
value: string
249+
user: string
250+
}): Promise<void> {
251+
const { page } = world.actorsEnvironment.getActor({ key: stepUser })
252+
const groupsObject = new objects.applicationAdminSettings.Groups({ page })
253+
254+
await groupsObject.changeGroup({
255+
key: user,
256+
attribute: attribute,
257+
value: value,
258+
action: 'context-menu'
259+
})
260+
}
261+
262+
export async function userAddsUserToGroup({
263+
world,
264+
stepUser,
265+
action,
266+
groups,
267+
user
268+
}: {
269+
world: World
270+
stepUser: string
271+
action: string
272+
groups: string[]
273+
user: string
274+
}): Promise<void> {
275+
const { page } = world.actorsEnvironment.getActor({ key: stepUser })
276+
const usersObject = new objects.applicationAdminSettings.Users({ page })
277+
switch (action) {
278+
case 'adds':
279+
await usersObject.addToGroups({
280+
key: user,
281+
groups,
282+
action: 'context-menu'
283+
})
284+
break
285+
case 'removes':
286+
await usersObject.removeFromGroups({
287+
key: user,
288+
groups,
289+
action: 'context-menu'
290+
})
291+
break
292+
default:
293+
throw new Error(`'${action}' not implemented`)
294+
}
295+
}

0 commit comments

Comments
 (0)