test(e2e): rbac roles (#23075)

This commit is contained in:
Jean-Sébastien Herbaux 2025-03-06 17:55:23 +01:00 committed by GitHub
parent b94e3d1209
commit c57731c6e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 536 additions and 0 deletions

View File

@ -0,0 +1,60 @@
import { test, expect, type Page } from '@playwright/test';
import { sharedSetup } from '../../../../utils/setup';
import { navToHeader, clickAndWait } from '../../../../utils/shared';
// Constants for the created role
const TARGET_USER = { firstName: 'Editor', lastName: 'Testing' };
const ROLES = { new: 'Author', old: 'Editor' };
test.describe('RBAC - Assign Role to Users', () => {
// Runs before each test
test.beforeEach(async ({ page }) => {
// Perform shared setup to reset the database, log in, and prepare the environment
await sharedSetup('rbac-assign-roles-to-user', page, {
login: true,
resetFiles: true,
importData: 'with-admin.tar',
skipTour: true,
});
// Navigate to the Users management page
await navToHeader(page, ['Settings', ['Administration Panel', 'Users']], 'Users');
});
// Test for verifying Super Admin can create a new role
test('Super Admin can assign a role to any user', async ({ page }) => {
const userFullName = `${TARGET_USER.firstName} ${TARGET_USER.lastName}`;
// Step 1: find the "Editor" user
const editorRowLocator = page.getByRole('row', { name: userFullName });
// Step 2: go to the user view, wait for the page to load
await clickAndWait(page, editorRowLocator.getByRole('link', { name: `Edit ${userFullName}` }));
// Step 3: update the user's roles
// Open the role selection list
await page.getByLabel("User's roles*").locator('svg').last().click();
// Remove the Editor role
await page.getByRole('listbox').getByLabel(ROLES.old).locator('button').uncheck();
// Add the Author role
await page.getByRole('listbox').getByLabel(ROLES.new).locator('button').check();
// Exit the roles' selection list context
await page.keyboard.press('Escape');
// Step 3: save the modifications
await clickAndWait(page, page.getByRole('button', { name: 'Save' }));
// Step 4: navigate back to the Users management page
await navToHeader(page, ['Settings', ['Administration Panel', 'Users']], 'Users');
// Step 5: make sure the user has the correct role and that the old one has been removed
await expect(
page.getByRole('row', { name: `${userFullName} editor@testing.com ${ROLES.old}` })
).not.toBeVisible();
await expect(
page.getByRole('row', { name: `${userFullName} editor@testing.com ${ROLES.new}` })
).toBeVisible();
});
});

View File

@ -0,0 +1,56 @@
import { test, expect, type Page } from '@playwright/test';
import { sharedSetup } from '../../../../utils/setup';
import { navToHeader, clickAndWait } from '../../../../utils/shared';
// Constants for the created role
const NEW_ROLE = { name: 'Publisher', description: 'Role with publishing capabilities' };
/**
* Navigate to the Roles management settings via the menu
*/
const goToAdminRolesPage = async (page: Page) => {
await navToHeader(page, ['Settings', ['Administration Panel', 'Roles']], 'Roles');
};
test.describe('RBAC - Create Roles', () => {
// Runs before each test
test.beforeEach(async ({ page }) => {
// Perform shared setup to reset the database, log in, and prepare the environment
await sharedSetup('rbac-roles', page, {
login: true,
resetFiles: true,
importData: 'with-admin.tar',
skipTour: true,
});
// Navigate to the Roles management page
await goToAdminRolesPage(page);
});
// Test for verifying Super Admin can create a new role
test('Super Admin can create a new role', async ({ page }) => {
// Step 1: click "Create new role"
await clickAndWait(page, page.getByRole('button', { name: 'Add new role' }).first());
// Step 2: fill in the role name and description
await page.getByRole('textbox', { name: 'Name' }).fill(NEW_ROLE.name);
await page.getByRole('textbox', { name: 'Description' }).fill(NEW_ROLE.description);
// Step 3: assign the public "publish" permission for articles
await page.getByRole('tab', { name: 'Collection Types' }).click(); // Select permissions tab
await page.getByRole('checkbox', { name: 'Select Publish article' }).check();
// Step 4: save the newly created role
await clickAndWait(page, page.getByRole('button', { name: 'Save' }));
// Step 5: verify the newly created role in the list
await goToAdminRolesPage(page); // Go back to the Roles management page
const roleLocator = page.getByRole('row', { name: NEW_ROLE.name });
await expect(roleLocator).toBeVisible();
await expect(roleLocator.getByRole('gridcell', { name: NEW_ROLE.name })).toBeVisible();
await expect(roleLocator.getByRole('gridcell', { name: NEW_ROLE.description })).toBeVisible();
});
});

View File

@ -0,0 +1,38 @@
import { test, expect } from '@playwright/test';
import { sharedSetup } from '../../../../utils/setup';
import { navToHeader, clickAndWait } from '../../../../utils/shared';
test.describe('RBAC - Delete Roles', () => {
// Runs before each test
test.beforeEach(async ({ page }) => {
// Perform shared setup to reset the database, log in, and prepare the environment
await sharedSetup('rbac-roles', page, {
login: true,
resetFiles: true,
importData: 'with-admin.tar',
skipTour: true,
});
// Navigate to the Roles management page
await navToHeader(page, ['Settings', ['Administration Panel', 'Roles']], 'Roles');
});
// Test for verifying Super Admin can delete an existing role
test('Super Admin can delete an existing role', async ({ page }) => {
// Step 1: locate the "Author" role row
const authorRowLocator = page.getByRole('row', { name: 'Author' });
// Step 2: delete the role
await authorRowLocator.getByRole('button', { name: 'Delete' }).click();
// Step 3: confirm deletion in the alert dialog
await clickAndWait(
page,
page.getByRole('alertdialog').getByRole('button', { name: 'Confirm' })
);
// Step 4: verify the role no longer appears in the list
await expect(page.getByRole('row', { name: 'Author', exact: true })).not.toBeVisible();
});
});

View File

@ -0,0 +1,67 @@
import { test, expect, type Page } from '@playwright/test';
import { sharedSetup } from '../../../../utils/setup';
import { navToHeader, clickAndWait } from '../../../../utils/shared';
// Constants for the edited role
const EDITED_ROLE = { name: 'Contractor', description: 'Role with contractor capabilities' };
/**
* Navigate to the Roles management settings via the menu
*/
const goToAdminRolesPage = async (page: Page) => {
await navToHeader(page, ['Settings', ['Administration Panel', 'Roles']], 'Roles');
};
test.describe('RBAC - Edit Roles', () => {
// Runs before each test
test.beforeEach(async ({ page }) => {
// Perform shared setup to reset the database, log in, and prepare the environment
await sharedSetup('rbac-edit-roles', page, {
login: true,
resetFiles: true,
importData: 'with-admin.tar',
skipTour: true,
});
// Navigate to the Roles management page
await goToAdminRolesPage(page);
});
// Test for verifying Super Admin can edit an existing role
test('Super Admin can edit an existing role', async ({ page }) => {
// Step 1: click the "Editor" role row
const editorRowLocator = page.getByRole('row', { name: 'Editor' });
await clickAndWait(page, editorRowLocator);
// Step 2: fill in the new role name and description
await page.getByRole('textbox', { name: 'Name' }).fill(EDITED_ROLE.name);
await page.getByRole('textbox', { name: 'Description' }).fill(EDITED_ROLE.description);
// Step 3: modify the public permissions for articles
await page.getByRole('tab', { name: 'Collection Types' }).click(); // Open permissions tab
await page.getByRole('checkbox', { name: 'Select Read article' }).uncheck();
await page.getByRole('checkbox', { name: 'Select Publish article' }).uncheck();
await page.getByRole('checkbox', { name: 'Select Update article' }).uncheck();
await page.getByRole('checkbox', { name: 'Select Delete article' }).uncheck();
await page.getByRole('checkbox', { name: 'Select Publish article' }).uncheck();
// Step 4: save the updated role
await clickAndWait(page, page.getByRole('button', { name: 'Save' }));
// Step 5: verify the changes in the role list
// Navigate back to the Roles management page
await goToAdminRolesPage(page);
const roleLocator = page.getByRole('row', { name: EDITED_ROLE.name });
await expect(roleLocator).toBeVisible();
await expect(
roleLocator.getByRole('gridcell', { name: EDITED_ROLE.name, exact: true })
).toBeVisible();
await expect(
roleLocator.getByRole('gridcell', { name: EDITED_ROLE.description, exact: true })
).toBeVisible();
});
});

View File

@ -0,0 +1,33 @@
import { test, expect } from '@playwright/test';
import { sharedSetup } from '../../../../utils/setup';
import { navToHeader, clickAndWait } from '../../../../utils/shared';
test.describe('RBAC - See Roles', () => {
// Runs before each test
test.beforeEach(async ({ page }) => {
// Perform shared setup to reset the database, log in, and prepare the environment
await sharedSetup('rbac-see-roles', page, {
login: true,
resetFiles: true,
importData: 'with-admin.tar',
skipTour: true,
});
// Navigate to the Roles management page
await navToHeader(page, ['Settings', ['Administration Panel', 'Roles']], 'Roles');
});
// Test for verifying Super Admin can view details of an existing role
test('Super Admin can see an existing role', async ({ page }) => {
// Step 1: click the "Editor" role row
const editorRowLocator = page.getByRole('row', { name: 'Editor' });
await clickAndWait(page, editorRowLocator);
// Verify the details of the role
await expect(page.getByRole('textbox', { name: 'Name' })).toHaveValue('Editor');
await expect(page.getByRole('textbox', { name: 'Description' })).toHaveValue(
'Editors can manage and publish contents including those of other users.'
);
});
});

View File

@ -0,0 +1,128 @@
# Test Suite for Role-Based Access Control
This test suite focuses on Strapi's Role-Based Access Control (RBAC) feature.
The tests ensure that administrators or users with appropriate privileges can manage roles and permissions effectively.
## Test Scenarios
The test scenarios are organized into two distinct groups: one dedicated to actions (individual tests focusing on
specific tasks) and another for scenarios (combinations of multiple actions to simulate real-world workflows).
---
### 1. **Assign Role to Users**
#### File: [`assign-role-to-user.spec.ts`](./actions/assign-role-to-user.spec.ts)
**Type:**
Action
**Goal:**
Ensure that the Super Admin can assign, remove, or update roles for users effectively.
**Test Steps:**
- Log in as a Super Admin and navigate to the Users management page.
- Select a user (Editor role) from the list and open their edit page.
- Remove the current role (`Editor`) and assign a new role (`Author`).
- Save the changes and navigate back to the Users management page.
- Verify that the user now has the updated role (`Author`) and that the old role (`Editor`) is removed.
---
### 2. **Delete Roles**
#### File: [`delete-role.spec.ts`](./actions/delete-role.spec.ts)
**Type:**
Action
**Goal:**
To validate that the Super Admin can delete an existing role successfully.
**Test Steps:**
- Log in as a Super Admin and navigate to the Roles management page.
- Identify the role to be deleted (for example, `Author`).
- Click on the delete button and confirm the deletion in the alert dialog.
- Verify that the role no longer appears in the list of roles.
---
### 3. **Edit Roles**
#### File: [`edit-role.spec.ts`](./actions/edit-role.spec.ts)
**Type:**
Action
**Goal:**
To verify that the Super Admin can edit the details and permissions of an existing role.
**Test Steps:**
- Log in as a Super Admin and navigate to the Roles management page.
- Select a role to edit (`Editor`) and modify its name, description, and permissions.
- Add or remove specific permissions (for example, disabling 'Update', 'Publish', and 'Delete article' permissions).
- Save the modifications and verify the changes by navigating back to the Roles page.
---
### 4. **See Roles**
#### File: [`see-role.spec.ts`](./actions/see-role.spec.ts)
**Type:**
Action
**Goal:**
To confirm that the Super Admin can view the details of an existing role, including its name, description, and
permissions.
**Test Steps:**
- Log in as a Super Admin and navigate to the Roles management page.
- Select an existing role (for example, `Editor`) to view its details.
- Verify that the role's name and description are displayed accurately.
---
### 5. **Create Roles**
#### File: [`create-role.spec.ts`](./actions/create-role.spec.ts)
**Type:**
Action
**Goal:**
To validate that the Super Admin can create a new role with customized permissions.
**Test Steps:**
- Log in as a Super Admin and navigate to the Roles management page.
- Click the "Add new role" button to open the role creation form.
- Fill in the role's name (for example, `Publisher`) and description.
- Assign specific permissions (for example, allow the `Publish article` permission).
- Save the newly created role and verify that it appears in the list.
---
### 6. **Full Role Management Flow**
#### File: [`create-new-role.scenario.spec.ts`](./scenarios/create-new-role.scenario.spec.ts)
**Type:**
Scenario
**Goal:**
To cover a comprehensive end-to-end flow combining creating, editing, assigning, and deleting roles to ensure the system supports a complete lifecycle of role management.
**Test Steps:**
- Create a new role (`Publisher`) and assign permissions.
- Verify the new role appears in the Roles list.
- Assign the new role to a user.
- Edit the role's permissions and verify the changes in the list.
- Revert the user to their previously assigned role.
- Delete the newly created role and verify that it has been successfully removed.

View File

@ -0,0 +1,154 @@
import { test, expect, type Page, type Locator } from '@playwright/test';
import { sharedSetup } from '../../../../utils/setup';
import { navToHeader, clickAndWait } from '../../../../utils/shared';
// Constants for the scenario
const OLD_ROLE = { name: 'Editor' };
const NEW_ROLE = { name: 'Publisher', description: 'Role with publishing capabilities' };
const TARGET_USER = { firstName: 'Editor', lastName: 'Testing', email: 'editor@testing.com' };
const USER_FULL_NAME = `${TARGET_USER.firstName} ${TARGET_USER.lastName}`;
/**
* Navigate to the Roles management settings via the menu
*/
const goToAdminRolesPage = async (page: Page) => {
await navToHeader(page, ['Settings', ['Administration Panel', 'Roles']], 'Roles');
};
/**
* Navigate to the Users management page via the menu
*/
const goToUsersManagementPage = async (page: Page) => {
await navToHeader(page, ['Settings', ['Administration Panel', 'Users']], 'Users');
};
test.describe('RBAC - Full Role Management Flow', () => {
test.beforeEach(async ({ page }) => {
// Perform shared setup to reset the database, log in, and prepare the environment
await sharedSetup('rbac-full-role-flow', page, {
login: true,
resetFiles: true,
importData: 'with-admin.tar',
skipTour: true,
});
});
test('Administrator creates, assigns, and edits a role', async ({ page }) => {
// Step 1: create a new role
await addPublisherRole(page);
await goToAdminRolesPage(page);
// Verify the new role in the list
const roleLocator = page.getByRole('row', { name: NEW_ROLE.name });
await expect(roleLocator).toBeVisible();
await expect(roleLocator.getByRole('gridcell', { name: NEW_ROLE.name })).toBeVisible();
await expect(roleLocator.getByRole('gridcell', { name: NEW_ROLE.description })).toBeVisible();
// Step 2: assign the new role to a user
await assignRoleToUser(page, USER_FULL_NAME, NEW_ROLE.name);
// Verify the user has the correct role
await goToUsersManagementPage(page);
await expect(
page.getByRole('row', { name: `${USER_FULL_NAME} ${TARGET_USER.email} ${NEW_ROLE.name}` })
).toBeVisible();
// Step 3: edit the permissions of the role
await editPublisherRole(page);
// Verify the updated role in the list
await goToAdminRolesPage(page);
await expect(page.getByRole('row', { name: NEW_ROLE.name })).toBeVisible();
// Step 4: revert the roles' assignment for the user
await assignRoleToUser(page, USER_FULL_NAME, OLD_ROLE.name);
// Step 5: delete the created role
await deletePublisherRole(page);
// Verify the role has been deleted
await expect(page.getByRole('row', { name: NEW_ROLE.name, exact: true })).not.toBeVisible();
});
});
const addPublisherRole = async (page: Page) => {
await goToAdminRolesPage(page);
await clickAndWait(page, page.getByRole('button', { name: 'Add new role' }).first());
await page.getByRole('textbox', { name: 'Name' }).fill(NEW_ROLE.name);
await page.getByRole('textbox', { name: 'Description' }).fill(NEW_ROLE.description);
// Assign the "publish" permission for articles initially
await page.getByRole('tab', { name: 'Collection Types' }).click();
await page.getByRole('checkbox', { name: 'Select Publish article' }).check();
// Save the newly created role
await clickAndWait(page, page.getByRole('button', { name: 'Save' }));
};
const editPublisherRole = async (page: Page) => {
await goToAdminRolesPage(page);
// Open the role edit page
await clickAndWait(page, page.getByRole('row', { name: NEW_ROLE.name }));
// Modify permissions
await page.getByRole('tab', { name: 'Collection Types' }).click(); // Open permissions tab
await page.getByRole('checkbox', { name: `Select Read article` }).check();
await page.getByRole('checkbox', { name: `Select Update article` }).check();
await page.getByRole('checkbox', { name: 'Select Create article' }).check();
await page.getByRole('checkbox', { name: 'Select Delete article' }).check();
await page.getByRole('checkbox', { name: 'Select Publish article' }).uncheck();
// Save the updated role
await clickAndWait(page, page.getByRole('button', { name: 'Save' }));
};
const deletePublisherRole = async (page: Page) => {
await goToAdminRolesPage(page);
await page
.getByRole('row', { name: NEW_ROLE.name })
.getByRole('button', { name: 'Delete' })
.click();
// Confirm the deletion in the alert dialog
await clickAndWait(page, page.getByRole('alertdialog').getByRole('button', { name: 'Confirm' }));
};
const assignRoleToUser = async (page: Page, userFullName: string, role: string) => {
await goToUsersManagementPage(page); // Navigate to Users management page
// Find the user's row
const userRowLocator = page.getByRole('row', { name: userFullName });
// Go to the user's edit view page
await clickAndWait(page, userRowLocator.getByRole('link', { name: `Edit ${userFullName}` }));
// Update the user's roles
await page.getByLabel("User's roles*").locator('svg').last().click(); // Open role selector
const listBoxLocator = page.getByRole('listbox');
// Make sure all the roles are unchecked before selecting the new one
for (const checkbox of await listBoxLocator.locator('button').all()) {
await checkbox.uncheck();
}
// Assign the new role
await listBoxLocator.getByLabel(role).locator('button').check();
// Exit role selection
await page.keyboard.press('Escape');
// Save changes
await clickAndWait(page, page.getByRole('button', { name: 'Save' }));
};