diff --git a/lib/static/components/controls/base-host-input.jsx b/lib/static/components/controls/base-host-input.jsx
index dc3385bf1..3d3acb4f6 100644
--- a/lib/static/components/controls/base-host-input.jsx
+++ b/lib/static/components/controls/base-host-input.jsx
@@ -4,6 +4,7 @@ import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
+import {TextInput} from '@gravity-ui/uikit';
import * as actions from '../../modules/actions';
class BaseHostInput extends Component {
@@ -19,12 +20,13 @@ class BaseHostInput extends Component {
render() {
return (
-
);
}
diff --git a/lib/static/components/controls/browser-list/index.jsx b/lib/static/components/controls/browser-list/index.jsx
index e94322b88..a8ee3f6b0 100644
--- a/lib/static/components/controls/browser-list/index.jsx
+++ b/lib/static/components/controls/browser-list/index.jsx
@@ -5,224 +5,169 @@ import {flatten, isEmpty, get, chain, compact} from 'lodash';
import PropTypes from 'prop-types';
import CheckboxTree from 'react-checkbox-tree';
-import Label from './label';
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';
-
-const BrowserList = (props) => {
- const {available, onChange, selected: selectedProp} = props;
-
- const [expanded, setExpanded] = useState([]);
- const [selected, setSelected] = useState(buidSelectedItems());
- const [elements, setElements] = useState([]);
- const treeDataMap = useMemo(buildTreeDataMap, [available]);
- const nodes = useMemo(prepareTreeData, [available]);
- const selectAll = useCallback(_selectAll, [setExpanded, treeDataMap]);
-
- useEffect(() => {
- updateLabels();
- onChange && onChange(formatSelectedData(selected));
- }, [selected]);
-
- function buildTreeDataMap() {
- return available.reduce((acc, {id: browserId, versions}) => {
- const hasChildren = !isEmpty(versions) && versions.length > 1;
-
- acc[buildComplexId(browserId)] = {browserId, isLeaf: !hasChildren};
-
- if (hasChildren) {
- versions.forEach(version => {
- acc[buildComplexId(browserId, version)] = {browserId, version, isLeaf: true};
- });
+import { Button, Select, useSelectOptions } from '@gravity-ui/uikit';
+
+const BrowserList = ({available, onChange, selected: selectedProp}) => {
+ const getOptions = () => {
+ const groups = {};
+ 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),
+ content:
{mkBrowserIcon(browserId)}{buildComplexId(browserId)}
});
+ return;
}
+ hasNestedOptions = true;
+ versions.forEach((version) => {
+ groups[browserId] = groups[browserId] || [];
+ groups[browserId].push({value: buildComplexId(browserId, version),
+ content: {mkBrowserIcon(browserId)}{buildComplexId(browserId, version)}
});
+ })
+ });
+ if (!hasNestedOptions) {
+ return groups[DEFAULT_GROUP];
+ }
+ else {
+ const optionsList = [];
+ Object.keys(groups).forEach((name) => {
+ optionsList.push({
+ label: name,
+ options: groups[name]
+ })
+ })
+ return optionsList;
+ }
- return acc;
- }, {});
}
-
- function buidSelectedItems() {
+ const getMapping = () => {
+ const mapping = {};
+ available.forEach(({id: browserId, versions}) => {
+ if (!versions || !versions.length) {
+ mapping[buildComplexId(browserId)] = {id: browserId};
+ return;
+ }
+ if (versions.length < 2) {
+ mapping[buildComplexId(browserId)] = {id: browserId, version: versions[0]};
+ return;
+ }
+ versions.forEach((version) => {
+ mapping[buildComplexId(browserId, version)] = {id: browserId, version};
+ })
+ });
+ return mapping;
+ }
+ const getSelected = () => {
+ const selectedOptions = [];
if (!selectedProp || !selectedProp.length) {
return [];
}
-
- const selectedItems = selectedProp.map(({id, versions}) => {
- if (!versions) {
- return [];
+ selectedProp.forEach(({id: browserId, versions}) => {
+ if (!versions || versions.length < 2) {
+ selectedOptions.push(buildComplexId(browserId));
+ return;
}
-
- const availableNode = available.find((item) => item.id === id);
- const shouldDrawOnlyRootNode = get(availableNode, 'versions.length', 1) === 1;
-
- if (shouldDrawOnlyRootNode) {
- return buildComplexId(id);
- }
-
- return versions.length
- ? versions.map((version) => buildComplexId(id, version))
- : availableNode.versions.map(version => buildComplexId(id, version));
+ versions.forEach((version) => {
+ selectedOptions.push(buildComplexId(browserId, version));
+ })
});
-
- return flatten(selectedItems);
+ return selectedOptions;
}
-
- function prepareTreeData() {
- const mkNode = ({browserId, version, icon}) => ({
- icon,
- data: {browserId, version},
- value: buildComplexId(browserId, version),
- label: mkLabel({browserId, version, elements})
- });
-
- return available.map(({id: browserId, versions}) => {
- const node = mkNode({browserId, icon: mkBrowserIcon(browserId)});
-
- if (!isEmpty(versions) && versions.length > 1) {
- node.children = versions.map(version => mkNode({browserId, version}));
+ const rawOptions = useMemo(getOptions, [available]);
+ const getOptionsFrom = (optionsData) => {
+ const allOptionsList = [];
+ optionsData.forEach((option) => {
+ if (option.label) {
+ getOptionsFrom(option.options).forEach((o) => allOptionsList.push(o));
}
-
- return node;
- });
+ else {
+ allOptionsList.push(option.value);
+ }
+ })
+ return allOptionsList;
+ }
+ const allOptions = useMemo(() => getOptionsFrom(rawOptions), [rawOptions]);
+ const options = useSelectOptions({
+ options: rawOptions
+ });
+ const mapping = useMemo(getMapping, [available]);
+ const [selected, setSelected] = useState(getSelected());
+
+ const selectAll = () => {
+ setSelected(allOptions);
}
- function _selectAll() {
- const leaves = Object.keys(treeDataMap).filter(key => treeDataMap[key].isLeaf);
- const cb = selected => selected.length !== leaves.length
- ? leaves
- : selected;
-
- setSelected(cb);
+ const formatSelectedData = () => {
+ const selectedData = {}
+ selected.forEach((option) => {
+ 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)}))
}
- function mkLabel({browserId, version, elements}) {
+ const renderFilter = () => {
+ const allSelected = selected.length == options.length;
return (
-
- );
+
+
+
+ )
}
- function buildElements() {
- const availableVersionsCount = available.reduce((acc, browser) => {
- acc[browser.id] = browser.versions ? browser.versions.length : undefined;
- return acc;
- }, {});
-
- const selectedBrowsers = selected.reduce((acc, value) => {
- if (!treeDataMap[value]) {
- return acc;
- }
-
- const {browserId, version} = treeDataMap[value];
-
- acc[browserId] = acc[browserId] || [];
-
- if (version) {
- acc[browserId].push(version);
- }
-
- return acc;
- }, {});
-
- const elementsNew = [];
-
- for (const browserId in selectedBrowsers) {
- const versions = selectedBrowsers[browserId];
- if (!versions.length || (availableVersionsCount[browserId] === versions.length)) {
- elementsNew.push(browserId);
- } else {
- elementsNew.push(...versions.map(version => buildComplexId(browserId, version)));
- }
+ const renderOption = (option) => {
+ const isTheOnlySelected = selected.includes(option.value) && selected.length == 1;
+ const selectOnly = (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ setSelected([option.value]);
}
-
- return elementsNew;
- }
-
- function updateLabels() {
- const newElements = buildElements();
-
- if (get(elements, 'length', 0) !== 1 && get(newElements, 'length', 0) !== 1) {
- setElements(newElements);
- return;
+ const selectExcept = (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ setSelected(allOptions.filter(o => o != option.value));
}
-
- const updatingValues = [
- get(newElements, 'length', undefined) === 1 && newElements[0],
- get(elements, 'length', undefined) === 1 && elements[0]
- ];
-
- const nodesFlat = nodes.reduce((arr, node) => {
- const children = node.children || [];
-
- arr.push(node);
- children.forEach(child => arr.push(child));
-
- return arr;
- }, []);
-
- const updatingNodes = nodesFlat.filter(node => {
- const {browserId, version} = node.data;
-
- return updatingValues.includes(buildComplexId(browserId, version));
- });
-
- updatingNodes.forEach(node => {
- const {browserId, version} = node.data;
- node.label = mkLabel({browserId, version, elements: newElements});
- });
-
- setElements(newElements);
- }
-
- function formatSelectedData(selectedItems) {
- return chain(selectedItems)
- .reduce((acc, value) => {
- const {browserId, version} = treeDataMap[value] || {};
-
- if (browserId) {
- acc[browserId] = acc[browserId] || [];
- acc[browserId].push(version);
- }
-
- return acc;
- }, {})
- .map((versions, id) => ({id, versions: compact(versions)}))
- .value();
- }
-
- if (isEmpty(available)) {
- return ();
+ return (
+
+
+ {option.content}
+
+
+
+ )
}
+
+ useEffect(() => {
+ onChange && onChange(formatSelectedData(selected));
+ }, [selected]);
return (
-
-
}
- action="click"
- >
-
-
-
-
-
-
- );
-};
+
+ )
+}
BrowserList.propTypes = {
available: PropTypes.arrayOf(PropTypes.shape({
diff --git a/lib/static/components/controls/browser-list/index.styl b/lib/static/components/controls/browser-list/index.styl
index 818e2d0c1..fb9e6c9f1 100644
--- a/lib/static/components/controls/browser-list/index.styl
+++ b/lib/static/components/controls/browser-list/index.styl
@@ -1,52 +1,36 @@
-.browserlist
- label-bg-color = #3333cc1a
- button-hover-bg-color = #99999950
-
- .array
- width 220px
-
- .rct-controls
- width 100%
- height 25px
- margin-bottom 10px
- border none
- border-radius 5px
- cursor pointer
- background-color label-bg-color
- transition background-color 150ms linear
-
- &:hover
- background-color button-hover-bg-color;
-
- .rct-node-parent
- .rct-node-leaf
- .rct-node-icon
- display none
-
- .rct-node-icon
- color black
- text-align center
+.g-popup
+ z-index 9999
+.browserlist__filter
+ width 100%
+ display inline-flex
+ justify-content center
+ padding 4px 4px
+
+.browserlist__row
+ width 100%
+ display flex
+ align-items center
+ gap 4px
+
+ .browserlist__row_content
+ flex 1 1 auto
+
+ .action-button
+ opacity 0
+
+.g-select-list__option:hover
+ .browserlist__row
+ .action-button
+ opacity 1
+
+.browserlist__popup
+ .g-select-list__option
+ gap 8px
+ flex-direction: row-reverse
+
+.browser-name
+ display inline-flex
+ gap 4px
- .rct-text
- label
- display inline-flex
- width 100%
- user-select none
-
- &:not(:hover)
- .rct-label__controls
- visibility hidden
-
- &:hover
- background-color: label-bg-color
-
- .rct-label__controls
- visibility visible
-
- .rct-title
- display inherit
- width 100%
-
- .rct-label
- display inherit
- width 100%
+.browserlist
+ width 250px
\ No newline at end of file
diff --git a/lib/static/components/controls/browser-list/label.jsx b/lib/static/components/controls/browser-list/label.jsx
deleted file mode 100644
index c00d1f605..000000000
--- a/lib/static/components/controls/browser-list/label.jsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import {buildComplexId} from './utils';
-
-import './label.styl';
-
-const Label = ({treeDataMap, browserId, version, elements, setSelected}) => {
- const id = buildComplexId(browserId, version);
- const isChildren = key => !version && treeDataMap[key].browserId === browserId;
- const getLeaves = () => Object.keys(treeDataMap).filter(key => treeDataMap[key].isLeaf);
-
- const onOnlyClick = (event) => {
- event.stopPropagation();
-
- const leaves = getLeaves();
- const ids = leaves.includes(id)
- ? [id]
- : leaves.filter(key => isChildren(key));
-
- setSelected(ids);
- };
-
- const onExceptClick = (event) => {
- event.stopPropagation();
-
- const leaves = getLeaves();
- const ids = leaves.includes(id)
- ? leaves.filter(key => key !== id)
- : leaves.filter(key => !isChildren(key));
-
- setSelected(ids);
- };
-
- return (
-
- {version || browserId}
- {elements && elements.length === 1 && elements[0] === id
- ?
- :
- }
-
- );
-};
-
-Label.propTypes = {
- treeDataMap: PropTypes.shape({
- [PropTypes.string]: PropTypes.shape({
- browserId: PropTypes.string.isRequired,
- version: PropTypes.string,
- isLeaf: PropTypes.bool.isRequired
- })
- }),
- browserId: PropTypes.string.isRequired,
- version: PropTypes.string,
- elements: PropTypes.arrayOf(PropTypes.string),
- setSelected: PropTypes.func.isRequired
-};
-
-export default Label;
diff --git a/lib/static/components/controls/browser-list/label.styl b/lib/static/components/controls/browser-list/label.styl
deleted file mode 100644
index 02b2bcfcb..000000000
--- a/lib/static/components/controls/browser-list/label.styl
+++ /dev/null
@@ -1,18 +0,0 @@
-.rct-label
- .rct-label__title
- margin-right 25px
-
- .rct-label__controls
- cursor pointer
- width 70px
- margin-left auto
- border none
- border-radius 5px
- background-color inherit
- opacity 0.5
- transition background-color 150ms linear,
- opacity 150ms linear
-
- &:hover
- background-color #99999950
- opacity 1
diff --git a/lib/static/components/controls/common-controls.jsx b/lib/static/components/controls/common-controls.jsx
index 52a6dcaae..ba4dbaeba 100644
--- a/lib/static/components/controls/common-controls.jsx
+++ b/lib/static/components/controls/common-controls.jsx
@@ -12,52 +12,55 @@ 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 {
+ _onUpdateExpand = (value) => {
+ const {actions} = this.props;
+ const actionsDict = {
+ [EXPAND_ALL]: actions.expandAll,
+ [COLLAPSE_ALL]: actions.collapseAll,
+ [EXPAND_ERRORS]: actions.expandErrors,
+ [EXPAND_RETRIES]: actions.expandRetries
+ }
+ actionsDict[value].call();
+ }
+
render() {
const {actions, view} = this.props;
return (
({value, text: capitalize(value)}))}
+ options = {Object.values(ViewMode).map((value) => ({value, content: capitalize(value)}))}
+ />
+
-
-
-
-
-
-
{
- return {value: dm.id, text: dm.title};
+ return {value: dm.id, content: dm.title};
})}
extendClassNames="diff-mode"
/>
diff --git a/lib/static/components/controls/control-button.tsx b/lib/static/components/controls/control-button.tsx
index 39fa189f1..73f992d30 100644
--- a/lib/static/components/controls/control-button.tsx
+++ b/lib/static/components/controls/control-button.tsx
@@ -1,6 +1,7 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
+import {Button} from '@gravity-ui/uikit';
interface ControlButtonProps {
label: string | Component;
@@ -39,7 +40,6 @@ export default class ControlButton extends Component {
isActive,
isAction,
isSuiteControl,
- isControlGroup,
isDisabled = false,
isRunning = false,
extendClassNames,
@@ -47,23 +47,20 @@ export default class ControlButton extends Component {
} = this.props;
const className = classNames(
- 'button',
{'button_type_suite-controls': isSuiteControl},
- {'button_checked': isActive},
- {'button_type_action': isAction},
- {'control-group__item': isControlGroup},
- {'button_blink': isRunning},
extendClassNames
);
- return ;
+ ;
}
}
diff --git a/lib/static/components/controls/controls.less b/lib/static/components/controls/controls.less
index df47743c9..27002d527 100644
--- a/lib/static/components/controls/controls.less
+++ b/lib/static/components/controls/controls.less
@@ -4,6 +4,9 @@
background-color: #fafaf9;
.control-container {
+ width: 100%;
+ display: inline-flex;
+ align-items: center;
margin-bottom: 15px;
&:last-child {
@@ -102,8 +105,38 @@
}
}
+.expand-dropdown {
+ width: 150px;
+}
+
+.base-host-input {
+ width: 210px;
+ margin-right: auto;
+}
+
+.test-name-filter {
+ width: 500px;
+}
+
+.select__dropdown-s {
+ width: 100px;
+}
+
+.select__dropdown-m {
+ width: 150px;
+}
+
+.select__dropdown-l {
+ width: 200px;
+}
+
.report-info {
.label {
margin: 0 15px 0 0;
}
+ .detail {
+ margin-left: 1em;
+ opacity: 0.8;
+ display: inline-block;
+ }
}
diff --git a/lib/static/components/controls/menu-bar.jsx b/lib/static/components/controls/menu-bar.jsx
index 5295169a7..6131989bb 100644
--- a/lib/static/components/controls/menu-bar.jsx
+++ b/lib/static/components/controls/menu-bar.jsx
@@ -8,15 +8,18 @@ import {isEmpty} from 'lodash';
import ExtensionPoint from '../extension-point';
import plugins from '../../modules/plugins';
import {MENU_BAR} from '../../../constants/extension-points';
+import { Button, DropdownMenu, Icon, Menu } from '@gravity-ui/uikit';
+import {Bars} from '@gravity-ui/icons';
+import classNames from 'classnames';
class MenuBar extends Component {
static propTypes = {extraItems: PropTypes.object.isRequired};
_getItems(extraItems) {
return Object.keys(extraItems).map((key, i) => (
-
- {key}
-
+ {}} className='menu-bar__content_item'>
+ {key}
+
));
}
@@ -32,13 +35,17 @@ class MenuBar extends Component {
return (
-
-
+ (
+
+ )}>
+
-
+
+
);
}
diff --git a/lib/static/components/controls/report-info.jsx b/lib/static/components/controls/report-info.jsx
index 8ab3abb9a..b905920bd 100644
--- a/lib/static/components/controls/report-info.jsx
+++ b/lib/static/components/controls/report-info.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
-import {Label} from 'semantic-ui-react';
import {version} from '../../../../package.json';
+import { Label } from '@gravity-ui/uikit';
class ReportInfo extends Component {
render() {
@@ -9,17 +9,13 @@ class ReportInfo extends Component {
return (
-
);
diff --git a/lib/static/components/controls/run-button/index.jsx b/lib/static/components/controls/run-button/index.jsx
index 5384ccc23..550ba9ae8 100644
--- a/lib/static/components/controls/run-button/index.jsx
+++ b/lib/static/components/controls/run-button/index.jsx
@@ -12,6 +12,7 @@ import {getFailedTests, getCheckedTests} from '../../../modules/selectors/tree';
import useLocalStorage from '../../../hooks/useLocalStorage';
import './index.styl';
+import { Button, Select } from '@gravity-ui/uikit';
const RunMode = Object.freeze({
ALL: 'All',
@@ -46,6 +47,18 @@ const RunButton = ({actions, autoRun, isDisabled, isRunning, failedTests, checke
action();
};
+ const handleSelect = (values) => {
+ if (values.length) {
+ const action = {
+ [RunMode.ALL]: selectAllTests,
+ [RunMode.FAILED]: selectFailedTests,
+ [RunMode.CHECKED]: selectCheckedTests
+ }[values[0]];
+
+ action();
+ }
+ }
+
useEffect(() => {
if (autoRun) {
runAllTests();
@@ -67,33 +80,20 @@ const RunButton = ({actions, autoRun, isDisabled, isRunning, failedTests, checke
return (
-
- {!isDisabled &&
}
- >
-
- -
- {RunMode.ALL}
-
- - {RunMode.FAILED}
-
- -
- {RunMode.CHECKED}
-
-
- }
+
+
);
};
diff --git a/lib/static/components/controls/run-button/index.styl b/lib/static/components/controls/run-button/index.styl
index 6e8e289cc..6287fc901 100644
--- a/lib/static/components/controls/run-button/index.styl
+++ b/lib/static/components/controls/run-button/index.styl
@@ -1,50 +1,6 @@
.run-button {
display: inline-flex;
- align-items: center;
- cursor: pointer;
- width: 143px;
- font-size: 11px;
- line-height: 11px;
- border: 1px solid #ccc;
- border-radius: var(--button-border-radius);
- background-color: var(--button-action-color);
-
- .btn {
- flex-grow: 1;
- height: 100%;
- background-color: var(--button-action-color);
- cursor: pointer;
- border: none;
- border-radius: var(--button-border-radius);
- }
-
.run-button__dropdown {
- font-family: Dropdown;
-
- &::before {
- content: '\f0d7';
- padding: 5px;
- border-left: 1px solid #ccc;
- }
- }
-
- .popup__content {
- padding: 0;
- }
-
- .run-mode {
- padding: 0;
-
- .run-mode__item {
- font-size: 13px;
- padding: 5px 10px;
- list-style: none;
- user-select: none;
-
- &.run-mode__item_disabled {
- color: #939393;
- cursor: auto;
- }
- }
+ width: 150px;
}
}
diff --git a/lib/static/components/controls/selects/control.jsx b/lib/static/components/controls/selects/control.jsx
index 1c9b9fd03..2a18e0e82 100644
--- a/lib/static/components/controls/selects/control.jsx
+++ b/lib/static/components/controls/selects/control.jsx
@@ -1,12 +1,15 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
-import {Label, Dropdown} from 'semantic-ui-react';
+import {Dropdown} from 'semantic-ui-react';
import classNames from 'classnames';
import './index.styl';
+import { Button, Label, Select } from '@gravity-ui/uikit';
+import CustomLabel from './label';
export default class ControlSelect extends Component {
static propTypes = {
+ size: PropTypes.string,
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
handler: PropTypes.func.isRequired,
@@ -14,15 +17,19 @@ export default class ControlSelect extends Component {
value: PropTypes.string,
text: PropTypes.string
})).isRequired,
- extendClassNames: PropTypes.oneOfType([PropTypes.array, PropTypes.string])
+ extendClassNames: PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
+ extendPopupClassNames: PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
+ qa: PropTypes.string,
};
- _onChange = (_, dom) => {
- this.props.handler(dom.value);
- };
+ _onUpdate = (values) => {
+ if (values.length) {
+ this.props.handler(values[0]);
+ }
+ }
render() {
- const {value, label, options, extendClassNames} = this.props;
+ const {size, value, label, options, extendClassNames, extendPopupClassNames, qa} = this.props;
const formattedOpts = options.map(({value, text}) => ({
value,
text,
@@ -35,15 +42,22 @@ export default class ControlSelect extends Component {
extendClassNames
);
+ const popupClassNames = classNames(
+ extendPopupClassNames
+ );
+
return (
- {label}
- {label}
+
);
diff --git a/lib/static/components/controls/selects/group-tests.jsx b/lib/static/components/controls/selects/group-tests.jsx
index 45569f3b5..154e59f46 100644
--- a/lib/static/components/controls/selects/group-tests.jsx
+++ b/lib/static/components/controls/selects/group-tests.jsx
@@ -12,6 +12,8 @@ import {SECTIONS, KEY_DELIMITER} from '../../../../constants/group-tests';
import {getParsedKeyToGroupTestsBy} from '../../../modules/selectors/grouped-tests';
import './index.styl';
+import CustomLabel from './label';
+import { Select } from '@gravity-ui/uikit';
class GroupTestsSelect extends Component {
static propTypes = {
@@ -23,58 +25,37 @@ class GroupTestsSelect extends Component {
selectedGroupKey: PropTypes.string
};
- _groupTestsByKey = (_, dom) => {
- if (dom.value !== this.props.keyToGroupTestsBy) {
- this.props.actions.groupTestsByKey(dom.value);
+ _groupTestsByKey = (values) => {
+ const value = values ? values[0] : undefined;
+ if (value !== this.props.keyToGroupTestsBy) {
+ this.props.actions.groupTestsByKey(value);
}
};
- _renderSection(sectionName) {
- const {groupedTests} = this.props;
- const keys = groupedTests[sectionName].allKeys;
-
- if (isEmpty(keys)) {
- return null;
- }
-
- return (
-
-
-
-
- {keys.map(key => {
- const id = getGroupElemId(sectionName, key);
- const isActive = id === this.props.keyToGroupTestsBy;
-
- return {key};
- })}
-
- );
- }
-
render() {
- const {selectedGroupKey} = this.props;
+ const {selectedGroupKey, groupedTests} = this.props;
const className = classNames(
'select',
'select_type_group'
);
+ const options = Object.values(SECTIONS).map((sectionName) => ({
+ label: sectionName,
+ options: groupedTests[sectionName].allKeys.map((k) => ({ value: `${sectionName}.${k}`, content: k}))
+ }));
return (
- Group by
-
-
- {Object.values(SECTIONS).map((sectionName) => this._renderSection(sectionName))}
-
-
+ Group By
+
);
}
diff --git a/lib/static/components/controls/selects/index.styl b/lib/static/components/controls/selects/index.styl
index 703f8f18a..a3815ab24 100644
--- a/lib/static/components/controls/selects/index.styl
+++ b/lib/static/components/controls/selects/index.styl
@@ -1,61 +1,9 @@
-.select
- display: inline-flex
- height: 25px
+.custom-label
+ border-top-right-radius: 0
+ border-bottom-right-radius: 0
- .select__label
- font-size: 11px
- color: var(--text-color)
- margin: 0
- padding: 0 8px
- line-height: 25px
- background-color: #e7e7e7
- border-radius: var(--button-border-radius)
- border-top-right-radius: 0
- border-bottom-right-radius: 0
+.group-by-dropdown
+ width: 150px
- .select__dropdown.ui.dropdown
- min-height: 25px
- min-width: 70px
- font-size: 11px
- line-height: 13px
- padding: 5px 8px
- padding-right: 25px
- border: 1px solid #ccc
- border-radius: var(--button-border-radius)
- border-top-left-radius: 0
- border-bottom-left-radius: 0
-
- &:hover
- border: 1px solid var(--button-hover-color);
-
- &.active
- .menu
- border-radius: 0 0 var(--button-border-radius) var(--button-border-radius)
- &:hover
- border-radius: 0 var(--button-border-radius) 0 0
- .menu
- border-color: var(--button-hover-color)
-
- .icon.dropdown
- padding: 0
- margin: 0
- line-height: initial
-
- &.diff-mode
- .select__dropdown.ui.dropdown
- min-width: 95px
-
- &.select_type_group
- .select__dropdown.ui.dropdown
- min-width: 110px
-
- .menu > .header
- margin: 0
- padding: 0 0 0 5px
- border-bottom: 0
-
- .menu > .divider
- margin: 5px 0
-
- .menu > .item
- padding-left: 10px !important
+.select_type_control, .select_type_group
+ display inline-flex
\ No newline at end of file
diff --git a/lib/static/components/controls/selects/label.jsx b/lib/static/components/controls/selects/label.jsx
new file mode 100644
index 000000000..cb44ec31c
--- /dev/null
+++ b/lib/static/components/controls/selects/label.jsx
@@ -0,0 +1,10 @@
+import React, {Component} from 'react';
+import { Label } from '@gravity-ui/uikit';
+import './index.styl';
+import classNames from 'classnames';
+
+const CustomLabel = ({className, ...otherProps}) => {
+ return ()
+}
+
+export default CustomLabel;
\ No newline at end of file
diff --git a/lib/static/components/controls/show-checkboxes-input.jsx b/lib/static/components/controls/show-checkboxes-input.jsx
index 1e485d45b..3697f1a89 100644
--- a/lib/static/components/controls/show-checkboxes-input.jsx
+++ b/lib/static/components/controls/show-checkboxes-input.jsx
@@ -3,6 +3,7 @@
import React from 'react';
import {Checkbox} from 'semantic-ui-react';
import useLocalStorage from '../../hooks/useLocalStorage';
+import { Switch } from '@gravity-ui/uikit';
const ShowCheckboxesInput = () => {
const [showCheckboxes, setShowCheckboxes] = useLocalStorage('showCheckboxes', false);
@@ -10,14 +11,7 @@ const ShowCheckboxesInput = () => {
const onChange = () => setShowCheckboxes(!showCheckboxes);
return (
-
-
-
+
);
};
diff --git a/lib/static/components/controls/strict-match-filter-input.jsx b/lib/static/components/controls/strict-match-filter-input.jsx
index 14dd226fd..6d70d4302 100644
--- a/lib/static/components/controls/strict-match-filter-input.jsx
+++ b/lib/static/components/controls/strict-match-filter-input.jsx
@@ -6,6 +6,7 @@ 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';
const StrictMatchFilterInput = ({strictMatchFilter, actions}) => {
const [checked, setChecked] = useState(strictMatchFilter);
@@ -17,15 +18,7 @@ const StrictMatchFilterInput = ({strictMatchFilter, actions}) => {
};
return (
-
-
-
+
);
};
diff --git a/lib/static/components/controls/test-name-filter-input.jsx b/lib/static/components/controls/test-name-filter-input.jsx
index 18d65690a..78f7c23f2 100644
--- a/lib/static/components/controls/test-name-filter-input.jsx
+++ b/lib/static/components/controls/test-name-filter-input.jsx
@@ -6,6 +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';
const TestNameFilterInput = ({actions, testNameFilter: testNameFilterProp}) => {
const [testNameFilter, setTestNameFilter] = useState(testNameFilterProp);
@@ -22,12 +23,13 @@ const TestNameFilterInput = ({actions, testNameFilter: testNameFilterProp}) => {
};
return (
-
);
};
diff --git a/lib/static/components/header/summary/dbBtn.jsx b/lib/static/components/header/summary/dbBtn.jsx
index 2d39b0409..4957b009c 100644
--- a/lib/static/components/header/summary/dbBtn.jsx
+++ b/lib/static/components/header/summary/dbBtn.jsx
@@ -1,26 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {Ref, Button} from 'semantic-ui-react';
+import {Ref} from 'semantic-ui-react';
import classNames from 'classnames';
+import { Button, ButtonIcon } from '@gravity-ui/uikit';
+import {ChevronDown} from '@gravity-ui/icons';
const DbBtn = ({fetchDbDetails}, ref) => {
const successFetchDbDetails = fetchDbDetails.filter(d => d.success);
const isFailed = successFetchDbDetails.length !== fetchDbDetails.length;
const value = `${successFetchDbDetails.length}/${fetchDbDetails.length}`;
const content = `Databases loaded: ${value}`;
- const className = classNames(
- 'db-info',
- {'db-info_failed': isFailed}
- );
return (
[
+ view={isFailed ? 'flat-danger' : 'flat'}
+ >
+ ]
+
+ {content}
+
+
);
};
diff --git a/lib/static/components/header/summary/dbSummary.jsx b/lib/static/components/header/summary/dbSummary.jsx
index aab8d60dc..8e035df1e 100644
--- a/lib/static/components/header/summary/dbSummary.jsx
+++ b/lib/static/components/header/summary/dbSummary.jsx
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import DbBtn from './dbBtn';
import Popup from '../../popup';
+import { Popover } from '@gravity-ui/uikit';
export default class DbSummaryKey extends Component {
/*
@@ -37,13 +38,17 @@ export default class DbSummaryKey extends Component {
));
return (
- }
+
+
- {additionalInfo}
-
+
+
+
);
}
}
diff --git a/lib/static/components/header/summary/summary.css b/lib/static/components/header/summary/summary.css
index fb0d8b876..c0b624cec 100644
--- a/lib/static/components/header/summary/summary.css
+++ b/lib/static/components/header/summary/summary.css
@@ -1,6 +1,7 @@
.summary {
margin: 0;
display: flex;
+ align-items: center;
}
.summary__key {
@@ -34,19 +35,15 @@
display: inline;
}
-.db-info__popup {
+.db-info-container {
+ --g-popover-max-width: 100vw;
margin-left: auto;
}
-.ui.basic.db-info {
- font-family: inherit;
- font-size: inherit;
- line-height: 18px;
- height: auto;
- padding: 0;
- box-shadow: none !important;
- border: none;
- color: #000 !important;
+.db-info {
+ display: inline-flex;
+ align-items: center;
+ gap: 2px;
}
.ui.basic.db-info:hover {
@@ -61,7 +58,7 @@
color: #e66767 !important;
}
-.popup__content .db-info__row {
+.db-info-container .db-info__row {
white-space: nowrap;
font-size: 15px;
}
diff --git a/lib/static/gui.css b/lib/static/gui.css
index 7d1a6f39d..e93546965 100644
--- a/lib/static/gui.css
+++ b/lib/static/gui.css
@@ -105,10 +105,6 @@
}
.button_type_suite-controls {
- padding: 2px 8px;
- border-radius: var(--button-border-radius);
- font-size: 13px;
- line-height: 18px;
margin-right: 10px;
}
diff --git a/test/func/fixtures/playwright/tests/screens/failed-describe-test-without-screenshot/chromium/header.png b/test/func/fixtures/playwright/tests/screens/failed-describe-test-without-screenshot/chromium/header.png
index 2baf53cb5..e2c552fe0 100644
Binary files a/test/func/fixtures/playwright/tests/screens/failed-describe-test-without-screenshot/chromium/header.png and b/test/func/fixtures/playwright/tests/screens/failed-describe-test-without-screenshot/chromium/header.png differ
diff --git a/test/func/tests/.testplane.conf.js b/test/func/tests/.testplane.conf.js
index 67d4b9915..8077cea91 100644
--- a/test/func/tests/.testplane.conf.js
+++ b/test/func/tests/.testplane.conf.js
@@ -22,6 +22,7 @@ if (!projectUnderTest) {
const commonConfig = getCommonConfig(__dirname);
const config = _.merge(commonConfig, {
+ retry: 4,
baseUrl: `http://${serverHost}:${serverPort}/fixtures/${projectUnderTest}/report/index.html`,
sets: {
diff --git a/test/func/tests/common-gui/index.testplane.js b/test/func/tests/common-gui/index.testplane.js
index ddc87b890..27a63cfdf 100644
--- a/test/func/tests/common-gui/index.testplane.js
+++ b/test/func/tests/common-gui/index.testplane.js
@@ -36,7 +36,8 @@ describe('GUI mode', () => {
guiProcess = await runGui(projectDir);
await browser.url(guiUrl);
- await browser.$('button*=Expand all').click();
+ await browser.$('//*[contains(@class, "expand-dropdown")]//button').click();
+ await browser.$('//*[contains(@class, "expand-popup")]//span[contains(normalize-space(), "All")]').click();
});
afterEach(async () => {
@@ -53,7 +54,7 @@ describe('GUI mode', () => {
it('should run a single test', async ({browser}) => {
const retryButton = await browser.$(
getTestSectionByNameSelector('successful test') +
- '//button[contains(text(), "Retry")]'
+ '//button[contains(normalize-space(), "Retry")]'
);
await retryButton.click();
@@ -83,7 +84,7 @@ describe('GUI mode', () => {
const acceptButton = await browser.$(
getTestSectionByNameSelector(fullTestName) +
- '//button[contains(text(), "Accept")]'
+ '//button[contains(normalize-space(), "Accept")]'
);
await acceptButton.click();
diff --git a/test/func/tests/common-tinder/index.testplane.js b/test/func/tests/common-tinder/index.testplane.js
index e17a33afe..33be89237 100644
--- a/test/func/tests/common-tinder/index.testplane.js
+++ b/test/func/tests/common-tinder/index.testplane.js
@@ -26,7 +26,8 @@ describe('Tinder mode', () => {
guiProcess = await runGui(projectDir);
await browser.url(guiUrl);
- await browser.$('button*=Expand all').click();
+ await browser.$('//*[contains(@class, "expand-dropdown")]//button').click();
+ await browser.$('//*[contains(@class, "expand-popup")]//span[contains(normalize-space(), "All")]').click();
await browser.$('button*=Switch accept mode').click();
});
@@ -45,7 +46,7 @@ describe('Tinder mode', () => {
beforeEach(async ({browser}) => {
const testFullName = await browser.$('span[data-test-id="screenshot-accepter-test-name"]').getText();
- const acceptButton = await browser.$('button[data-test-id="screenshot-accepter-accept"]');
+ const acceptButton = await browser.$('button[data-qa="screenshot-accepter-accept"]');
await acceptButton.click();
await browser.waitUntil(async () => {
@@ -54,13 +55,13 @@ describe('Tinder mode', () => {
return progress === '1/2';
}, {interval: 100});
- const switchAcceptModeButton = await browser.$('button[data-test-id="screenshot-accepter-switch-accept-mode"]');
+ const switchAcceptModeButton = await browser.$('button[data-qa="screenshot-accepter-switch-accept-mode"]');
await switchAcceptModeButton.click();
- const testNameFilterInput = await browser.$('input[data-test-id="header-test-name-filter"]');
+ const testNameFilterInput = await browser.$('//*[@data-qa="header-test-name-filter"]//input');
await testNameFilterInput.setValue(testFullName);
- await browser.$('div[data-test-id="header-strict-match"]').click();
+ await browser.$('*[data-qa="header-strict-match"]').click();
await waitForFsChanges(screensDir);
});
@@ -73,7 +74,7 @@ describe('Tinder mode', () => {
});
it('should make the test pass on next run', async ({browser}) => {
- const retryButton = await browser.$('button[data-test-id="test-retry"]');
+ const retryButton = await browser.$('button[data-qa="test-retry"]');
// TODO: find a correct sign to wait for. Issue is that retry button is totally clickable, but doesn't
// work right away after switch accept mode and applying filtering for some reason.
@@ -92,7 +93,7 @@ describe('Tinder mode', () => {
describe(`undo accepting screenshot`, () => {
it('should leave project files intact', async ({browser}) => {
- const acceptButton = await browser.$('button[data-test-id="screenshot-accepter-accept"]');
+ const acceptButton = await browser.$('button[data-qa="screenshot-accepter-accept"]');
await acceptButton.click();
await browser.waitUntil(async () => {
@@ -104,7 +105,7 @@ describe('Tinder mode', () => {
await waitForFsChanges(screensDir);
const fsDiffBeforeUndo = getFsDiffFromVcs(screensDir);
- const undoButton = await browser.$('button[data-test-id="screenshot-accepter-undo"]');
+ const undoButton = await browser.$('button[data-qa="screenshot-accepter-undo"]');
await undoButton.click();
await waitForFsChanges(screensDir, (output) => output.length === 0);
@@ -117,7 +118,7 @@ describe('Tinder mode', () => {
});
it('should show success screen after accepting all screenshots', async ({browser}) => {
- const acceptButton = await browser.$('button[data-test-id="screenshot-accepter-accept"]');
+ const acceptButton = await browser.$('button[data-qa="screenshot-accepter-accept"]');
for (let i = 1; i <= 2; i++) {
await acceptButton.click();
diff --git a/test/func/tests/common/error-group.testplane.js b/test/func/tests/common/error-group.testplane.js
index 4049b4d15..867ec9103 100644
--- a/test/func/tests/common/error-group.testplane.js
+++ b/test/func/tests/common/error-group.testplane.js
@@ -1,10 +1,10 @@
describe('Error grouping', function() {
it('should group errors', async ({browser}) => {
- const groupByDropdown = await browser.$('div[data-test-id="group-by-dropdown"]');
+ const groupByDropdown = await browser.$('[data-qa="group-by-dropdown"]');
await groupByDropdown.click();
- await groupByDropdown.$('div=error').click();
+ await browser.$('div=error').click();
const groupedTestsContainer = await browser.$('.grouped-tests');
diff --git a/test/func/tests/common/test-results-appearance.testplane.js b/test/func/tests/common/test-results-appearance.testplane.js
index a9cfbc336..6248554c8 100644
--- a/test/func/tests/common/test-results-appearance.testplane.js
+++ b/test/func/tests/common/test-results-appearance.testplane.js
@@ -8,7 +8,8 @@ const {
describe('Test results appearance', () => {
beforeEach(async ({browser}) => {
- await browser.$('button*=Expand all').click();
+ await browser.$('//*[contains(@class, "expand-dropdown")]//button').click();
+ await browser.$('//*[contains(@class, "expand-popup")]//span[contains(normalize-space(), "All")]').click();
});
describe('Passed test', () => {
diff --git a/test/func/tests/common/tests-header.testplane.js b/test/func/tests/common/tests-header.testplane.js
index 0b2a5a3be..e668a1c65 100644
--- a/test/func/tests/common/tests-header.testplane.js
+++ b/test/func/tests/common/tests-header.testplane.js
@@ -15,13 +15,13 @@ describe('Report header', function() {
describe('Main menu', function() {
it('should show creation date', async ({browser}) => {
- const creationLabel = await browser.$('div[data-test-id="created-at-label"]');
+ const creationLabel = await browser.$('div[data-qa="created-at-label"]');
await expect(creationLabel).toBeDisplayed();
});
it('should show report version', async ({browser}) => {
- const versionLabel = await browser.$('div[data-test-id="version-label"]');
+ const versionLabel = await browser.$('div[data-qa="version-label"]');
await expect(versionLabel).toBeDisplayed();
});
diff --git a/test/func/tests/eye/index.testplane.js b/test/func/tests/eye/index.testplane.js
index 7d9076e27..e34def25f 100644
--- a/test/func/tests/eye/index.testplane.js
+++ b/test/func/tests/eye/index.testplane.js
@@ -2,7 +2,8 @@ const {Key} = require('webdriverio');
describe('View in browser button behavior', () => {
beforeEach(async ({browser}) => {
- await browser.$('button*=Expand all').click();
+ await browser.$('//*[contains(@class, "expand-dropdown")]//button').click();
+ await browser.$('//*[contains(@class, "expand-popup")]//span[contains(normalize-space(), "All")]').click();
});
it('should be clickable', async ({browser}) => {
@@ -19,7 +20,7 @@ describe('View in browser button behavior', () => {
});
it('should change in accordance to the baseHost in header', async ({browser}) => {
- const baseHostInput = await browser.$('input[data-test-id="base-host"]');
+ const baseHostInput = await browser.$('[data-qa="base-host"]').$('input');
await baseHostInput.click();
baseHostInput.setValue('http://some-host.dev:33');
await browser.keys([Key.Enter]);
diff --git a/test/func/tests/plugins/tests-menu-bar-plugin.testplane.js b/test/func/tests/plugins/tests-menu-bar-plugin.testplane.js
index bb1b5de37..c0987bec1 100644
--- a/test/func/tests/plugins/tests-menu-bar-plugin.testplane.js
+++ b/test/func/tests/plugins/tests-menu-bar-plugin.testplane.js
@@ -1,7 +1,5 @@
-const {mkNestedSelector} = require('../../utils');
-
describe('Test menu bar plugin', function() {
- const selector = 'div[data-test-id="menu-bar"]';
+ const selector = '.menu-bar__dropdown';
it('should show menu bar with plugins applied', async ({browser}) => {
await browser.$(selector).waitForDisplayed();
@@ -9,7 +7,7 @@ describe('Test menu bar plugin', function() {
});
it('should show menu bar item on click', async ({browser}) => {
- const menuSelector = mkNestedSelector(selector, '.menu');
+ const menuSelector = '.menu-bar__content';
await browser.$(selector).waitForDisplayed();
await browser.$(selector).click();
diff --git a/test/func/tests/screens/3144090/chrome/menu bar plugins clicked.png b/test/func/tests/screens/3144090/chrome/menu bar plugins clicked.png
index c410bd41a..6dfeeb729 100644
Binary files a/test/func/tests/screens/3144090/chrome/menu bar plugins clicked.png and b/test/func/tests/screens/3144090/chrome/menu bar plugins clicked.png differ
diff --git a/test/func/tests/screens/5c90021/chrome/basic plugins.png b/test/func/tests/screens/5c90021/chrome/basic plugins.png
index 5b4481b00..77595ada2 100644
Binary files a/test/func/tests/screens/5c90021/chrome/basic plugins.png and b/test/func/tests/screens/5c90021/chrome/basic plugins.png differ
diff --git a/test/func/tests/screens/972e9ff/chrome/menu bar plugins.png b/test/func/tests/screens/972e9ff/chrome/menu bar plugins.png
index 357de007c..b65e3da64 100644
Binary files a/test/func/tests/screens/972e9ff/chrome/menu bar plugins.png and b/test/func/tests/screens/972e9ff/chrome/menu bar plugins.png differ
diff --git a/test/func/tests/screens/be4ff5b/chrome/basic plugins clicked.png b/test/func/tests/screens/be4ff5b/chrome/basic plugins clicked.png
index 4c2e132d0..18daa28f8 100644
Binary files a/test/func/tests/screens/be4ff5b/chrome/basic plugins clicked.png and b/test/func/tests/screens/be4ff5b/chrome/basic plugins clicked.png differ
diff --git a/test/func/tests/screens/d8c5b8a/chrome/redux plugin clicked.png b/test/func/tests/screens/d8c5b8a/chrome/redux plugin clicked.png
index ce6b09dc3..76f389334 100644
Binary files a/test/func/tests/screens/d8c5b8a/chrome/redux plugin clicked.png and b/test/func/tests/screens/d8c5b8a/chrome/redux plugin clicked.png differ
diff --git a/test/func/tests/utils.js b/test/func/tests/utils.js
index f918d6591..39f54053e 100644
--- a/test/func/tests/utils.js
+++ b/test/func/tests/utils.js
@@ -13,7 +13,7 @@ const getTestStateByNameSelector = (stateName) => `//div[contains(text(),'${stat
const getImageSectionSelector = (status) => `//div[contains(text(), '${status}')]/..`;
/** Returns an element containing specified text */
-const getElementWithTextSelector = (tagName, text) => `//${tagName}[contains(text(),'${text}')]`;
+const getElementWithTextSelector = (tagName, text) => `//${tagName}[contains(normalize-space(),'${text}')]`;
/** Returns element which has summary containing name */
const getSpoilerByNameSelector = (name) => `details[.//summary[contains(text(), "${name}")]]`;
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 c96d917ec..399bda296 100644
--- a/test/unit/lib/static/components/controls/browser-list/index.jsx
+++ b/test/unit/lib/static/components/controls/browser-list/index.jsx
@@ -1,5 +1,6 @@
import React from 'react';
import BrowserList from '../../../../../../../lib/static/components/controls/browser-list';
+import { ThemeProvider } from '@gravity-ui/uikit';
describe('', () => {
const sandbox = sinon.sandbox.create();
@@ -13,9 +14,10 @@ describe('', () => {
{id: 'bro2'}
]
};
- const component = mount();
-
- assert.equal(component.find('.array__container .array__item').length, 0);
+ 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);
});
it('should contain selected items', () => {
@@ -30,14 +32,15 @@ describe('', () => {
{id: 'bro3', versions: ['unknown']}
]
};
- const component = mount();
+ const component = mount();
+ component.first().find('.g-select-control__button').simulate('click');
- assert.equal(component.find('.array__container .array__item').length, 2);
- assert.equal(component.find('.array__container .array__item').at(0).text(), 'bro2');
- assert.equal(component.find('.array__container .array__item').at(1).text(), 'bro3');
+ assert.equal(component.first().find('.g-list__items .g-list__item_selected').length, 2);
+ assert.equal(component.first().find('.g-list__items .g-list__item_selected .browserlist__row_content').at(0).text(), 'bro2');
+ assert.equal(component.first().find('.g-list__items .g-list__item_selected .browserlist__row_content').at(1).text(), 'bro3');
});
- it('should create nested checkboxes for versions', async () => {
+ it('should create groups for versions', async () => {
const props = {
available: [
{id: 'bro1', versions: ['v1', 'v2', 'v3']}
@@ -48,11 +51,10 @@ describe('', () => {
onChange: () => {}
};
- const component = mount();
- component.find('.rct-collapse').first().simulate('click');
+ const component = mount();
+ component.first().find('.g-select-control__button').simulate('click');
- assert.equal(component.find('.rct-node-leaf .rct-label__title').at(0).text(), 'v1');
- assert.equal(component.find('.rct-node-leaf .rct-label__title').at(1).text(), 'v2');
+ assert.equal(component.find('.g-select-list__group-label-content').at(0).text(), 'bro1');
});
it('should trigger "change" event with selected browsers and versions', () => {
@@ -60,23 +62,25 @@ describe('', () => {
available: [
{id: 'bro'},
{id: 'bro1', versions: ['v1']},
- {id: 'bro2', versions: ['v1', 'v2']}
+ {id: 'bro2', versions: ['v1', 'v2', 'v3']}
],
selected: [
{id: 'bro'},
{id: 'bro1', versions: ['v1']},
- {id: 'bro2', versions: ['v1']}
+ {id: 'bro2', versions: ['v1', 'v2', 'v3']}
],
onChange: sandbox.spy()
};
- const component = mount();
+ const component = mount();
- component.find('.rct-checkbox').first().simulate('click');
+ component.first().find('.g-select-control__button').simulate('click');
+ component.first().find('.g-popup .g-select-list__option').last().simulate('click');
- assert.equal(props.onChange.callCount, 1);
- assert.deepEqual(props.onChange.firstCall.lastArg, [
- {id: 'bro1', versions: []},
- {id: 'bro2', versions: ['v1']}
+ assert.equal(props.onChange.callCount, 2);
+ assert.deepEqual(props.onChange.lastCall.lastArg, [
+ {id: 'bro', versions: []},
+ {id: 'bro1', versions: ['v1']},
+ {id: 'bro2', versions: ['v1', 'v2']}
]);
});
});
diff --git a/test/unit/lib/static/components/controls/browser-list/label.jsx b/test/unit/lib/static/components/controls/browser-list/label.jsx
deleted file mode 100644
index 2597ad718..000000000
--- a/test/unit/lib/static/components/controls/browser-list/label.jsx
+++ /dev/null
@@ -1,162 +0,0 @@
-import React from 'react';
-import Label from '../../../../../../../lib/static/components/controls/browser-list/label';
-
-describe('', () => {
- const sandbox = sinon.sandbox.create();
-
- let setSelected;
-
- beforeEach(() => {
- setSelected = sandbox.stub();
- });
-
- afterEach(() => sandbox.restore());
-
- function mkProps_(opts) {
- const browserId = opts.browserId || 'bro1';
- const isLeaf = opts.isLeaf !== undefined && opts.isLeaf;
- const version = opts.isLeaf !== false && (opts.version || 'v1');
- const id = isLeaf ? `${browserId} (${version})` : browserId;
- const treeDataMap = opts.treeDataMap || {[id]: {browserId, version, isLeaf}};
- const elements = opts.elements || [];
-
- return {treeDataMap, browserId, version, elements, setSelected};
- }
-
- describe('label', () => {
- function assertText_(opts, label) {
- const props = mkProps_(opts);
-
- const component = mount();
-
- assert.equal(component.find('.rct-label__title').text(), label);
- }
-
- it('should show browserId for parent node', () => {
- assertText_({browserId: 'bro1', isLeaf: false}, 'bro1');
- });
-
- it('should show version for child node', () => {
- assertText_({version: 'v1', isLeaf: true}, 'v1');
- });
- });
-
- describe('should have "Only" button', () => {
- function check_(opts) {
- const props = mkProps_(opts);
-
- const component = mount();
-
- assert.equal(component.find('.rct-label__controls').text(), 'Only');
- }
-
- it('if no elements selected', () => {
- check_({elements: []});
- });
-
- it('if element is not selected', () => {
- check_({browser: 'bro1', version: 'v1', elements: ['bro1 (v2)']});
- });
-
- it('if other elements selected', () => {
- check_({browser: 'bro1', version: 'v1', elements: ['bro1 (v1)', 'bro1 (v2)']});
- });
-
- it('if parent only selected', () => {
- const elements = ['bro1'];
- const treeDataMap = {
- bro1: {browserId: 'bro1'},
- 'bro1 (v1)': {browserId: 'bro1', version: 'v1', isLeaf: true}
- };
-
- check_({browser: 'bro1', version: 'v1', treeDataMap, elements});
- });
- });
-
- describe('should have "Except" button', () => {
- function check_(opts) {
- const props = mkProps_(opts);
-
- const component = mount();
-
- assert.equal(component.find('.rct-label__controls').text(), 'Except');
- }
-
- it('if only this leaf is selected', () => {
- check_({browserId: 'bro1', version: 'v1', elements: ['bro1 (v1)']});
- });
-
- it('if only this parent is selected', () => {
- const browserId = 'bro1';
- const elements = ['bro1 (v1)'];
- const treeDataMap = {
- bro1: {browserId: 'bro1'},
- 'bro1 (v1)': {browserId: 'bro1', version: 'v1', isLeaf: true}
- };
-
- check_({browserId, treeDataMap, elements});
- });
- });
-
- describe('controls click', () => {
- let treeDataMap;
-
- beforeEach(() => {
- // V bro1
- // | v1
- // | v2
- //
- // V bro2
- // | v1
- // | v2
- //
- // bro3
-
- treeDataMap = {
- 'bro1': {browserId: 'bro1'},
- 'bro1 (v1)': {browserId: 'bro1', version: 'v1', isLeaf: true},
- 'bro1 (v2)': {browserId: 'bro1', version: 'v2', isLeaf: true},
- 'bro2': {browserId: 'bro2'},
- 'bro2 (v1)': {browserId: 'bro2', version: 'v1', isLeaf: true},
- 'bro2 (v2)': {browserId: 'bro2', version: 'v2', isLeaf: true},
- 'bro3': {browserId: 'bro3', isLeaf: true}
- };
- });
-
- function click_(opts) {
- const props = mkProps_(Object.assign(opts, {treeDataMap}));
-
- const component = mount();
-
- component.find('.rct-label__controls').first().simulate('click');
- }
-
- describe('"Only" click', () => {
- it('should select this leaf node', () => {
- click_({browserId: 'bro1', version: 'v1', elements: ['bro1 (v2)', 'bro2'], isLeaf: true});
-
- assert.calledOnceWith(setSelected, ['bro1 (v1)']);
- });
-
- it('should select child nodes', () => {
- click_({browserId: 'bro1', elements: ['bro2 (v2)'], isLeaf: false});
-
- assert.calledOnceWith(setSelected, ['bro1 (v1)', 'bro1 (v2)']);
- });
- });
-
- describe('"Except" click', () => {
- it('should select all nodes leaf node', () => {
- click_({browserId: 'bro1', version: 'v1', elements: ['bro1 (v1)'], isLeaf: true});
-
- assert.calledOnceWith(setSelected, ['bro1 (v2)', 'bro2 (v1)', 'bro2 (v2)', 'bro3']);
- });
-
- it('should select child nodes', () => {
- click_({browserId: 'bro2', elements: ['bro2'], isLeaf: false});
-
- assert.calledOnceWith(setSelected, ['bro1 (v1)', 'bro1 (v2)', 'bro3']);
- });
- });
- });
-});
diff --git a/test/unit/lib/static/components/controls/menu-bar.jsx b/test/unit/lib/static/components/controls/menu-bar.jsx
index 5ae599c60..624394a57 100644
--- a/test/unit/lib/static/components/controls/menu-bar.jsx
+++ b/test/unit/lib/static/components/controls/menu-bar.jsx
@@ -7,17 +7,18 @@ describe('', () => {
const component = mkConnectedComponent(, {
initialState: {apiValues: {extraItems: {some: 'link'}}}
});
- const dropdown = component.find('.menu-bar .dropdown .item').first();
+ component.find('button.menu-bar__dropdown').simulate('click');
+ const item = component.first().find('.menu-bar__content_item').first();
- assert.equal(dropdown.text(), 'some');
- assert.equal(dropdown.first().props().children.props.href, 'link');
+ assert.equal(item.text(), 'some');
+ assert.equal(item.first().props().children.props.href, 'link');
});
it('should not show dropdown menu if extra items are not passed', () => {
const component = mkConnectedComponent(, {
initialState: {apiValues: {extraItems: {}}}
});
- const dropdown = component.find('.menu-bar .dropdown .item').first();
+ const dropdown = component.find('.button.menu-bar__dropdown').first();
assert.equal(dropdown.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 d296925a1..d491e8d3f 100644
--- a/test/unit/lib/static/components/controls/run-button.jsx
+++ b/test/unit/lib/static/components/controls/run-button.jsx
@@ -33,7 +33,7 @@ describe('', () => {
initialState: {tree: {suites: {allRootIds: []}}, processing: false}
});
- assert.isTrue(component.find('button').prop('disabled'));
+ assert.isTrue(component.find('button.run-button__button').prop('disabled'));
});
it('should be enabled if suites exist to run', () => {
@@ -41,7 +41,7 @@ describe('', () => {
initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false}
});
- assert.isFalse(component.find('button').prop('disabled'));
+ assert.isFalse(component.find('button.run-button__button').prop('disabled'));
});
it('should be disabled while processing something', () => {
@@ -49,7 +49,7 @@ describe('', () => {
initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: true}
});
- assert.isTrue(component.find('button').prop('disabled'));
+ assert.isTrue(component.find('button.run-button__button').prop('disabled'));
});
it('should run all tests with "autoRun" prop', () => {
@@ -65,7 +65,7 @@ describe('', () => {
initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false}
});
- component.find('button').simulate('click');
+ component.find('button.run-button__button').simulate('click');
assert.calledOnce(actionsStub.runAllTests);
});
@@ -76,9 +76,9 @@ describe('', () => {
const state = mkState({initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false}});
selectorsStub.getFailedTests.withArgs(state).returns(failedTests);
const component = mkConnectedComponent(, {state});
- component.find({children: 'Failed'}).simulate('click');
+ component.find({children: 'Failed Tests'}).simulate('click');
- component.find('button').simulate('click');
+ component.find('button.run-button__button').simulate('click');
assert.calledOnceWith(actionsStub.runFailedTests, failedTests);
});
@@ -89,9 +89,9 @@ describe('', () => {
const state = mkState({initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false}});
selectorsStub.getCheckedTests.withArgs(state).returns(checkedTests);
const component = mkConnectedComponent(, {state});
- component.find({children: 'Checked'}).simulate('click');
+ component.find({children: 'Checked Tests'}).simulate('click');
- component.find('button').simulate('click');
+ component.find('button.run-button__button').simulate('click');
assert.calledOnceWith(actionsStub.retrySuite, checkedTests);
});
@@ -102,7 +102,7 @@ describe('', () => {
initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false, running: true}
});
- assert.equal(component.find('button').text(), 'Running');
+ assert.equal(component.find('button.run-button__button').text(), 'Running');
});
it('should be "Run all tests" by default if there is no checked tests', () => {
@@ -111,7 +111,7 @@ describe('', () => {
initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false}
});
- assert.equal(component.find('button').text(), 'Run all tests');
+ assert.equal(component.find('div.run-button__dropdown').text(), 'All Tests');
});
it('should switch to "Run checked tests" if there are checked tests', () => {
@@ -126,13 +126,14 @@ describe('', () => {
describe('localStorage', () => {
it('should save "Run all tests" if picked', () => {
+ useLocalStorageStub.withArgs('RunMode', 'Failed').returns(['Failed', writeValueStub]);
selectorsStub.getCheckedTests.returns([{testName: 'testName', browserName: 'browserName'}]);
selectorsStub.getFailedTests.returns([{testName: 'testName', browserName: 'browserName'}]);
const component = mkConnectedComponent(, {
initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false}
});
-
- component.find({children: 'All'}).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');
});
@@ -142,7 +143,8 @@ describe('', () => {
initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false}
});
- component.find({children: 'Failed'}).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');
});
@@ -152,7 +154,8 @@ describe('', () => {
initialState: {tree: {suites: {allRootIds: ['suite']}}, processing: false}
});
- component.find({children: 'Checked'}).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 cd4c5ef51..a59bbbf2d 100644
--- a/test/unit/lib/static/components/controls/show-checkboxes-input.jsx
+++ b/test/unit/lib/static/components/controls/show-checkboxes-input.jsx
@@ -32,7 +32,7 @@ describe('', () => {
useLocalStorageStub.withArgs('showCheckboxes', false).returns([checked, hookHandler]);
const component = mount();
- component.find(Checkbox).simulate('change');
+ component.find('input[type="checkbox"]').simulate('change');
assert.calledOnceWith(hookHandler, !checked);
});
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 80c24fba4..11613a500 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
@@ -42,7 +42,7 @@ describe('', () => {
initialState: {view: {strictMatchFilter: false}}
});
- component.find(Checkbox).simulate('change');
+ component.find('input[type="checkbox"]').simulate('change');
assert.calledOnceWith(actionsStub.setStrictMatchFilter, true);
});
@@ -52,7 +52,7 @@ describe('', () => {
initialState: {view: {strictMatchFilter: true}}
});
- component.find(Checkbox).simulate('change');
+ component.find('input[type="checkbox"]').simulate('change');
assert.calledOnceWith(actionsStub.setStrictMatchFilter, false);
});
diff --git a/test/unit/lib/static/components/modals/screenshot-accepter/header.jsx b/test/unit/lib/static/components/modals/screenshot-accepter/header.jsx
index dde18092d..93ab9f9f8 100644
--- a/test/unit/lib/static/components/modals/screenshot-accepter/header.jsx
+++ b/test/unit/lib/static/components/modals/screenshot-accepter/header.jsx
@@ -71,13 +71,13 @@ describe('', () => {
it('should be disabled if the current image is the last', () => {
const component = mkHeaderComponent({stateNameImageIds: ['state1']});
- assert.isTrue(component.find(btnClass).prop('disabled'));
+ assert.isTrue(component.find(`button${btnClass}`).prop('disabled'));
});
it('should be disabled if there are no images left', () => {
const component = mkHeaderComponent({stateNameImageIds: []});
- assert.isTrue(component.find(btnClass).prop('disabled'));
+ assert.isTrue(component.find(`button${btnClass}`).prop('disabled'));
});
});
});
@@ -103,7 +103,7 @@ describe('', () => {
onActiveImageChange
});
- component.find('.screenshot-accepter__arrow-up-btn').simulate('click');
+ component.find('button.screenshot-accepter__arrow-up-btn').simulate('click');
assert.calledOnceWith(onActiveImageChange, expectedActiveImageIndex);
});
@@ -158,7 +158,7 @@ describe('', () => {
onActiveImageChange
});
- component.find('.screenshot-accepter__arrow-down-btn').simulate('click');
+ component.find('button.screenshot-accepter__arrow-down-btn').simulate('click');
assert.calledOnceWith(onActiveImageChange, expectedActiveImageIndex);
});
@@ -368,7 +368,7 @@ describe('', () => {
it('should be disabled if no screenshotes were accepted', () => {
const component = mkHeaderComponent({acceptedImages: 0});
- assert.isTrue(component.find('.screenshot-accepter__undo-btn').prop('disabled'));
+ assert.isTrue(component.find('button.screenshot-accepter__undo-btn').prop('disabled'));
});
it('should call "onScreenshotUndo" handler on click', () => {
@@ -386,7 +386,7 @@ describe('', () => {
const onClose = sandbox.stub();
const component = mkHeaderComponent({onClose});
- component.find('.screenshot-accepter__arrows-close-btn').simulate('click');
+ component.find('button.screenshot-accepter__arrows-close-btn').simulate('click');
assert.calledOnce(onClose);
});
diff --git a/test/unit/lib/static/components/state/index.jsx b/test/unit/lib/static/components/state/index.jsx
index d9be59846..b4a4c2fcc 100644
--- a/test/unit/lib/static/components/state/index.jsx
+++ b/test/unit/lib/static/components/state/index.jsx
@@ -281,7 +281,7 @@ describe('', () => {
const stateComponent = mkStateComponent({imageId: 'img-id'}, {gui: true, ...initialState});
- assert.lengthOf(stateComponent.find('[title="Open mode with fast screenshot accepting"]'), 2);
+ assert.lengthOf(stateComponent.find('button[title="Open mode with fast screenshot accepting"]'), 1);
});
it('should not call "getLastImageByStateName" selector if image id is not passed', () => {