github.com/argoproj/argo-cd/v3@v3.2.1/ui-test/src/applications-list/applications-list.ts (about) 1 import {By, until, WebDriver} from 'selenium-webdriver'; 2 import UiTestUtilities from '../UiTestUtilities'; 3 import * as Const from '../Constants'; 4 import {Base} from '../base'; 5 import {ApplicationCreatePanel} from '../application-create-panel/application-create-panel'; 6 import {ApplicationsSyncPanel, SYNC_PANEL_SYNCHRONIZE_BUTTON} from '../applications-sync-panel/applications-sync-panel'; 7 import {PopupManager} from '../popup/popup-manager'; 8 import Configuration from '../Configuration'; 9 10 const NEW_APP_BUTTON: By = By.xpath('.//button[@qe-id="applications-list-button-new-app"]'); 11 // Uncomment to use: 12 // const CREATE_APPLICATION_BUTTON: By = By.xpath('.//button[@qe-id="applications-list-button-create-application"]'); 13 14 export class ApplicationsList extends Base { 15 private applicationCreatePanel: ApplicationCreatePanel; 16 private applicationsSyncPanel: ApplicationsSyncPanel; 17 private popupManager: PopupManager; 18 19 public constructor(driver: WebDriver) { 20 super(driver); 21 this.applicationCreatePanel = new ApplicationCreatePanel(driver); 22 this.applicationsSyncPanel = new ApplicationsSyncPanel(driver); 23 this.popupManager = new PopupManager(driver); 24 } 25 26 public async clickTile(appName: string): Promise<void> { 27 try { 28 const tile = await UiTestUtilities.findUiElement(this.driver, this.getApplicationTileLocator(appName)); 29 await tile.click(); 30 } catch (err: any) { 31 throw new Error(err); 32 } 33 } 34 35 /** 36 * Click the Add New Button 37 */ 38 public async clickNewAppButton(): Promise<ApplicationCreatePanel> { 39 try { 40 const newAppButton = await UiTestUtilities.findUiElement(this.driver, NEW_APP_BUTTON); 41 await newAppButton.click(); 42 } catch (err: any) { 43 throw new Error(err); 44 } 45 return this.applicationCreatePanel; 46 } 47 48 /** 49 * Click the Sync button on the App tile 50 * 51 * @param appName 52 */ 53 public async clickSyncButtonOnApp(appName: string): Promise<ApplicationsSyncPanel> { 54 try { 55 const syncButton = await UiTestUtilities.findUiElement(this.driver, this.getSyncButtonLocatorForApp(appName)); 56 await syncButton.click(); 57 // Wait until the Synchronize sliding panel appears 58 const synchronizeButton = await this.driver.wait(until.elementLocated(SYNC_PANEL_SYNCHRONIZE_BUTTON), Const.TEST_TIMEOUT); 59 await this.driver.wait(until.elementIsVisible(synchronizeButton), Const.TEST_TIMEOUT); 60 } catch (err: any) { 61 throw new Error(err); 62 } 63 return this.applicationsSyncPanel; 64 } 65 66 /** 67 * Delete an application via the Delete button on the App tile 68 * 69 * @param appName 70 */ 71 public async clickDeleteButtonOnApp(appName: string): Promise<PopupManager> { 72 try { 73 const deleteButton = await UiTestUtilities.findUiElement(this.driver, this.getDeleteButtonLocatorForApp(appName)); 74 await deleteButton.click(); 75 } catch (err: any) { 76 throw new Error(err); 77 } 78 return this.popupManager; 79 } 80 81 public async waitUntilOperationStatusDisappearsOnApp(appName: string) { 82 const opStateElem = await UiTestUtilities.findUiElement(this.driver, this.getApplicationOperationsTitle(appName)); 83 await this.driver.wait(async () => { 84 return UiTestUtilities.untilOperationStatusDisappears(opStateElem); 85 }, Const.TEST_TIMEOUT); 86 } 87 88 /** 89 * Click on the Refresh button on the App tile 90 * 91 * @param appName 92 */ 93 public async clickRefreshButtonOnApp(appName: string): Promise<void> { 94 try { 95 const refreshButton = await UiTestUtilities.findUiElement(this.driver, this.getRefreshButtonLocatorForApp(appName)); 96 await this.driver.wait(until.elementIsVisible(refreshButton), Const.TEST_TIMEOUT); 97 await refreshButton.click(); 98 } catch (err: any) { 99 throw new Error(err); 100 } 101 } 102 103 /** 104 * Use with wait. Wait for the health status of the app to change to Healthy 105 * 106 * @param appName 107 */ 108 public async waitForHealthStatusOnApp(appName: string): Promise<void> { 109 try { 110 const healthStatusElement = await UiTestUtilities.findUiElement(this.driver, this.getApplicationHealthTitle(appName)); 111 await this.driver.wait(async () => { 112 return UiTestUtilities.untilAttributeIs(healthStatusElement, 'title', 'Healthy'); 113 }, Const.TEST_TIMEOUT); 114 } catch (err: any) { 115 throw new Error(err); 116 } 117 } 118 119 /** 120 * Use with wait. Wait for the sync status of the app to change to Synced 121 * 122 * @param appName 123 */ 124 public async waitForSyncStatusOnApp(appName: string): Promise<void> { 125 try { 126 const statusElement = await UiTestUtilities.findUiElement(this.driver, this.getApplicationSyncTitle(appName)); 127 await this.driver.wait(async () => { 128 return UiTestUtilities.untilAttributeIs(statusElement, 'title', 'Synced'); 129 }, Const.TEST_TIMEOUT); 130 } catch (err: any) { 131 throw new Error(err); 132 } 133 } 134 135 /** 136 * Check that there are no operations associated with the app 137 * 138 * @param appName 139 */ 140 public async checkNoAdditionalOperations(appName: string): Promise<void> { 141 // Check if there are no operations still running 142 UiTestUtilities.log('Checking if there are any additional operations'); 143 let opStateElem; 144 let opState; 145 try { 146 opStateElem = await this.driver.wait(until.elementLocated(this.getApplicationOperationsTitle(appName)), Const.TEST_IS_NOT_VISIBLE_TIMEOUT); 147 UiTestUtilities.logError('Unexpected to locate Operation element.'); 148 opState = await opStateElem.getAttribute('title'); 149 } catch (e) { 150 // ignore since we expect to not have any existing operations 151 } 152 if (opStateElem) { 153 throw new Error('Expecting no other operations. Actual: ' + opState); 154 } 155 } 156 157 // Locators 158 159 // By.css('#app .applications-tiles .applications-list-argocd_" + appName + "''); 160 161 private getApplicationTileSelector(appName: string): string { 162 return './/div[contains(@class,"qe-applications-list-' + Configuration.ARGOCD_NAMESPACE + '_' + appName + '")]'; 163 } 164 165 private getApplicationTileLocator(appName: string): By { 166 return By.xpath(this.getApplicationTileSelector(appName)); 167 } 168 169 private getSyncButtonLocatorForApp(appName: string): By { 170 return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//ancestor::a[@qe-id="applications-tiles-button-sync"]'); 171 } 172 173 private getDeleteButtonLocatorForApp(appName: string): By { 174 return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//ancestor::a[@qe-id="applications-tiles-button-delete"]'); 175 } 176 177 private getRefreshButtonLocatorForApp(appName: string): By { 178 return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//ancestor::a[@qe-id="applications-tiles-button-refresh"]'); 179 } 180 181 private getApplicationHealthTitle(appName: string): By { 182 return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//div[@qe-id="applications-tiles-health-status"]//i[@qe-id="utils-health-status-title"]'); 183 } 184 185 private getApplicationSyncTitle(appName: string): By { 186 return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//div[@qe-id="applications-tiles-health-status"]//i[@qe-id="utils-sync-status-title"]'); 187 } 188 189 private getApplicationOperationsTitle(appName: string): By { 190 return By.xpath( 191 this.getApplicationTileSelector(appName) + '//div[@class="row"]//div[@qe-id="applications-tiles-health-status"]//i[@qe-id="utils-operations-status-title"]' 192 ); 193 } 194 }