test: playkit v0.3.1 adoption, Zod widening, PROD smoke, NextAuth write gates #68
@@ -26,6 +26,15 @@ export class ManageUsersPanel extends BasePage {
|
||||
return this.page.locator('tbody tr').filter({ hasText: email });
|
||||
}
|
||||
|
||||
/** The row's action buttons (Edit is always first; Deactivate/Delete is
|
||||
* second and only rendered for active users). Positional rather than
|
||||
* aria-label-based — proved more reliable against the live table than
|
||||
* exact accessible-name matching. */
|
||||
private actionButton(email: string, position: 'first' | 'last'): Locator {
|
||||
const buttons = this.row(email).getByRole('button');
|
||||
return position === 'first' ? buttons.first() : buttons.last();
|
||||
}
|
||||
|
||||
/** Scopes to the currently-open dialog matching a heading, to avoid
|
||||
* ambiguous matches against hidden/portalled sibling dialogs. */
|
||||
private dialog(headingText: string): Locator {
|
||||
@@ -53,7 +62,7 @@ export class ManageUsersPanel extends BasePage {
|
||||
}
|
||||
|
||||
async openEditDialog(email: string): Promise<void> {
|
||||
await this.click(this.row(email).getByRole('button', { name: `Edit ${email}`, exact: true }));
|
||||
await this.click(this.actionButton(email, 'first'));
|
||||
await waitForVisible(this.dialog('Edit User'));
|
||||
}
|
||||
|
||||
@@ -82,9 +91,7 @@ export class ManageUsersPanel extends BasePage {
|
||||
* Hard-deletes if the account has no related records, otherwise the
|
||||
* backend soft-deactivates it — either way `isActive` ends up false. */
|
||||
async deleteUser(email: string): Promise<void> {
|
||||
await this.click(
|
||||
this.row(email).getByRole('button', { name: `Deactivate ${email}`, exact: true }),
|
||||
);
|
||||
await this.click(this.actionButton(email, 'last'));
|
||||
const dialog = this.dialog('Delete User');
|
||||
await waitForVisible(dialog);
|
||||
await this.click(dialog.getByRole('button', { name: 'Delete', exact: true }));
|
||||
|
||||
Reference in New Issue
Block a user