Skip to content

Commit 505a873

Browse files
Merge branch 'feature/fix_import_duration' into Bug51-export-creation
2 parents 8fe41f3 + faecf42 commit 505a873

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1129
-168
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# CHANGELOG
22

3+
## 0.3.8 (unreleased)
4+
5+
Features:
6+
- Test Run List: Add posibility to filter by Inactive Milestone -> [View Issue](https://github.com/aquality-automation/aquality-tracking/issues/73)
7+
- Mark import af failed when import is failed -> [View Issue](https://github.com/aquality-automation/aquality-tracking/issues/79)
8+
9+
Bugfixes:
10+
- Test Runs: Fix Filter for No Resolution Column -> [View Issue](https://github.com/aquality-automation/aquality-tracking/issues/22)
11+
- Test Run View: Chart is not updated when user updating results in a bulk -> [View Issue](https://github.com/aquality-automation/aquality-tracking/issues/78)
12+
313
## 0.3.7 (2020-03-02)
414

515
Features:

e2e/api/base.api.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Project } from '../../src/app/shared/models/project';
2+
import { ATError } from '../../src/app/shared/models/error';
3+
import { ApiAssertMessages } from '../specs/api/api.constants';
4+
5+
export class BaseAPI {
6+
project: Project;
7+
token: string;
8+
9+
constructor(project: Project, token: string) {
10+
this.project = project;
11+
this.token = token;
12+
}
13+
14+
public async assertNegativeResponse(promise: Promise<object>, expectedError: string): Promise<void> {
15+
let atError: ATError;
16+
try {
17+
await promise;
18+
} catch (error) {
19+
atError = error;
20+
}
21+
22+
expect(atError).toBeDefined(ApiAssertMessages.errorNotRaised);
23+
expect(atError.message).toBe(expectedError, ApiAssertMessages.errorIsWrong);
24+
}
25+
}

e2e/api/editor.api.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { TestRun } from '../../src/app/shared/models/testRun';
55
import { Milestone } from '../../src/app/shared/models/milestone';
66
import { sendPost, sendGet, sendDelete } from '../utils/aqualityTrackingAPI.util';
77
import { TestResult } from '../../src/app/shared/models/test-result';
8-
import { Project } from '../../src/app/shared/models/project';
8+
import { BaseAPI } from './base.api';
99

1010
enum Endpoints {
1111
suite = '/suite',
@@ -18,14 +18,7 @@ enum Endpoints {
1818
testToSuite = '/testToSuite'
1919
}
2020

21-
export class EditorAPI {
22-
project: Project;
23-
token: string;
24-
25-
constructor(project: Project, token: string) {
26-
this.project = project;
27-
this.token = token;
28-
}
21+
export class EditorAPI extends BaseAPI {
2922

3023
public async createSuite(suite: TestSuite): Promise<TestSuite> {
3124
suite.project_id = this.project.id;

e2e/api/importer.api.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { logger } from '../utils/log.util';
33
import { Project } from '../../src/app/shared/models/project';
44
import { EditorAPI } from './editor.api';
55
import { TestRun } from '../../src/app/shared/models/testRun';
6+
import { BaseAPI } from './base.api';
67

78
export class ImportParams {
89
projectId?: number;
@@ -20,14 +21,11 @@ export enum ImportFormats {
2021

2122
const CHECK_IMPORTED_DELAY = 2000;
2223

23-
export class Importer {
24-
project: Project;
25-
token: string;
24+
export class Importer extends BaseAPI {
2625
editorAPI: EditorAPI;
2726

2827
constructor(project: Project, token: string) {
29-
this.project = project;
30-
this.token = token;
28+
super(project, token);
3129
this.editorAPI = new EditorAPI(this.project, this.token);
3230
}
3331

e2e/api/public.api.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { TestSuite } from '../../src/app/shared/models/testSuite';
2+
import { Test } from '../../src/app/shared/models/test';
3+
import { TestRun } from '../../src/app/shared/models/testRun';
4+
import { sendPost, sendGet } from '../utils/aqualityTrackingAPI.util';
5+
import { TestResult } from '../../src/app/shared/models/test-result';
6+
import { Project } from '../../src/app/shared/models/project';
7+
import { BaseAPI } from './base.api';
8+
9+
enum Endpoints {
10+
suite_create_or_update = '/public/suite/create-or-update',
11+
testrun_start = '/public/testrun/start',
12+
testrun_finish = '/public/testrun/finish',
13+
test_result_start = '/public/test/result/start',
14+
test_result_finish = '/public/test/result/finish',
15+
test_create_or_update = '/public/test/create-or-update'
16+
}
17+
18+
export class PublicAPI extends BaseAPI {
19+
20+
public createOrUpdateSuite(suite: TestSuite): Promise<TestSuite> {
21+
return sendPost(Endpoints.suite_create_or_update, undefined, suite, this.token, this.project.id);
22+
}
23+
24+
public createOrUpdateTest(test: Test): Promise<Test> {
25+
return sendPost(Endpoints.test_create_or_update, undefined, test, this.token, this.project.id);
26+
}
27+
28+
public startTestrun(testrun: TestRun): Promise<TestRun> {
29+
return sendPost(Endpoints.testrun_start, undefined, testrun, this.token, this.project.id);
30+
}
31+
32+
public finishTestRun(project_id: number, id: number) {
33+
return sendGet(Endpoints.testrun_finish, { project_id, id }, this.token, this.project.id);
34+
}
35+
36+
public testResultStart(test_id: number, test_run_id: number, project_id: number) {
37+
return sendGet(Endpoints.test_result_start, { test_id, test_run_id, project_id }, this.token, this.project.id);
38+
}
39+
40+
public testResultFinish(testResult: TestResult): Promise<TestResult> {
41+
return sendPost(Endpoints.test_result_finish, undefined, testResult, this.token, this.project.id);
42+
}
43+
}

e2e/data/import/cucumber.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"result": {
2828
"status": "passed",
29-
"duration": 7033
29+
"duration": 1684328900
3030
}
3131
},
3232
{
@@ -39,7 +39,7 @@
3939
},
4040
"result": {
4141
"status": "passed",
42-
"duration": 86
42+
"duration": 1684328900
4343
}
4444
}
4545
]
@@ -61,7 +61,7 @@
6161
},
6262
"result": {
6363
"status": "passed",
64-
"duration": 7033
64+
"duration": 2667613100
6565
}
6666
},
6767
{
@@ -74,7 +74,7 @@
7474
},
7575
"result": {
7676
"status": "failed",
77-
"duration": 86,
77+
"duration": 2667613100,
7878
"error_message": "step was failed"
7979
}
8080
}
@@ -97,7 +97,7 @@
9797
},
9898
"result": {
9999
"status": "passed",
100-
"duration": 7033
100+
"duration": 2667613100
101101
}
102102
},
103103
{
@@ -110,7 +110,7 @@
110110
},
111111
"result": {
112112
"status": "skipped",
113-
"duration": 86,
113+
"duration": 1684328900,
114114
"error_message": "step was skipped"
115115
}
116116
}

e2e/data/import/cucumberSpecialSymbols.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"result": {
2828
"status": "passed",
29-
"duration": 7033
29+
"duration": 1684328900
3030
}
3131
},
3232
{
@@ -39,7 +39,7 @@
3939
},
4040
"result": {
4141
"status": "passed",
42-
"duration": 86
42+
"duration": 1684328900
4343
}
4444
}
4545
]
@@ -61,7 +61,7 @@
6161
},
6262
"result": {
6363
"status": "passed",
64-
"duration": 7033
64+
"duration": 1684328900
6565
}
6666
},
6767
{
@@ -74,7 +74,7 @@
7474
},
7575
"result": {
7676
"status": "failed",
77-
"duration": 86,
77+
"duration": 1684328900,
7878
"error_message": "step was failed !”#$%&’()*+,-./:;<=>?@[\\]^_`{|}~"
7979
}
8080
}
@@ -97,7 +97,7 @@
9797
},
9898
"result": {
9999
"status": "passed",
100-
"duration": 7033
100+
"duration": 1684328900
101101
}
102102
},
103103
{
@@ -110,7 +110,7 @@
110110
},
111111
"result": {
112112
"status": "skipped",
113-
"duration": 86,
113+
"duration": 1684328900,
114114
"error_message": "step was skipped"
115115
}
116116
}

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
}

0 commit comments

Comments
 (0)