diff --git a/client/components/TestRun/TestNavigator.jsx b/client/components/TestRun/TestNavigator.jsx
index 65b891e3d..956304baa 100644
--- a/client/components/TestRun/TestNavigator.jsx
+++ b/client/components/TestRun/TestNavigator.jsx
@@ -5,14 +5,15 @@ import {
faArrowLeft,
faArrowRight
} from '@fortawesome/free-solid-svg-icons';
-import { Col } from 'react-bootstrap';
-import React from 'react';
+import { Col, Overlay, Tooltip } from 'react-bootstrap';
+import React, { useRef, useState } from 'react';
const TestNavigator = ({
show = true,
isSignedIn = false,
tests = [],
currentTestIndex = 0,
+ testPlanRunId = 0,
toggleShowClick = () => {},
handleTestClick = () => {}
}) => {
@@ -69,27 +70,48 @@ const TestNavigator = ({
}
}
+ const [show, setShow] = useState(false);
+ const target = useRef(null);
+
return (
await handleTestClick(test.index)
}
+ onBlur={() => setShow(false)}
+ onFocus={() => setShow(true)}
+ onMouseLeave={() => setShow(false)}
+ onMouseEnter={() => setShow(true)}
className="test-name"
aria-current={
test.index === currentTestIndex
}
+ aria-label={`${test.title} (${resultStatus})`}
>
{test.title}
+
+ {props => (
+
+ {resultStatus}
+
+ )}
+
);
})}
@@ -107,6 +129,7 @@ TestNavigator.propTypes = {
testResult: PropTypes.object,
conflicts: PropTypes.object,
currentTestIndex: PropTypes.number,
+ testPlanRunId: PropTypes.number,
toggleShowClick: PropTypes.func,
handleTestClick: PropTypes.func
};
diff --git a/client/components/TestRun/index.jsx b/client/components/TestRun/index.jsx
index f41de2e88..06c0a4fac 100644
--- a/client/components/TestRun/index.jsx
+++ b/client/components/TestRun/index.jsx
@@ -1,6 +1,6 @@
import React, { useState, useEffect, useRef } from 'react';
import { Helmet } from 'react-helmet';
-import { Link, useParams, useHistory } from 'react-router-dom';
+import { Link, useParams, useHistory, Redirect } from 'react-router-dom';
import useRouterQuery from '../../hooks/useRouterQuery';
import { useQuery, useMutation } from '@apollo/client';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -79,7 +79,11 @@ const TestRun = () => {
const testRendererSubmitButtonRef = useRef();
const conflictMarkdownRef = useRef();
- const { runId: testPlanRunId, testPlanReportId } = params;
+ const {
+ runId: testPlanRunId,
+ taskId: testPlanTaskId,
+ testPlanReportId
+ } = params;
const { loading, data, error, refetch } = useQuery(
testPlanRunId ? TEST_RUN_PAGE_QUERY : TEST_RUN_PAGE_ANON_QUERY,
@@ -197,7 +201,24 @@ const TestRun = () => {
testResult: testResults.find(t => t.test.id === test.id),
hasConflicts: !!conflicts.find(c => c.source.test.id === test.id)
}));
- const currentTest = tests[currentTestIndex];
+
+ // Validate any /task/\d+ route parameter
+ if (
+ testPlanTaskId !== undefined &&
+ testPlanTaskId > 0 &&
+ tests.length < testPlanTaskId
+ ) {
+ return ;
+ }
+
+ if (
+ testPlanTaskId !== undefined &&
+ testPlanTaskId - 1 !== currentTestIndex
+ ) {
+ setCurrentTestIndex(testPlanTaskId - 1);
+ }
+
+ const currentTest = tests[testPlanTaskId - 1 || currentTestIndex];
const hasTestsToRun = tests.length;
if (!currentTest.testResult && !pageReadyRef.current && isSignedIn)
@@ -814,6 +835,7 @@ const TestRun = () => {
{
+ return (
+
+
+
+ );
+ }
+ },
{
path: '/run/:runId(\\d+)',
component: () => {