Skip to content

Commit f1a7b7e

Browse files
authored
feat: add ability to sort by duration and start time (#623)
* feat: add ability to sort by duration and start time * fix: display average time, use duration field for testplane tests * test: implement unit tests for tree sorting * test: fix tests after modifying tree builder helpers and fix review issues
1 parent a8428a5 commit f1a7b7e

File tree

31 files changed

+1462
-489
lines changed

31 files changed

+1462
-489
lines changed

lib/adapters/test-result/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export interface ReporterTestResult {
2121
readonly state: { name: string };
2222
readonly status: TestStatus;
2323
readonly testPath: string[];
24+
/** Test start timestamp in ms */
2425
readonly timestamp: number | undefined;
2526
readonly url?: string;
27+
/** Test duration in ms */
28+
readonly duration: number;
2629
}

lib/adapters/test-result/playwright.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,4 +364,8 @@ export class PlaywrightTestResultAdapter implements ReporterTestResult {
364364

365365
return _.groupBy(imageAttachments, a => a.name.replace(ANY_IMAGE_ENDING_REGEXP, ''));
366366
}
367+
368+
get duration(): number {
369+
return this._testResult.duration;
370+
}
367371
}

lib/adapters/test-result/reporter.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,8 @@ export class ReporterTestAdapter implements ReporterTestResult {
107107
get url(): string | undefined {
108108
return this._testResult.url;
109109
}
110+
111+
get duration(): number {
112+
return this._testResult.duration;
113+
}
110114
}

lib/adapters/test-result/sqlite.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,8 @@ export class SqliteTestResultAdapter implements ReporterTestResult {
151151
get url(): string | undefined {
152152
return this._testResult[DB_COLUMN_INDEXES.suiteUrl];
153153
}
154+
155+
get duration(): number {
156+
return this._testResult[DB_COLUMN_INDEXES.duration];
157+
}
154158
}

lib/adapters/test-result/testplane.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,16 @@ const getHistory = (history?: TestplaneTestResult['history']): TestStepCompresse
7373
export interface TestplaneTestResultAdapterOptions {
7474
attempt: number;
7575
status: TestStatus;
76+
duration: number;
7677
}
7778

7879
export class TestplaneTestResultAdapter implements ReporterTestResult {
7980
private _testResult: TestplaneTest | TestplaneTestResult;
8081
private _errorDetails: ErrorDetails | null;
81-
private _timestamp: number | undefined;
82+
private _timestamp: number;
8283
private _attempt: number;
8384
private _status: TestStatus;
85+
private _duration: number;
8486

8587
static create(
8688
this: new (testResult: TestplaneTest | TestplaneTestResult, options: TestplaneTestResultAdapterOptions) => TestplaneTestResultAdapter,
@@ -90,18 +92,20 @@ export class TestplaneTestResultAdapter implements ReporterTestResult {
9092
return new this(testResult, options);
9193
}
9294

93-
constructor(testResult: TestplaneTest | TestplaneTestResult, {attempt, status}: TestplaneTestResultAdapterOptions) {
95+
constructor(testResult: TestplaneTest | TestplaneTestResult, {attempt, status, duration}: TestplaneTestResultAdapterOptions) {
9496
this._testResult = testResult;
9597
this._errorDetails = null;
96-
this._timestamp = (this._testResult as TestplaneTestResult).timestamp ??
97-
(this._testResult as TestplaneTestResult).startTime ?? Date.now();
98+
this._timestamp = (this._testResult as TestplaneTestResult).startTime
99+
?? (this._testResult as TestplaneTestResult).timestamp
100+
?? Date.now();
98101
this._status = status;
99102

100103
const browserVersion = _.get(this._testResult, 'meta.browserVersion', this._testResult.browserVersion);
101104

102105
_.set(this._testResult, 'meta.browserVersion', browserVersion);
103106

104107
this._attempt = attempt;
108+
this._duration = duration;
105109
}
106110

107111
get fullName(): string {
@@ -259,7 +263,11 @@ export class TestplaneTestResultAdapter implements ReporterTestResult {
259263

260264
set timestamp(timestamp) {
261265
if (!_.isNumber(this._timestamp)) {
262-
this._timestamp = timestamp;
266+
this._timestamp = timestamp ?? 0;
263267
}
264268
}
269+
270+
get duration(): number {
271+
return this._duration;
272+
}
265273
}

lib/adapters/test-result/transformers/db.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ export class DbTestResultTransformer {
3838
screenshot: Boolean(testResult.screenshot),
3939
multipleTabs: testResult.multipleTabs,
4040
status: testResult.status,
41-
timestamp: testResult.timestamp ?? Date.now()
41+
timestamp: testResult.timestamp ?? Date.now(),
42+
duration: testResult.duration
4243
};
4344
}
4445
}

lib/adapters/test-result/utils/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export const copyAndUpdate = (
3131
'status',
3232
'testPath',
3333
'timestamp',
34-
'url'
34+
'url',
35+
'duration'
3536
] as const;
3637

3738
// Type-level check that we didn't forget to include any keys

lib/adapters/test/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ export interface CreateTestResultOpts {
1010
sessionId?: string;
1111
meta?: {
1212
url?: string;
13-
}
13+
};
14+
duration: number;
1415
}
1516

1617
export interface TestAdapter {

lib/adapters/test/testplane.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class TestplaneTestAdapter implements TestAdapter {
5353
}
5454

5555
createTestResult(opts: CreateTestResultOpts): ReporterTestResult {
56-
const {status, assertViewResults, error, sessionId, meta, attempt = UNKNOWN_ATTEMPT} = opts;
56+
const {status, assertViewResults, error, sessionId, meta, attempt = UNKNOWN_ATTEMPT, duration} = opts;
5757
const test = this._test.clone();
5858

5959
[
@@ -68,7 +68,7 @@ export class TestplaneTestAdapter implements TestAdapter {
6868
}
6969
});
7070

71-
return TestplaneTestResultAdapter.create(test, {attempt, status});
71+
return TestplaneTestResultAdapter.create(test, {attempt, status, duration});
7272
}
7373
}
7474

lib/constants/database.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export const DB_COLUMNS = {
1414
SCREENSHOT: 'screenshot',
1515
MULTIPLE_TABS: 'multipleTabs',
1616
STATUS: 'status',
17-
TIMESTAMP: 'timestamp'
17+
TIMESTAMP: 'timestamp',
18+
DURATION: 'duration'
1819
} as const;
1920

2021
export const SUITES_TABLE_COLUMNS = [
@@ -31,7 +32,8 @@ export const SUITES_TABLE_COLUMNS = [
3132
{name: DB_COLUMNS.SCREENSHOT, type: DB_TYPES.int}, //boolean - 0 or 1
3233
{name: DB_COLUMNS.MULTIPLE_TABS, type: DB_TYPES.int}, //boolean - 0 or 1
3334
{name: DB_COLUMNS.STATUS, type: DB_TYPES.text},
34-
{name: DB_COLUMNS.TIMESTAMP, type: DB_TYPES.int}
35+
{name: DB_COLUMNS.TIMESTAMP, type: DB_TYPES.int},
36+
{name: DB_COLUMNS.DURATION, type: DB_TYPES.int}
3537
] as const;
3638

3739
export const DB_MAX_AVAILABLE_PAGE_SIZE = 65536; // helps to speed up queries
@@ -55,7 +57,7 @@ interface DbColumnIndexes {
5557
[DB_COLUMNS.MULTIPLE_TABS]: 11,
5658
[DB_COLUMNS.STATUS]: 12,
5759
[DB_COLUMNS.TIMESTAMP]: 13,
58-
60+
[DB_COLUMNS.DURATION]: 14,
5961
}
6062

6163
export const DB_COLUMN_INDEXES = SUITES_TABLE_COLUMNS.reduce((acc: Record<string, number>, {name}, index) => {

0 commit comments

Comments
 (0)