diff --git a/lib/constants/view-modes.js b/lib/constants/view-modes.js index badb6950e..7dd6a4544 100644 --- a/lib/constants/view-modes.js +++ b/lib/constants/view-modes.js @@ -2,5 +2,8 @@ module.exports = { ALL: 'all', - FAILED: 'failed' + PASSED: 'passed', + FAILED: 'failed', + RETRIED: 'retried', + SKIPPED: 'skipped' }; diff --git a/lib/static/components/controls/common-controls.js b/lib/static/components/controls/common-controls.js index 4354d8081..eada7dfe2 100644 --- a/lib/static/components/controls/common-controls.js +++ b/lib/static/components/controls/common-controls.js @@ -51,11 +51,6 @@ class ControlButtons extends Component { /> -
-
diff --git a/lib/static/components/header/index.js b/lib/static/components/header/index.js index 52108873b..d7b63b465 100644 --- a/lib/static/components/header/index.js +++ b/lib/static/components/header/index.js @@ -8,24 +8,24 @@ import Summary from './summary'; import './header.css'; class Header extends Component { - static propTypes = { - date: PropTypes.string - }; + static propTypes = { + date: PropTypes.string + }; - render() { - const {date} = this.props; + render() { + const {date} = this.props; - const dateBlock = date ? ( -
created at {date}
- ) : null; + const dateBlock = date ? ( +
created at {date}
+ ) : null; - return ( -
- - {dateBlock} -
- ); - } + return ( +
+ + {dateBlock} +
+ ); + } } export default connect((state) => { diff --git a/lib/static/components/report.js b/lib/static/components/report.js index 4f58851ab..06f6cfd35 100644 --- a/lib/static/components/report.js +++ b/lib/static/components/report.js @@ -9,7 +9,6 @@ import * as actions from '../modules/actions'; import Loading from './loading'; import Header from './header'; import ControlButtons from './controls/report-controls'; -import SkippedList from './skipped-list'; import MainTree from './main-tree'; import CustomScripts from './custom-scripts'; import FaviconChanger from './favicon-changer'; @@ -55,7 +54,6 @@ class Report extends Component {
-
diff --git a/lib/static/components/skipped-list.js b/lib/static/components/skipped-list.js deleted file mode 100644 index 570b0762a..000000000 --- a/lib/static/components/skipped-list.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; - -import React, {Component} from 'react'; -import PropTypes from 'prop-types'; -import Parser from 'html-react-parser'; -import classNames from 'classnames'; -import {connect} from 'react-redux'; - -class SkippedList extends Component { - static propTypes = { - showSkipped: PropTypes.bool.isRequired, - skips: PropTypes.array.isRequired - } - - render() { - const {showSkipped, skips} = this.props; - const collapsed = !showSkipped; - const className = classNames('skipped__list', {collapsed}); - - const skipsTmpl = skips.length > 0 - ? this._drawSkips(skips) - : 'There are no skipped tests'; - - return (
{skipsTmpl}
); - } - - _drawSkips(skips) { - return skips.map((skip, index) => { - const {browser, comment, suite} = skip; - return ( -
- {suite} > {browser} - {comment && ' reason: '} - {comment && Parser(comment)} -
- ); - }); - } -} - -export default connect( - (state) => ({ - showSkipped: state.view.showSkipped, - skips: state.skips - }) -)(SkippedList); diff --git a/lib/static/components/suites.js b/lib/static/components/suites.js index c69ccebdb..813a90f32 100644 --- a/lib/static/components/suites.js +++ b/lib/static/components/suites.js @@ -89,8 +89,8 @@ class Suites extends Component { msgs.push(`test name should match to "${testNameFilter}" ${strictMatchFilter ? '' : 'not '}strictly;`); } - if (viewMode === viewModes.FAILED) { - msgs.push(`test should be failed due to selected view mode: "Show only ${viewMode}";`); + if (viewMode !== viewModes.ALL) { + msgs.push(`test should be ${viewMode} due to selected view mode;`); } if (filteredBrowsers) { diff --git a/lib/static/modules/action-names.js b/lib/static/modules/action-names.js index 40746dd79..0cb3cc632 100644 --- a/lib/static/modules/action-names.js +++ b/lib/static/modules/action-names.js @@ -26,9 +26,7 @@ export default { VIEW_EXPAND_ERRORS: 'VIEW_EXPAND_ERRORS', VIEW_EXPAND_RETRIES: 'VIEW_EXPAND_RETRIES', VIEW_COLLAPSE_ALL: 'VIEW_COLLAPSE_ALL', - VIEW_SHOW_ALL: 'VIEW_SHOW_ALL', - VIEW_SHOW_FAILED: 'VIEW_SHOW_FAILED', - VIEW_TOGGLE_SKIPPED: 'VIEW_TOGGLE_SKIPPED', + CHANGE_VIEW_MODE: 'CHANGE_VIEW_MODE', VIEW_UPDATE_BASE_HOST: 'VIEW_UPDATE_BASE_HOST', VIEW_UPDATE_FILTER_BY_NAME: 'VIEW_UPDATE_FILTER_BY_NAME', VIEW_SET_STRICT_MATCH_FILTER: 'VIEW_SET_STRICT_MATCH_FILTER', diff --git a/lib/static/modules/actions.js b/lib/static/modules/actions.js index be4747cd1..83dc70638 100644 --- a/lib/static/modules/actions.js +++ b/lib/static/modules/actions.js @@ -5,7 +5,6 @@ import StaticTestsTreeBuilder from '../../tests-tree-builder/static'; import actionNames from './action-names'; import {types as modalTypes} from '../components/modals'; import {QUEUED} from '../../constants/test-statuses'; -import viewModes from '../../constants/view-modes'; import diffModes from '../../constants/diff-modes'; import {getHttpErrorMessage} from './utils'; import {fetchDataFromDatabases, mergeDatabases, connectToDatabase, getMainDatabaseUrl, getSuitesTableRows} from '../../db-utils/client'; @@ -188,7 +187,6 @@ export const expandAll = () => ({type: actionNames.VIEW_EXPAND_ALL}); export const expandErrors = () => ({type: actionNames.VIEW_EXPAND_ERRORS}); export const expandRetries = () => ({type: actionNames.VIEW_EXPAND_RETRIES}); export const collapseAll = () => ({type: actionNames.VIEW_COLLAPSE_ALL}); -export const toggleSkipped = () => ({type: actionNames.VIEW_TOGGLE_SKIPPED}); export const processBegin = () => ({type: actionNames.PROCESS_BEGIN}); export const processEnd = () => ({type: actionNames.PROCESS_END}); export const updateBaseHost = (host) => ({type: actionNames.VIEW_UPDATE_BASE_HOST, host}); @@ -202,6 +200,7 @@ export const togglePageScreenshot = () => ({type: actionNames.TOGGLE_PAGE_SCREEN export const updateBottomProgressBar = (payload) => ({type: actionNames.UPDATE_BOTTOM_PROGRESS_BAR, payload}); export const toggleTestsGroup = (payload) => ({type: actionNames.TOGGLE_TESTS_GROUP, payload}); export const groupTestsByKey = (payload) => ({type: actionNames.GROUP_TESTS_BY_KEY, payload}); +export const changeViewMode = (payload) => ({type: actionNames.CHANGE_VIEW_MODE, payload}); export const runCustomGuiAction = (payload) => { return async (dispatch) => { @@ -225,16 +224,6 @@ export const setStrictMatchFilter = (strictMatchFilter) => { return {type: actionNames.VIEW_SET_STRICT_MATCH_FILTER, strictMatchFilter}; }; -export function changeViewMode(mode) { - switch (mode) { - case viewModes.FAILED: - return {type: actionNames.VIEW_SHOW_FAILED}; - case viewModes.ALL: - default: - return {type: actionNames.VIEW_SHOW_ALL}; - } -} - export function changeDiffMode(mode) { switch (mode) { case diffModes.ONLY_DIFF.id: diff --git a/lib/static/modules/default-state.js b/lib/static/modules/default-state.js index a6270c992..98f18cfe6 100644 --- a/lib/static/modules/default-state.js +++ b/lib/static/modules/default-state.js @@ -69,7 +69,6 @@ export default Object.assign(defaults, { viewMode: viewModes.ALL, diffMode: diffModes.THREE_UP.id, expand: EXPAND_ERRORS, - showSkipped: false, baseHost: '', testNameFilter: '', strictMatchFilter: false, diff --git a/lib/static/modules/middlewares/local-storage.js b/lib/static/modules/middlewares/local-storage.js index c21424c40..d24baef7a 100644 --- a/lib/static/modules/middlewares/local-storage.js +++ b/lib/static/modules/middlewares/local-storage.js @@ -13,7 +13,6 @@ export default store => next => action => { expand: view.expand, viewMode: view.viewMode, diffMode: view.diffMode, - showSkipped: view.showSkipped, strictMatchFilter: view.strictMatchFilter }); } diff --git a/lib/static/modules/middlewares/metrika.js b/lib/static/modules/middlewares/metrika.js index 61c320719..a928a41cf 100644 --- a/lib/static/modules/middlewares/metrika.js +++ b/lib/static/modules/middlewares/metrika.js @@ -61,13 +61,11 @@ export default metrikaClass => store => next => action => { case actionNames.RUN_FAILED_TESTS: case actionNames.RETRY_SUITE: case actionNames.RETRY_TEST: - case actionNames.VIEW_SHOW_ALL: - case actionNames.VIEW_SHOW_FAILED: + case actionNames.CHANGE_VIEW_MODE: case actionNames.VIEW_EXPAND_ALL: case actionNames.VIEW_COLLAPSE_ALL: case actionNames.VIEW_EXPAND_ERRORS: case actionNames.VIEW_EXPAND_RETRIES: - case actionNames.VIEW_TOGGLE_SKIPPED: case actionNames.VIEW_UPDATE_BASE_HOST: case actionNames.VIEW_THREE_UP_DIFF: case actionNames.VIEW_THREE_UP_SCALED_DIFF: diff --git a/lib/static/modules/reducers/grouped-tests/index.js b/lib/static/modules/reducers/grouped-tests/index.js index 58741ebc0..caa3495dc 100644 --- a/lib/static/modules/reducers/grouped-tests/index.js +++ b/lib/static/modules/reducers/grouped-tests/index.js @@ -14,8 +14,7 @@ export default produce((state, action) => { case actionNames.BROWSERS_SELECTED: case actionNames.VIEW_UPDATE_FILTER_BY_NAME: case actionNames.VIEW_SET_STRICT_MATCH_FILTER: - case actionNames.VIEW_SHOW_ALL: - case actionNames.VIEW_SHOW_FAILED: + case actionNames.CHANGE_VIEW_MODE: case actionNames.ACCEPT_SCREENSHOT: case actionNames.ACCEPT_OPENED_SCREENSHOTS: { const { diff --git a/lib/static/modules/reducers/tree/index.js b/lib/static/modules/reducers/tree/index.js index ad84f6cd6..f80df7012 100644 --- a/lib/static/modules/reducers/tree/index.js +++ b/lib/static/modules/reducers/tree/index.js @@ -112,8 +112,7 @@ export default produce((state, action) => { break; } - case actionNames.VIEW_SHOW_ALL: - case actionNames.VIEW_SHOW_FAILED: + case actionNames.CHANGE_VIEW_MODE: case actionNames.VIEW_UPDATE_FILTER_BY_NAME: case actionNames.VIEW_SET_STRICT_MATCH_FILTER: { const {tree, view} = state; diff --git a/lib/static/modules/reducers/tree/nodes/browsers.js b/lib/static/modules/reducers/tree/nodes/browsers.js index e73f7c076..53095f27a 100644 --- a/lib/static/modules/reducers/tree/nodes/browsers.js +++ b/lib/static/modules/reducers/tree/nodes/browsers.js @@ -1,5 +1,5 @@ import {isEmpty, last, initial} from 'lodash'; -import {isStatusMatchViewMode, isTestNameMatchFilters, shouldShowBrowser} from '../../../utils'; +import {isBrowserMatchViewMode, isTestNameMatchFilters, shouldShowBrowser} from '../../../utils'; import {isNodeFailed} from '../../../utils'; import {changeNodeState, shouldNodeBeOpened} from '../helpers'; @@ -84,7 +84,7 @@ function calcBrowserOpenness(browser, lastResult, expand, tree) { function calcBrowserShowness(browser, lastResult, view) { const {viewMode, filteredBrowsers, testNameFilter, strictMatchFilter} = view; - if (!isStatusMatchViewMode(lastResult.status, viewMode)) { + if (!isBrowserMatchViewMode(browser, lastResult, viewMode)) { return false; } diff --git a/lib/static/modules/reducers/view.js b/lib/static/modules/reducers/view.js index 39c9c016c..a370e18a6 100644 --- a/lib/static/modules/reducers/view.js +++ b/lib/static/modules/reducers/view.js @@ -4,7 +4,6 @@ import {isEmpty} from 'lodash'; import {getViewQuery} from '../custom-queries'; import * as localStorageWrapper from '../local-storage-wrapper'; import actionNames from '../action-names'; -import viewModes from '../../../constants/view-modes'; import diffModes from '../../../constants/diff-modes'; import {EXPAND_ALL, COLLAPSE_ALL, EXPAND_ERRORS, EXPAND_RETRIES} from '../../../constants/expand-modes'; @@ -45,18 +44,8 @@ export default produce((state, action) => { break; } - case actionNames.VIEW_SHOW_ALL: { - state.view.viewMode = viewModes.ALL; - break; - } - - case actionNames.VIEW_SHOW_FAILED: { - state.view.viewMode = viewModes.FAILED; - break; - } - - case actionNames.VIEW_TOGGLE_SKIPPED: { - state.view.showSkipped = !state.view.showSkipped; + case actionNames.CHANGE_VIEW_MODE: { + state.view.viewMode = action.payload; break; } diff --git a/lib/static/modules/utils.js b/lib/static/modules/utils.js index 67044c3a9..db482c0db 100644 --- a/lib/static/modules/utils.js +++ b/lib/static/modules/utils.js @@ -77,16 +77,26 @@ function isTestNameMatchFilters(testName, testNameFilter, strictMatchFilter) { : testName.includes(testNameFilter); } -function isStatusMatchViewMode(status, viewMode) { +function isBrowserMatchViewMode(browser, lastResult, viewMode) { + const {status} = lastResult; + if (viewMode === viewModes.ALL) { return true; } + if (viewMode === viewModes.PASSED && isSuccessStatus(status)) { + return true; + } + if (viewMode === viewModes.FAILED && (isFailStatus(status) || isErroredStatus(status))) { return true; } - return false; + if (viewMode === viewModes.RETRIED) { + return browser.resultIds.length > 1; + } + + return status === viewMode; } function shouldShowBrowser(browser, filteredBrowsers) { @@ -154,7 +164,7 @@ module.exports = { dateToLocaleString, getHttpErrorMessage, isTestNameMatchFilters, - isStatusMatchViewMode, + isBrowserMatchViewMode, shouldShowBrowser, iterateSuites, parseKeyToGroupTestsBy diff --git a/test/unit/lib/static/modules/middlewares/local-storage.js b/test/unit/lib/static/modules/middlewares/local-storage.js index f79b99113..c6fbe73cb 100644 --- a/test/unit/lib/static/modules/middlewares/local-storage.js +++ b/test/unit/lib/static/modules/middlewares/local-storage.js @@ -57,7 +57,6 @@ describe('lib/static/modules/middlewares/local-storage', () => { assert.calledOnceWith(localStorageWrapper.setItem, 'view', { expand: EXPAND_ERRORS, - showSkipped: false, strictMatchFilter: false, viewMode: viewModes.ALL, diffMode: diffModes.THREE_UP.id diff --git a/test/unit/lib/static/modules/middlewares/metrika.js b/test/unit/lib/static/modules/middlewares/metrika.js index 755ffa39f..25d3c59e8 100644 --- a/test/unit/lib/static/modules/middlewares/metrika.js +++ b/test/unit/lib/static/modules/middlewares/metrika.js @@ -326,13 +326,11 @@ describe('lib/static/modules/middlewares/metrika', () => { actionNames.RUN_FAILED_TESTS, actionNames.RETRY_SUITE, actionNames.RETRY_TEST, - actionNames.VIEW_SHOW_ALL, - actionNames.VIEW_SHOW_FAILED, + actionNames.CHANGE_VIEW_MODE, actionNames.VIEW_EXPAND_ALL, actionNames.VIEW_COLLAPSE_ALL, actionNames.VIEW_EXPAND_ERRORS, actionNames.VIEW_EXPAND_RETRIES, - actionNames.VIEW_TOGGLE_SKIPPED, actionNames.VIEW_UPDATE_BASE_HOST, actionNames.VIEW_THREE_UP_DIFF, actionNames.VIEW_THREE_UP_SCALED_DIFF, diff --git a/test/unit/lib/static/modules/reducers/grouped-tests/index.js b/test/unit/lib/static/modules/reducers/grouped-tests/index.js index 7958e8cc2..0afe824cc 100644 --- a/test/unit/lib/static/modules/reducers/grouped-tests/index.js +++ b/test/unit/lib/static/modules/reducers/grouped-tests/index.js @@ -40,8 +40,7 @@ describe('lib/static/modules/reducers/grouped-tests', () => { actionNames.BROWSERS_SELECTED, actionNames.VIEW_UPDATE_FILTER_BY_NAME, actionNames.VIEW_SET_STRICT_MATCH_FILTER, - actionNames.VIEW_SHOW_ALL, - actionNames.VIEW_SHOW_FAILED, + actionNames.CHANGE_VIEW_MODE, actionNames.ACCEPT_SCREENSHOT, actionNames.ACCEPT_OPENED_SCREENSHOTS ].forEach((actionName) => { diff --git a/test/unit/lib/static/modules/reducers/view.js b/test/unit/lib/static/modules/reducers/view.js index 6ab4531ca..1a939f508 100644 --- a/test/unit/lib/static/modules/reducers/view.js +++ b/test/unit/lib/static/modules/reducers/view.js @@ -166,7 +166,17 @@ describe('lib/static/modules/reducers/view', () => { assert.deepStrictEqual(newState.view.viewMode, viewModes.ALL); }); - it('should set "viewMode" property to specified value', () => { + it('should set "viewMode" property to "passed" value', () => { + global.window.location = new URL(`${baseUrl}?viewMode=passed`); + + const action = {type, payload: _mkInitialState()}; + + const newState = reducer(defaultState, action); + + assert.deepStrictEqual(newState.view.viewMode, viewModes.PASSED); + }); + + it('should set "viewMode" property to "failed" value', () => { global.window.location = new URL(`${baseUrl}?viewMode=failed`); const action = {type, payload: _mkInitialState()}; @@ -175,6 +185,26 @@ describe('lib/static/modules/reducers/view', () => { assert.deepStrictEqual(newState.view.viewMode, viewModes.FAILED); }); + + it('should set "viewMode" property to "retried" value', () => { + global.window.location = new URL(`${baseUrl}?viewMode=retried`); + + const action = {type, payload: _mkInitialState()}; + + const newState = reducer(defaultState, action); + + assert.deepStrictEqual(newState.view.viewMode, viewModes.RETRIED); + }); + + it('should set "viewMode" property to "skipped" value', () => { + global.window.location = new URL(`${baseUrl}?viewMode=skipped`); + + const action = {type, payload: _mkInitialState()}; + + const newState = reducer(defaultState, action); + + assert.deepStrictEqual(newState.view.viewMode, viewModes.SKIPPED); + }); }); describe('"expand" option', () => { @@ -199,24 +229,16 @@ describe('lib/static/modules/reducers/view', () => { }); }); - describe(`"${actionNames.VIEW_SHOW_ALL}" action`, () => { - it('should change "viewMode" field on "all" value', () => { - const action = {type: actionNames.VIEW_SHOW_ALL}; + describe(`"${actionNames.CHANGE_VIEW_MODE}" action`, () => { + Object.keys(viewModes).forEach(((viewModeKey) => { + it(`should change "viewMode" field to selected ${viewModeKey} value`, () => { + const action = {type: actionNames.CHANGE_VIEW_MODE, payload: viewModes[viewModeKey]}; - const newState = reducer(defaultState, action); + const newState = reducer(defaultState, action); - assert.equal(newState.view.viewMode, viewModes.ALL); - }); - }); - - describe(`"${actionNames.VIEW_SHOW_FAILED}" action`, () => { - it('should change "viewMode" field on "failed" value', () => { - const action = {type: actionNames.VIEW_SHOW_FAILED}; - - const newState = reducer(defaultState, action); - - assert.equal(newState.view.viewMode, viewModes.FAILED); - }); + assert.equal(newState.view.viewMode, viewModes[viewModeKey]); + }); + })); }); describe(`"${actionNames.GROUP_TESTS_BY_KEY}" action`, () => { diff --git a/test/unit/lib/static/modules/utils.js b/test/unit/lib/static/modules/utils.js index 951517eb3..155ea77f6 100644 --- a/test/unit/lib/static/modules/utils.js +++ b/test/unit/lib/static/modules/utils.js @@ -6,6 +6,8 @@ const viewModes = require('lib/constants/view-modes'); const {SECTIONS, RESULT_KEYS, KEY_DELIMITER} = require('lib/constants/group-tests'); const {NO_REF_IMAGE_ERROR} = require('lib/constants/errors').getCommonErrors(); +const {mkBrowser, mkResult} = require('../../static/state-utils'); + describe('static/modules/utils', () => { describe('isSuiteIdle', () => { it('should return true for idle test', () => { @@ -136,23 +138,59 @@ describe('static/modules/utils', () => { }); }); - describe('"isStatusMatchViewMode"', () => { + describe('"isBrowserMatchViewMode"', () => { describe('should return "true" if', () => { - [SUCCESS, ERROR, FAIL].forEach((status) => { + [SUCCESS, ERROR, FAIL, SKIPPED].forEach((status) => { it(`viewMode is "${viewModes.ALL}" and node status is "${status}"`, () => { - assert.isTrue(utils.isStatusMatchViewMode(status, viewModes.ALL)); + const browsersById = mkBrowser({id: 'browser1', resultIds: ['result1']}); + const resultsById = mkResult({id: 'result1', status}); + + assert.isTrue(utils.isBrowserMatchViewMode(browsersById.browser1, resultsById.result1, viewModes.ALL)); }); }); [ERROR, FAIL].forEach((status) => { it(`viewMode is "${viewModes.FAILED}" and node status is "${status}"`, () => { - assert.isTrue(utils.isStatusMatchViewMode(status, viewModes.FAILED)); + const browsersById = mkBrowser({id: 'browser1', resultIds: ['result1']}); + const resultsById = mkResult({id: 'result1', status}); + + assert.isTrue(utils.isBrowserMatchViewMode(browsersById.browser1, resultsById.result1, viewModes.FAILED)); }); }); + + [[viewModes.PASSED, SUCCESS], [viewModes.SKIPPED, SKIPPED]].forEach(([viewMode, status]) => { + it(`viewMode is "${viewMode}" and node status is "${status}"`, () => { + const browsersById = mkBrowser({id: 'browser1', resultIds: ['result1']}); + const resultsById = mkResult({id: 'result1', status}); + + assert.isTrue(utils.isBrowserMatchViewMode(browsersById.browser1, resultsById.result1, viewMode)); + }); + }); + + it(`viewMode is "${viewModes.RETRIED}" and browser has one or more retries`, () => { + const browsersById = mkBrowser({id: 'browser1', resultIds: ['result1', 'result2']}); + const resultsById = mkResult({id: 'result2', status: IDLE}); + + assert.isTrue(utils.isBrowserMatchViewMode(browsersById.browser1, resultsById.result2, viewModes.RETRIED)); + }); }); - it(`should return "false" if viewMode is "${viewModes.FAILED}" and node status is "${SUCCESS}"`, () => { - assert.isFalse(utils.isStatusMatchViewMode(SUCCESS, viewModes.FAILED)); + describe('should return "false" if', () => { + [SUCCESS, SKIPPED].forEach((status) => { + it(`viewMode is "${viewModes.FAILED}" and node status is "${status}"`, () => { + const browsersById = mkBrowser({id: 'browser1', resultIds: ['result1']}); + const resultsById = mkResult({id: 'result1', status}); + + assert.isFalse(utils.isBrowserMatchViewMode(browsersById.browser1, resultsById.result1, viewModes.FAILED)); + }); + }); + + it(`viewMode is "${viewModes.RETRIED}" and browser has zero retries`, () => { + const browsersById = mkBrowser({id: 'browser1', resultIds: ['result1']}); + const resultsById = mkResult({id: 'result1', status: IDLE}); + + assert.isFalse(utils.isBrowserMatchViewMode(browsersById.browser1, resultsById.result1, viewModes.RETRIED)); + }); }); });