| /** | 
|  * @file        S&OP Button component to wrap common methods the team encounter during development | 
|  * @description Button class extending Abstraction API's QButton | 
|  * All S&OP page objects inherit from our own class (inheriting e2e/libappbase), but we can propose common methods to them. | 
|  * @author      Clarence (clarence.chan@3ds.com) | 
|  * @copyright   Dassault Systèmes | 
|  */ | 
| import { QUtils } from '../e2elib/lib/src/main/qutils.class'; | 
| import { QObject } from '../e2elib/lib/src/pageobjects/base/qobject.class'; | 
| import { LogMessage } from '../libappbase/logmessage'; | 
| import { QToastButtonName } from '../e2elib/lib/api/types'; | 
| import { WebMessageBox } from '../libappbase/webmessagebox'; | 
| import { UIActionSOP } from './objectsop'; | 
| import { QButton } from '../e2elib/lib/api/pageobjects/qbutton.component'; | 
| import { by, ElementFinder } from '../e2elib/node_modules/protractor'; | 
|   | 
| export class ButtonSOP extends QButton implements UIActionSOP { | 
|   public title: string; // Display name | 
|   | 
|   public constructor(componentPath: string, contextMenuComponenetPath?: string, btnTitle?: string) { | 
|     super(componentPath, contextMenuComponenetPath); | 
|   | 
|     this.title = btnTitle ? btnTitle : this.componentName; | 
|   } | 
|   | 
|   /** | 
|    * Get icon element finder. One use case is to retrieve the icon color via the icon element. | 
|    */ | 
|   public get iconElement(): ElementFinder { | 
|     return this.element.element(by.css('div.dsIcon')); | 
|   } | 
|   | 
|   /** | 
|    * Click button and a web message box prompts. Click Yes or No to dismiss. | 
|    * | 
|    * @param dismissPrompt Click Yes or No. | 
|    */ | 
|   public async clickAndDismissPrompt(dismissPrompt: QToastButtonName): Promise<void> { | 
|     await this.click(); | 
|   | 
|     const webMessageBox = new WebMessageBox(); | 
|     await webMessageBox.waitUntilPresent(false); | 
|     if (dismissPrompt === QToastButtonName.Yes) { | 
|       await webMessageBox.selectYes(); | 
|     } else { | 
|       await webMessageBox.selectNo(); | 
|     } | 
|     await webMessageBox.waitUntilHidden(); | 
|   } | 
|   | 
|   /** | 
|    * Click button and wait for one or more components to be shown/hidden. | 
|    * | 
|    * @param components One more components of QObject type. | 
|    * @param waitVisible Wait for components to be visible or hidden. | 
|    * @param waitTime [Optional] miliseconds of how long it should wait for button to be clickable. | 
|    */ | 
|   public async clickAndWaitVisible(components: QObject[], waitVisible: boolean = true, waitTime?: number): Promise<void> { | 
|     await this.clickWithOptionalWaitTime(waitTime); | 
|   | 
|     // Wait for each component to be shown/visible | 
|     if (waitVisible) { | 
|       for (const c of components) { | 
|         await c.waitForScreenUpdate(); | 
|       } | 
|     } else { | 
|       // Wait for each component to be hidden | 
|       for (const c of components) { | 
|         await c.waitUntilHidden(); | 
|       } | 
|     } | 
|   } | 
|   | 
|   /** | 
|    * Perform click action on button if it is clickable with option to wait for x milliseconds. | 
|    * | 
|    * @param waitTime [Optional] miliseconds of how long it should wait for button to be clickable. | 
|    */ | 
|   public async clickWithOptionalWaitTime(waitTime?: number): Promise<void> { | 
|     const [canClickOk, disabledTooltip ] = await this.getIsClickable(true, waitTime); | 
|   | 
|     expect(canClickOk).toBe(true, LogMessage.btn_notClickable(await this.getComponentLabel(), disabledTooltip)); | 
|   | 
|     if (canClickOk) { | 
|       await this.click(); | 
|     } | 
|   } | 
|   | 
|   public async clickActionLinkText(_expectedActionLinkText: string): Promise<void> { | 
|     // Implements UIActionSOP. Not implementing | 
|   } | 
|   | 
|   /** | 
|    * Returns if button enabled and if disabled retrieve the disabled tooltip. | 
|    * | 
|    * @param getTooltip Set true if to retrieve tooltip. e2e get tooltip limitation will fail if no tooltip set. | 
|    * @param waitTime (Optional) Wait time in milliseconds. | 
|    * @param isEscapeHTMLCharacter (Optional) If true, escape characters such as < to be < for easy reading. | 
|    * @returns Tuplet containing clickable state and disabled tooltip. | 
|    */ | 
|   public async getIsClickable(getTooltip: boolean = true, waitTime?: number, isEscapeHTMLCharacter?: boolean): Promise<[boolean, string]> { | 
|     let btnDisabledTooltip = ''; | 
|     // Need delay, as QButton.isClickable browser.wait for enabled state thus fail for scenario where | 
|     // we expect button disable but since browser.wait condition based on enabled state it immediate return without | 
|     // waiting for the entire duration of waitTime (thus never able to verify disabled correctly) | 
|     await this.waitForScreenUpdate(waitTime); | 
|   | 
|     const enabled = await this.isClickable(false, waitTime); // Pass false as QButton will fail if button enabled as no tooltip can be retrieved | 
|     if (!enabled && getTooltip) { | 
|       // Only if disabled, we try get the tooltip | 
|       btnDisabledTooltip = await QUtils.getTooltip(this.tooltipElement, true, isEscapeHTMLCharacter); | 
|     } | 
|     return [enabled, btnDisabledTooltip]; | 
|   } | 
|   | 
|   public async getValueString(): Promise<string> { | 
|     // Implements UIActionSOP. Not implementing | 
|     return Promise.resolve(''); | 
|   } | 
|   | 
|   public async setValue(_value: string): Promise<void> { | 
|     // Implements UIActionSOP. Not implementing | 
|   } | 
|   | 
|   public async verifyBatchEditEnabled(_expectedEnable: boolean, _expectedActionLinkText: string): Promise<void> { | 
|     // Implements UIActionSOP. Not implementing | 
|   } | 
|   | 
|   public async verifyEnabled(expectedEnable: boolean, expectedDisabledTooltip?: string): Promise<void> { | 
|     // Implements UIActionSOP | 
|     const [isEnabled, disabledTooltip] = await this.getIsClickable(expectedDisabledTooltip !== undefined); // Sometimes scriptor do not want to verify tooltip even if disabled (as no tooltip set on button) | 
|   | 
|     expect(isEnabled).toBe(expectedEnable, `Verify enable state for button ${await this.getComponentLabel()}.`); | 
|     if (expectedDisabledTooltip) { | 
|       expect(disabledTooltip).toBe(expectedDisabledTooltip, `Verify button ${await this.getComponentLabel()} disabled tooltip.`); | 
|     } | 
|   } | 
|   | 
|   /** | 
|    * Compare button icon color code with pass-in color code, these values should be same. | 
|    * If not, fail the test with error message. | 
|    * | 
|    * @param colorHexCode Hex color code (e.g #4a8bbe) | 
|    */ | 
|   public async verifyIconColor(colorHexCode: string): Promise<void> { | 
|     const value = await QUtils.getCssStyle(this.iconElement, '--icon-color'); | 
|     expect(value).toBe(colorHexCode, `Verify button "${this.title}" icon color fail.`); | 
|   } | 
|   | 
|   public async verifyHasMaskError(_expectedValue: boolean): Promise<void> { | 
|     // Implements UIActionSOP, do nothing as no mask error | 
|   } | 
|   | 
|   public async verifyTooltip(expectedValue: string): Promise<void> { | 
|     // Implements UIActionSOP | 
|     const tooltip = await QUtils.getTooltip(this.tooltipElement, true, true, true); | 
|     expect(tooltip).toBe(expectedValue, `Hover ${await this.getComponentLabel()} to verify tooltip.`); | 
|   } | 
|   | 
|   public async verifyValue(_expectedValue: string): Promise<void> { | 
|     // Implements UIActionSOP. Not implementing | 
|   } | 
|   | 
|   public async verifyVisible(expectedValue: string): Promise<void> { | 
|     expect(await this.isVisible()).toBe(expectedValue.toLowerCase() === 'true', `Verify visible state for button ${await this.getComponentLabel()}.`); | 
|   } | 
|  } | 
|   | 
|  // Step description to re-use in spec file to prevent scriptor re-write each time | 
| const stepButton = { | 
|   click: (title: string): string => `Click button "${title}".`, | 
|   clickAndWaitVisible: (buttonName: string, waitVisible: boolean, components: QObject[]): string => { | 
|     const visibility = waitVisible ? 'shown' : 'hidden'; | 
|     const arr: string[] = []; | 
|     for (const component of components) { | 
|       arr.push(component.componentName); | 
|     } | 
|     return `Click button ${buttonName} and wait for '${arr.join(', ')}' to be ${visibility}.`; | 
|   }, | 
|   verifyIconColor: (title: string, color: string): string => `Verify button "${title}" icon color is ${color}.`, | 
| }; | 
|   | 
| export { stepButton as StepButton }; |