/** 
 | 
 * @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 }; 
 |