Skip to content

Commit 198739d

Browse files
committed
Added e2e tests for groups management
1 parent d2d91a0 commit 198739d

File tree

3 files changed

+167
-3
lines changed

3 files changed

+167
-3
lines changed

playwright.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export default defineConfig({
107107

108108
webServer: [
109109
{
110-
command: './tests/start-test-server.sh 2.4.0a2',
110+
command: './tests/start-test-server.sh 2.4.0',
111111
port: 8000,
112112
waitForPort: true,
113113
stdout: 'pipe',

tests/utils.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ export async function uploadFile(page, selectorText, fileName, data, parentFolde
6464
* @param {import('@playwright/test').Page} page
6565
* @param {import('@playwright/test').Locator} selector
6666
* @param {string} optionValue
67+
* @param {boolean} multiple
6768
*/
68-
export async function selectSlimSelect(page, selector, optionValue) {
69+
export async function selectSlimSelect(page, selector, optionValue, multiple = false) {
6970
await selector.click();
7071
const items = await page.getByRole('option').all();
7172
let selectedItem = null;
@@ -78,5 +79,9 @@ export async function selectSlimSelect(page, selector, optionValue) {
7879
}
7980
expect(selectedItem).not.toBeNull();
8081
await /** @type {import('@playwright/test').Locator} */ (selectedItem).click();
81-
await expect(selector).toHaveText(optionValue);
82+
if (multiple) {
83+
await expect(selector).toHaveText(new RegExp(`(${optionValue}$)|(^\\d+ selected$)`));
84+
} else {
85+
await expect(selector).toHaveText(optionValue);
86+
}
8287
}

tests/v2/admin_groups.spec.js

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import { expect, test } from '@playwright/test';
2+
import { selectSlimSelect, waitModalClosed, waitPageLoading } from '../utils.js';
3+
4+
test('Admin groups management', async ({ page }) => {
5+
let user1;
6+
await test.step('Create test users', async () => {
7+
user1 = await createTestUser(page);
8+
});
9+
10+
let group1;
11+
await test.step('Create test group1', async () => {
12+
group1 = await createTestGroup(page);
13+
});
14+
15+
/** @type {string[]} */
16+
let availableUsers;
17+
await test.step('Add all available users to the group', async () => {
18+
const dragArea = page.getByText('drag the users here');
19+
availableUsers = await page.locator('[draggable="true"]').allInnerTexts();
20+
expect(availableUsers.length).toBeGreaterThan(1);
21+
for (const user of availableUsers) {
22+
const userBadge = page.getByRole('button', { name: user, exact: true });
23+
await userBadge.dragTo(dragArea);
24+
await expect(page.locator('.spinner-border-sm')).not.toBeVisible();
25+
}
26+
await expect(page.getByText('No more users available')).toBeVisible();
27+
});
28+
29+
await test.step('Check group info page', async () => {
30+
await page.goto('/v2/admin/groups');
31+
await waitPageLoading(page);
32+
await page.getByRole('row', { name: group1 }).getByRole('link', { name: 'Info' }).click();
33+
await page.getByText('Members of the group').waitFor();
34+
for (const user of availableUsers) {
35+
const userBadge = page.getByRole('link', { name: user, exact: true });
36+
await expect(userBadge).toBeVisible();
37+
}
38+
});
39+
40+
let group2;
41+
await test.step('Create other 2 test groups', async () => {
42+
group2 = await createTestGroup(page);
43+
await createTestGroup(page);
44+
});
45+
46+
const groupBadges = page.locator('.row', { hasText: 'Groups' }).locator('.badge');
47+
48+
await test.step('Open user editing page', async () => {
49+
await page.goto('/v2/admin/users');
50+
await waitPageLoading(page);
51+
await page.getByRole('row', { name: user1 }).getByRole('link', { name: 'Edit' }).click();
52+
await waitPageLoading(page);
53+
const currentGroups = await groupBadges.allInnerTexts();
54+
expect(currentGroups.length).toEqual(2);
55+
expect(currentGroups.includes('All')).toBeTruthy();
56+
expect(currentGroups.includes(group1)).toBeTruthy();
57+
});
58+
59+
let selectableGroups1;
60+
await test.step('Select group2 from "Add group" modal', async () => {
61+
await page.getByRole('button', { name: 'Add group' }).click();
62+
const modal = page.locator('.modal.show');
63+
await modal.waitFor();
64+
selectableGroups1 = await page.getByRole('option').count();
65+
await selectSlimSelect(page, page.getByLabel('Select groups'), group2, true);
66+
await modal.getByRole('button', { name: 'Add' }).click();
67+
await waitModalClosed(page);
68+
await expect(groupBadges).toHaveCount(3);
69+
});
70+
71+
await test.step('Reopen modal and check options', async () => {
72+
await page.getByRole('button', { name: 'Add group' }).click();
73+
const modal = page.locator('.modal.show');
74+
await modal.waitFor();
75+
const selectableGroups2 = await page.getByRole('option').count();
76+
expect(selectableGroups2).toEqual(selectableGroups1 - 1);
77+
await modal.getByRole('button', { name: 'Cancel' }).click();
78+
await waitModalClosed(page);
79+
});
80+
81+
await test.step('Remove group2 from groups to add', async () => {
82+
await page.getByLabel(`Remove group ${group2}`).click();
83+
await expect(groupBadges).toHaveCount(2);
84+
});
85+
86+
let finalCount;
87+
await test.step('Reopen modal and add all the groups to the user', async () => {
88+
await page.getByRole('button', { name: 'Add group' }).click();
89+
const modal = page.locator('.modal.show');
90+
await modal.waitFor();
91+
const selectableGroups = await page.getByRole('option').allInnerTexts();
92+
expect(selectableGroups.length).toEqual(selectableGroups1);
93+
for (const group of selectableGroups) {
94+
await selectSlimSelect(page, page.getByLabel('Select groups'), group, true);
95+
}
96+
await modal.getByRole('button', { name: 'Add' }).click();
97+
await waitModalClosed(page);
98+
finalCount = selectableGroups.length + 2;
99+
await expect(groupBadges).toHaveCount(finalCount);
100+
await expect(page.getByRole('button', { name: 'Add group' })).not.toBeVisible();
101+
});
102+
103+
await test.step('Save and check', async () => {
104+
await page.getByRole('button', { name: 'Save' }).click();
105+
await page.getByText('Users list').waitFor();
106+
await page.getByRole('row', { name: user1 }).getByRole('link', { name: 'Info' }).click();
107+
await waitPageLoading(page);
108+
await expect(page.getByRole('row', { name: 'Groups' }).getByRole('link')).toHaveCount(
109+
finalCount
110+
);
111+
});
112+
113+
await test.step('Attempt to create a group using the name of an existing group', async () => {
114+
await page.goto('/v2/admin/groups');
115+
await waitPageLoading(page);
116+
await page.getByRole('button', { name: 'Create new group' }).click();
117+
const modal = page.locator('.modal.show');
118+
await modal.waitFor();
119+
await modal.getByRole('textbox', { name: 'Group name' }).fill(group1);
120+
await modal.getByRole('button', { name: 'Create' }).click();
121+
await expect(modal.getByText('A group with the same name already exists')).toBeVisible();
122+
await modal.getByRole('button', { name: 'Cancel' }).click();
123+
await waitModalClosed(page);
124+
});
125+
});
126+
127+
/**
128+
* @param {import('@playwright/test').Page} page
129+
* @returns {Promise<string>}
130+
*/
131+
async function createTestUser(page) {
132+
const randomEmail = Math.random().toString(36).substring(7) + '@example.com';
133+
await page.goto('/v2/admin/users/register');
134+
await waitPageLoading(page);
135+
await page.getByRole('textbox', { name: 'E-mail' }).fill(randomEmail);
136+
await page.getByLabel('Password', { exact: true }).fill('test');
137+
await page.getByLabel('Confirm password').fill('test');
138+
await page.getByRole('button', { name: 'Save' }).click();
139+
await waitPageLoading(page);
140+
await page.getByText('Users list').waitFor();
141+
return randomEmail;
142+
}
143+
144+
/**
145+
* @param {import('@playwright/test').Page} page
146+
* @returns {Promise<string>}
147+
*/
148+
async function createTestGroup(page) {
149+
const randomGroupName = Math.random().toString(36).substring(7);
150+
await page.goto('/v2/admin/groups');
151+
await waitPageLoading(page);
152+
await page.getByRole('button', { name: 'Create new group' }).click();
153+
const modal = page.locator('.modal.show');
154+
await modal.waitFor();
155+
await modal.getByRole('textbox', { name: 'Group name' }).fill(randomGroupName);
156+
await modal.getByRole('button', { name: 'Create' }).click();
157+
await page.getByText('Members of the group').waitFor();
158+
return randomGroupName;
159+
}

0 commit comments

Comments
 (0)