Skip to content

Commit 07f371e

Browse files
Merge pull request #95 from aquality-automation/feature/tests_for_milestome
Feature/tests for milestome
2 parents 0c013c4 + 586a05b commit 07f371e

File tree

21 files changed

+562
-66
lines changed

21 files changed

+562
-66
lines changed

e2e/api/base.api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class BaseAPI {
1111
this.token = token;
1212
}
1313

14-
public async assertNegativeresponse(promise: Promise<object>, expectedError: string): Promise<void> {
14+
public async assertNegativeResponse(promise: Promise<object>, expectedError: string): Promise<void> {
1515
let atError: ATError;
1616
try {
1717
await promise;

e2e/elements/autocomplete.element.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,9 @@ export class Autocomplete extends BaseElement implements WithSearch {
4444
async isEnabled() {
4545
return !(await this.disabledElement.isPresent());
4646
}
47+
48+
async hasOption(value: string) {
49+
await this.enterValue(value);
50+
return this.findOption(value).isPresent();
51+
}
4752
}

e2e/elements/datepicker.element.ts

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,77 @@
1-
import { ElementFinder, Locator } from 'protractor';
1+
import { ElementFinder, Locator, by } from 'protractor';
22
import { BaseElement } from './base.element';
3+
import { Input } from './input.element';
34

45
export class DatePicker extends BaseElement {
56
constructor(locatorOrElement: Locator | ElementFinder) {
67
super(locatorOrElement);
78
}
9+
monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
10+
'July', 'August', 'September', 'October', 'November', 'December'
11+
];
12+
13+
linkInput = new Input(this.element.element(by.css('.ngx-datepicker-input')));
14+
topBarTitle = this.element.element(by.css('.topbar-title'));
15+
prevMonth = this.element.element(by.id('prevMonth'));
16+
nextMonth = this.element.element(by.id('nextMonth'));
17+
yearButton = (year: number) => this.element
18+
.element(by.xpath(
19+
`.//*[contains(@class, 'main-calendar-years')]//*[contains(@class, 'year-unit') and normalize-space(text())='${year}']`))
20+
dayButton = (day: number) => this.element
21+
.element(by.xpath(
22+
`.//*[contains(@class, 'main-calendar-days')]//*[contains(@class, 'day-unit') and normalize-space(text())='${day}']`))
23+
24+
openCalendar() {
25+
return this.linkInput.click();
26+
}
827

928
async select(date: Date) {
10-
throw new Error('Date Picker is not implemented.');
29+
const selectDate = new Date(date);
30+
const month = this.monthNames[selectDate.getMonth()];
31+
const year = selectDate.getFullYear();
32+
const day = selectDate.getDate();
33+
34+
await this.openCalendar();
35+
await this.selectYear(year);
36+
await this.selectMonth(month);
37+
return this.dayButton(day).click();
38+
}
39+
40+
isEditable(): Promise<boolean> {
41+
return this.linkInput.isPresent();
42+
}
43+
44+
private async selectMonth(month: string): Promise<void> {
45+
for (let i = 0; i < this.monthNames.length; i++) {
46+
const currentMonth = await this.getCurrentMonth();
47+
if (currentMonth !== month) {
48+
if (this.monthNames.indexOf(currentMonth) < this.monthNames.indexOf(month)) {
49+
await this.nextMonth.click();
50+
}
51+
if (this.monthNames.indexOf(currentMonth) > this.monthNames.indexOf(month)) {
52+
await this.prevMonth.click();
53+
}
54+
} else {
55+
return;
56+
}
57+
}
58+
}
59+
60+
private async selectYear(year: number): Promise<void> {
61+
const currentYear = await this.getCurrentYear();
62+
if (currentYear !== year) {
63+
await this.topBarTitle.click();
64+
return this.yearButton(year).click();
65+
}
66+
}
67+
68+
private async getCurrentMonth(): Promise<string> {
69+
const currentMonthYear = await this.topBarTitle.getText();
70+
return currentMonthYear.split(' ')[0];
71+
}
72+
73+
private async getCurrentYear(): Promise<number> {
74+
const currentMonthYear = await this.topBarTitle.getText();
75+
return +currentMonthYear.split(' ')[1];
1176
}
1277
}

e2e/elements/multiselect.element.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { by, Locator, ElementFinder } from 'protractor';
1+
import { by, Locator, ElementFinder, protractor } from 'protractor';
22
import { BaseElement } from './base.element';
33
import { WithSearch } from './interfaces/elementWithSearch';
44

@@ -28,11 +28,17 @@ export class Multiselect extends BaseElement implements WithSearch {
2828

2929
public async select(value: string) {
3030
await this.enterValue(value);
31-
return this.selectOption(value);
31+
await this.selectOption(value);
32+
if (await this.isOpened()) {
33+
return this.search.sendKeys(protractor.Key.ESCAPE);
34+
}
3235
}
3336

34-
public remove(name: string) {
35-
return this.removeMsBox(name).click();
37+
public async remove(name: string) {
38+
await this.removeMsBox(name).click();
39+
if (await this.isOpened()) {
40+
return this.search.sendKeys(protractor.Key.ESCAPE);
41+
}
3642
}
3743

3844
public async isEditable() {
@@ -52,6 +58,10 @@ export class Multiselect extends BaseElement implements WithSearch {
5258
return (await this.disabledElement.getText()).split(', ');
5359
}
5460

61+
private isOpened() {
62+
return this.search.isPresent();
63+
}
64+
5565
private findOption(value: string) {
5666
return this.element.element(by.css(`.selector-suggestions li[title="${value}"]`));
5767
}

e2e/elements/smartTable.element/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ export class SmartTable extends BaseElement {
212212
return rightClick(cell);
213213
}
214214

215-
public async editRow(value: string | boolean, column: string, searchValue: string, searchColumn: string) {
215+
public async editRow(value: string | boolean | Date, column: string, searchValue: string, searchColumn: string) {
216216
const row = await this.getRow(searchValue, searchColumn);
217217
const columnIndex = await this.getColumnIndex(column);
218218
return row.editRowCellValueByColumnIndex(value, columnIndex);

e2e/elements/smartTable.element/row.element.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { logger } from '../../utils/log.util';
99
import { InlineAttach } from '../inlineAttach.element';
1010
import { Multiselect } from '../multiselect.element';
1111
import { Dots } from '../dots.element';
12+
import { DatePicker } from '../datepicker.element';
1213

1314
export class Row extends BaseElement {
1415
constructor(locator: ElementFinder | Locator) {
@@ -60,13 +61,17 @@ export class Row extends BaseElement {
6061
lookup: () => new Lookup(cell.element(by.xpath('.//lookup-colored'))),
6162
inlineAttachment: () => new InlineAttach(cell.element(by.xpath('.//attachment-inline'))),
6263
multiselect: () => new Multiselect(cell.element(by.xpath('.//lookup-autocomplete-multiselect'))),
64+
date: () => new DatePicker(cell.element(by.xpath('.//ng-datepicker'))),
6365
dots: () => new Dots(cell.element(by.xpath('.//app-color-dots')))
6466
};
6567
}
6668

67-
public async editRowCellValueByColumnIndex(value: string | boolean | number, columnIndex: number) {
69+
public async editRowCellValueByColumnIndex(value: string | boolean | number | Date, columnIndex: number) {
6870
const rowElements = await this.getRowElements(columnIndex);
6971
if (await this.isCellContainsEditableElement(columnIndex)) {
72+
if (await rowElements.date().element.isPresent()) {
73+
return rowElements.date().select(new Date(value as Date));
74+
}
7075
if (await rowElements.inlineEditor().element.isPresent()) {
7176
return rowElements.inlineEditor().changeAndSetValue(value as string);
7277
}
@@ -85,6 +90,9 @@ export class Row extends BaseElement {
8590
if (await rowElements.coloredLookup().element.isPresent()) {
8691
return rowElements.coloredLookup().select(value as string);
8792
}
93+
if (await rowElements.multiselect().element.isPresent()) {
94+
return rowElements.multiselect().select(value as string);
95+
}
8896
}
8997

9098
throw new Error(`You are trying to edit not editable ${columnIndex} column!`);
@@ -199,4 +207,5 @@ export class CellElements {
199207
inlineAttachment: () => InlineAttach;
200208
multiselect: () => Multiselect;
201209
dots: () => Dots;
210+
date: () => DatePicker;
202211
}

e2e/elements/ui-switch.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,9 @@ export class UiSwitch extends BaseElement {
2828
return this.element.click();
2929
}
3030
}
31+
32+
async isEnabled() {
33+
const elementClass = await this.element.element(by.tagName('span')).getAttribute('class');
34+
return !elementClass.includes('disabled');
35+
}
3136
}

e2e/pages/milestone/list.po/constants.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ export const names = {
1414

1515
export const columns = {
1616
name: 'Name',
17-
action: 'Action'
17+
action: 'Action',
18+
active: 'Active',
19+
suites: 'Suites',
20+
dueDate: 'Due Date'
1821
};

e2e/pages/milestone/list.po/index.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,30 @@ class MilestoneList extends BasePage {
4646
}
4747

4848
openMilestone(name: string) {
49-
return elements.milestonesTable.clickRow(name, columns.name);
49+
return elements.milestonesTable.clickCell(columns.name, name, columns.name);
50+
}
51+
52+
addMilestoneSuite(suiteName: string, name: string) {
53+
return elements.milestonesTable.editRow(suiteName, columns.suites, name, columns.name);
54+
}
55+
56+
updateMilestoneDueDate(date: Date, name: string) {
57+
return elements.milestonesTable.editRow(date, columns.dueDate, name, columns.name);
58+
}
59+
60+
updateMilestoneActive(value: boolean, name: string) {
61+
return elements.milestonesTable.editRow(value, columns.active, name, columns.name);
5062
}
5163

5264
async isTableEditable(): Promise<boolean> {
5365
const isActionColumnExist = await elements.milestonesTable.isColumnExist(columns.action);
5466
const isRowContainEditableElements = await elements.milestonesTable.isRowEditableByIndex(0);
5567
return isActionColumnExist || isRowContainEditableElements;
5668
}
69+
70+
async isRowEditable(name: string) {
71+
return elements.milestonesTable.isRowEditableByValue(name, columns.name);
72+
}
5773
}
5874

5975
export const milestoneList = new MilestoneList();

e2e/pages/milestone/view.po/constants.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { SmartTable } from '../../../elements/smartTable.element';
33
import { UiSwitch } from '../../../elements/ui-switch';
44
import { ResultPieChart } from '../../../elements/charts/resultPie.element';
55
import { ResolutionPieChart } from '../../../elements/charts/resolution.Pie.element';
6+
import { Multiselect } from '../../../elements/multiselect.element';
7+
import { DatePicker } from '../../../elements/datepicker.element';
68

79
export const baseUrl = (projectId: number, milestoneId: number) => `/project/${projectId}/milestone/${milestoneId}`;
810

@@ -11,7 +13,13 @@ export const elements = {
1113
milestonesTable: new SmartTable(by.id('suite-results')),
1214
distinctTest: new UiSwitch(by.css('#stack-suites ui-switch')),
1315
resultsChart: new ResultPieChart(by.id('finalResultsChart')),
14-
resolutionsChart: new ResolutionPieChart(by.id('resultResolutionsChart'))
16+
resolutionsChart: new ResolutionPieChart(by.id('resultResolutionsChart')),
17+
suites: new Multiselect(by.id('suites')),
18+
notExecutedSuites: element(by.id('not-executed-suites')),
19+
dueDate: new DatePicker(by.id('milestone-due-date')),
20+
warning: element(by.css('#milestone-view fa-icon.warning-icon')),
21+
warningTitle: element(by.css('#milestone-view fa-icon.warning-icon title')),
22+
activeSwitch: new UiSwitch(by.css('#active-switch ui-switch'))
1523
};
1624

1725
export const names = {

0 commit comments

Comments
 (0)