import { AppBase } from '../libappbase/appbase'; 
 | 
import { 
 | 
  ActionBarPageData, 
 | 
  ActionBarPageDevelop, 
 | 
  ActionBarPageHome, 
 | 
  ActionBarPageInventory, 
 | 
  ActionBarPageScenario, 
 | 
  ActionBarPageScenarioAnalysis, 
 | 
  ActionBarPagePlan, 
 | 
  ActionBarPageScenarioSelection, 
 | 
  ActionBarPageSales, 
 | 
  ActionBarPageScenarioComparison, 
 | 
  ActionBarPageWorkflow, 
 | 
} from './actionbarpages'; 
 | 
import { DialogSelectDemoDataset } from './dialogs/dialog.demodataset'; 
 | 
import { DialogStrategy } from './dialogs/dialog.strategy'; 
 | 
import { FormKPI, GaugeIDValueMap, ListKPISelectionContextMenuItem } from './forms/form.kpi'; 
 | 
import { FormNavigationPanel } from './forms/navigationpanel/form.navigationpanel'; 
 | 
import { 
 | 
  ViewAccount, 
 | 
  ViewEntity, 
 | 
  ViewExternalSupplies, 
 | 
  ViewInventoryCosts, 
 | 
  ViewOperationCost, 
 | 
  ViewStockingCost, 
 | 
  ViewUnitCost, 
 | 
  ViewOptimizerStrategies, 
 | 
  ViewCurrency, 
 | 
  ViewPeriod, 
 | 
  ViewScenarioAnalysisCost, 
 | 
  ViewScenario, 
 | 
  ViewSupplyPlanning, 
 | 
  ViewProduct, 
 | 
  ViewGeneralSettings, 
 | 
  ViewCampaignsAndTransitions, 
 | 
  ViewCampaigns, 
 | 
  ViewStockCapacity, 
 | 
  ViewSalesSegments, 
 | 
  ViewUnitsOfMeasure, 
 | 
  ViewScenarioAnalysisOverview, 
 | 
  ViewRecipes, 
 | 
  ViewCapacitiesTime, 
 | 
  ViewCapacitiesQuantity, 
 | 
  ViewCapacitiesStockingPoints, 
 | 
  ViewScenarioComparisonCost, 
 | 
  ViewForecasts, 
 | 
  ViewCustomerOrders, 
 | 
  ViewFeedback, 
 | 
  ViewProductionPlan, 
 | 
  ViewSupplyCost, 
 | 
  ViewCalendar, 
 | 
  ViewTripPlan, 
 | 
  ViewPurchasingPlan, 
 | 
  ViewTransportationCost, 
 | 
  ViewBlendingPlan, 
 | 
  ViewRouting, 
 | 
} from './views'; 
 | 
import { DataKPIName, DataKPIPercentage } from '../libmp/data/data.kpi'; 
 | 
import { by, ElementFinder } from '../e2elib/node_modules/protractor/built'; 
 | 
import { ListScenarioContextMenuItem, ScenarioManager } from './forms/form.scenario'; 
 | 
import { ViewBase } from '../libappbase/viewbase'; 
 | 
import { UIWaitSOP } from '../libappsop/objectsop'; 
 | 
import { DropDownListSOP } from '../libappsop/dropdownlistsop'; 
 | 
import { ButtonSOP } from '../libappsop/buttonsop'; 
 | 
import { ViewScenarioAnalysisUnitCapacity } from './views/view.scenarioanalysis.unitcapacity'; 
 | 
import { ViewScenarioAnalysisBottleneckResources } from './views/view.scenarioanalysis.bottleneckresources'; 
 | 
  
 | 
export class AppMP extends AppBase { 
 | 
  private static _appMP: AppMP; 
 | 
  
 | 
  // Action bar page 
 | 
  public abpDevelop = new ActionBarPageDevelop(); 
 | 
  public abpInventory = new ActionBarPageInventory(); 
 | 
  public abpScenario = new ActionBarPageScenario(); 
 | 
  public abpPlan = new ActionBarPagePlan(); 
 | 
  public abpHome = new ActionBarPageHome(); 
 | 
  public abpScenarioAnalysis = new ActionBarPageScenarioAnalysis(); 
 | 
  public abpScenarioSelection = new ActionBarPageScenarioSelection(); 
 | 
  public abpSales = new ActionBarPageSales(); 
 | 
  public abpData = new ActionBarPageData(); 
 | 
  public abpScenarioComparison = new ActionBarPageScenarioComparison(); 
 | 
  public abpWorkflow = new ActionBarPageWorkflow(); 
 | 
  
 | 
  // Views 
 | 
  public viewScenario = new ViewScenario(); 
 | 
  public viewCustomerOrders = new ViewCustomerOrders(); 
 | 
  public viewCurrency = new ViewCurrency(); 
 | 
  public viewExternalSupplies = new ViewExternalSupplies(); 
 | 
  public viewOptimizerStrategies = new ViewOptimizerStrategies(); 
 | 
  public viewUnitCost = new ViewUnitCost(); 
 | 
  public viewSupplyPlanning = new ViewSupplyPlanning(); 
 | 
  public viewInventoryCosts = new ViewInventoryCosts(); 
 | 
  public viewAccount = new ViewAccount(); 
 | 
  public viewEntity = new ViewEntity(); 
 | 
  public viewForecasts = new ViewForecasts(); 
 | 
  public viewOperationCost = new ViewOperationCost(); 
 | 
  public viewStockingCost = new ViewStockingCost(); 
 | 
  public viewSupplyCost = new ViewSupplyCost(); 
 | 
  public viewScenarioAnalysisOverview = new ViewScenarioAnalysisOverview(); 
 | 
  public viewScenarioAnalysisCost = new ViewScenarioAnalysisCost(); 
 | 
  public viewPeriod = new ViewPeriod(); 
 | 
  public viewProduct = new ViewProduct(); 
 | 
  public viewRecipes = new ViewRecipes(); 
 | 
  public viewGeneralSettings = new ViewGeneralSettings(); 
 | 
  public viewCampaignsAndTransitions = new ViewCampaignsAndTransitions(); 
 | 
  public viewCampaign = new ViewCampaigns(); 
 | 
  public viewFeedback = new ViewFeedback(); 
 | 
  public viewStockCapacity = new ViewStockCapacity(); 
 | 
  public viewSalesSegments = new ViewSalesSegments(); 
 | 
  public viewUnitsOfMeasure = new ViewUnitsOfMeasure(); 
 | 
  public viewCapacitiesTime = new ViewCapacitiesTime(); 
 | 
  public viewScenarioAnalysisUnitCapacity = new ViewScenarioAnalysisUnitCapacity(); 
 | 
  public viewScenarioAnalysisBottleneckResources = new ViewScenarioAnalysisBottleneckResources(); 
 | 
  public viewCapacitiesQuantity = new ViewCapacitiesQuantity(); 
 | 
  public viewCapacitiesStockingPoints = new ViewCapacitiesStockingPoints(); 
 | 
  public viewScenarioComparisonCost = new ViewScenarioComparisonCost(); 
 | 
  public viewCalendar = new ViewCalendar(); 
 | 
  public viewProductionPlan = new ViewProductionPlan(); 
 | 
  public viewTripPlan = new ViewTripPlan(); 
 | 
  public viewPurchasingPlan = new ViewPurchasingPlan(); 
 | 
  public viewTransportationCost = new ViewTransportationCost(); 
 | 
  public viewBlendingPlan = new ViewBlendingPlan(); 
 | 
  public viewRouting = new ViewRouting(); 
 | 
  
 | 
  // Forms 
 | 
  public frmKPI = new FormKPI(); 
 | 
  public formNavigation = new FormNavigationPanel(); 
 | 
  
 | 
  // Dialogs 
 | 
  public dlgDemoDataset = new DialogSelectDemoDataset(); 
 | 
  public dlgStrategy = new DialogStrategy(); 
 | 
  
 | 
  // UI elements at fixed action bar (top right) 
 | 
  public btnCreateAssumption = new ButtonSOP('ButtonCreateAssumption'); 
 | 
  public btnUndo = new ButtonSOP('buttonUndo'); 
 | 
  public ddlActiveScenario = new DropDownListSOP('DropDownListScenario'); // Shows current selected/active scenario 
 | 
  
 | 
  // Get singleton instance of AppMP 
 | 
  public static getInstance(): AppMP { 
 | 
    if (AppMP._appMP === undefined) { 
 | 
      AppMP._appMP = new AppMP(); 
 | 
    } 
 | 
  
 | 
    return AppMP._appMP; 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Copied from e2elib qinputtype as the logic is bugged (not able retrieve action link text) 
 | 
   * Retrieve action link text of input component such as editfield, etc 
 | 
   * Remove once e2elib fixes the bug 
 | 
   * 
 | 
   * @param element ElementFinder of input component to retrieve action link text 
 | 
   * @returns Action link text 
 | 
   */ 
 | 
  public static async getActionLinkText(element: ElementFinder): Promise<string> { 
 | 
    const elem = element.element(by.css('.qActionLink')); 
 | 
  
 | 
    return elem.isPresent().then((ispresent: boolean) => { 
 | 
      if (ispresent) { 
 | 
        // Original code from e2elib which is bugged (as actionlinktext is always empty, the actual text is contained within child button html node) 
 | 
        // return element.getAttribute('actionlinktext'); 
 | 
        return elem.getText(); 
 | 
      } else { 
 | 
        return ''; 
 | 
      } 
 | 
    }); 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Returns the step to create demo data for spec file "it" description. 
 | 
   * 
 | 
   * @param demoType Demo data such as Metal, Food, etc. 
 | 
   * @param scenario The scenario within the demo data (e.g Base) 
 | 
   * @returns The step informing which UI to use and which demo data to be used 
 | 
   */ 
 | 
  public static getDemoDataPath(demoType: string, scenario: string): string { 
 | 
    return `Open ${AppMP.getInstance().abpDevelop.startDemoPath}, select ${demoType} demo and ${scenario} scenario`; 
 | 
  } 
 | 
  
 | 
  // To avoid initialization externally 
 | 
  private constructor() { 
 | 
    super(); 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Create demo dataset in MP 
 | 
   * 
 | 
   * @param demo type of demo, types could be Food or Metals 
 | 
   * @param scenario type of scenario 
 | 
   * @param needWaitOptimizerComplete Default true to wait for optimizer run completion by checking fulfillment target KPI = 100% 
 | 
   * @example await createDemoDataset('Food', 'Base') 
 | 
   */ 
 | 
  public async createDemoDataset(demo: string, scenario: string, needWaitOptimizerComplete: boolean = true): Promise<void> { 
 | 
    // wait until abp develop is visible 
 | 
    await this.abpDevelop.isVisible(); 
 | 
    // Open Develop action bar page 
 | 
    await this.abpDevelop.click(); 
 | 
    // Click on the Start Demo button 
 | 
    await this.abpDevelop.btnStartDemo.click(); 
 | 
    // Wait until Start Demo Dialog is present 
 | 
    await this.dlgDemoDataset.waitUntilPresent(); 
 | 
  
 | 
    await this.dlgDemoDataset.selectDemoDataset(demo, scenario); 
 | 
  
 | 
    if (needWaitOptimizerComplete) { 
 | 
      // Wait until the optimizer run finished by verifying KPI Fulfillment Target = 100.0% 
 | 
      const gaugeValueMap: GaugeIDValueMap[] = [{ gaugeName: DataKPIName.FulfillmentTarget, value: DataKPIPercentage._100_0 }]; 
 | 
      await this.waitForKPICompletion(gaugeValueMap); 
 | 
    } 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Use in each spec's afterall() to cleanup demo datasets and logout. 
 | 
   */ 
 | 
  public async cleanupAndLogout(): Promise<void> { 
 | 
    const excludeDeleteScenarioWithPrefix = 'ADSO-'; // Not to delete scenario with this prefix, reused for few tests 
 | 
  
 | 
    // Delete all datasets 
 | 
    await this.viewScenario.switchTo(); 
 | 
    await this.viewScenario.formScenario.lstScenario.deleteAllScenarios(ScenarioManager.AllScenarios, excludeDeleteScenarioWithPrefix); 
 | 
    await this.viewScenario.formScenario.lstScenario.deleteAllScenarios(ScenarioManager.RecycleBin); 
 | 
    await this.logout(); 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Open Scenario view and select scenario as active. 
 | 
   * 
 | 
   * @param scenarioName Scenario name to set as active. 
 | 
   */ 
 | 
  public async selectScenario(scenarioName: string): Promise<void> { 
 | 
    await this.viewScenario.switchTo(); 
 | 
    await this.viewScenario.formScenario.lstScenario.expandFolderAndSelectMenu(scenarioName, ListScenarioContextMenuItem.Select); 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Quick way to select active scenario via top right dropdown which is accesible in all views. 
 | 
   * Caveat is the scenario name must be unique to use this method. 
 | 
   * 
 | 
   * @param scenarioName Scenario name to select. 
 | 
   */ 
 | 
  public async selectScenarioViaDropdown(scenarioName: string): Promise<void> { 
 | 
    await this.ddlActiveScenario.selectItemSOP(scenarioName); 
 | 
    await this.verifyActiveScenario(scenarioName); 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Verify if active scenario dropdown (top right) is showing the correct scenario. 
 | 
   * 
 | 
   * @param name Expected scenario name to be active. 
 | 
   */ 
 | 
  public async verifyActiveScenario(name: string): Promise<void> { 
 | 
    expect(await this.ddlActiveScenario.getSelectedString()).toBe(name, `Expected scenario '${name}' to be selected in active scenario dropdown (top right).`); 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Open view Scenario Analyisis > Costs, and ensure the target KPI(s) reaches the expected value 
 | 
   * 
 | 
   * @param targetKPI target KPI and its expected value 
 | 
   */ 
 | 
  public async waitForKPICompletion(targetKPI: GaugeIDValueMap[]): Promise<void> { 
 | 
    // Open view Scenario Analysis > Costs 
 | 
    await this.viewScenarioAnalysisCost.switchTo(); 
 | 
    // Open KPI Selection panel 
 | 
    await this.frmKPI.openKPISelectionPanel(); 
 | 
    // Deselect all KPI 
 | 
    await this.frmKPI.panelKPISelection.lstKPISelection.deselectAllKPI(); 
 | 
  
 | 
    // Select KPI in KPI selection list 
 | 
    for (const map of targetKPI) { 
 | 
      const row = await this.frmKPI.panelKPISelection.lstKPISelection.getRow({ Name: map.gaugeName }); 
 | 
      await this.frmKPI.panelKPISelection.lstKPISelection.selectContextMenu(ListKPISelectionContextMenuItem.Select, row); 
 | 
    } 
 | 
    // Open KPI dashboard panel 
 | 
    await this.frmKPI.openKPIDashboardPanel(); 
 | 
  
 | 
    // Wait until the KPI reaches the expected value 
 | 
    for (const map of targetKPI) { 
 | 
      await this.frmKPI.panelKPIDashboard.gaugeKPIDashboard.waitForKPI(map.gaugeName, map.value); 
 | 
    } 
 | 
    // Reset view Scenario Analysis > Costs 
 | 
    await this.resetActiveView(this.viewScenarioAnalysisCost); 
 | 
  } 
 | 
  
 | 
  /** 
 | 
   * Reset active view via Home action bar page. This much faster than opening view manager and search the list to reset. 
 | 
   * Local test faster by ~20 seconds which is significant saving. 
 | 
   * If use this (compare to the base Reset in ViewBase), ensure reset before opening new view as reset is always on current active view. 
 | 
   * 
 | 
   * @param view View to reset which should implement @interface UIWaitSOP 
 | 
   */ 
 | 
  public async resetActiveView(view: ViewBase): Promise<void> { 
 | 
    await this.abpHome.click(); 
 | 
    await this.abpHome.btnResetActiveView.click(); 
 | 
  
 | 
    const viewImplementWaitSOP = view as unknown as UIWaitSOP; // Need cast to unknown before able check if implement interface UIWaitSOP 
 | 
    if (viewImplementWaitSOP) { 
 | 
      await viewImplementWaitSOP.waitUILoaded(); 
 | 
    } 
 | 
  } 
 | 
} 
 | 
  
 | 
export enum Demo { 
 | 
  Food = 'Food', 
 | 
  Metals = 'Metals', 
 | 
} 
 | 
  
 | 
export enum Scenario { 
 | 
  Base = 'Base', 
 | 
  FoodBaseWithRecall = 'Base + recall', 
 | 
} 
 | 
  
 | 
export enum Timeout { 
 | 
  Short = 10000, 
 | 
  Medium = 30000, 
 | 
  Long = 60000, 
 | 
  ButtonState = 1000, 
 | 
} 
 | 
  
 | 
/** 
 | 
 * Image attribute names common to all lists. 
 | 
 */ 
 | 
export enum ImageAttribute { 
 | 
  IsEmpty = 'EMPTY', // No image attribute 
 | 
  IsDefault = 'FLASH', // Default row in list (used by currency and UoM for now) 
 | 
} 
 | 
  
 | 
export enum QuintiqUser { 
 | 
  Administrator = 'administrator', 
 | 
  QuintiqService = 'svc_qtq.sqc', // Admin user in the pipeline (created by DevOps for all teams) 
 | 
} 
 | 
  
 | 
// Step description to re-use in spec file to prevent scriptor re-write each time 
 | 
const stepAppMP = { 
 | 
  loginAs: (user: string): string => `Login as "${user}".`, 
 | 
  logout: (): string => 'Logout from the application.', 
 | 
  selectScenario: (scenarioName: string): string => 
 | 
    `Open view ${AppMP.getInstance().viewScenario.viewPath}. Right click scenario '${scenarioName}' and click menu ${ 
 | 
      ListScenarioContextMenuItem.Select.Label 
 | 
    } to set as active scenario.`, 
 | 
  selectScenarioViaDropdown: (scenarioName: string): string => `In fixed action bar (top right), select active scenario = ${scenarioName}.`, 
 | 
}; 
 | 
  
 | 
export { stepAppMP as StepAppMP }; 
 |