import { QContextMenu } from '../e2elib/lib/api/pageobjects/qcontextmenu.component';
|
import { GanttChartNode } from '../e2elib/lib/src/pageobjects/ganttchart/ganttchartnode';
|
import { GanttChartRow } from '../e2elib/lib/src/pageobjects/ganttchart/ganttchartrow';
|
import { GanttChartBase } from '../libappbase/ganttchartbase';
|
import { convertDateToUTC } from '../libappbase/timeutils';
|
import { getHtmlContent } from '../libappbase/utils';
|
import { ColorSOP } from './colorsop';
|
import { ContextMenuItemSOP, ContextMenuSOP } from './contextmenusop';
|
|
export class GanttChartSOP extends GanttChartBase {
|
private readonly _contextMenu: QContextMenu;
|
private readonly _cmMenuMap: Map<string, QContextMenu> = new Map();
|
|
/**
|
* Format the node filtering criteria to be used in step description object.
|
*
|
* @param nodeCriteria The node filtering criteria (e.g filter by color).
|
* @returns The filtering text to be used in step description object.
|
*/
|
public static formatStepDescriptionNodeCriteria(nodeCriteria?: GanttChartNodeSOPCriteria): string {
|
const criteriaArr: string[] = [];
|
if (nodeCriteria) {
|
if (nodeCriteria.ColorHex) {
|
criteriaArr.push(`ColorHex = ${nodeCriteria?.ColorHex}`);
|
}
|
|
// Extend with more criteria in future
|
}
|
|
// If node criteria undefined, meaning retrieve nodes without filtering thus no criteria text to return
|
const criteriaTextResult = nodeCriteria ? ` Node filtering criteria: ${criteriaArr.join(', ')}.` : '';
|
|
return criteriaTextResult;
|
}
|
|
public constructor(formName: string, componentPath: string, contextMenuName?: string) {
|
super(formName, componentPath);
|
|
if (contextMenuName) {
|
this._contextMenu = new QContextMenu(contextMenuName);
|
}
|
}
|
|
/**
|
* Select multiple nodes (based on one or more index, 0-based) in a gantt chart row, right click and select context menu item.
|
*
|
* @param row Row to right click select nodes
|
* @param indexes Index of nodes to select (0-based index)
|
* @param contextMenuItem Context menu item to select
|
*/
|
public async rightClickNodeIndexesAndSelectContextMenu(row: GanttChartRow, indexes: number[], contextMenuItem: ContextMenuItemSOP): Promise<void> {
|
const nodes = await this.getAllNodes(row);
|
for (const i of indexes) {
|
const node = nodes[i];
|
await this.rightClickNode(node, await node.getStartDate(), true);
|
}
|
await this._contextMenu.selectMenuItem(contextMenuItem.Name);
|
}
|
|
/**
|
* Right click row and select menu in context menu.
|
*
|
* @param gcRow row to right click.
|
* @param contextMenuItem Context menu item to select.
|
*/
|
public async rightClickRowAndSelectMenu(gcRow: GanttChartRow, contextMenuItem: ContextMenuItemSOP): Promise<void> {
|
const contextMenu = this.findCreateContextMenu(contextMenuItem.ContextMenu);
|
await this.rightClickRow(gcRow);
|
|
expect(await contextMenu!.isVisible()).toBe(true, 'ContextMenu on GanttChart shall be seen');
|
await contextMenu!.selectMenuItem(contextMenuItem.Name);
|
}
|
|
/**
|
* To find and verify the gantt chart node exists for certain start and end date.
|
*
|
* @param rowName The gantt chart row name.
|
* @param start The start date of the node.
|
* @param end The end date of the node.
|
* @param nodeColor The background color of the node.
|
*/
|
public async verifyNodeExists(rowName: string, start: Date, end: Date, nodeColor?: ColorSOP): Promise<void> {
|
const rows = await this.getAllRows();
|
let row: GanttChartRow | undefined;
|
|
// Find matching row
|
for (const r of rows) {
|
const rTitle = await r.getTitle();
|
// Remove HTML content to get the title
|
if (getHtmlContent(rTitle)[0] === rowName) {
|
row = r;
|
break;
|
}
|
}
|
|
if (row !== undefined) {
|
const s = await (await row.getNode(0))?.getStartDate();
|
const e = await (await row.getNode(0))?.getEndDate();
|
|
expect(s?.getTime()).toBe(convertDateToUTC(start).getTime(), 'Start date is different.');
|
expect(e?.getTime()).toBe(convertDateToUTC(end).getTime(), 'End date is different.');
|
|
if (nodeColor) {
|
const bgcolor = (await row.getNode(0))?.getBackgroundColor();
|
expect(bgcolor).toBe(nodeColor.Hex, 'Node color is different.');
|
}
|
} else {
|
fail(`Unable to find the gantt chart row ${ rowName}`);
|
}
|
}
|
|
/**
|
* Verifies if the gantt chart row has the expected number of nodes.
|
*
|
* @param gcRow The row to check if it has the expected number of nodes.
|
* @param expectedNum The expected number of nodes.
|
* @param nodeCriteria The criteria to count node
|
*/
|
public async verifyNodeCount(gcRow: GanttChartRow, expectedNum: number, nodeCriteria?: GanttChartNodeSOPCriteria): Promise<void> {
|
let numNodes = 0;
|
if (nodeCriteria) {
|
const nodes = await this.getAllNodes(gcRow);
|
for (const node of nodes) {
|
if (nodeCriteria.ColorHex && nodeCriteria.ColorHex === (await node.getBackgroundColor())) {
|
numNodes++;
|
}
|
}
|
} else {
|
numNodes = await gcRow.getNumNodes();
|
}
|
expect(numNodes).toBe(expectedNum, `Verify fail for retrieving node count.${GanttChartSOP.formatStepDescriptionNodeCriteria(nodeCriteria)}`);
|
}
|
|
/**
|
* Verifies when node is right clicked, the context menu item is disabled and shows the expected tooltip.
|
*
|
* @param rowTitle Gantt chart row title
|
* @param nodeStartOrIndex Node index number (to enhance with start in future if needed)
|
* @param contextMenuItem Context menu item that should be disabled
|
* @param tooltip Tooltip expected when context menu item is about to be selected
|
*/
|
public async verifyNodeContextMenuItemDisabled(rowTitle: string, nodeStartOrIndex: number, contextMenuItem: ContextMenuItemSOP, tooltip: string): Promise<void> {
|
const contextMenu = this.findCreateContextMenu(contextMenuItem.ContextMenu);
|
|
const row = (await this.getRowsByTitle(rowTitle))[0];
|
const node = (await row.getNode(nodeStartOrIndex)) as GanttChartNode;
|
|
if (this.verifyNodeDefined(node, rowTitle, nodeStartOrIndex)) {
|
await this.rightClickNode(node);
|
|
const [isClickable, actualToolTip] = await ContextMenuSOP.verifyIsMenuItemClickable(contextMenu!, contextMenuItem.Name, true);
|
expect(isClickable).toBe(false, `Expected context menu "${contextMenuItem.Label}" disabled for node index ${nodeStartOrIndex} in row = "${rowTitle}".`);
|
expect(actualToolTip).toBe(tooltip, `Verify tooltip fail for context menu "${contextMenuItem.Label}" on node index ${nodeStartOrIndex} in row = "${rowTitle}"."`);
|
}
|
}
|
|
/**
|
* Verifies when row is right clicked, the context menu item is disabled and shows the expected tool tip.
|
*
|
* @param rowTitle Row title to right click and check
|
* @param contextMenuItem Context menu item that should be disabled
|
* @param tooltip Tooltip expected when context menu item is about to be selected
|
* @param tooltipExactMatch true by default. If true, the expected tooltip is to be exactly the same. Else, the expected tooltip is expected to contain the tooltip parameter.
|
*/
|
public async verifyRowContextMenuItemDisabled(rowTitle: string, contextMenuItem: ContextMenuItemSOP, tooltip: string, tooltipExactMatch: boolean = true): Promise<void> {
|
const contextMenu = this.findCreateContextMenu(contextMenuItem.ContextMenu);
|
|
const row = (await this.getRowsByTitle(rowTitle))[0];
|
await this.rightClickRow(row);
|
|
const [isClickable, actualToolTip] = await ContextMenuSOP.verifyIsMenuItemClickable(contextMenu!, contextMenuItem.Name, true);
|
expect(isClickable).toBe(false, `Expected context menu "${contextMenuItem.Label}" disabled for row = "${rowTitle}".`);
|
if (tooltipExactMatch) {
|
expect(actualToolTip).toBe(tooltip, `Verify tooltip fail for context menu "${contextMenuItem.Label}" on row = "${rowTitle}".`);
|
} else {
|
expect(actualToolTip).toContain(tooltip, `Verify tooltip fail for context menu "${contextMenuItem.Label}" on row = "${rowTitle}".`);
|
}
|
}
|
|
/**
|
* Throws error if gantt chart node is undefined. Use in method to verify before proceeding with more node related actions.
|
*
|
* @param node Node to verify.
|
* @param rowTitle Gantt chart row title, to be used in error message if node is undefined.
|
* @param nodeStartOrIndex Gantt chart node start time or index, to be used in error message if node is undefined.
|
* @returns True if node is defined, else method will already throw error before reach return statement.
|
*/
|
private verifyNodeDefined(node: GanttChartNode | undefined, rowTitle: string, nodeStartOrIndex: number): boolean {
|
if (node === undefined) {
|
throw Error(`Cannot find gantt chart node with row title = "${rowTitle}" and node index = "${nodeStartOrIndex}".`);
|
}
|
|
return true;
|
}
|
|
public async verifyRowExists(rowTitle: string): Promise<void> {
|
const rows = await this.getRowsByTitle(rowTitle);
|
expect(rows.length === 1).toBe(true, `Cannot find gantt chart row with title "${rowTitle}".`);
|
}
|
|
/**
|
* Returns the context menu from stored map if previously created, else create, store and return it.
|
*
|
* @param name Context menu name.
|
* @returns Context menu from stored map.
|
*/
|
private findCreateContextMenu(name: string): QContextMenu | undefined {
|
let cmMenu: QContextMenu | undefined;
|
if (this._cmMenuMap.has(name)) {
|
cmMenu = this._cmMenuMap.get(name);
|
} else {
|
cmMenu = new QContextMenu(name);
|
this._cmMenuMap.set(name, cmMenu);
|
}
|
|
return cmMenu;
|
}
|
}
|
|
/**
|
* One or more criteria defining the gantt chart node. To be used when verifying if node(s) fulfills the criteria.
|
* Example: verify number of nodes that are blue in color.
|
*/
|
export interface GanttChartNodeSOPCriteria {
|
ColorHex?: string;
|
}
|
|
// Step description to re-use in spec file to prevent scriptor re-write each time
|
const stepGanttChart = {
|
ensureVisible: (gcName: string, startDate: string): string => `In gantt chart "${gcName}", scroll gantt chart time such that date "${startDate}" is visible.`,
|
rightClickNodeIndexesAndSelectContextMenu: (gcName: string, gcRowTitle: string, indexes: number[], menuLabel: string): string => `In gantt chart "${gcName}" and in row "${gcRowTitle}", right click node(s) with index "${indexes}" and select menu "${menuLabel}".`,
|
rightClickRowAndSelectContextMenu: (gcName: string, gcRowTitle: string, menuLabel: string): string => `In gantt chart "${gcName}", right click row "${gcRowTitle}" and select menu "${menuLabel}".`,
|
verifyNodeExists: (gcName: string, gcRowTitle: string, start: Date, end: Date, nodeColor?: string): string => {
|
const verifyColor = nodeColor ? ` Verify node color = "${nodeColor}".` : '';
|
return `In gantt chart "${gcName}", verify node exists for row = "${gcRowTitle}", start = "${start.toString()}" and end = "${end.toString()}".${verifyColor}`;
|
},
|
verifyNodeValue: (gcName: string, gcRowTitle: string, start: string, end: string, expectedValue: string): string => `In gantt chart "${gcName}", verify node value = ${expectedValue} for row = "${gcRowTitle}", start = "${start}" and end = "${end}".`,
|
verifyNodeContextMenuItemDisabled: (gcName: string, gcRowTitle: string, gcNodeIndex: string, menuLabel: string, tooltip: string): string =>
|
`In gantt chart "${gcName}", verify node at row "${gcRowTitle}" and node index "${gcNodeIndex}" when right clicked, menu item "${menuLabel}" is disabled and shows tooltip "${tooltip}".`,
|
verifyNodeCount: (gcName: string, gcRowTitle: string, expectedNum: number, nodeCriteria?: GanttChartNodeSOPCriteria): string =>
|
`In gantt chart "${gcName}", verify number of nodes in row "${gcRowTitle}" to be "${expectedNum}".${GanttChartSOP.formatStepDescriptionNodeCriteria(nodeCriteria)}`,
|
verifyRowContextMenuItemDisabled: (gcName: string, gcRowTitle: string, label: string, tooltip: string): string =>
|
`In gantt chart "${gcName}", verify when row "${gcRowTitle}" is right clicked, menu item "${label}" is disabled and shows tooltip "${tooltip}".`,
|
verifyRowExists: (gcName: string, rowTitle: string): string => `In gantt chart "${gcName}", verify row "${rowTitle}" exists.`,
|
};
|
|
export { stepGanttChart as StepGanttChart };
|