Skip to content

Commit 4583d87

Browse files
authored
Merge pull request #422 from gemini-testing/FEI-24677.cozy_diffs_with_grid
feat: add new modes to view image diffs
2 parents 9e40340 + 318c3b4 commit 4583d87

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+8146
-11355
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,16 @@ directory.
4141
* `all` - show all tests. Default value.
4242
* `failed` - show only failed tests.
4343

44+
* **diffMode** (optional) - `String` - default diff mode. Available values are:
45+
46+
* `3-up` - show all images (expected, actual, diff) in column. Default value;
47+
* `3-up-scaled` - show all images in row (fit into page width);
48+
* `only-diff` - show only diff image;
49+
* `switch` - mode with ability to switch between expected and actual images (use click on mouse in images field to switch);
50+
* `swipe` - mode with ability to move divider between expected and actual images;
51+
* `onion-skin` - mode with ability to change the transparency of actual image.
52+
4453
* **baseHost** (optional) - `String` - it changes original host for view in the browser; by default original host does not change
45-
* **scaleImages** (optional) – `Boolean` – fit images into page width; `false` by default.
4654
* **errorPatterns** (optional) - `Array` - error message patterns are used:
4755

4856
* to show more understandable information about matched error;

lib/config/index.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const chalk = require('chalk');
66

77
const {logger} = require('../common-utils');
88
const {config: configDefaults} = require('../constants/defaults');
9+
const diffModes = require('../constants/diff-modes');
910
const saveFormats = require('../constants/save-formats');
1011
const {assertCustomGui} = require('./custom-gui-asserts');
1112

@@ -114,6 +115,18 @@ const assertPluginDescription = (description) => {
114115
return true;
115116
};
116117

118+
const assertDiffMode = (diffMode) => {
119+
if (!_.isString(diffMode)) {
120+
throw new Error(`"diffMode" option must be a string, but got ${typeof diffMode}`);
121+
}
122+
123+
const availableValues = Object.values(diffModes).map(v => v.id);
124+
125+
if (!availableValues.includes(diffMode)) {
126+
throw new Error(`"diffMode" must be one of "${availableValues.join('", "')}", but got "${diffMode}"`);
127+
}
128+
};
129+
117130
const mapErrorPatterns = (errorPatterns) => {
118131
return errorPatterns.map(patternInfo => {
119132
return _.isString(patternInfo)
@@ -156,16 +169,14 @@ const getParser = () => {
156169
defaultValue: configDefaults.defaultView,
157170
validate: assertString('defaultView')
158171
}),
172+
diffMode: option({
173+
defaultValue: configDefaults.diffMode,
174+
validate: assertDiffMode
175+
}),
159176
baseHost: option({
160177
defaultValue: configDefaults.baseHost,
161178
validate: assertString('baseHost')
162179
}),
163-
scaleImages: option({
164-
defaultValue: configDefaults.scaleImages,
165-
parseEnv: JSON.parse,
166-
parseCli: JSON.parse,
167-
validate: assertBoolean('scaleImages')
168-
}),
169180
lazyLoadOffset: option({
170181
defaultValue: configDefaults.lazyLoadOffset,
171182
validate: (value) => _.isNull(value) || deprecationWarning('lazyLoadOffset')

lib/constants/defaults.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

3+
const diffModes = require('./diff-modes');
34
const viewModes = require('./view-modes');
45

56
module.exports = {
@@ -8,8 +9,8 @@ module.exports = {
89
saveErrorDetails: false,
910
commandsWithShortHistory: [],
1011
defaultView: viewModes.ALL,
12+
diffMode: diffModes.THREE_UP.id,
1113
baseHost: '',
12-
scaleImages: false,
1314
lazyLoadOffset: null,
1415
errorPatterns: [],
1516
metaInfoBaseUrls: {},

lib/constants/diff-modes.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module.exports = {
2+
THREE_UP: {
3+
id: '3-up',
4+
title: '3-up',
5+
description: 'images in column'
6+
},
7+
THREE_UP_SCALED: {
8+
id: '3-up-scaled',
9+
title: '3-up scaled',
10+
description: 'scaled images in row'
11+
},
12+
ONLY_DIFF: {
13+
id: 'only-diff',
14+
title: 'Only diff',
15+
description: 'click on image to see area with diff'
16+
},
17+
SWITCH: {
18+
id: 'switch',
19+
title: 'Switch',
20+
description: 'click on image to switch'
21+
},
22+
SWIPE: {
23+
id: 'swipe',
24+
title: 'Swipe',
25+
description: 'move divider'
26+
},
27+
ONION_SKIN: {
28+
id: 'onion-skin',
29+
title: 'Onion skin',
30+
description: 'move slider'
31+
}
32+
};

lib/server-utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ function getConfigForStaticFile(pluginConfig) {
180180
pluginConfig,
181181
[
182182
'defaultView',
183+
'diffMode',
183184
'baseHost',
184-
'scaleImages',
185185
'errorPatterns',
186186
'metaInfoBaseUrls',
187187
'customScripts',

lib/static/components/controls/common-controls.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
'use strict';
21
import React, {Component} from 'react';
32
import {bindActionCreators} from 'redux';
43
import {connect} from 'react-redux';
4+
import {capitalize} from 'lodash';
55
import * as actions from '../../modules/actions';
66
import ControlButton from './control-button';
7-
import ViewSelect from './view-select';
7+
import ControlSelect from './control-select';
88
import BaseHostInput from './base-host-input';
99
import MenuBar from './menu-bar';
1010
import viewModes from '../../../constants/view-modes';
11+
import diffModes from '../../../constants/diff-modes';
1112
import {EXPAND_ALL, COLLAPSE_ALL, EXPAND_ERRORS, EXPAND_RETRIES} from '../../../constants/expand-modes';
1213

1314
class ControlButtons extends Component {
@@ -16,10 +17,12 @@ class ControlButtons extends Component {
1617

1718
return (
1819
<div className="common-controls">
19-
<ViewSelect options = {[
20-
{value: viewModes.ALL, text: 'Show all'},
21-
{value: viewModes.FAILED, text: 'Show only failed'}
22-
]}/>
20+
<ControlSelect
21+
label="Show tests"
22+
value={view.viewMode}
23+
handler={actions.changeViewMode}
24+
options = {Object.values(viewModes).map((value) => ({value, text: capitalize(value)}))}
25+
/>
2326
<div className="control-group">
2427
<ControlButton
2528
label="Expand all"
@@ -51,15 +54,14 @@ class ControlButtons extends Component {
5154
isActive={view.showSkipped}
5255
handler={actions.toggleSkipped}
5356
/>
54-
<ControlButton
55-
label="Show only diff"
56-
isActive={view.showOnlyDiff}
57-
handler={actions.toggleOnlyDiff}
58-
/>
59-
<ControlButton
60-
label="Scale images"
61-
isActive={view.scaleImages}
62-
handler={actions.toggleScaleImages}
57+
<ControlSelect
58+
label="Diff mode"
59+
value={view.diffMode}
60+
handler={actions.changeDiffMode}
61+
options = {Object.values(diffModes).map((dm) => {
62+
return {value: dm.id, text: dm.title};
63+
})}
64+
extendClassNames="diff-mode"
6365
/>
6466
<ControlButton
6567
label="Group by error"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React, {Component} from 'react';
2+
import PropTypes from 'prop-types';
3+
import {Label, Dropdown} from 'semantic-ui-react';
4+
import classNames from 'classnames';
5+
6+
import './index.styl';
7+
8+
export default class ControlSelect extends Component {
9+
static propTypes = {
10+
label: PropTypes.string.isRequired,
11+
value: PropTypes.string.isRequired,
12+
handler: PropTypes.func.isRequired,
13+
options: PropTypes.arrayOf(PropTypes.shape({
14+
value: PropTypes.string,
15+
text: PropTypes.string
16+
})).isRequired,
17+
extendClassNames: PropTypes.oneOfType([PropTypes.array, PropTypes.string])
18+
}
19+
20+
_onChange = (_, dom) => {
21+
this.props.handler(dom.value);
22+
}
23+
24+
render() {
25+
const {value, label, options, extendClassNames} = this.props;
26+
const formattedOpts = options.map(({value, text}) => ({
27+
value,
28+
text,
29+
key: value
30+
}));
31+
32+
const className = classNames(
33+
'control-select',
34+
extendClassNames
35+
);
36+
37+
return (
38+
<div className={className}>
39+
<Label className="control-select__label">{label}</Label>
40+
<Dropdown
41+
className="control-select__dropdown"
42+
selection
43+
options={formattedOpts}
44+
value={value}
45+
onChange={this._onChange}
46+
/>
47+
</div>
48+
);
49+
}
50+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
.control-select
2+
display: inline-flex
3+
margin-right: 15px
4+
margin-bottom: 15px
5+
6+
.control-select__label
7+
font-size: 11px
8+
margin: 0
9+
padding: 0 5px
10+
line-height: 25px
11+
background-color: #e7e7e7
12+
border-radius: 2px
13+
border-top-right-radius: 0
14+
border-bottom-right-radius: 0
15+
16+
.control-select__dropdown.ui.dropdown
17+
min-height: 25px
18+
min-width: 60px
19+
font-size: 11px
20+
line-height: 13px
21+
padding: 5px
22+
border: 1px solid #ccc
23+
border-radius: 2px
24+
border-top-left-radius: 0
25+
border-bottom-left-radius: 0
26+
27+
&:hover
28+
border: 1px solid #555;
29+
30+
&.active
31+
&:hover
32+
.menu
33+
border-color: #ffd947
34+
35+
.icon
36+
top: 50%
37+
right: 10px
38+
padding: 0
39+
margin: 0
40+
transform: translateY(-50%)
41+
42+
&.diff-mode
43+
.control-select__dropdown.ui.dropdown
44+
min-width: 90px

lib/static/components/controls/controls.less

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -62,34 +62,3 @@
6262
border-color: #555;
6363
}
6464
}
65-
66-
.viewmode {
67-
width: 115px;
68-
display: inline-block;
69-
margin-right: 15px;
70-
margin-bottom: 15px;
71-
}
72-
73-
.viewmode .ui.fluid.dropdown {
74-
font-size: 11px;
75-
}
76-
77-
.viewmode .ui.selection.dropdown {
78-
padding: 6px;
79-
min-height: 25px;
80-
border: 1px solid #ccc;
81-
border-radius: 2px;
82-
}
83-
84-
.viewmode .ui.selection.dropdown:hover {
85-
border: 1px solid #555;
86-
}
87-
88-
.viewmode .ui.selection.dropdown>.dropdown.icon {
89-
top: 5px;
90-
}
91-
92-
.viewmode .ui.selection.active.dropdown:hover,
93-
.viewmode .ui.selection.active.dropdown .menu {
94-
border-color: #ffd947;
95-
}

lib/static/components/controls/view-select.js

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)