From ce2ee2ba9b16a18413a7ee474a4efed561de1f60 Mon Sep 17 00:00:00 2001 From: Ivan Kabir Date: Mon, 22 Jul 2024 14:09:24 +0300 Subject: [PATCH] chore: add linter & fix errors --- .../components/bottom-progress-bar/index.jsx | 6 ++ lib/static/components/bullet.jsx | 3 +- .../controls/accept-opened-button.jsx | 6 +- .../controls/browser-list/index.jsx | 93 +++++++++---------- .../components/controls/common-controls.jsx | 34 ++++--- .../components/controls/common-filters.jsx | 26 +++++- .../controls/custom-gui-controls.jsx | 13 +++ .../controls/find-same-diffs-button.jsx | 3 +- .../components/controls/gui-controls.jsx | 3 +- lib/static/components/controls/menu-bar.jsx | 5 +- .../components/controls/report-info.jsx | 6 ++ .../components/controls/run-button/index.jsx | 21 ++--- .../components/controls/selects/control.jsx | 12 +-- .../controls/selects/group-tests.jsx | 16 +--- .../components/controls/selects/label.jsx | 15 ++- .../controls/show-checkboxes-input.jsx | 3 +- .../controls/strict-match-filter-input.jsx | 3 +- .../controls/test-name-filter-input.jsx | 2 +- lib/static/components/custom-scripts.jsx | 9 +- lib/static/components/extension-point.jsx | 3 +- lib/static/components/group-tests/item.jsx | 1 + lib/static/components/group-tests/list.jsx | 3 +- lib/static/components/gui.jsx | 4 +- .../components/header/summary/dbBtn.jsx | 9 +- .../components/header/summary/index.jsx | 7 +- .../icons/view-in-browser/index.jsx | 5 +- lib/static/components/loading.jsx | 3 +- lib/static/components/modals/modal.jsx | 16 +++- .../modals/screenshot-accepter/header.jsx | 8 +- .../modals/screenshot-accepter/index.jsx | 18 ++-- lib/static/components/popup/index.jsx | 3 +- lib/static/components/progress-bar/index.jsx | 11 ++- lib/static/components/report.jsx | 3 +- lib/static/components/section/body/index.jsx | 3 +- .../section/body/meta-info/index.jsx | 3 +- .../components/section/section-browser.jsx | 4 +- .../components/section/section-common.jsx | 3 +- .../section/title/browser-skipped.jsx | 3 +- .../components/section/title/browser.jsx | 7 +- .../components/section/title/simple.jsx | 3 +- lib/static/components/state/error-details.jsx | 2 +- lib/static/components/state/index.jsx | 20 +++- .../components/state/screenshot/full.jsx | 3 +- .../components/state/screenshot/resized.jsx | 4 +- lib/static/components/state/state-error.jsx | 22 ++--- .../components/state/state-fail/index.jsx | 11 ++- lib/static/components/sticky-header/index.jsx | 5 + lib/static/components/suites.jsx | 9 +- lib/static/containers/array/index.jsx | 6 +- lib/static/containers/modal.jsx | 3 +- package.json | 2 +- test/func/packages/basic/lib/color-border.jsx | 7 +- .../redux-with-server/lib/color-border.jsx | 11 ++- test/func/packages/redux/lib/color-border.jsx | 10 +- .../controls/browser-list/index.jsx | 4 +- .../static/components/controls/run-button.jsx | 14 +-- .../controls/show-checkboxes-input.jsx | 1 - .../controls/strict-match-filter-input.jsx | 1 - .../modals/screenshot-accepter/index.jsx | 3 + .../components/section/body/history.jsx | 2 +- .../components/section/title/browser.jsx | 2 +- .../components/section/title/simple.jsx | 4 +- .../static/components/state/state-error.jsx | 4 +- test/unit/lib/static/components/suites.jsx | 2 +- test/unit/lib/static/components/utils.jsx | 2 +- 65 files changed, 348 insertions(+), 205 deletions(-) diff --git a/lib/static/components/bottom-progress-bar/index.jsx b/lib/static/components/bottom-progress-bar/index.jsx index ff0fae95d..77498bd68 100644 --- a/lib/static/components/bottom-progress-bar/index.jsx +++ b/lib/static/components/bottom-progress-bar/index.jsx @@ -2,6 +2,7 @@ import {extend, isNumber} from 'lodash'; import React from 'react'; +import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import {getVisibleRootSuiteIds} from '../../modules/selectors/tree'; @@ -34,6 +35,11 @@ const BottomProgressBar = (props) => { ); }; +BottomProgressBar.propTypes = { + progressBar: PropTypes.object.isRequired, + visibleRootSuiteIds: PropTypes.arrayOf(PropTypes.number) +}; + export default connect( (state) => ({ progressBar: state.progressBar, diff --git a/lib/static/components/bullet.jsx b/lib/static/components/bullet.jsx index cb303d582..a937f4f61 100644 --- a/lib/static/components/bullet.jsx +++ b/lib/static/components/bullet.jsx @@ -31,7 +31,8 @@ const Bullet = ({status, onClick, className}) => { Bullet.propTypes = { status: PropTypes.oneOf([CHECKED, UNCHECKED, INDETERMINATE]), onClick: PropTypes.func, - bulletClassName: PropTypes.string + bulletClassName: PropTypes.string, + className: PropTypes.string }; export default Bullet; diff --git a/lib/static/components/controls/accept-opened-button.jsx b/lib/static/components/controls/accept-opened-button.jsx index 269441624..376912a03 100644 --- a/lib/static/components/controls/accept-opened-button.jsx +++ b/lib/static/components/controls/accept-opened-button.jsx @@ -11,7 +11,9 @@ class AcceptOpenedButton extends Component { isSuiteContol: PropTypes.bool, // from store processing: PropTypes.bool.isRequired, - acceptableOpenedImageIds: PropTypes.arrayOf(PropTypes.string).isRequired + acceptableOpenedImageIds: PropTypes.arrayOf(PropTypes.string).isRequired, + isStaticImageAccepterEnabled: PropTypes.bool, + actions: PropTypes.object.isRequired }; _acceptOpened = () => { @@ -39,7 +41,7 @@ export default connect( return { processing: state.processing, acceptableOpenedImageIds: getAcceptableOpenedImageIds(state), - isStaticImageAccepterEnabled: state.staticImageAccepter.enabled, + isStaticImageAccepterEnabled: state.staticImageAccepter.enabled }; }, (dispatch) => ({actions: bindActionCreators(actions, dispatch)}) diff --git a/lib/static/components/controls/browser-list/index.jsx b/lib/static/components/controls/browser-list/index.jsx index a8ee3f6b0..6fce2df2e 100644 --- a/lib/static/components/controls/browser-list/index.jsx +++ b/lib/static/components/controls/browser-list/index.jsx @@ -1,52 +1,47 @@ 'use strict'; -import React, {useState, useMemo, useEffect, useCallback} from 'react'; -import {flatten, isEmpty, get, chain, compact} from 'lodash'; +import React, {useState, useMemo, useEffect} from 'react'; +import {compact} from 'lodash'; import PropTypes from 'prop-types'; -import CheckboxTree from 'react-checkbox-tree'; import {mkBrowserIcon, buildComplexId} from './utils'; -import Popup from '../../popup'; -import ArrayContainer from '../../../containers/array'; import 'react-checkbox-tree/lib/react-checkbox-tree.css'; import './index.styl'; -import { Button, Select, useSelectOptions } from '@gravity-ui/uikit'; +import {Button, Select, useSelectOptions} from '@gravity-ui/uikit'; const BrowserList = ({available, onChange, selected: selectedProp}) => { const getOptions = () => { const groups = {}; - const DEFAULT_GROUP = "other"; + const DEFAULT_GROUP = 'other'; let hasNestedOptions = false; available.forEach(({id: browserId, versions}) => { if (!versions || versions.length < 2) { groups[DEFAULT_GROUP] = groups[DEFAULT_GROUP] || []; - groups[DEFAULT_GROUP].push({value: buildComplexId(browserId), + groups[DEFAULT_GROUP].push({value: buildComplexId(browserId), content:
{mkBrowserIcon(browserId)}{buildComplexId(browserId)}
}); return; } hasNestedOptions = true; versions.forEach((version) => { groups[browserId] = groups[browserId] || []; - groups[browserId].push({value: buildComplexId(browserId, version), + groups[browserId].push({value: buildComplexId(browserId, version), content:
{mkBrowserIcon(browserId)}{buildComplexId(browserId, version)}
}); - }) + }); }); if (!hasNestedOptions) { return groups[DEFAULT_GROUP]; - } - else { + } else { const optionsList = []; Object.keys(groups).forEach((name) => { optionsList.push({ label: name, options: groups[name] - }) - }) + }); + }); return optionsList; } - - } + }; const getMapping = () => { const mapping = {}; available.forEach(({id: browserId, versions}) => { @@ -60,10 +55,10 @@ const BrowserList = ({available, onChange, selected: selectedProp}) => { } versions.forEach((version) => { mapping[buildComplexId(browserId, version)] = {id: browserId, version}; - }) + }); }); return mapping; - } + }; const getSelected = () => { const selectedOptions = []; if (!selectedProp || !selectedProp.length) { @@ -76,23 +71,22 @@ const BrowserList = ({available, onChange, selected: selectedProp}) => { } versions.forEach((version) => { selectedOptions.push(buildComplexId(browserId, version)); - }) + }); }); return selectedOptions; - } + }; const rawOptions = useMemo(getOptions, [available]); const getOptionsFrom = (optionsData) => { const allOptionsList = []; optionsData.forEach((option) => { if (option.label) { getOptionsFrom(option.options).forEach((o) => allOptionsList.push(o)); - } - else { + } else { allOptionsList.push(option.value); } - }) + }); return allOptionsList; - } + }; const allOptions = useMemo(() => getOptionsFrom(rawOptions), [rawOptions]); const options = useSelectOptions({ options: rawOptions @@ -102,52 +96,53 @@ const BrowserList = ({available, onChange, selected: selectedProp}) => { const selectAll = () => { setSelected(allOptions); - } + }; const formatSelectedData = () => { - const selectedData = {} + const selectedData = {}; selected.forEach((option) => { - if (!mapping[option] || !mapping[option].id) return; + if (!mapping[option] || !mapping[option].id) { + return; + } const {id: browserId, version} = mapping[option]; selectedData[browserId] = selectedData[browserId] || []; selectedData[browserId].push(version); - }) - return Object.entries(selectedData).map(([id, versions]) => ({id, versions: compact(versions)})) - } + }); + return Object.entries(selectedData).map(([id, versions]) => ({id, versions: compact(versions)})); + }; const renderFilter = () => { - const allSelected = selected.length == options.length; return (
- +
- ) - } + ); + }; const renderOption = (option) => { - const isTheOnlySelected = selected.includes(option.value) && selected.length == 1; + const isTheOnlySelected = selected.includes(option.value) && selected.length === 1; const selectOnly = (e) => { e.preventDefault(); e.stopPropagation(); setSelected([option.value]); - } + }; const selectExcept = (e) => { e.preventDefault(); e.stopPropagation(); - setSelected(allOptions.filter(o => o != option.value)); - } + setSelected(allOptions.filter(o => o !== option.value)); + }; return ( -
-
- {option.content} +
+
+ {option.content} +
+
- -
- ) - } - + ); + }; + useEffect(() => { onChange && onChange(formatSelectedData(selected)); }, [selected]); @@ -166,8 +161,8 @@ const BrowserList = ({available, onChange, selected: selectedProp}) => { popupClassName='browserlist__popup' className='browserlist' /> - ) -} + ); +}; BrowserList.propTypes = { available: PropTypes.arrayOf(PropTypes.shape({ diff --git a/lib/static/components/controls/common-controls.jsx b/lib/static/components/controls/common-controls.jsx index e0d02e111..566cceed1 100644 --- a/lib/static/components/controls/common-controls.jsx +++ b/lib/static/components/controls/common-controls.jsx @@ -1,9 +1,9 @@ import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; -import {capitalize, pull} from 'lodash'; +import {capitalize} from 'lodash'; import * as actions from '../../modules/actions'; -import ControlButton from './control-button'; import ControlSelect from './selects/control'; import GroupTestsSelect from './selects/group-tests'; import BaseHostInput from './base-host-input'; @@ -12,9 +12,19 @@ import ReportInfo from './report-info'; import {ViewMode} from '../../../constants/view-modes'; import {DiffModes} from '../../../constants/diff-modes'; import {EXPAND_ALL, COLLAPSE_ALL, EXPAND_ERRORS, EXPAND_RETRIES} from '../../../constants/expand-modes'; -import { RadioButton, Select } from '@gravity-ui/uikit'; class ControlButtons extends Component { + static propTypes = { + view: PropTypes.shape({ + expand: PropTypes.string.isRequired, + viewMode: PropTypes.string.isRequired, + diffMode: PropTypes.string.isRequired, + changeViewMode: PropTypes.func.isRequired + }), + isStatisImageAccepterEnabled: PropTypes.bool, + actions: PropTypes.object.isRequired + }; + _onUpdateExpand = (value) => { const {actions} = this.props; const actionsDict = { @@ -22,10 +32,10 @@ class ControlButtons extends Component { [COLLAPSE_ALL]: actions.collapseAll, [EXPAND_ERRORS]: actions.expandErrors, [EXPAND_RETRIES]: actions.expandRetries - } + }; actionsDict[value].call(); - } - + }; + _getShowTestsOptions() { const viewModes = Object.values(ViewMode).map(value => ({value, content: capitalize(value)})); @@ -46,17 +56,17 @@ class ControlButtons extends Component { handler={actions.changeViewMode} options = {this._getShowTestsOptions()} /> - { const onCommitChanges = () => { props.actions.staticAccepterOpenConfirm(); - } + }; const renderStaticImageAccepterControls = () => { const {staticImageAccepter} = props; @@ -34,8 +36,8 @@ const CommonFilters = (props) => { handler={onCommitChanges} />
- ) - } + ); + }; return (
@@ -50,14 +52,28 @@ const CommonFilters = (props) => { {renderStaticImageAccepterControls()}
); -} +}; + +CommonFilters.propTypes = { + gui: PropTypes.bool.isRequired, + browsers: PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.string, + versions: PropTypes.arrayOf(PropTypes.string) + })).isRequired, + filteredBrowsers: PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.string, + versions: PropTypes.arrayOf(PropTypes.string) + })), + staticImageAccepter: staticImageAccepterPropType, + actions: PropTypes.object.isRequired +}; export default connect( ({view, browsers, gui, staticImageAccepter}) => ({ filteredBrowsers: view.filteredBrowsers, browsers, gui, - staticImageAccepter, + staticImageAccepter }), (dispatch) => ({actions: bindActionCreators(actions, dispatch)}) )(CommonFilters); diff --git a/lib/static/components/controls/custom-gui-controls.jsx b/lib/static/components/controls/custom-gui-controls.jsx index ab5a9f03e..f9eeb0990 100644 --- a/lib/static/components/controls/custom-gui-controls.jsx +++ b/lib/static/components/controls/custom-gui-controls.jsx @@ -1,6 +1,7 @@ 'use strict'; import React, {PureComponent} from 'react'; +import PropTypes from 'prop-types'; import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; import {isEmpty, map} from 'lodash'; @@ -9,6 +10,18 @@ import {Button} from 'semantic-ui-react'; import * as actions from '../../modules/actions'; class CustomGuiControls extends PureComponent { + static propTypes = { + actions: PropTypes.object.isRequired, + customGui: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.shape({ + type: PropTypes.string, + controls: PropTypes.arrayOf(PropTypes.shape({ + label: PropTypes.string, + value: PropTypes.string, + active: PropTypes.bool + })) + }))).isRequired + }; + _renderButtons(opts) { const {sectionName, groupIndex, controls} = opts; const {actions} = this.props; diff --git a/lib/static/components/controls/find-same-diffs-button.jsx b/lib/static/components/controls/find-same-diffs-button.jsx index fe8eeb905..f2daf645f 100644 --- a/lib/static/components/controls/find-same-diffs-button.jsx +++ b/lib/static/components/controls/find-same-diffs-button.jsx @@ -14,7 +14,8 @@ class FindSameDiffsButton extends Component { isDisabled: PropTypes.bool.isRequired, // from store browserName: PropTypes.string.isRequired, - failedOpenedImageIds: PropTypes.arrayOf(PropTypes.string).isRequired + failedOpenedImageIds: PropTypes.arrayOf(PropTypes.string).isRequired, + actions: PropTypes.object.isRequired }; _findSameDiffs = () => { diff --git a/lib/static/components/controls/gui-controls.jsx b/lib/static/components/controls/gui-controls.jsx index 77534982d..6cb3b395a 100644 --- a/lib/static/components/controls/gui-controls.jsx +++ b/lib/static/components/controls/gui-controls.jsx @@ -16,7 +16,8 @@ class GuiControls extends Component { static propTypes = { // from store running: PropTypes.bool.isRequired, - stopping: PropTypes.bool.isRequired + stopping: PropTypes.bool.isRequired, + actions: PropTypes.object.isRequired }; render() { diff --git a/lib/static/components/controls/menu-bar.jsx b/lib/static/components/controls/menu-bar.jsx index 72d323be6..31eea1a5e 100644 --- a/lib/static/components/controls/menu-bar.jsx +++ b/lib/static/components/controls/menu-bar.jsx @@ -3,12 +3,11 @@ import React, {Component} from 'react'; import {connect} from 'react-redux'; import PropTypes from 'prop-types'; -import {Dropdown} from 'semantic-ui-react'; import {isEmpty} from 'lodash'; import ExtensionPoint from '../extension-point'; import * as plugins from '../../modules/plugins'; import {MENU_BAR} from '../../../constants/extension-points'; -import { Button, DropdownMenu, Icon, Menu } from '@gravity-ui/uikit'; +import {Button, DropdownMenu, Icon, Menu} from '@gravity-ui/uikit'; import {Bars} from '@gravity-ui/icons'; import classNames from 'classnames'; @@ -37,7 +36,7 @@ class MenuBar extends Component {
( )}> diff --git a/lib/static/components/controls/report-info.jsx b/lib/static/components/controls/report-info.jsx index d52f7bc56..40a5af026 100644 --- a/lib/static/components/controls/report-info.jsx +++ b/lib/static/components/controls/report-info.jsx @@ -1,10 +1,16 @@ import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import {Label} from '@gravity-ui/uikit'; import {isEmpty} from 'lodash'; import {version} from '../../../../package.json'; class ReportInfo extends Component { + static propTypes = { + gui: PropTypes.bool.isRequired, + timestamp: PropTypes.number.isRequired + }; + render() { const {gui, timestamp} = this.props; const lang = isEmpty(navigator.languages) ? navigator.language : navigator.languages[0]; diff --git a/lib/static/components/controls/run-button/index.jsx b/lib/static/components/controls/run-button/index.jsx index 550ba9ae8..800e0e94d 100644 --- a/lib/static/components/controls/run-button/index.jsx +++ b/lib/static/components/controls/run-button/index.jsx @@ -1,18 +1,16 @@ 'use strict'; -import React, {useEffect, useState} from 'react'; +import React, {useEffect} from 'react'; import {bindActionCreators} from 'redux'; import {isEmpty} from 'lodash'; import {connect} from 'react-redux'; import PropTypes from 'prop-types'; -import classNames from 'classnames'; import * as actions from '../../../modules/actions'; -import Popup from '../../popup'; import {getFailedTests, getCheckedTests} from '../../../modules/selectors/tree'; import useLocalStorage from '../../../hooks/useLocalStorage'; import './index.styl'; -import { Button, Select } from '@gravity-ui/uikit'; +import {Button, Select} from '@gravity-ui/uikit'; const RunMode = Object.freeze({ ALL: 'All', @@ -24,8 +22,6 @@ const RunButton = ({actions, autoRun, isDisabled, isRunning, failedTests, checke const [mode, setMode] = useLocalStorage('RunMode', RunMode.FAILED); const [showCheckboxes] = useLocalStorage('showCheckboxes', false); - const btnClassName = classNames('btn', {'button_blink': isRunning}); - const shouldDisableFailed = isEmpty(failedTests); const shouldDisableChecked = !showCheckboxes || isEmpty(checkedTests); @@ -54,10 +50,10 @@ const RunButton = ({actions, autoRun, isDisabled, isRunning, failedTests, checke [RunMode.FAILED]: selectFailedTests, [RunMode.CHECKED]: selectCheckedTests }[values[0]]; - + action(); } - } + }; useEffect(() => { if (autoRun) { @@ -85,13 +81,13 @@ const RunButton = ({actions, autoRun, isDisabled, isRunning, failedTests, checke
@@ -110,7 +106,8 @@ RunButton.propTypes = { checkedTests: PropTypes.arrayOf(PropTypes.shape({ testName: PropTypes.string, browserName: PropTypes.string - })).isRequired + })).isRequired, + actions: PropTypes.object.isRequired }; export default connect( diff --git a/lib/static/components/controls/selects/control.jsx b/lib/static/components/controls/selects/control.jsx index 2a18e0e82..7d945f347 100644 --- a/lib/static/components/controls/selects/control.jsx +++ b/lib/static/components/controls/selects/control.jsx @@ -1,10 +1,9 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; -import {Dropdown} from 'semantic-ui-react'; import classNames from 'classnames'; import './index.styl'; -import { Button, Label, Select } from '@gravity-ui/uikit'; +import {Select} from '@gravity-ui/uikit'; import CustomLabel from './label'; export default class ControlSelect extends Component { @@ -19,22 +18,17 @@ export default class ControlSelect extends Component { })).isRequired, extendClassNames: PropTypes.oneOfType([PropTypes.array, PropTypes.string]), extendPopupClassNames: PropTypes.oneOfType([PropTypes.array, PropTypes.string]), - qa: PropTypes.string, + qa: PropTypes.string }; _onUpdate = (values) => { if (values.length) { this.props.handler(values[0]); } - } + }; render() { const {size, value, label, options, extendClassNames, extendPopupClassNames, qa} = this.props; - const formattedOpts = options.map(({value, text}) => ({ - value, - text, - key: value - })); const className = classNames( 'select', diff --git a/lib/static/components/controls/selects/group-tests.jsx b/lib/static/components/controls/selects/group-tests.jsx index 154e59f46..99a035cad 100644 --- a/lib/static/components/controls/selects/group-tests.jsx +++ b/lib/static/components/controls/selects/group-tests.jsx @@ -1,19 +1,17 @@ -import React, {Component, Fragment} from 'react'; +import React, {Component} from 'react'; import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; import PropTypes from 'prop-types'; -import {Label, Dropdown} from 'semantic-ui-react'; import classNames from 'classnames'; -import {isEmpty} from 'lodash'; import * as actions from '../../../modules/actions'; import {groupedTestsType} from '../../group-tests/prop-types'; -import {SECTIONS, KEY_DELIMITER} from '../../../../constants/group-tests'; +import {SECTIONS} from '../../../../constants/group-tests'; import {getParsedKeyToGroupTestsBy} from '../../../modules/selectors/grouped-tests'; import './index.styl'; import CustomLabel from './label'; -import { Select } from '@gravity-ui/uikit'; +import {Select} from '@gravity-ui/uikit'; class GroupTestsSelect extends Component { static propTypes = { @@ -40,7 +38,7 @@ class GroupTestsSelect extends Component { ); const options = Object.values(SECTIONS).map((sectionName) => ({ label: sectionName, - options: groupedTests[sectionName].allKeys.map((k) => ({ value: `${sectionName}.${k}`, content: k})) + options: groupedTests[sectionName].allKeys.map((k) => ({value: `${sectionName}.${k}`, content: k})) })); return ( @@ -55,7 +53,7 @@ class GroupTestsSelect extends Component { pin='brick-round' placeholder='select key' qa='group-by-dropdown' - /> + /> ); } @@ -70,7 +68,3 @@ export default connect( }, (dispatch) => ({actions: bindActionCreators(actions, dispatch)}) )(GroupTestsSelect); - -function getGroupElemId(groupName, groupKey) { - return `${groupName}${KEY_DELIMITER}${groupKey}`; -} diff --git a/lib/static/components/controls/selects/label.jsx b/lib/static/components/controls/selects/label.jsx index cb44ec31c..3bf9cc677 100644 --- a/lib/static/components/controls/selects/label.jsx +++ b/lib/static/components/controls/selects/label.jsx @@ -1,10 +1,15 @@ -import React, {Component} from 'react'; -import { Label } from '@gravity-ui/uikit'; +import React from 'react'; +import PropTypes from 'prop-types'; +import {Label} from '@gravity-ui/uikit'; import './index.styl'; import classNames from 'classnames'; const CustomLabel = ({className, ...otherProps}) => { - return () -} + return (); +}; -export default CustomLabel; \ No newline at end of file +CustomLabel.propTypes = { + className: PropTypes.string +}; + +export default CustomLabel; diff --git a/lib/static/components/controls/show-checkboxes-input.jsx b/lib/static/components/controls/show-checkboxes-input.jsx index 3697f1a89..33ce8da06 100644 --- a/lib/static/components/controls/show-checkboxes-input.jsx +++ b/lib/static/components/controls/show-checkboxes-input.jsx @@ -1,9 +1,8 @@ 'use strict'; import React from 'react'; -import {Checkbox} from 'semantic-ui-react'; import useLocalStorage from '../../hooks/useLocalStorage'; -import { Switch } from '@gravity-ui/uikit'; +import {Switch} from '@gravity-ui/uikit'; const ShowCheckboxesInput = () => { const [showCheckboxes, setShowCheckboxes] = useLocalStorage('showCheckboxes', false); diff --git a/lib/static/components/controls/strict-match-filter-input.jsx b/lib/static/components/controls/strict-match-filter-input.jsx index 6d70d4302..b34f19bb2 100644 --- a/lib/static/components/controls/strict-match-filter-input.jsx +++ b/lib/static/components/controls/strict-match-filter-input.jsx @@ -4,9 +4,8 @@ import React, {useState} from 'react'; import PropTypes from 'prop-types'; import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; -import {Checkbox} from 'semantic-ui-react'; import * as actions from '../../modules/actions'; -import { Switch } from '@gravity-ui/uikit'; +import {Switch} from '@gravity-ui/uikit'; const StrictMatchFilterInput = ({strictMatchFilter, actions}) => { const [checked, setChecked] = useState(strictMatchFilter); diff --git a/lib/static/components/controls/test-name-filter-input.jsx b/lib/static/components/controls/test-name-filter-input.jsx index 78f7c23f2..018c50f41 100644 --- a/lib/static/components/controls/test-name-filter-input.jsx +++ b/lib/static/components/controls/test-name-filter-input.jsx @@ -6,7 +6,7 @@ import {bindActionCreators} from 'redux'; import {connect} from 'react-redux'; import {debounce} from 'lodash'; import * as actions from '../../modules/actions'; -import { TextInput } from '@gravity-ui/uikit'; +import {TextInput} from '@gravity-ui/uikit'; const TestNameFilterInput = ({actions, testNameFilter: testNameFilterProp}) => { const [testNameFilter, setTestNameFilter] = useState(testNameFilterProp); diff --git a/lib/static/components/custom-scripts.jsx b/lib/static/components/custom-scripts.jsx index fddf20e9b..74b2be878 100644 --- a/lib/static/components/custom-scripts.jsx +++ b/lib/static/components/custom-scripts.jsx @@ -1,7 +1,8 @@ import React, {useEffect, useRef} from 'react'; +import PropTypes from 'prop-types'; import {isEmpty} from 'lodash'; -export default function CustomScripts(props) { +function CustomScripts(props) { const {scripts} = props; if (isEmpty(scripts)) { @@ -21,3 +22,9 @@ export default function CustomScripts(props) { return
; } + +CustomScripts.propTypes = { + scripts: PropTypes.array.isRequired +}; + +export default CustomScripts; diff --git a/lib/static/components/extension-point.jsx b/lib/static/components/extension-point.jsx index 8baf7ed7a..fdf7f9a3e 100644 --- a/lib/static/components/extension-point.jsx +++ b/lib/static/components/extension-point.jsx @@ -5,7 +5,8 @@ import * as plugins from '../modules/plugins'; export default class ExtensionPoint extends Component { static propTypes = { - name: PropTypes.string.isRequired + name: PropTypes.string.isRequired, + children: PropTypes.oneOfType([PropTypes.element, PropTypes.string]) }; render() { diff --git a/lib/static/components/group-tests/item.jsx b/lib/static/components/group-tests/item.jsx index cd81f3641..948ef7305 100644 --- a/lib/static/components/group-tests/item.jsx +++ b/lib/static/components/group-tests/item.jsx @@ -46,6 +46,7 @@ const GroupTestsItem = ({group, isActive, onClick, checkStatus, actions}) => { }; GroupTestsItem.propTypes = { + actions: PropTypes.object.isRequired, group: PropTypes.object.isRequired, isActive: PropTypes.bool.isRequired, onClick: PropTypes.func.isRequired, diff --git a/lib/static/components/group-tests/list.jsx b/lib/static/components/group-tests/list.jsx index 1610d428c..889065494 100644 --- a/lib/static/components/group-tests/list.jsx +++ b/lib/static/components/group-tests/list.jsx @@ -13,7 +13,8 @@ class GroupTestsList extends Component { // from store groupedTests: groupedTestsType.isRequired, selectedGroupSection: PropTypes.string.isRequired, - selectedGroupKey: PropTypes.string.isRequired + selectedGroupKey: PropTypes.string.isRequired, + actions: PropTypes.object.isRequired }; state = { diff --git a/lib/static/components/gui.jsx b/lib/static/components/gui.jsx index 81bcf2c72..c1276a511 100644 --- a/lib/static/components/gui.jsx +++ b/lib/static/components/gui.jsx @@ -24,7 +24,9 @@ class Gui extends Component { content: PropTypes.string }).isRequired, customScripts: PropTypes.array, - notifications: PropTypes.array + notifications: PropTypes.array, + actions: PropTypes.object.isRequired, + allRootSuiteIds: PropTypes.array.isRequired }; componentDidMount() { diff --git a/lib/static/components/header/summary/dbBtn.jsx b/lib/static/components/header/summary/dbBtn.jsx index 4957b009c..a8deee380 100644 --- a/lib/static/components/header/summary/dbBtn.jsx +++ b/lib/static/components/header/summary/dbBtn.jsx @@ -1,11 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Ref} from 'semantic-ui-react'; -import classNames from 'classnames'; -import { Button, ButtonIcon } from '@gravity-ui/uikit'; +import {Button} from '@gravity-ui/uikit'; import {ChevronDown} from '@gravity-ui/icons'; -const DbBtn = ({fetchDbDetails}, ref) => { +const ForwardedDbBtn = React.forwardRef(function DbBtn({fetchDbDetails}, ref) { const successFetchDbDetails = fetchDbDetails.filter(d => d.success); const isFailed = successFetchDbDetails.length !== fetchDbDetails.length; const value = `${successFetchDbDetails.length}/${fetchDbDetails.length}`; @@ -23,9 +22,7 @@ const DbBtn = ({fetchDbDetails}, ref) => { ); -}; - -const ForwardedDbBtn = React.forwardRef(DbBtn); +}); ForwardedDbBtn.propTypes = { fetchDbDetails: PropTypes.arrayOf(PropTypes.shape({ diff --git a/lib/static/components/header/summary/index.jsx b/lib/static/components/header/summary/index.jsx index 807ccebe2..ac270e727 100644 --- a/lib/static/components/header/summary/index.jsx +++ b/lib/static/components/header/summary/index.jsx @@ -15,7 +15,12 @@ class Summary extends Component { failed: PropTypes.number, skipped: PropTypes.number, retries: PropTypes.number - }) + }), + fetchDbDetails: PropTypes.arrayOf(PropTypes.shape({ + url: PropTypes.string, + status: PropTypes.number, + success: PropTypes.bool + })).isRequired }; render() { diff --git a/lib/static/components/icons/view-in-browser/index.jsx b/lib/static/components/icons/view-in-browser/index.jsx index cd656b61d..a0a5fceb1 100644 --- a/lib/static/components/icons/view-in-browser/index.jsx +++ b/lib/static/components/icons/view-in-browser/index.jsx @@ -16,7 +16,8 @@ class ViewInBrowser extends Component { extendClassNames: PropTypes.oneOfType([PropTypes.array, PropTypes.string]), // from store suiteUrl: PropTypes.string, - baseHost: PropTypes.string + baseHost: PropTypes.string, + actions: PropTypes.object.isRequired }; onViewInBrowser = (e) => { @@ -44,7 +45,7 @@ class ViewInBrowser extends Component { onClick={this.onViewInBrowser} title="view in browser" target="_blank" - data-test-id='view-in-browser' + data-test-id='view-in-browser' rel="noreferrer" > ); } diff --git a/lib/static/components/loading.jsx b/lib/static/components/loading.jsx index ab0c9a068..0110db559 100644 --- a/lib/static/components/loading.jsx +++ b/lib/static/components/loading.jsx @@ -7,7 +7,8 @@ import {Dimmer, Loader} from 'semantic-ui-react'; export default class Loading extends Component { static propTypes = { active: PropTypes.bool, - content: PropTypes.string + content: PropTypes.string, + children: PropTypes.oneOfType([PropTypes.element, PropTypes.string]) }; render() { diff --git a/lib/static/components/modals/modal.jsx b/lib/static/components/modals/modal.jsx index f3dfa03bb..0d9462fd1 100644 --- a/lib/static/components/modals/modal.jsx +++ b/lib/static/components/modals/modal.jsx @@ -1,9 +1,10 @@ import React, {Component} from 'react'; -import { Portal } from '@gravity-ui/uikit'; +import {Portal} from '@gravity-ui/uikit'; +import PropTypes from 'prop-types'; import './modal.css'; -export default class Modal extends Component { - componentWillMount() { +class Modal extends Component { + componentDidMount() { document.body.classList.add('modal-open'); } @@ -20,6 +21,13 @@ export default class Modal extends Component { {children} - ) + ); } } + +Modal.propTypes = { + className: PropTypes.string, + children: PropTypes.oneOfType([PropTypes.element, PropTypes.string]) +}; + +export default Modal; diff --git a/lib/static/components/modals/screenshot-accepter/header.jsx b/lib/static/components/modals/screenshot-accepter/header.jsx index 9e99e635a..7971df775 100644 --- a/lib/static/components/modals/screenshot-accepter/header.jsx +++ b/lib/static/components/modals/screenshot-accepter/header.jsx @@ -9,10 +9,13 @@ import ControlSelect from '../../controls/selects/control'; import RetrySwitcher from '../../retry-switcher'; import {DiffModes} from '../../../../constants/diff-modes'; import {ChevronsExpandUpRight, ArrowUturnCcwDown, ArrowUp, ArrowDown, Check} from '@gravity-ui/icons'; -import {staticImageAccepterPropType} from "../../../modules/static-image-accepter"; +import {staticImageAccepterPropType} from '../../../modules/static-image-accepter'; export default class ScreenshotAccepterHeader extends Component { static propTypes = { + view: PropTypes.shape({ + diffMode: PropTypes.string.isRequired + }), images: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string, parentId: PropTypes.string @@ -30,7 +33,8 @@ export default class ScreenshotAccepterHeader extends Component { onScreenshotUndo: PropTypes.func.isRequired, onShowMeta: PropTypes.func.isRequired, onCommitChanges: PropTypes.func.isRequired, - staticImageAccepter: staticImageAccepterPropType + staticImageAccepter: staticImageAccepterPropType, + actions: PropTypes.object.isRequired }; constructor(props) { diff --git a/lib/static/components/modals/screenshot-accepter/index.jsx b/lib/static/components/modals/screenshot-accepter/index.jsx index f564fb99f..bb561c9f0 100644 --- a/lib/static/components/modals/screenshot-accepter/index.jsx +++ b/lib/static/components/modals/screenshot-accepter/index.jsx @@ -1,17 +1,15 @@ import React, {Component, Fragment} from 'react'; -import ReactDOM from 'react-dom'; import {connect} from 'react-redux'; import {bindActionCreators} from 'redux'; import PropTypes from 'prop-types'; -import {isEmpty, isNumber, size, get, findIndex, last, pick, map} from 'lodash'; +import {isEmpty, isNumber, size, get, findIndex, last} from 'lodash'; import * as actions from '../../../modules/actions'; import ScreenshotAccepterHeader from './header'; import ScreenshotAccepterMeta from './meta'; import ScreenshotAccepterBody from './body'; -import StaticAccepterConfirm from "../static-accepter-confirm"; import {getAcceptableImagesByStateName} from '../../../modules/selectors/tree'; -import {staticImageAccepterPropType} from "../../../modules/static-image-accepter"; +import {staticImageAccepterPropType} from '../../../modules/static-image-accepter'; import {preloadImage} from '../../../modules/utils'; import './style.css'; @@ -20,6 +18,9 @@ const PRELOAD_IMAGE_COUNT = 3; class ScreenshotAccepter extends Component { static propTypes = { + view: PropTypes.shape({ + diffMode: PropTypes.string.isRequired + }), image: PropTypes.shape({ id: PropTypes.string.isRequired, parentId: PropTypes.string.isRequired, @@ -32,6 +33,7 @@ class ScreenshotAccepter extends Component { stateNameImageIds: PropTypes.arrayOf(PropTypes.string).isRequired, activeImageIndex: PropTypes.number.isRequired, staticImageAccepter: staticImageAccepterPropType, + actions: PropTypes.object.isRequired }; constructor(props) { @@ -49,6 +51,7 @@ class ScreenshotAccepter extends Component { retryIndex, showMeta: false }; + this.topRef = React.createRef(); this.totalImagesCount = size(imagesByStateName); @@ -58,7 +61,7 @@ class ScreenshotAccepter extends Component { } componentDidUpdate() { - ReactDOM.findDOMNode(this).parentNode.scrollTo(0, 0); + this.topRef.current.parentNode.scrollTo(0, 0); } onRetryChange = (retryIndex) => { @@ -169,7 +172,7 @@ class ScreenshotAccepter extends Component { onCommitChanges = () => { this.props.actions.staticAccepterOpenConfirm(); - } + }; _getActiveImages( activeImageIndex = this.state.activeImageIndex, @@ -227,6 +230,7 @@ class ScreenshotAccepter extends Component { return ( +
({actions: bindActionCreators(actions, dispatch)}) diff --git a/lib/static/components/popup/index.jsx b/lib/static/components/popup/index.jsx index 62d10e086..6fe43ae3f 100644 --- a/lib/static/components/popup/index.jsx +++ b/lib/static/components/popup/index.jsx @@ -83,7 +83,8 @@ const Popup = (props) => { Popup.propTypes = { action: PropTypes.oneOf(['hover', 'click']).isRequired, target: PropTypes.node.isRequired, - hideOnClick: PropTypes.bool + hideOnClick: PropTypes.bool, + children: PropTypes.oneOfType([PropTypes.element, PropTypes.string]) }; export default Popup; diff --git a/lib/static/components/progress-bar/index.jsx b/lib/static/components/progress-bar/index.jsx index aa0e9ff40..b7d0d094d 100644 --- a/lib/static/components/progress-bar/index.jsx +++ b/lib/static/components/progress-bar/index.jsx @@ -1,8 +1,9 @@ import React from 'react'; +import PropTypes from 'prop-types'; import './index.styl'; -export default ({done, total, dataTestId}) => { +const ProgressBar = ({done, total, dataTestId}) => { const percent = (done / total).toFixed(2) * 100; return ( @@ -11,3 +12,11 @@ export default ({done, total, dataTestId}) => { ); }; + +ProgressBar.propTypes = { + done: PropTypes.number.isRequired, + total: PropTypes.number.isRequired, + dataTestId: PropTypes.string +}; + +export default ProgressBar; diff --git a/lib/static/components/report.jsx b/lib/static/components/report.jsx index ae1106b67..45f9c39e1 100644 --- a/lib/static/components/report.jsx +++ b/lib/static/components/report.jsx @@ -21,7 +21,8 @@ class Report extends Component { allRootSuiteIds: PropTypes.arrayOf(PropTypes.string).isRequired, fetchDbDetails: PropTypes.array.isRequired, customScripts: PropTypes.array, - notifications: PropTypes.array + notifications: PropTypes.array, + actions: PropTypes.object.isRequired }; componentDidMount() { diff --git a/lib/static/components/section/body/index.jsx b/lib/static/components/section/body/index.jsx index 465eac5c4..cfa5fab79 100644 --- a/lib/static/components/section/body/index.jsx +++ b/lib/static/components/section/body/index.jsx @@ -20,7 +20,8 @@ class Body extends Component { // from store gui: PropTypes.bool.isRequired, running: PropTypes.bool.isRequired, - retryIndex: PropTypes.number + retryIndex: PropTypes.number, + actions: PropTypes.object.isRequired }; onRetrySwitcherChange = (index) => { diff --git a/lib/static/components/section/body/meta-info/index.jsx b/lib/static/components/section/body/meta-info/index.jsx index 4eb283020..b5802d460 100644 --- a/lib/static/components/section/body/meta-info/index.jsx +++ b/lib/static/components/section/body/meta-info/index.jsx @@ -8,7 +8,8 @@ import Details from '../../../details'; class MetaInfo extends Component { static propTypes = { - resultId: PropTypes.string.isRequired + resultId: PropTypes.string.isRequired, + actions: PropTypes.object.isRequired }; onToggleMetaInfo = () => { diff --git a/lib/static/components/section/section-browser.jsx b/lib/static/components/section/section-browser.jsx index 774d03fa6..e047ad62a 100644 --- a/lib/static/components/section/section-browser.jsx +++ b/lib/static/components/section/section-browser.jsx @@ -16,6 +16,7 @@ class SectionBrowser extends Component { browserId: PropTypes.string.isRequired, // from store browser: PropTypes.shape({ + id: PropTypes.string.isRequired, name: PropTypes.string.isRequired, resultIds: PropTypes.arrayOf(PropTypes.string).isRequired, parentId: PropTypes.string.isRequired @@ -31,7 +32,8 @@ class SectionBrowser extends Component { shouldBeShown: PropTypes.bool.isRequired, shouldBeOpened: PropTypes.bool.isRequired, // from SectionCommonWrapper - sectionStatusResolver: PropTypes.func.isRequired + sectionStatusResolver: PropTypes.func.isRequired, + actions: PropTypes.object.isRequired }; onToggleSection = () => { diff --git a/lib/static/components/section/section-common.jsx b/lib/static/components/section/section-common.jsx index 87698aa5f..654341903 100644 --- a/lib/static/components/section/section-common.jsx +++ b/lib/static/components/section/section-common.jsx @@ -19,7 +19,8 @@ class SectionCommon extends Component { shouldBeShown: PropTypes.bool.isRequired, shouldBeOpened: PropTypes.bool.isRequired, // from SectionCommonWrapper - sectionStatusResolver: PropTypes.func.isRequired + sectionStatusResolver: PropTypes.func.isRequired, + actions: PropTypes.object.isRequired }; onToggleSection = () => { diff --git a/lib/static/components/section/title/browser-skipped.jsx b/lib/static/components/section/title/browser-skipped.jsx index bfc513163..cdc5ce6fa 100644 --- a/lib/static/components/section/title/browser-skipped.jsx +++ b/lib/static/components/section/title/browser-skipped.jsx @@ -30,7 +30,8 @@ BrowserSkippedTitle.propTypes = { title: PropTypes.object.isRequired, browserId: PropTypes.string.isRequired, // from store - checkStatus: PropTypes.number.isRequired + checkStatus: PropTypes.number.isRequired, + actions: PropTypes.object.isRequired }; export default connect( diff --git a/lib/static/components/section/title/browser.jsx b/lib/static/components/section/title/browser.jsx index f3208c923..724b23870 100644 --- a/lib/static/components/section/title/browser.jsx +++ b/lib/static/components/section/title/browser.jsx @@ -34,6 +34,10 @@ const ShareButtonComponent = ({status, ...rest}) => { ); }; +ShareButtonComponent.propTypes = { + status: PropTypes.string.isRequired +}; + const BrowserTitle = (props) => { const testUrl = React.useMemo(() => { return appendQuery(window.location.href, { @@ -83,7 +87,8 @@ BrowserTitle.propTypes = { checkStatus: PropTypes.number.isRequired, testName: PropTypes.string.isRequired, retryIndex: PropTypes.number.isRequired, - suiteUrl: PropTypes.string + suiteUrl: PropTypes.string, + actions: PropTypes.object.isRequired }; export default connect( diff --git a/lib/static/components/section/title/simple.jsx b/lib/static/components/section/title/simple.jsx index 6620062e6..bc71320d9 100644 --- a/lib/static/components/section/title/simple.jsx +++ b/lib/static/components/section/title/simple.jsx @@ -78,7 +78,8 @@ SectionTitle.propTypes = { browserName: PropTypes.string })).isRequired, running: PropTypes.bool, - runningThis: PropTypes.bool + runningThis: PropTypes.bool, + actions: PropTypes.object.isRequired }; export default connect( diff --git a/lib/static/components/state/error-details.jsx b/lib/static/components/state/error-details.jsx index 49e85abbd..4a2259833 100644 --- a/lib/static/components/state/error-details.jsx +++ b/lib/static/components/state/error-details.jsx @@ -11,7 +11,7 @@ export default class ErrorDetails extends Component { render() { const {title, filePath} = this.props.errorDetails; - const content =
{title}
; + const content =
{title}
; return
; } diff --git a/lib/static/components/state/index.jsx b/lib/static/components/state/index.jsx index 81b353ae1..72300b741 100644 --- a/lib/static/components/state/index.jsx +++ b/lib/static/components/state/index.jsx @@ -21,7 +21,8 @@ class State extends Component { static propTypes = { result: PropTypes.shape({ status: PropTypes.string.isRequired, - error: PropTypes.object + error: PropTypes.object, + parentId: PropTypes.string }).isRequired, imageId: PropTypes.string, // from store @@ -30,12 +31,21 @@ class State extends Component { status: PropTypes.string, error: PropTypes.object, stateName: PropTypes.string, - expectedImg: PropTypes.object + expectedImg: PropTypes.object, + actualImg: PropTypes.object, + diffRatio: PropTypes.number, + differentPixels: PropTypes.number }).isRequired, + node: PropTypes.shape({ + error: PropTypes.object, + status: PropTypes.string + }), shouldImageBeOpened: PropTypes.bool.isRequired, isScreenshotAccepterDisabled: PropTypes.bool.isRequired, isStaticImageAccepterEnabled: PropTypes.bool.isRequired, - isLastResult: PropTypes.bool.isRequired + isStaticAccepterAcceptDisabled: PropTypes.bool, + isLastResult: PropTypes.bool.isRequired, + actions: PropTypes.object.isRequired }; toggleModal = () => { @@ -158,7 +168,7 @@ class State extends Component { } _getStateTitleWithDiffCount() { - const {image, shouldImageBeOpened} = this.props; + const {image} = this.props; if (!image.stateName) { return null; @@ -190,7 +200,7 @@ class State extends Component { } else if (isSuccessStatus(status) || isUpdatedStatus(status) || (isIdleStatus(status) && get(image.expectedImg, 'path'))) { elem = ; } else if (isStagedStatus(status) || isCommitedStatus(status)) { - elem = + elem = ; } else if (isFailStatus(status)) { elem = error ? diff --git a/lib/static/components/state/screenshot/full.jsx b/lib/static/components/state/screenshot/full.jsx index c89144e4d..5b4034f56 100644 --- a/lib/static/components/state/screenshot/full.jsx +++ b/lib/static/components/state/screenshot/full.jsx @@ -15,7 +15,8 @@ class FullScreenshot extends Component { visibility: PropTypes.string }), // from withEncodeUri - imageUrl: PropTypes.string.isRequired + imageUrl: PropTypes.string.isRequired, + className: PropTypes.string }; render() { diff --git a/lib/static/components/state/screenshot/resized.jsx b/lib/static/components/state/screenshot/resized.jsx index fac93319c..9bfd4b93d 100644 --- a/lib/static/components/state/screenshot/resized.jsx +++ b/lib/static/components/state/screenshot/resized.jsx @@ -17,6 +17,7 @@ class ResizedScreenshot extends Component { } static propTypes = { + style: PropTypes.object, image: PropTypes.shape({ path: PropTypes.string.isRequired, size: PropTypes.shape({ @@ -27,7 +28,8 @@ class ResizedScreenshot extends Component { diffClusters: PropTypes.array, overrideWidth: PropTypes.number, // from withEncodeUri - imageUrl: PropTypes.string.isRequired + imageUrl: PropTypes.string.isRequired, + className: PropTypes.string }; _getScreenshotComponent(elem, diffClusters) { diff --git a/lib/static/components/state/state-error.jsx b/lib/static/components/state/state-error.jsx index 6f3b80e39..3330c047a 100644 --- a/lib/static/components/state/state-error.jsx +++ b/lib/static/components/state/state-error.jsx @@ -6,23 +6,23 @@ import {bindActionCreators} from 'redux'; import PropTypes from 'prop-types'; import {isEmpty, map, isFunction} from 'lodash'; import ReactHtmlParser from 'react-html-parser'; -import escapeHtml from "escape-html"; -import ansiHtml from "ansi-html-community"; +import escapeHtml from 'escape-html'; +import ansiHtml from 'ansi-html-community'; import * as actions from '../../modules/actions'; import ResizedScreenshot from './screenshot/resized'; import ErrorDetails from './error-details'; import Details from '../details'; import {ERROR_TITLE_TEXT_LENGTH} from '../../../constants/errors'; import {isAssertViewError, isImageDiffError, isNoRefImageError, mergeSnippetIntoErrorStack, trimArray} from '../../../common-utils'; -import { Card } from '@gravity-ui/uikit'; +import {Card} from '@gravity-ui/uikit'; ansiHtml.setColors({ - reset: ["#", "#"], - cyan: "ff6188", - yellow: "5cb008", - magenta: "8e81cd", - green: "aa8720", -}) + reset: ['#', '#'], + cyan: 'ff6188', + yellow: '5cb008', + magenta: '8e81cd', + green: 'aa8720' +}); class StateError extends Component { static propTypes = { @@ -59,7 +59,7 @@ class StateError extends Component { _wrapInDiv = (html) => { return html ? `
${html}
` : html; - } + }; _errorToElements(error) { if (isEmpty(error)) { @@ -96,7 +96,7 @@ class StateError extends Component { } const title = {key}: {titleText}; - const asHtml = typeof content === "string"; + const asHtml = typeof content === 'string'; return
{ const [diffMode, setDiffMode] = useState(diffModeProp); @@ -28,7 +27,7 @@ const StateFail = ({image, diffMode: diffModeProp, isScreenshotAccepterOpened})
setDiffMode(mode)} size='m'/>
- ) + ); }; const getLabelKey = () => { @@ -125,7 +124,11 @@ StateFail.propTypes = { expectedImg: PropTypes.object.isRequired, actualImg: PropTypes.object.isRequired, diffImg: PropTypes.object.isRequired, - diffClusters: PropTypes.array + diffClusters: PropTypes.array, + size: PropTypes.shape({ + width: PropTypes.number, + height: PropTypes.number + }) }).isRequired, // from store diffMode: PropTypes.string, diff --git a/lib/static/components/sticky-header/index.jsx b/lib/static/components/sticky-header/index.jsx index 796fdb876..f05cfb0f4 100644 --- a/lib/static/components/sticky-header/index.jsx +++ b/lib/static/components/sticky-header/index.jsx @@ -1,5 +1,6 @@ import React, {useState, useCallback} from 'react'; import {throttle} from 'lodash'; +import PropTypes from 'prop-types'; import './index.styl'; import useEventListener from '../../hooks/useEventListener'; @@ -33,4 +34,8 @@ const StickyHeader = ({children}) => { ); }; +StickyHeader.propTypes = { + children: PropTypes.oneOfType([PropTypes.element, PropTypes.string]) +}; + export default StickyHeader; diff --git a/lib/static/components/suites.jsx b/lib/static/components/suites.jsx index 740febdc3..881ed5557 100644 --- a/lib/static/components/suites.jsx +++ b/lib/static/components/suites.jsx @@ -15,7 +15,14 @@ class Suites extends Component { static propTypes = { // from store visibleRootSuiteIds: PropTypes.arrayOf(PropTypes.string), - viewMode: PropTypes.string + viewMode: PropTypes.string, + actions: PropTypes.object.isRequired, + testNameFilter: PropTypes.string, + strictMatchFilter: PropTypes.bool, + filteredBrowsers: PropTypes.arrayOf(PropTypes.objectOf({ + id: PropTypes.string, + versions: PropTypes.arrayOf(PropTypes.string) + })) }; _suitesMeasurementCache = new CellMeasurerCache({ diff --git a/lib/static/containers/array/index.jsx b/lib/static/containers/array/index.jsx index efe90d0be..b2ef4b8df 100644 --- a/lib/static/containers/array/index.jsx +++ b/lib/static/containers/array/index.jsx @@ -5,7 +5,7 @@ import PropTypes from 'prop-types'; import './array.styl'; -const ArrayContainer = (props, ref) => { +const ForwardedArrayContainer = React.forwardRef(function ArrayContainer(props, ref) { const {elements, placeholder, ...rest} = props; const containerRef = useRef(null); @@ -49,9 +49,7 @@ const ArrayContainer = (props, ref) => { ); -}; - -const ForwardedArrayContainer = React.forwardRef(ArrayContainer); +}); ForwardedArrayContainer.propTypes = { elements: PropTypes.arrayOf(PropTypes.string).isRequired, diff --git a/lib/static/containers/modal.jsx b/lib/static/containers/modal.jsx index 8f88505bc..07c68227f 100644 --- a/lib/static/containers/modal.jsx +++ b/lib/static/containers/modal.jsx @@ -15,7 +15,8 @@ class ModalContainer extends Component { type: PropTypes.string, className: PropTypes.string, data: PropTypes.object - })).isRequired + })).isRequired, + actions: PropTypes.object.isRequired }; render() { diff --git a/package.json b/package.json index 645a54acc..cb0601577 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "e2e:generate-fixtures": "npm run --workspace=test/func/fixtures generate", "e2e:test": "npm run --workspace=test/func/tests test", "e2e": "npm run e2e:build-packages && npm run e2e:generate-fixtures ; npm run e2e:test", - "lint": "eslint .", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx", "test": "npm run lint && npm run test-unit && npm run check-types", "test-unit": "cross-env NODE_ENV=test mocha test/unit", "precommit": "npm run lint", diff --git a/test/func/packages/basic/lib/color-border.jsx b/test/func/packages/basic/lib/color-border.jsx index c3e4d7bc3..82565b799 100644 --- a/test/func/packages/basic/lib/color-border.jsx +++ b/test/func/packages/basic/lib/color-border.jsx @@ -1,5 +1,6 @@ import React from 'react'; +import PropTypes from 'prop-types'; import './color-border.css'; const nextColors = { @@ -9,6 +10,10 @@ const nextColors = { }; export class ColorBorder extends React.Component { + static propTypes = { + children: PropTypes.oneOfType([PropTypes.element, PropTypes.string]) + }; + state = {color: 'red'}; onBorderClick = (e) => { @@ -18,7 +23,7 @@ export class ColorBorder extends React.Component { color: nextColors[state.color] }; }); - } + }; render() { const className = `${this.state.color}-border basic-border`; diff --git a/test/func/packages/redux-with-server/lib/color-border.jsx b/test/func/packages/redux-with-server/lib/color-border.jsx index c3affcbba..1ec492d29 100644 --- a/test/func/packages/redux-with-server/lib/color-border.jsx +++ b/test/func/packages/redux-with-server/lib/color-border.jsx @@ -1,3 +1,4 @@ +import PropTypes from 'prop-types'; import './color-border.css'; export default [ @@ -13,11 +14,19 @@ export default [ {pluginName} ) { class ColorBorder extends React.Component { + static propTypes = { + actions: PropTypes.object.isRequired, + children: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), + resultId: PropTypes.string.isRequired, + color: PropTypes.string.isRequired, + changesCount: PropTypes.number.isRequired + }; + onBorderClick = (e) => { e.stopPropagation(); // "result" point provides resultId in props this.props.actions.changeBorderColor(this.props.resultId, this.props.color); - } + }; render() { const className = `${this.props.color}-border redux-server-border`; diff --git a/test/func/packages/redux/lib/color-border.jsx b/test/func/packages/redux/lib/color-border.jsx index 9cada8472..40b0accff 100644 --- a/test/func/packages/redux/lib/color-border.jsx +++ b/test/func/packages/redux/lib/color-border.jsx @@ -1,3 +1,4 @@ +import PropTypes from 'prop-types'; import './color-border.css'; const nextColors = { @@ -12,11 +13,18 @@ export default ['react', 'redux', 'react-redux', function(React, {bindActionCrea // allow the component to be placed only on "result" extension point static point = 'result'; + static propTypes = { + actions: PropTypes.object.isRequired, + children: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), + resultId: PropTypes.string.isRequired, + color: PropTypes.string.isRequired + }; + onBorderClick = (e) => { e.stopPropagation(); // "result" point provides resultId in props this.props.actions.changeBorderColor(this.props.resultId); - } + }; render() { const className = `${this.props.color}-border redux-border`; diff --git a/test/unit/lib/static/components/controls/browser-list/index.jsx b/test/unit/lib/static/components/controls/browser-list/index.jsx index 399bda296..764894a31 100644 --- a/test/unit/lib/static/components/controls/browser-list/index.jsx +++ b/test/unit/lib/static/components/controls/browser-list/index.jsx @@ -1,6 +1,6 @@ import React from 'react'; import BrowserList from '../../../../../../../lib/static/components/controls/browser-list'; -import { ThemeProvider } from '@gravity-ui/uikit'; +import {ThemeProvider} from '@gravity-ui/uikit'; describe('', () => { const sandbox = sinon.sandbox.create(); @@ -16,7 +16,7 @@ describe('', () => { }; const component = mount(); component.first().find('.g-select-control__button').simulate('click'); - + assert.equal(component.first().find('.g-list__items .g-list__item_selected').length, 0); }); diff --git a/test/unit/lib/static/components/controls/run-button.jsx b/test/unit/lib/static/components/controls/run-button.jsx index d491e8d3f..dac4ac51f 100644 --- a/test/unit/lib/static/components/controls/run-button.jsx +++ b/test/unit/lib/static/components/controls/run-button.jsx @@ -116,7 +116,7 @@ describe('', () => { it('should switch to "Run checked tests" if there are checked tests', () => { selectorsStub.getCheckedTests.returns([{testName: 'testName', browserName: 'browserName'}]); - const component = mkConnectedComponent(, { + mkConnectedComponent(, { initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false} }); @@ -132,8 +132,8 @@ describe('', () => { const component = mkConnectedComponent(, { initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false} }); - component.first().find('button.g-select-control__button').simulate('click') - component.first().findWhere(node => node.text() == 'All Tests' && node.hasClass('g-list__item')).simulate('click'); + component.first().find('button.g-select-control__button').simulate('click'); + component.first().findWhere(node => node.text() === 'All Tests' && node.hasClass('g-list__item')).simulate('click'); assert.calledWith(writeValueStub, 'All'); }); @@ -143,8 +143,8 @@ describe('', () => { initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false} }); - component.first().find('button.g-select-control__button').simulate('click') - component.first().findWhere(node => node.text() == 'Failed Tests' && node.hasClass('g-list__item')).simulate('click'); + component.first().find('button.g-select-control__button').simulate('click'); + component.first().findWhere(node => node.text() === 'Failed Tests' && node.hasClass('g-list__item')).simulate('click'); assert.calledOnceWith(writeValueStub, 'Failed'); }); @@ -154,8 +154,8 @@ describe('', () => { initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false} }); - component.first().find('button.g-select-control__button').simulate('click') - component.first().findWhere(node => node.text() == 'Checked Tests' && node.hasClass('g-list__item')).simulate('click'); + component.first().find('button.g-select-control__button').simulate('click'); + component.first().findWhere(node => node.text() === 'Checked Tests' && node.hasClass('g-list__item')).simulate('click'); assert.calledWith(writeValueStub, 'Checked'); }); }); diff --git a/test/unit/lib/static/components/controls/show-checkboxes-input.jsx b/test/unit/lib/static/components/controls/show-checkboxes-input.jsx index a59bbbf2d..acac69748 100644 --- a/test/unit/lib/static/components/controls/show-checkboxes-input.jsx +++ b/test/unit/lib/static/components/controls/show-checkboxes-input.jsx @@ -1,6 +1,5 @@ import React from 'react'; import proxyquire from 'proxyquire'; -import {Checkbox} from 'semantic-ui-react'; describe('', () => { const sandbox = sinon.sandbox.create(); diff --git a/test/unit/lib/static/components/controls/strict-match-filter-input.jsx b/test/unit/lib/static/components/controls/strict-match-filter-input.jsx index 11613a500..7f4060e0d 100644 --- a/test/unit/lib/static/components/controls/strict-match-filter-input.jsx +++ b/test/unit/lib/static/components/controls/strict-match-filter-input.jsx @@ -1,7 +1,6 @@ import React from 'react'; import {mkConnectedComponent} from '../utils'; import proxyquire from 'proxyquire'; -import {Checkbox} from 'semantic-ui-react'; describe('', () => { const sandbox = sinon.sandbox.create(); diff --git a/test/unit/lib/static/components/modals/screenshot-accepter/index.jsx b/test/unit/lib/static/components/modals/screenshot-accepter/index.jsx index 253f6a158..11a916843 100644 --- a/test/unit/lib/static/components/modals/screenshot-accepter/index.jsx +++ b/test/unit/lib/static/components/modals/screenshot-accepter/index.jsx @@ -35,6 +35,9 @@ describe('', () => { }; const mkScreenshotAccepterComponent = (props = {}, initialState = {}) => { + if (!global.Element.prototype.scrollTo) { + global.Element.prototype.scrollTo = () => {}; // scrollTo isn't implemented in JSDOM + } props = defaults(props, { image: mkImage(), onClose: sandbox.stub() diff --git a/test/unit/lib/static/components/section/body/history.jsx b/test/unit/lib/static/components/section/body/history.jsx index 547312e76..da1eebd92 100644 --- a/test/unit/lib/static/components/section/body/history.jsx +++ b/test/unit/lib/static/components/section/body/history.jsx @@ -1,6 +1,6 @@ import React from 'react'; import {defaultsDeep, set} from 'lodash'; -import History from 'lib/static/components/section/body/history'; +import History from 'lib/static/components/section/body/history'; import {mkConnectedComponent} from '../../utils'; describe('', () => { diff --git a/test/unit/lib/static/components/section/title/browser.jsx b/test/unit/lib/static/components/section/title/browser.jsx index 165de49ae..b5ced7878 100644 --- a/test/unit/lib/static/components/section/title/browser.jsx +++ b/test/unit/lib/static/components/section/title/browser.jsx @@ -103,7 +103,7 @@ describe('', () => { const browsersStateById = {'yabro': {checkStatus: UNCHECKED}}; const tree = mkStateTree({browsersById, resultsById, browsersStateById}); - const component = mkBrowserTitleComponent({browserId: 'yabro', browserName: 'yabro'}, {tree}); + mkBrowserTitleComponent({browserId: 'yabro', browserName: 'yabro'}, {tree}); assert.calledOnce(queryParams.appendQuery); assert.calledWithExactly(queryParams.appendQuery, 'about:blank', { diff --git a/test/unit/lib/static/components/section/title/simple.jsx b/test/unit/lib/static/components/section/title/simple.jsx index bfbd48dfd..9ddd81288 100644 --- a/test/unit/lib/static/components/section/title/simple.jsx +++ b/test/unit/lib/static/components/section/title/simple.jsx @@ -4,8 +4,8 @@ import {defaultsDeep, set} from 'lodash'; import {mkConnectedComponent} from 'test/unit/lib/static/components/utils'; import {mkStateTree} from 'test/unit/lib/static/state-utils'; import {CHECKED, UNCHECKED, INDETERMINATE} from 'lib/constants/checked-statuses'; -import { Checkbox, Spin } from '@gravity-ui/uikit'; -import { TestStatus } from 'lib/constants'; +import {Checkbox, Spin} from '@gravity-ui/uikit'; +import {TestStatus} from 'lib/constants'; describe('', () => { const sandbox = sinon.sandbox.create(); diff --git a/test/unit/lib/static/components/state/state-error.jsx b/test/unit/lib/static/components/state/state-error.jsx index 3ae4850b4..79b580e09 100644 --- a/test/unit/lib/static/components/state/state-error.jsx +++ b/test/unit/lib/static/components/state/state-error.jsx @@ -142,8 +142,8 @@ describe(' component', () => { const component = mkStateErrorComponent({result: {error}}); component.find('.details__summary').last().simulate('click'); - assert.isFalse(component.find('.details__content').html().includes("some")); - assert.isTrue(component.find('.details__content').html().includes("some<line>")); + assert.isFalse(component.find('.details__content').html().includes('some')); + assert.isTrue(component.find('.details__content').html().includes('some<line>')); }); }); }); diff --git a/test/unit/lib/static/components/suites.jsx b/test/unit/lib/static/components/suites.jsx index a3bde3e13..154ac77bd 100644 --- a/test/unit/lib/static/components/suites.jsx +++ b/test/unit/lib/static/components/suites.jsx @@ -42,7 +42,7 @@ describe('', () => { it('should render few section common components', () => { if (!global.SVGElement) { - global.SVGElement = HTMLElement; // Without this line test throws an error "ReferenceError: SVGElement is not defined" + global.SVGElement = global.HTMLElement; // Without this line test throws an error "ReferenceError: SVGElement is not defined" } getVisibleRootSuiteIds.returns(['suite-id-1', 'suite-id-2']); diff --git a/test/unit/lib/static/components/utils.jsx b/test/unit/lib/static/components/utils.jsx index a9cdd1990..26c5634e3 100644 --- a/test/unit/lib/static/components/utils.jsx +++ b/test/unit/lib/static/components/utils.jsx @@ -3,7 +3,7 @@ import _ from 'lodash'; import configureStore from 'redux-mock-store'; import {Provider} from 'react-redux'; import defaultState from 'lib/static/modules/default-state'; -import { ThemeProvider } from '@gravity-ui/uikit'; +import {ThemeProvider} from '@gravity-ui/uikit'; exports.mkState = ({initialState} = {}) => { return _.defaultsDeep(initialState, defaultState);