/**
|
* @file S&OP DateTimeSelector component to wrap common methods the team encounter during development
|
* @description DateTimeSelector class extending Abstraction API's QDateTimeSelector.
|
* All S&OP page objects inherit from our own class (inheriting e2e/Abstraction API), but we can propose common methods to them.
|
* @author Clarence (clarence.chan@3ds.com)
|
* @copyright Dassault Systèmes
|
*/
|
import { QDateTimeSelector } from '../e2elib/lib/api/pageobjects/qdatetimeselector.component';
|
import { ElementFinder } from '../e2elib/node_modules/protractor/built';
|
import { UIActionSOP } from './objectsop';
|
import { QUtils } from '../e2elib/lib/src/main/qutils.class';
|
import { QDateTimeOmitOptions } from '../e2elib/lib/api/types';
|
|
export class DateTimeSelectorSOP extends QDateTimeSelector implements UIActionSOP {
|
private readonly _separator = '-';
|
private readonly _omit: QDateTimeOmitOptions; // Hide the datetime portions that are not present for this field in web app
|
|
public constructor(componentPath: string, omit: QDateTimeOmitOptions = {hour: true, minute: true, second: true}, isCustomPath?: boolean, elementObj?: ElementFinder) {
|
super(componentPath, isCustomPath, elementObj);
|
this._omit = omit;
|
}
|
|
public async clickActionLinkText(expectedActionLinkText: string): Promise<void> {
|
const isActionLinkMatch = await this.hasActionLink() && await this.getActionLinkText() === expectedActionLinkText;
|
expect(isActionLinkMatch).toBe(true, `Unable to proceed click action link for datetimeselector ${await this.getComponentLabel()}. Expecting action link text '${expectedActionLinkText}'.`);
|
|
if (isActionLinkMatch) {
|
await this.clickActionLink();
|
}
|
}
|
|
public getDateFromString(value: string): Date {
|
let date = new Date(1899, 11, 31, 0, 0, 0, 0); // This is default Quintiq value if datetime component only shows time
|
let dateOnly = '';
|
if (!this._omit.date) {
|
const dateMatchArr = value.match(new RegExp('(\\d{1,2}-\\w{3}-\\d{4})', 'g'));
|
if (dateMatchArr !== null) {
|
dateOnly = dateMatchArr[0];
|
|
const tokens = dateOnly.split(this._separator);
|
date = new Date(`${tokens[1]} ${tokens[0]}, ${tokens[2]}`); // Format "Jan 1, 2020"
|
}
|
}
|
|
const timeMatchArr = value.match(new RegExp('(\\d{2}:\\d{2}(:\\d{2})?)', 'g'));
|
let timeOnly = '';
|
if (timeMatchArr !== null) {
|
timeOnly = timeMatchArr[0];
|
}
|
|
const timeTokens = timeOnly.split(':');
|
if (!this._omit.hour) {
|
const hourToken = timeTokens.shift();
|
date.setHours(Number(hourToken));
|
}
|
|
if (!this._omit.minute) {
|
const minToken = timeTokens.shift();
|
date.setMinutes(Number(minToken));
|
}
|
|
if (!this._omit.second) {
|
const secToken = timeTokens.shift();
|
date.setSeconds(Number(secToken));
|
}
|
|
return date;
|
}
|
|
/**
|
* Returns the string representation of the datetimeselector for the visible datetime portions only.
|
* Thus not able use Abstraction API getDate/getDateTime methods as that returns Date.
|
* Example: If datetimeselector showing only hours and minutes, we will return only what is visible as string value.
|
*
|
* @returns Full datetime value string that potential to be returned is "1-Jan-2020 14:30:20" (down to the seconds). Or just either the date or time portion as string.
|
*/
|
public async getValueString(): Promise<string> {
|
let dateStr = '';
|
// If field showing date, format the date str with format "1-Jan-2020"
|
if (!this._omit.date) {
|
const day = (await this.getDay()).padStart(2, '0');
|
const month = await this.getMonth();
|
const year = await this.getYear();
|
dateStr = `${day}${this._separator}${month}${this._separator}${year}`;
|
}
|
|
// If field showing any time portions, format the string value
|
let timeStr = '';
|
if (!this._omit.hour) {
|
timeStr = timeStr + (await this.getHour()).padStart(2, '0');
|
}
|
|
if (!this._omit.minute) {
|
if (timeStr !== '') {
|
timeStr = `${timeStr }:`;
|
}
|
|
timeStr = timeStr + (await this.getMinute()).padStart(2, '0');
|
}
|
|
if (!this._omit.second) {
|
if (timeStr !== '') {
|
timeStr = `${timeStr }:`;
|
}
|
|
timeStr = timeStr + (await this.getSecond()).padStart(2, '0');
|
}
|
|
// Format the final string to return (either both date+time available, or only one of them).
|
const spaceBetweenDateAndTime = (dateStr !== '' && timeStr !== '') ? ' ' : ''; // If both date+time available, put a space between them.
|
const finalDateStr = `${dateStr}${spaceBetweenDateAndTime}${timeStr}`;
|
|
return finalDateStr;
|
}
|
|
public async setValue(value: string): Promise<void> {
|
// Convert user input string into Date object
|
const dateTime: Date = this.getDateFromString(value);
|
|
// Send the Date object into Abstraction API method which knows how to fill in our datetimeselector in web app
|
await this.setDateTime(dateTime, this._omit);
|
}
|
|
public async toggleValue(): Promise<void> {
|
const previousDateValue = await this.getValueString();
|
const previousDate = this.getDateFromString(previousDateValue);
|
previousDate.setDate(previousDate.getDate() + 1);
|
previousDate.setHours(previousDate.getHours() + 1);
|
previousDate.setMinutes (previousDate.getMinutes() + 1);
|
previousDate.setSeconds(previousDate.getSeconds() + 1);
|
await this.setDateTime(previousDate, this._omit);
|
}
|
|
public async verifyBatchEditEnabled(expectedEnable: boolean, expectedActionLinkText: string): Promise<void> {
|
const isBatchEditEnableDisableOK = await this.hasActionLink() &&
|
await this.getActionLinkText() === expectedActionLinkText &&
|
!await this.isDisabled() === expectedEnable;
|
expect(isBatchEditEnableDisableOK).toBe(true, `Verify datetimeselector ${await this.getComponentLabel()} supports batch edit (expected enable = ${expectedEnable} & action link = ${expectedActionLinkText}).`);
|
}
|
|
public async verifyHasMaskError(expectedValue: boolean): Promise<void> {
|
// Implements UIActionSOP
|
await this.hasMaskError(expectedValue);
|
}
|
|
public async verifyTooltip(expectedValue: string): Promise<void> {
|
const tooltip = await QUtils.getTooltip(this.tooltipLabelElement, true, true, true);
|
expect(tooltip).toBe(expectedValue, `Hover ${await this.getComponentLabel()} to verify tooltip.`);
|
}
|
|
public async verifyEnabled(expectedEnable: boolean): Promise<void> {
|
expect(!await this.isDisabled()).toBe(expectedEnable, `Verify enable state for datetimeselector ${await this.getComponentLabel()}.`);
|
}
|
|
public async verifyValue(expectedValue: string): Promise<void> {
|
const actualDate = await this.getDateTime(); // Get Date object from the datetimeselector component in web app
|
const expectedDate = this.getDateFromString(expectedValue); // Get Date object from user expected string
|
|
// Cannot direct compare Dates, use valueOf which returns the primitive underlying value such as 823230245000
|
const datesEqual = actualDate.valueOf() === expectedDate.valueOf();
|
expect(datesEqual).toBe(true, `Verify value fail for datetimeselector ${await this.getComponentLabel()}. Expected = ${expectedValue}, actual = ${await this.getValueString()}.`);
|
}
|
|
public async verifyVisible(expectedValue: string): Promise<void> {
|
expect(await this.isVisible()).toBe(expectedValue.toLowerCase() === 'true', `Verify visible state for datetimeselector ${await this.getComponentLabel()}.`);
|
}
|
}
|