yanweiyuan3
2023-08-09 588bc7829387dfc761cc25f06f77d4c81818bd10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/**
 * @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 &lt; 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 };