Skip to content

Commit

Permalink
fix: apply edits
Browse files Browse the repository at this point in the history
  • Loading branch information
KuznetsovRoman committed Jul 17, 2024
1 parent 6b0ca64 commit 4ae6769
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ import {formatCommitPayload} from '../../../modules/static-image-accepter';
import './style.css';

interface Props {
toolName: typeof defaultState['apiValues']['toolName'];
staticImageAccepter: typeof defaultState['staticImageAccepter'];
staticAccepterConfig: typeof defaultState['config']['staticImageAccepter'];
imagesById: typeof defaultState['tree']['images']['byId'];
actions: typeof actions;
}

const StaticAccepterConfirm: React.FC<Props> = ({staticImageAccepter, staticAccepterConfig, imagesById, actions}) => {
const defaultCommitMessage = 'fix: update tests screenshot references';
const StaticAccepterConfirm: React.FC<Props> = ({toolName, staticImageAccepter, staticAccepterConfig, imagesById, actions}) => {
const defaultCommitMessage = `chore: update ${toolName} screenshot references`;
const pullRequestUrl = staticAccepterConfig.pullRequestUrl;
const textAreaRef = useRef<HTMLTextAreaElement>(null);

Expand Down Expand Up @@ -96,11 +97,13 @@ const StaticAccepterConfirm: React.FC<Props> = ({staticImageAccepter, staticAcce

export default connect(
(state: typeof defaultState): Omit<Props, 'actions'> => {
const toolName = state.apiValues.toolName;
const staticImageAccepter = state.staticImageAccepter;
const staticAccepterConfig = state.config.staticImageAccepter;
const imagesById = state.tree.images.byId;

return {
toolName,
staticImageAccepter,
staticAccepterConfig,
imagesById
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import axios from 'axios';
import {isEmpty, difference} from 'lodash';
import {notify, dismissNotification as dismissNotify, POSITIONS} from 'reapop';
import {StaticTestsTreeBuilder} from '../../tests-tree-builder/static';
import actionNames from './action-names';
import {types as modalTypes} from '../components/modals';
import {QUEUED} from '../../constants/test-statuses';
import {DiffModes} from '../../constants/diff-modes';
import {getBlob, getHttpErrorMessage} from './utils';
import {fetchDataFromDatabases, mergeDatabases, connectToDatabase, getMainDatabaseUrl, getSuitesTableRows} from '../../db-utils/client';
import {setFilteredBrowsers} from './query-params';
import plugins from './plugins';
import performanceMarks from '../../constants/performance-marks';
import {storeCommitInLocalStorage} from './static-image-accepter';
import {StaticTestsTreeBuilder} from '../../../tests-tree-builder/static';
import actionNames from '../action-names';
import {types as modalTypes} from '../../components/modals';
import {QUEUED} from '../../../constants/test-statuses';
import {DiffModes} from '../../../constants/diff-modes';
import {getHttpErrorMessage} from '../utils';
import {fetchDataFromDatabases, mergeDatabases, connectToDatabase, getMainDatabaseUrl, getSuitesTableRows} from '../../../db-utils/client';
import {setFilteredBrowsers} from '../query-params';
import plugins from '../plugins';
import performanceMarks from '../../../constants/performance-marks';

export * from './static-accepter';

export const createNotification = (id, status, message, props = {}) => {
const notificationProps = {
Expand Down Expand Up @@ -206,80 +207,6 @@ export const undoAcceptImages = (imageIds, {skipTreeUpdate = false} = {}) => {

export const undoAcceptImage = (imageId, opts) => undoAcceptImages([imageId], opts);

export const staticAccepterDelayScreenshot = (images) => {
return {type: actionNames.STATIC_ACCEPTER_DELAY_SCREENSHOT, payload: images};
};

export const staticAccepterUndoDelayScreenshot = () => {
return {type: actionNames.STATIC_ACCEPTER_UNDO_DELAY_SCREENSHOT};
};

export const staticAccepterStageScreenshot = (images) => {
return {type: actionNames.STATIC_ACCEPTER_STAGE_SCREENSHOT, payload: images};
};

export const staticAccepterUnstageScreenshot = (imageId) => {
return {type: actionNames.STATIC_ACCEPTER_UNSTAGE_SCREENSHOT, payload: {imageId}};
};

export const staticAccepterOpenConfirm = () => openModal({
id: modalTypes.STATIC_ACCEPTER_CONFIRM,
type: modalTypes.STATIC_ACCEPTER_CONFIRM
});

export const staticAccepterCloseConfirm = () => closeModal({id: modalTypes.STATIC_ACCEPTER_CONFIRM});

export const staticAccepterCommitScreenshot = (imagesInfo, {repositoryUrl, pullRequestUrl, serviceUrl, message, axiosRequestOptions = {}, meta}) => {
return async (dispatch) => {
dispatch({type: actionNames.PROCESS_BEGIN});
dispatch(staticAccepterCloseConfirm());

try {
const payload = new FormData();

payload.append('repositoryUrl', repositoryUrl);
payload.append('pullRequestUrl', pullRequestUrl);
payload.append('message', message);

if (!isEmpty(meta)) {
payload.append('meta', JSON.stringify(meta));
}

await Promise.all(imagesInfo.map(async imageInfo => {
const blob = await getBlob(imageInfo.image);

payload.append('image', blob, imageInfo.path);
}));

const response = await axios.post(serviceUrl, payload, axiosRequestOptions);

const commitedImageIds = imagesInfo.map(imageInfo => imageInfo.id);
const commitedImages = imagesInfo.map(imageInfo => ({
imageId: imageInfo.id,
stateNameImageId: imageInfo.stateNameImageId
}));

if (response.status >= 200 && response.status < 400) {
dispatch({type: actionNames.STATIC_ACCEPTER_COMMIT_SCREENSHOT, payload: commitedImageIds});

storeCommitInLocalStorage(commitedImages);
} else {
const errorMessage = [
`Unexpected statuscode from the service: ${response.status}.`,
`Server response: '${response.data}'`
].join('\n');

throw new Error(errorMessage);
}
} catch (e) {
console.error('Error while comitting screenshot:', e);
dispatch(createNotificationError('commitScreenshot', e));
} finally {
dispatch({type: actionNames.PROCESS_END});
}
};
};

export const stopTests = () => async dispatch => {
try {
await axios.post('/stop');
Expand Down
112 changes: 112 additions & 0 deletions lib/static/modules/actions/static-accepter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import axios from 'axios';
import {isEmpty} from 'lodash';
import {types as modalTypes} from '../../components/modals';
import {openModal, closeModal, createNotificationError, createNotification} from './index';
import {getBlob} from '../utils';
import {storeCommitInLocalStorage} from '../static-image-accepter';
import actionNames from '../action-names';
import defaultState from '../default-state';
import type {Action, Dispatch, Store} from './types';
import {ThunkAction} from 'redux-thunk';

type StaticAccepterDelayScreenshotPayload = {imageId: string, stateName: string, stateNameImageId: string}[];
type StaticAccepterDelayScreenshotAction = Action<typeof actionNames.STATIC_ACCEPTER_DELAY_SCREENSHOT, StaticAccepterDelayScreenshotPayload>
export const staticAccepterDelayScreenshot = (images: StaticAccepterDelayScreenshotPayload): StaticAccepterDelayScreenshotAction => {
return {type: actionNames.STATIC_ACCEPTER_DELAY_SCREENSHOT, payload: images} as const;
};

type StaticAccepterUndoDelayScreenshotAction = Action<typeof actionNames.STATIC_ACCEPTER_UNDO_DELAY_SCREENSHOT>;
export const staticAccepterUndoDelayScreenshot = (): StaticAccepterUndoDelayScreenshotAction => {
return {type: actionNames.STATIC_ACCEPTER_UNDO_DELAY_SCREENSHOT};
};

type StaticAccepterStageScreenshotAction = Action<typeof actionNames.STATIC_ACCEPTER_STAGE_SCREENSHOT, string[]>;
export const staticAccepterStageScreenshot = (imageIds: string[]): StaticAccepterStageScreenshotAction => {
return {type: actionNames.STATIC_ACCEPTER_STAGE_SCREENSHOT, payload: imageIds};
};

type StaticAccepterUnstageScreenshotAction = Action<typeof actionNames.STATIC_ACCEPTER_UNSTAGE_SCREENSHOT, {imageId: string}>;
export const staticAccepterUnstageScreenshot = (imageId: string): StaticAccepterUnstageScreenshotAction => {
return {type: actionNames.STATIC_ACCEPTER_UNSTAGE_SCREENSHOT, payload: {imageId}};
};

type StaticAccepterOpenConfirmAction = Action<typeof actionNames.OPEN_MODAL, {
id: typeof modalTypes.STATIC_ACCEPTER_CONFIRM,
type: typeof modalTypes.STATIC_ACCEPTER_CONFIRM
}>;

export const staticAccepterOpenConfirm = (): StaticAccepterOpenConfirmAction => openModal({
id: modalTypes.STATIC_ACCEPTER_CONFIRM,
type: modalTypes.STATIC_ACCEPTER_CONFIRM
});

type StaticAccepterCloseConfirmAction = Action<typeof actionNames.CLOSE_MODAL>;
export const staticAccepterCloseConfirm = (): StaticAccepterCloseConfirmAction => closeModal({id: modalTypes.STATIC_ACCEPTER_CONFIRM});

type StaticAccepterConfig = typeof defaultState['config']['staticImageAccepter'];
type StaticAccepterPayload = {id: string, stateNameImageId: string, image: string, path: string}[];
type StaticAccepterCommitScreenshotOptions = Pick<StaticAccepterConfig, 'repositoryUrl' | 'pullRequestUrl' | 'serviceUrl' | 'axiosRequestOptions' | 'meta'> & {message: string};

type StaticAccepterCommitScreenshotAction = Action<typeof actionNames.STATIC_ACCEPTER_COMMIT_SCREENSHOT, string[]>;
export const staticAccepterCommitScreenshot = (
imagesInfo: StaticAccepterPayload,
{
repositoryUrl,
pullRequestUrl,
serviceUrl,
message,
axiosRequestOptions = {},
meta
}: StaticAccepterCommitScreenshotOptions
): ThunkAction<Promise<void>, Store, void, StaticAccepterCommitScreenshotAction> => {
return async (dispatch: Dispatch) => {
dispatch({type: actionNames.PROCESS_BEGIN});
dispatch(staticAccepterCloseConfirm());

try {
const payload = new FormData();

payload.append('repositoryUrl', repositoryUrl);
payload.append('pullRequestUrl', pullRequestUrl);
payload.append('message', message);

if (!isEmpty(meta)) {
payload.append('meta', JSON.stringify(meta));
}

await Promise.all(imagesInfo.map(async imageInfo => {
const blob = await getBlob(imageInfo.image);

payload.append('image', blob, imageInfo.path);
}));

const response = await axios.post(serviceUrl, payload, axiosRequestOptions);

const commitedImageIds = imagesInfo.map(imageInfo => imageInfo.id);
const commitedImages = imagesInfo.map(imageInfo => ({
imageId: imageInfo.id,
stateNameImageId: imageInfo.stateNameImageId
}));

if (response.status >= 200 && response.status < 400) {
dispatch({type: actionNames.STATIC_ACCEPTER_COMMIT_SCREENSHOT, payload: commitedImageIds});

storeCommitInLocalStorage(commitedImages);

dispatch(createNotification('commitScreenshot', 'success', 'Screenshots were successfully committed'));
} else {
const errorMessage = [
`Unexpected statuscode from the service: ${response.status}.`,
`Server response: '${response.data}'`
].join('\n');

throw new Error(errorMessage);
}
} catch (e) {
console.error('Error while comitting screenshot:', e);
dispatch(createNotificationError('commitScreenshot', e));
} finally {
dispatch({type: actionNames.PROCESS_END});
}
};
};
12 changes: 12 additions & 0 deletions lib/static/modules/actions/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type actionNames from '../action-names';
import type {Action as ReduxAction} from 'redux';
import type defaultState from '../default-state';

export type {Dispatch} from 'redux';

export type Store = typeof defaultState;

export type Action<
Type extends typeof actionNames[keyof typeof actionNames],
Payload = void
> = Payload extends void ? ReduxAction<Type> : ReduxAction<Type> & {payload: Payload};
2 changes: 2 additions & 0 deletions lib/static/modules/default-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {ViewMode} from '../../constants/view-modes';
import {DiffModes} from '../../constants/diff-modes';
import {EXPAND_ERRORS} from '../../constants/expand-modes';
import {RESULT_KEYS} from '../../constants/group-tests';
import {ToolName} from '../../constants';

export default Object.assign({config: configDefaults}, {
gui: true,
Expand Down Expand Up @@ -46,6 +47,7 @@ export default Object.assign({config: configDefaults}, {
},
closeIds: [],
apiValues: {
toolName: ToolName.Testplane,
extraItems: {},
metaInfoExtenders: {}
},
Expand Down
1 change: 0 additions & 1 deletion lib/static/modules/reducers/tree/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ export function resolveUpdatedStatuses(results, imagesById, suites) {
}

/**
*
* @note only one of "(imageIdsArray, newStatus)" or "images" need to be specified
* @param {Object} param0
* @param {{id: String, status: String}[]} param0.images
Expand Down
2 changes: 1 addition & 1 deletion lib/static/modules/reducers/tree/nodes/browsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function calcBrowsersShowness({tree, view, browserIds = [], diff = tree})
const lastResultStatus = getUpdatedProperty(tree, diff, ['results', 'byId', lastResultId, 'status']);

const shouldBeShown = calcBrowserShowness(browser, lastResultStatus, view, diffBrowser);
const checkStatus = shouldBeShown && tree.browsers.stateById[browserId].checkStatus;
const checkStatus = shouldBeShown ? tree.browsers.stateById[browserId].checkStatus : UNCHECKED;

changeBrowserState(tree, browserId, {shouldBeShown, checkStatus}, diff);
});
Expand Down
17 changes: 15 additions & 2 deletions lib/static/modules/reducers/tree/nodes/suites.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import _ from 'lodash';
import {getSuiteResults} from '../../../selectors/tree';
import {isNodeFailed} from '../../../utils';
import {ensureDiffProperty, getUpdatedProperty} from '../../../utils/state';
import {determineFinalStatus, isFailStatus} from '../../../../../common-utils';
import {determineFinalStatus, isErrorStatus, isFailStatus} from '../../../../../common-utils';
import {changeNodeState, getShownCheckedChildCount, shouldNodeBeOpened} from '../helpers';
import {EXPAND_RETRIES} from '../../../../../constants/expand-modes';
import {FAIL} from '../../../../../constants/test-statuses';
Expand Down Expand Up @@ -143,7 +143,7 @@ export function failSuites(tree, suiteIds, diff = tree) {

_.set(diff, ['suites', 'byId', suiteId, 'status'], FAIL);

if (!suite.parentId) {
if (!suite.parentId && !diff.suites.failedRootIds.includes(suite.id)) {
diff.suites.failedRootIds.push(suite.id);
} else {
processingSuiteIds.push(suite.parentId);
Expand Down Expand Up @@ -245,6 +245,9 @@ export function updateParentSuitesStatus(tree, suitesIds = [], filteredBrowsers,
return;
}

diff.suites ||= {};
diff.suites.failedRootIds ||= [].concat(tree.suites.failedRootIds);

const suites = suitesIds.map((id) => tree.suites.byId[id]);
const parentsToUpdate = new Set();

Expand All @@ -257,8 +260,18 @@ export function updateParentSuitesStatus(tree, suitesIds = [], filteredBrowsers,
_.set(diff, ['suites', 'byId', s.id, 'status'], newStatus);

const parentId = getUpdatedProperty(tree, diff, ['suites', 'byId', s.id, 'parentId']);

if (parentId) {
parentsToUpdate.add(parentId);
} else {
const isRootStatusFailed = isErrorStatus(newStatus) || isFailStatus(newStatus);
const isConsideredFailedNow = diff.suites.failedRootIds.includes(s.id);

if (isRootStatusFailed && !isConsideredFailedNow) {
diff.suites.failedRootIds.push(s.id);
} else if (!isRootStatusFailed && isConsideredFailedNow) {
diff.suites.failedRootIds = diff.suites.failedRootIds.filter(id => id !== s.id);
}
}
});

Expand Down
6 changes: 3 additions & 3 deletions lib/static/modules/static-image-accepter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type CommitPayload = Array<{
path: string;
}>

const STATIC_ACCEPTER_PERSISTENT_LOCAL_STORAGE_KEY = 'static-image-accepter';
const STATIC_ACCEPTER_LOCAL_STORAGE_KEY = 'static-image-accepter';

export const checkIsEnabled = (config: ReporterConfig['staticImageAccepter'], isGui: boolean): boolean => {
if (isEnabled !== null) {
Expand Down Expand Up @@ -86,7 +86,7 @@ const getLocalStorageCommitedImages = (): Record<string, string> => {
const date = get(window, ['data', 'date']);
const pathName = get(window, ['location', 'pathname']);

const value = localStorage.getItem(STATIC_ACCEPTER_PERSISTENT_LOCAL_STORAGE_KEY, null) as LocalStorageValue;
const value = localStorage.getItem(STATIC_ACCEPTER_LOCAL_STORAGE_KEY, null) as LocalStorageValue;

if (!value || value.date !== date || value.pathName !== pathName) {
return {};
Expand All @@ -108,7 +108,7 @@ export const storeCommitInLocalStorage = (newCommitedImages: Array<{imageId: str
return acc;
}, {} as Record<string, string>);

localStorage.setItem(STATIC_ACCEPTER_PERSISTENT_LOCAL_STORAGE_KEY, {
localStorage.setItem(STATIC_ACCEPTER_LOCAL_STORAGE_KEY, {
date,
pathName,
commitedImages: {...currentState, ...update}
Expand Down
Loading

0 comments on commit 4ae6769

Please sign in to comment.