1- import { Page , expect } from '@playwright/test' ;
1+ import { Page , expect , test } from '@playwright/test' ;
22import { GrafanaPanel } from '@interfaces/grafanaPanel' ;
33import { GetService } from '@interfaces/inventory' ;
44import { replaceWildcards } from '@helpers/metrics.helper' ;
@@ -58,11 +58,7 @@ export default class Dashboards {
5858 }
5959
6060 private elements = {
61- expandRow : ( ) => this . page . locator ( '//*[@aria-label="Expand row"]' ) ,
62- row : ( ) =>
63- this . page . locator (
64- '//button[contains(@data-testid, "dashboard-row-title")]//ancestor::div[contains(@class, "react-grid-item")]' ,
65- ) ,
61+ expandRow : ( ) => this . page . getByLabel ( 'Expand row' ) ,
6662 panelName : ( ) => this . page . locator ( '//section[contains(@data-testid, "Panel header")]//h2' ) ,
6763 noDataPanel : ( ) =>
6864 this . page . locator (
@@ -72,102 +68,66 @@ export default class Dashboards {
7268 this . page . locator (
7369 '//*[(text()="No data") or (text()="NO DATA") or (text()="N/A") or (text()="-") or (text() = "No Data") or (@data-testid="data-testid Panel data error message")]//ancestor::section//h2' ,
7470 ) ,
75- rowByName : ( rowName : string ) =>
76- this . page . locator (
77- `//button[contains(@data-testid, "dashboard-row-title") and contains(@data-testid, "${ rowName } ")]` ,
78- ) ,
71+ refreshButton : ( ) => this . page . getByLabel ( 'Refresh' , { exact : true } ) ,
72+ loadingIndicator : ( ) => this . page . getByLabel ( 'data-testid Loading indicator' , { exact : true } ) ,
73+ loadingText : ( ) => this . page . getByText ( 'Loading plugin panel...' , { exact : true } ) ,
7974 loadingBar : ( ) => this . page . getByLabel ( 'Panel loading bar' ) ,
8075 gridItems : ( ) => this . page . locator ( '.react-grid-item' ) ,
8176 } ;
8277
83- public async loadAllPanels ( ) {
84- await this . expandAllRows ( ) ;
85-
86- const items = this . elements . gridItems ( ) ;
87- const totalItems = await items . count ( ) ;
88-
89- // Open every item and wait until the item has at least one child, indicating content started to load.
90- for ( let i = 0 ; i < totalItems ; i ++ ) {
91- const item = items . nth ( i ) ;
92- await item . scrollIntoViewIfNeeded ( ) ;
93- await expect
94- . poll ( async ( ) => await item . locator ( ':scope > *' ) . count ( ) , { timeout : Timeouts . ONE_MINUTE } )
95- . toBeGreaterThan ( 0 ) ;
96- }
78+ private async loadAllPanels ( ) {
79+ const expectPanel = expect . configure ( { timeout : Timeouts . ONE_MINUTE } ) ;
80+ // Wait for the dashboard to be visible before proceeding.
81+ await test . step ( 'Wait for initial loading to finish' , async ( ) => {
82+ await expectPanel ( this . elements . refreshButton ( ) ) . toBeVisible ( ) ;
83+ await expectPanel ( this . elements . loadingIndicator ( ) ) . toHaveCount ( 0 ) ;
84+ await expectPanel ( this . elements . loadingText ( ) ) . toHaveCount ( 0 ) ;
85+ } ) ;
86+
87+ // Expand rows if present and wait for content in each item.
88+ await test . step ( 'Expand rows and load panel content' , async ( ) => {
89+ for ( let i = 0 ; i < ( await this . elements . gridItems ( ) . count ( ) ) ; i ++ ) {
90+ const item = this . elements . gridItems ( ) . nth ( i ) ;
91+ await item . scrollIntoViewIfNeeded ( ) ;
92+
93+ const expandButton = item . getByLabel ( 'Expand row' ) ;
94+ if ( await expandButton . isVisible ( ) ) {
95+ await expandButton . click ( ) ;
96+ }
97+
98+ await expectPanel ( item . locator ( ':scope > *' ) ) . not . toHaveCount ( 0 ) ;
99+ }
100+ } ) ;
97101
98- // Confirm no loading bars remain.
99- await expect
100- . poll ( async ( ) => await this . elements . loadingBar ( ) . count ( ) , {
101- timeout : Timeouts . ONE_MINUTE ,
102- } )
103- . toBe ( 0 ) ;
102+ // Confirms that there are no remaining loading bars.
103+ await test . step ( 'Wait for loading to finish' , async ( ) => {
104+ await expectPanel ( this . elements . loadingBar ( ) ) . toHaveCount ( 0 ) ;
105+ } ) ;
104106 }
105107
106- public async verifyAllPanelsHaveData ( noDataMetrics : string [ ] ) {
107- const noDataPanels = new Set < string > ( ) ;
108-
109- for ( let i = 0 ; i < 10 ; i ++ ) {
110- const noDataPanelNames = await this . elements . noDataPanelName ( ) . allTextContents ( ) ;
111- noDataPanelNames . forEach ( ( panelName : string ) => noDataPanels . add ( panelName ) ) ;
112-
113- await this . page . keyboard . press ( 'PageDown' ) ;
114- await this . page . waitForTimeout ( Timeouts . HALF_SECOND ) ;
115- }
116-
117- await this . page . keyboard . press ( 'Home' ) ;
118- await this . page . waitForTimeout ( Timeouts . HALF_SECOND ) ;
119-
108+ async verifyAllPanelsHaveData ( noDataMetrics : string [ ] ) {
109+ await this . loadAllPanels ( ) ;
110+ const noDataPanels = await this . elements . noDataPanelName ( ) . allTextContents ( ) ;
120111 const missingMetrics = Array . from ( noDataPanels ) . filter ( ( e ) => ! noDataMetrics . includes ( e ) ) ;
121- const extraMetrics = noDataMetrics . filter ( ( e ) => ! noDataPanels . has ( e ) ) ;
112+ const extraMetrics = noDataMetrics . filter ( ( e ) => ! noDataPanels . includes ( e ) ) ;
122113
123114 expect . soft ( missingMetrics , `Metrics without data are: ${ missingMetrics } ` ) . toHaveLength ( 0 ) ;
124115 expect
125116 . soft ( extraMetrics , `Metrics with data that are expected to be empty are: ${ extraMetrics } ` )
126117 . toHaveLength ( 0 ) ;
127118 }
128119
129- public async verifyMetricsPresent ( expectedMetrics : GrafanaPanel [ ] , serviceList ?: GetService [ ] ) {
120+ async verifyMetricsPresent ( expectedMetrics : GrafanaPanel [ ] , serviceList ?: GetService [ ] ) {
130121 expectedMetrics = serviceList ? replaceWildcards ( expectedMetrics , serviceList ) : expectedMetrics ;
131122 const expectedMetricsNames = expectedMetrics . map ( ( e ) => e . name ) ;
132- await this . page . keyboard . press ( 'Home' ) ;
133- const availableMetrics = await this . getAllAvailablePanels ( ) ;
123+ await this . loadAllPanels ( ) ;
124+ const availableMetrics = await this . elements . panelName ( ) . allTextContents ( ) ;
134125
135126 expect ( availableMetrics . sort ( ) ) . toEqual ( expectedMetricsNames . sort ( ) ) ;
136-
137- await this . page . keyboard . press ( 'Home' ) ;
138- await this . page . waitForTimeout ( Timeouts . HALF_SECOND ) ;
139- }
140-
141- expandAllRows = async ( ) => {
142- await this . elements . row ( ) . first ( ) . waitFor ( { state : 'visible' } ) ;
143- await this . page . keyboard . press ( 'End' ) ;
144- await this . page . waitForTimeout ( Timeouts . ONE_SECOND ) ;
145- const rowsName = await this . elements . expandRow ( ) . allTextContents ( ) ;
146-
147- for ( const rowName of rowsName ) {
148- await this . elements . rowByName ( rowName ) . click ( ) ;
149- await this . page . waitForTimeout ( Timeouts . ONE_SECOND ) ;
150- }
151-
152- await this . page . keyboard . press ( 'Home' ) ;
153- await this . page . waitForTimeout ( Timeouts . ONE_SECOND ) ;
154- } ;
155-
156- private async getAllAvailablePanels ( ) : Promise < string [ ] > {
157- const availableMetrics = new Set < string > ( ) ;
158-
159- for ( let i = 0 ; i < 10 ; i ++ ) {
160- await this . page . keyboard . press ( 'PageDown' ) ;
161- await this . page . waitForTimeout ( Timeouts . ONE_SECOND ) ;
162- ( await this . elements . panelName ( ) . allTextContents ( ) ) . forEach ( ( availableMetric ) =>
163- availableMetrics . add ( availableMetric ) ,
164- ) ;
165- }
166-
167- return Array . from ( availableMetrics . values ( ) ) ;
168127 }
169128
170- public verifyPanelValues = async ( panels : GrafanaPanel [ ] , serviceList ?: GetService [ ] ) => {
129+ async verifyPanelValues ( panels : GrafanaPanel [ ] , serviceList ?: GetService [ ] ) {
130+ await this . loadAllPanels ( ) ;
171131 const panelList = serviceList ? replaceWildcards ( panels , serviceList ) : panels ;
172132 for ( const panel of panelList ) {
173133 switch ( panel . type ) {
0 commit comments