Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/176 - Compare and Search views #181

Merged
merged 22 commits into from
Apr 19, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion end_to_end_tests/robot_tests/__init__.robot
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
*** Settings ***
Resource ${EXECDIR}/resources/resource.robot
Resource ${EXECDIR}${/}resources${/}resource.robot
Suite Setup Open Browser To Epimetheus Landing Page ${BROWSER} ${remote_url}

Suite Teardown Custom Teardown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ Resource ./history_keywords.robot

Test Build Amount Dropdown
Open history page of series 3
Select From Dropdown ${history_build_selector_5}
Select From Dropdown ${history_build_selector_5}
Table should be limited to number=5
Select From Dropdown ${history_build_selector_10}
Select From Dropdown ${history_build_selector_10}
Table should be limited to number=10
Select From Dropdown ${history_build_selector_30}
Select From Dropdown ${history_build_selector_30}
Table should be limited to number=30

Test Offset Functionality
Expand Down Expand Up @@ -69,7 +69,7 @@ Most Recent Build Number should be
[Arguments] ${build}
Wait Until Element Is Enabled ${series_history_most_recent}
${temp_most_recent}= Get Text ${series_history_most_recent}

Should be equal as Strings ${build} ${temp_most_recent}

Offset should be
Expand All @@ -86,5 +86,5 @@ Check offset url
Click Right Button
Click Element ${offset_right}
Click Left Button
Click Element ${offset_left}
Click Element ${offset_left}

2 changes: 1 addition & 1 deletion frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ ENV REACT_APP_SERVER_URL=backend-server

CMD [ "npm", "start" ]

EXPOSE 3000
EXPOSE 3000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

11 changes: 11 additions & 0 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import BuildHistory from './pages/BuildHistory';
import Frontpage from './pages/Frontpage';
import Team from './pages/Team';
import Suite from './pages/Suite';
import Comparison from './pages/Comparison';
import Search from './pages/Search.jsx';
import { useStateValue } from './contexts/state';
import './utils/i118n';
import 'normalize.css';
Expand Down Expand Up @@ -67,6 +69,15 @@ const App = () => {
<Route path="/series/:seriesId/build/:buildId/analysis">
<Analysis />
</Route>
<Route path="/compare/:seriesId/:buildId/to/:seriesId2/:buildId2">
<Comparison />
</Route>
<Route path="/compare">
<Comparison />
</Route>
<Route path="/search">
<Search />
</Route>
<Route exact path="/team">
<Team />
</Route>
Expand Down
30 changes: 29 additions & 1 deletion frontend/src/components/BreadcrumbNav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ const LinkItem = props => {
};

const ListItems = ({ status }) => {
const { name, series, seriesId, buildId, suiteId } = useParams();
const {
name,
series,
seriesId,
buildId,
suiteId,
seriesId2,
buildId2,
} = useParams();
const [{ selectedBranchState }] = useStateValue();
const teamName = name || selectedBranchState.team;
const seriesName = series || selectedBranchState.id;
Expand Down Expand Up @@ -59,6 +67,16 @@ const ListItems = ({ status }) => {
id: 'SuiteBreadCrumb',
ariaLabel: `${suiteId}: suite's id`,
name: suiteId,
})
.set('compare', {
to: `/compare`,
id: 'CompareBreadCrumb',
name: 'Compare',
})
.set('compareBuilds', {
to: `/compare/${seriesId}/${buildId}/to/${seriesId2}/${buildId2}`,
id: 'CompareBuildsBreadCrumb',
name: `Compare series ${seriesId} build ${buildId} to series ${seriesId2} build ${buildId2}`,
});

const breadcrumbArray = [];
Expand Down Expand Up @@ -93,6 +111,16 @@ const ListItems = ({ status }) => {
<LinkItem key="suite" link={links.get('suite')} current />
);
break;
case 'compare':
breadcrumbArray.push(
<LinkItem key="compare" link={links.get('compare')} />,
<LinkItem
key="compareBuilds"
link={links.get('compareBuilds')}
current
/>
);
break;
default:
breadcrumbArray.push('');
}
Expand Down
6 changes: 2 additions & 4 deletions frontend/src/components/MainContent.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
export const StyledDiv = styled.main`
overflow: auto;
width: 100%;
min-height: calc(
100vh - var(--space-80) - var(--space-48) - var(--space-64)
);
margin-bottom: var(--space-64);
min-height: calc(100vh - var(--space-80) - var(--space-48));
padding-bottom: var(--space-64);
`;
14 changes: 13 additions & 1 deletion frontend/src/components/MainNav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,30 @@ const MainNav = () => {
const team =
location.pathname.includes('team') ||
location.pathname.includes('series');
const compare = location.pathname.includes('compare');
const search = location.pathname.includes('search');

return (
<header>
<NavBar id="main-nav">
<SiteLogo className="logo">{t('logo')}</SiteLogo>
<LinkContainer team={team}>
<NavLink exact to="/" className={!team ? 'active' : ''}>
<NavLink
exact
to="/"
className={location.pathname === '/' ? 'active' : ''}
>
{t('help')}
</NavLink>
<NavLink to="/team" className={team ? 'active' : ''}>
{t('team')}
</NavLink>
<NavLink to="/compare" className={compare ? 'active' : ''}>
{t('compare')}
</NavLink>
<NavLink to="/search" className={search ? 'active' : ''}>
{t('search')}
</NavLink>
<a
href="https://github.com/salabs/Epimetheus"
target="_blank"
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/MainNav.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const SiteLogo = styled.div`
font-size: 30px;
font-weight: 700;

@media only screen and (max-width: 540px) {
@media only screen and (max-width: 768px) {
width: var(--space-16);
margin-right: 0;
overflow: hidden;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const BuildsTestResultTable = ({ id }) => {
const [t] = useTranslation(['history']);

return (
<Table table-id="last-run-table">
<Table tableId="last-run-table">
<thead>
<tr>
<WideTh>{t('build.table.suite')}</WideTh>
Expand Down
110 changes: 110 additions & 0 deletions frontend/src/components/comparisonTable/Body.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React from 'react';
import Row from './Row';
import { useStateValue } from '../../contexts/state';
import { useParams } from 'react-router';

const Body = () => {
const [
{ comparedDataState, compareFilterMatch, compareFilterMismatch },
] = useStateValue();
let { buildId, buildId2 } = useParams();

// Do we want last-run page filters to work on suite-level (false)
// or test-level (true)?
// const SUITE_FILTER_NESTED = true;

// Get result for this specific run , as well as parse the full name of a test case and the result of the test case.

const firstBuildByBuildNumber = comparedDataState[0]
.filter(({ test_cases }) => {
return test_cases.some(({ builds }) => {
return builds.some(
({ build_number }) => build_number === Number(buildId)
);
});
})
.flatMap(x => x.test_cases)
.map(test => {
return {
full_name: test.full_name,
status1: test.builds[0].test_status,
status2: '',
};
});
//Done twice since 2 builds
const secondBuildByBuildNumber = comparedDataState[1]
.filter(({ test_cases }) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function is repeated above so it could be moved to a single function

return test_cases.some(({ builds }) => {
return builds.some(
({ build_number }) => build_number === Number(buildId2)
);
});
})
.flatMap(x => x.test_cases)
.map(test => {
return {
full_name: test.full_name,
status1: '',
status2: test.builds[0].test_status,
};
});

//We create an array of matching test cases

const matching_array = [];
secondBuildByBuildNumber.forEach(test_case2 => {
firstBuildByBuildNumber.forEach(test_case1 => {
if (test_case1.full_name === test_case2.full_name) {
matching_array.push({
full_name: test_case1.full_name,
status1: test_case1.status1,
status2: test_case2.status2,
});
}
});
});

const second_not_matching = secondBuildByBuildNumber.filter(test_case => {
return !matching_array.some(matcher => {
return matcher.full_name === test_case.full_name;
});
});

const first_not_matching = firstBuildByBuildNumber.filter(test_case => {
return !matching_array.some(matcher => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is also some repetition.

return matcher.full_name === test_case.full_name;
});
});

//We now have 3 arrays, one with matching elements and 2 with unmatching elements
let combined_json = [];
if (!compareFilterMatch.isChecked && !compareFilterMismatch.isChecked) {
combined_json = first_not_matching.concat(
matching_array,
second_not_matching
);
} else if (
compareFilterMatch.isChecked &&
!compareFilterMismatch.isChecked
) {
combined_json = first_not_matching.concat(second_not_matching);
} else if (
!compareFilterMatch.isChecked &&
compareFilterMismatch.isChecked
) {
combined_json = matching_array;
}

return combined_json.map(({ full_name, status1, status2 }) => {
return (
<Row
full_name={full_name}
status1={status1}
status2={status2}
key={full_name}
/>
);
});
};

export default Body;
69 changes: 69 additions & 0 deletions frontend/src/components/comparisonTable/ComparisonCheckbox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useState } from 'react';
import { useStateValue } from '../../contexts/state';
import {
StyledInput,
StyledLabel,
} from '../testFilters/LastRunCheckbox.styles';
import { ReactComponent as Checked } from '../../images/checked.svg';
import { ReactComponent as Unchecked } from '../../images/unchecked.svg';
import { CheckboxContainer } from './ComparisonCheckbox.styles';

const Checkbox = () => {
// eslint-disable-next-line
const [{ compareFilterMatch, compareFilterMismatch }, dispatch] = useStateValue();
const [mismatchFilter, setMismatchFilter] = useState(
compareFilterMatch.isChecked
);
const [matchFilter, setMatchFilter] = useState(
compareFilterMismatch.isChecked
);

const handleMatchFilterChange = e => {
dispatch({
type: 'setCompareMatchFilter',
filterType: matchFilter ? '' : e.target.value,
isChecked: !matchFilter,
});

setMatchFilter(!matchFilter);
};

const handleMismatchFilterChange = e => {
dispatch({
type: 'setCompareMismatchFilter',
filterType: mismatchFilter ? '' : e.target.value,
isChecked: !mismatchFilter,
});

setMismatchFilter(!mismatchFilter);
};

return (
<CheckboxContainer id="last-run-checkbox-container">
<StyledLabel labelfor="filterMatch">
<StyledInput
type="checkbox"
name="filterMatch"
value="match"
checked={matchFilter}
onChange={e => handleMatchFilterChange(e)}
/>
<span>{matchFilter ? <Checked /> : <Unchecked />}</span>
Hide Matching tests
</StyledLabel>
<StyledLabel labelfor="filterMismatch">
<StyledInput
type="checkbox"
name="filterMismatch"
value="mismatch"
checked={mismatchFilter}
onChange={e => handleMismatchFilterChange(e)}
/>
<span>{mismatchFilter ? <Checked /> : <Unchecked />}</span>
Hide Mismatched tests
</StyledLabel>
</CheckboxContainer>
);
};

export default Checkbox;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import styled from 'styled-components';

export const CheckboxContainer = styled.div`
display: flex;
flex-direction: column;
border: 1px solid var(--evidence-grey);
border-radius: var(--space-4);
max-width: 300px;
line-height: 30px;
padding: 0 var(--space-8);
margin-bottom: var(--space-24);

span {
padding-right: var(--space-8);
position: relative;
top: -1px;

svg {
position: relative;
top: -1px;
}
}
`;
Loading