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