Skip to content

Commit

Permalink
chore(new-ui): implement test steps display in new ui (#599)
Browse files Browse the repository at this point in the history
* feat: implement test steps display in new ui

* fix: fix minor visual glitches and remove console logs

* fix: fix review issues
  • Loading branch information
shadowusr authored Sep 11, 2024
1 parent de93a62 commit 7a7b9b1
Show file tree
Hide file tree
Showing 55 changed files with 19,042 additions and 23,024 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ sqlite.db
.DS_Store
.nyc_output
tmp
**/.testplane

**/playwright-report
hermione-report
Expand Down
4 changes: 2 additions & 2 deletions lib/adapters/test-result/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {TestStatus} from '../../constants';
import {ErrorDetails, ImageBase64, ImageFile, ImageInfoFull, TestError} from '../../types';
import {ErrorDetails, ImageBase64, ImageFile, ImageInfoFull, TestError, TestStepCompressed} from '../../types';

export interface ReporterTestResult {
readonly attempt: number;
Expand All @@ -9,7 +9,7 @@ export interface ReporterTestResult {
readonly errorDetails: ErrorDetails | null;
readonly file: string;
readonly fullName: string;
readonly history: string[];
readonly history: TestStepCompressed[];
readonly id: string;
readonly imageDir: string;
readonly imagesInfo: ImageInfoFull[];
Expand Down
17 changes: 14 additions & 3 deletions lib/adapters/test-result/playwright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
ImageInfoDiff,
ImageInfoFull, ImageInfoNoRef, ImageInfoPageError, ImageInfoPageSuccess, ImageInfoSuccess, ImageInfoUpdated,
ImageSize,
TestError
TestError, TestStepCompressed, TestStepKey
} from '../../types';
import type {CoordBounds} from 'looks-same';

Expand Down Expand Up @@ -153,6 +153,17 @@ const getImageData = (attachment: PlaywrightAttachment | undefined): PlaywrightI
};
};

const getHistory = (steps?: PlaywrightTestResult['steps']): TestStepCompressed[] => {
return steps?.map(step => ({
[TestStepKey.Name]: step.title,
[TestStepKey.Args]: [],
[TestStepKey.IsFailed]: Boolean(step.error),
[TestStepKey.Duration]: step.duration,
[TestStepKey.Children]: getHistory(step.steps),
[TestStepKey.IsGroup]: step.steps?.length > 0
})) ?? [];
};

export class PlaywrightTestResultAdapter implements ReporterTestResult {
private readonly _testCase: PlaywrightTestCase;
private readonly _testResult: PlaywrightTestResult;
Expand Down Expand Up @@ -219,8 +230,8 @@ export class PlaywrightTestResultAdapter implements ReporterTestResult {
return this.testPath.join(DEFAULT_TITLE_DELIMITER);
}

get history(): string[] {
return this._testResult.steps.map(step => `${step.title} <- ${step.duration}ms\n`);
get history(): TestStepCompressed[] {
return getHistory(this._testResult.steps);
}

get id(): string {
Expand Down
4 changes: 2 additions & 2 deletions lib/adapters/test-result/reporter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {TestStatus} from '../../constants';
import {TestError, ErrorDetails, ImageInfoFull, ImageBase64, ImageFile} from '../../types';
import {TestError, ErrorDetails, ImageInfoFull, ImageBase64, ImageFile, TestStepCompressed} from '../../types';
import {ReporterTestResult} from './index';
import _ from 'lodash';
import {extractErrorDetails} from './utils';
Expand Down Expand Up @@ -52,7 +52,7 @@ export class ReporterTestAdapter implements ReporterTestResult {
return this._testResult.fullName;
}

get history(): string[] {
get history(): TestStepCompressed[] {
return this._testResult.history;
}

Expand Down
8 changes: 4 additions & 4 deletions lib/adapters/test-result/sqlite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
ImageInfoFull,
ImageBase64,
ImageFile,
RawSuitesRow
RawSuitesRow, TestStepCompressed
} from '../../types';
import {ReporterTestResult} from './index';
import {Writable} from 'type-fest';
Expand Down Expand Up @@ -76,12 +76,12 @@ export class SqliteTestResultAdapter implements ReporterTestResult {
return this._parsedTestResult.fullName as string;
}

get history(): string[] {
get history(): TestStepCompressed[] {
if (!_.has(this._parsedTestResult, 'history')) {
this._parsedTestResult.history = tryParseJson(this._testResult[DB_COLUMN_INDEXES.history]) as string[];
this._parsedTestResult.history = tryParseJson(this._testResult[DB_COLUMN_INDEXES.history]) as TestStepCompressed[];
}

return this._parsedTestResult.history as string[];
return this._parsedTestResult.history as TestStepCompressed[];
}

get id(): string {
Expand Down
25 changes: 21 additions & 4 deletions lib/adapters/test-result/testplane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type Testplane from 'testplane';
import type {Test as TestplaneTest} from 'testplane';
import {ValueOf} from 'type-fest';

import {getCommandsHistory} from '../../history-utils';
import {ERROR, FAIL, SUCCESS, TestStatus, UNKNOWN_SESSION_ID, UPDATED} from '../../constants';
import {getError, hasUnrelatedToScreenshotsErrors, isImageDiffError, isNoRefImageError, wrapLinkByTag} from '../../common-utils';
import {
Expand All @@ -20,7 +19,7 @@ import {
ImageInfoPageSuccess,
ImageInfoSuccess,
ImageInfoUpdated,
TestError
TestError, TestStepCompressed, TestStepKey
} from '../../types';
import {ReporterTestResult} from './index';
import {getSuitePath} from '../../plugin-utils';
Expand All @@ -47,6 +46,24 @@ const wrapSkipComment = (skipComment: string | null | undefined): string => {
return skipComment ? wrapLinkByTag(skipComment) : 'Unknown reason';
};

const getHistory = (history?: TestplaneTestResult['history']): TestStepCompressed[] => {
return history?.map(h => {
const result: TestStepCompressed = {
[TestStepKey.Name]: h[TestStepKey.Name],
[TestStepKey.Args]: h[TestStepKey.Args],
[TestStepKey.Duration]: h[TestStepKey.Duration],
[TestStepKey.IsFailed]: h[TestStepKey.IsFailed],
[TestStepKey.IsGroup]: h[TestStepKey.IsGroup]
};

if (h[TestStepKey.Children] && h[TestStepKey.IsFailed]) {
result[TestStepKey.Children] = getHistory(h[TestStepKey.Children]);
}

return result;
}) ?? [];
};

export interface TestplaneTestResultAdapterOptions {
attempt: number;
status: TestStatus;
Expand Down Expand Up @@ -163,8 +180,8 @@ export class TestplaneTestResultAdapter implements ReporterTestResult {
return this._attempt;
}

get history(): string[] {
return getCommandsHistory((this._testResult as TestplaneTestResult).history) as string[];
get history(): TestStepCompressed[] {
return getHistory((this._testResult as TestplaneTestResult).history);
}

get error(): undefined | TestError {
Expand Down
1 change: 1 addition & 0 deletions lib/adapters/test/testplane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export class TestplaneTestAdapter implements TestAdapter {
{key: 'meta', value: meta}
].forEach(({key, value}) => {
if (value) {
// @ts-expect-error TODO: fix this assignment.
test[key] = value;
}
});
Expand Down
55 changes: 0 additions & 55 deletions lib/history-utils.js

This file was deleted.

2 changes: 1 addition & 1 deletion lib/plugin-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {TestplaneSuite} from './types';

export const getSuitePath = (suite?: TestplaneSuite): string[] => {
export const getSuitePath = (suite?: TestplaneSuite | null): string[] => {
if (!suite) {
return [];
}
Expand Down
4 changes: 2 additions & 2 deletions lib/sqlite-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import NestedError from 'nested-error-stacks';
import {getShortMD5} from './common-utils';
import {TestStatus, DB_SUITES_TABLE_NAME, SUITES_TABLE_COLUMNS, LOCAL_DATABASE_NAME, DATABASE_URLS_JSON_NAME} from './constants';
import {createTablesQuery} from './db-utils/common';
import type {ImageInfoFull, TestError} from './types';
import type {ImageInfoFull, TestError, TestStepCompressed} from './types';
import {HtmlReporter} from './plugin-api';
import {ReporterTestResult} from './adapters/test-result';
import {DbTestResultTransformer} from './adapters/test-result/transformers/db';
Expand All @@ -33,7 +33,7 @@ interface DeleteParams {
export interface DbTestResult {
description?: string | null;
error?: TestError;
history: string[];
history: TestStepCompressed[];
imagesInfo: ImageInfoFull[];
metaInfo: Record<string, unknown>;
multipleTabs: boolean;
Expand Down
29 changes: 24 additions & 5 deletions lib/static/components/section/body/history/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,36 @@ import Details from '../../../details';

import './index.styl';
import {Card, List} from '@gravity-ui/uikit';
import {TestStepKey} from '@/types';

const History = ({history}) => {
function transformHistoryTreeToNestedArrays(item, level) {
const transformedItem = Object.assign({}, item);
transformedItem[TestStepKey.Name] = `${'\t'.repeat(level)}${transformedItem[TestStepKey.Name]}`;

const stepArgs = transformedItem[TestStepKey.Args];
if (stepArgs && stepArgs.length > 0) {
transformedItem[TestStepKey.Name] += `(${stepArgs.map(arg => `"${arg}"`).join(', ')})`;
}

if (!transformedItem[TestStepKey.Children]) {
return [transformedItem];
}

return [transformedItem].concat(transformedItem[TestStepKey.Children].map(childItem => transformHistoryTreeToNestedArrays(childItem, level + 1)));
}

const flatHistory = history.map(item => transformHistoryTreeToNestedArrays(item, 0)).flat(Infinity);

const renderHistoryItem = (item) => {
const [name, time] = item.split(' <- ');
return (
<div className='history-item'>
<span className='history-item__name'>{name}</span>
<span className='history-item__time'>{time}</span>
<span className='history-item__name'>{item[TestStepKey.Name]}</span>
<span className='history-item__time'>{item[TestStepKey.Duration]} ms</span>
</div>
);
};

return (
isEmpty(history)
? null
Expand All @@ -25,7 +44,7 @@ const History = ({history}) => {
content={
<Card className='details__card' view='filled'>
<div style={{display: `flex`}}>
<List items={history} renderItem={renderHistoryItem} filterable={false} virtualized={false}/>
<List items={flatHistory} renderItem={renderHistoryItem} filterable={false} virtualized={false}/>
</div>
</Card>
}
Expand All @@ -37,7 +56,7 @@ const History = ({history}) => {
History.propTypes = {
resultId: PropTypes.string.isRequired,
// from store
history: PropTypes.arrayOf(PropTypes.string)
history: PropTypes.arrayOf(PropTypes.object)
};

export default connect(({tree}, {resultId}) => {
Expand Down
3 changes: 2 additions & 1 deletion lib/static/modules/action-names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,6 @@ export default {
GROUP_TESTS_BY_KEY: 'GROUP_TESTS_BY_KEY',
TOGGLE_BROWSER_CHECKBOX: 'TOGGLE_BROWSER_CHECKBOX',
SUITES_PAGE_SET_CURRENT_SUITE: 'SUITES_PAGE_SET_CURRENT_SUITE',
SUITES_PAGE_SET_SECTION_EXPANDED: 'SUITES_PAGE_SET_SECTION_EXPANDED'
SUITES_PAGE_SET_SECTION_EXPANDED: 'SUITES_PAGE_SET_SECTION_EXPANDED',
SUITES_PAGE_SET_STEPS_EXPANDED: 'SUITES_PAGE_SET_STEPS_EXPANDED'
} as const;
11 changes: 10 additions & 1 deletion lib/static/modules/actions/suites-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ type SetSectionExpandedStateAction = Action<typeof actionNames.SUITES_PAGE_SET_S
export const setSectionExpandedState = (payload: SetSectionExpandedStateAction['payload']): SetSectionExpandedStateAction =>
({type: actionNames.SUITES_PAGE_SET_SECTION_EXPANDED, payload});

type SetStepsExpandedStateAction = Action<typeof actionNames.SUITES_PAGE_SET_STEPS_EXPANDED, {
resultId: string;
expandedById: Record<string, boolean>;
}>;

export const setStepsExpandedState = (payload: SetStepsExpandedStateAction['payload']): SetStepsExpandedStateAction =>
({type: actionNames.SUITES_PAGE_SET_STEPS_EXPANDED, payload});

export type SuitesPageAction =
| SuitesPageSetCurrentSuiteAction
| SetSectionExpandedStateAction;
| SetSectionExpandedStateAction
| SetStepsExpandedStateAction;
3 changes: 2 additions & 1 deletion lib/static/modules/default-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ export default Object.assign({config: configDefaults}, {
},
ui: {
suitesPage: {
expandedSectionsById: {}
expandedSectionsById: {},
expandedStepsByResultId: {}
}
}
}) satisfies State;
15 changes: 15 additions & 0 deletions lib/static/modules/reducers/suites-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ export default (state: State, action: SuitesPageAction): State => {
}
}) as State;
}
case actionNames.SUITES_PAGE_SET_STEPS_EXPANDED: {
if (!action.payload.resultId) {
return state;
}

return applyStateUpdate(state, {
ui: {
suitesPage: {
expandedStepsByResultId: {
[action.payload.resultId]: action.payload.expandedById
}
}
}
}) as State;
}
default:
return state;
}
Expand Down
3 changes: 3 additions & 0 deletions lib/static/new-ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
--color-link-hover: #818cf8;
--color-bg-dark: #101827;
--color-bg-gray: #eee;

--color-pink-100: #fce0ff;
--color-pink-600: #be00ffbf;
}

.g-root {
Expand Down
12 changes: 6 additions & 6 deletions lib/static/new-ui/components/AttemptPickerItem/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
}

.attempt-picker-item--fail {
--g-button-background-color: #fce0ff;
--g-button-text-color: #bd1993;
--g-button-border-color: #bd1993;
--g-button-background-color: var(--color-pink-100);
--g-button-text-color: var(--color-pink-600);
--g-button-border-color: var(--color-pink-600);
}

.attempt-picker-item--fail_error {
--g-button-background-color: #fce0ff;
--g-button-text-color: #bd1993;
--g-button-border-color: #bd1993;
--g-button-background-color: var(--color-pink-100);
--g-button-text-color: var(--color-pink-600);
--g-button-border-color: var(--color-pink-600);
}

.attempt-picker-item--non-matched {
Expand Down
Loading

0 comments on commit 7a7b9b1

Please sign in to comment.