@@ -17,6 +17,7 @@ export enum DiagnosticsTab {
1717 HotKeys = 'Hot keys' ,
1818 Describe = 'Describe' ,
1919 Storage = 'Storage' ,
20+ Access = 'Access' ,
2021}
2122
2223export class Table {
@@ -230,6 +231,7 @@ export class Diagnostics {
230231 storage : StoragePage ;
231232 nodes : NodesPage ;
232233 memoryViewer : MemoryViewer ;
234+ private page : Page ;
233235
234236 private tabs : Locator ;
235237 private schemaViewer : Locator ;
@@ -245,8 +247,12 @@ export class Diagnostics {
245247 private tableRadioButton : Locator ;
246248 private fixedHeightQueryElements : Locator ;
247249 private copyLinkButton : Locator ;
250+ private ownerCard : Locator ;
251+ private changeOwnerButton : Locator ;
252+ private grantAccessButton : Locator ;
248253
249254 constructor ( page : Page ) {
255+ this . page = page ;
250256 this . storage = new StoragePage ( page ) ;
251257 this . nodes = new NodesPage ( page ) ;
252258 this . memoryViewer = new MemoryViewer ( page ) ;
@@ -269,6 +275,9 @@ export class Diagnostics {
269275 this . storageCard = page . locator ( '.metrics-cards__tab:has-text("Storage")' ) ;
270276 this . memoryCard = page . locator ( '.metrics-cards__tab:has-text("Memory")' ) ;
271277 this . healthcheckCard = page . locator ( '.ydb-healthcheck-preview' ) ;
278+ this . ownerCard = page . locator ( '.ydb-access-rights__owner-card' ) ;
279+ this . changeOwnerButton = page . locator ( '.ydb-access-rights__owner-card button' ) ;
280+ this . grantAccessButton = page . locator ( 'button:has-text("Grant Access")' ) ;
272281 }
273282
274283 async isSchemaViewerVisible ( ) {
@@ -423,4 +432,160 @@ export class Diagnostics {
423432 const rowElementClass = await rowElement . getAttribute ( 'class' ) ;
424433 return rowElementClass ?. includes ( 'kv-top-queries__row_active' ) || false ;
425434 }
435+
436+ async isOwnerCardVisible ( ) : Promise < boolean > {
437+ await this . ownerCard . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
438+ return true ;
439+ }
440+
441+ async getOwnerName ( ) : Promise < string > {
442+ const ownerNameElement = this . ownerCard . locator ( '.ydb-subject-with-avatar__subject' ) ;
443+
444+ return await ownerNameElement . innerText ( ) ;
445+ }
446+
447+ async clickChangeOwnerButton ( ) : Promise < void > {
448+ await this . changeOwnerButton . click ( ) ;
449+ }
450+
451+ async changeOwner ( newOwnerName : string ) : Promise < void > {
452+ await this . clickChangeOwnerButton ( ) ;
453+
454+ // Wait for the dialog to appear
455+ const dialog = this . page . locator ( '.g-dialog' ) ;
456+ await dialog . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
457+
458+ // Wait for the owner input field to appear
459+ const ownerInput = dialog . locator ( 'input[placeholder="Enter subject"]' ) ;
460+ await ownerInput . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
461+
462+ // Clear the input and type the new owner name
463+ await ownerInput . clear ( ) ;
464+ await ownerInput . fill ( newOwnerName ) ;
465+
466+ // Click the Apply button
467+ const applyButton = dialog . locator ( 'button:has-text("Apply")' ) ;
468+
469+ // Wait for the button to be enabled
470+ await this . page . waitForTimeout ( 500 ) ;
471+ // Wait for the button to become enabled
472+ await this . page . waitForSelector ( '.g-dialog button:has-text("Apply"):not([disabled])' , {
473+ timeout : VISIBILITY_TIMEOUT ,
474+ } ) ;
475+ await applyButton . click ( ) ;
476+
477+ // Wait for the dialog to close and changes to be applied
478+ await dialog . waitFor ( { state : 'hidden' , timeout : VISIBILITY_TIMEOUT } ) ;
479+ await this . page . waitForTimeout ( 500 ) ;
480+ }
481+
482+ async clickGrantAccessButton ( ) : Promise < void > {
483+ await this . grantAccessButton . click ( ) ;
484+ }
485+
486+ async isGrantAccessDrawerVisible ( ) : Promise < boolean > {
487+ const grantAccessDialog = this . page . locator ( '.ydb-grant-access' ) ;
488+ await grantAccessDialog . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
489+ return true ;
490+ }
491+
492+ async enterSubjectInGrantAccessDialog ( subject : string ) : Promise < void > {
493+ const subjectInput = this . page . locator ( '.ydb-grant-access input[name="subjectInput"]' ) ;
494+ await subjectInput . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
495+ await subjectInput . fill ( subject ) ;
496+ await subjectInput . press ( 'Enter' ) ;
497+ }
498+
499+ async isRightsWrapperVisible ( ) : Promise < boolean > {
500+ const rightsWrapper = this . page . locator ( '.ydb-grant-access__rights-wrapper' ) ;
501+ return rightsWrapper . isVisible ( ) ;
502+ }
503+
504+ async isApplyButtonDisabled ( ) : Promise < boolean > {
505+ const applyButton = this . page . locator ( '.ydb-grant-access__footer-button:has-text("Apply")' ) ;
506+ await applyButton . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
507+ return await applyButton . isDisabled ( ) ;
508+ }
509+
510+ async clickFullAccessSwitch ( ) : Promise < void > {
511+ const fullAccessCard = this . page . locator ( '.ydb-grant-access__single-right' ) . first ( ) ;
512+ await fullAccessCard . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
513+ const switchElement = fullAccessCard . locator ( '.g-switch__indicator' ) ;
514+ await switchElement . click ( ) ;
515+ }
516+
517+ async clickApplyButton ( ) : Promise < void > {
518+ const applyButton = this . page . locator ( 'button:has-text("Apply")' ) ;
519+ await applyButton . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
520+ await applyButton . click ( ) ;
521+ }
522+
523+ async isSubjectInRightsTable ( subject : string ) : Promise < boolean > {
524+ const rightsTable = this . page . locator ( '.ydb-access-rights__rights-table' ) ;
525+ await rightsTable . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
526+
527+ const rows = rightsTable . locator ( '.data-table__row' ) ;
528+
529+ await rows
530+ . filter ( { hasText : subject } )
531+ . waitFor ( { state : 'visible' , timeout : VISIBILITY_TIMEOUT } ) ;
532+
533+ // for (const row of Array.from(rows)) {
534+ // // Get the first cell (Subject column)
535+ // const firstCell = row.querySelector('.data-table__td');
536+ // if (!firstCell) {
537+ // continue;
538+ // }
539+
540+ // // Find the subject text element
541+ // const subjectElement = firstCell.querySelector('.ydb-subject-with-avatar__subject');
542+ // if (!subjectElement) {
543+ // continue;
544+ // }
545+
546+ // // Check if the subject text contains the search text
547+ // const subjectText = subjectElement.textContent || '';
548+ // if (subjectText.includes(searchText)) {
549+ // return true;
550+ // }
551+ // }
552+
553+ return true ;
554+ }
555+
556+ // export function isSubjectInRightsTable(searchText: string): boolean {
557+ // // Find the rights table
558+ // const rightsTable = document.querySelector(
559+ // '.ydb-resizeable-data-table.ydb-access-rights__rights-table',
560+ // );
561+ // if (!rightsTable) {
562+ // return false;
563+ // }
564+
565+ // // Find all rows in the table
566+ // const rows = rightsTable.querySelectorAll('.data-table__row');
567+
568+ // // Check each row
569+ // for (const row of Array.from(rows)) {
570+ // // Get the first cell (Subject column)
571+ // const firstCell = row.querySelector('.data-table__td');
572+ // if (!firstCell) {
573+ // continue;
574+ // }
575+
576+ // // Find the subject text element
577+ // const subjectElement = firstCell.querySelector('.ydb-subject-with-avatar__subject');
578+ // if (!subjectElement) {
579+ // continue;
580+ // }
581+
582+ // // Check if the subject text contains the search text
583+ // const subjectText = subjectElement.textContent || '';
584+ // if (subjectText.includes(searchText)) {
585+ // return true;
586+ // }
587+ // }
588+
589+ // return false;
590+ // }
426591}
0 commit comments