Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-36712

Test Results screen throws "unique keys" error

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Minor Minor
    • blueocean-plugin
    • None
    • 1.0-m11, 1.0-m12

      To repro:

      1. Navigate to a pipeline that publishes test results (I used the JDL)
      2. Choose a Run
      3. Select the "Tests" tab

      Each child in an array or iterator should have a unique "key" prop. Check the render method of `TestResult`. See https://fb.me/react-warning-keys for more information.

      JSON from endpoint:

          "_class": "hudson.tasks.junit.TestResult",
          "testActions": [],
          "duration": 0.151,
          "empty": false,
          "failCount": 0,
          "passCount": 26,
          "skipCount": 0,
          "suites": [{
              "cases": [{
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).CommitHash",
                  "duration": 0.049,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "CommitHash renders dash with no data",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).CommitHash",
                  "duration": 0.003,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "CommitHash renders dash with invalid data",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).CommitHash",
                  "duration": 0.006,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "CommitHash renders sha-1 char hash with proper length",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                  "duration": 0.006,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "FileSize renders dash with no data",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                  "duration": 0.003,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "FileSize renders dash with invalid data",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                  "duration": 0.002,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "FileSize renders 4 bytes",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                  "duration": 0.009,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "FileSize renders 1.5 MB",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                  "duration": 0.002,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "FileSize renders very large values reasonably",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                  "duration": 0.007,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ReadableDate renders dash with no data",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                  "duration": 0.017,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ReadableDate renders dash with non-ISO-8601 date string",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                  "duration": 0.02,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ReadableDate renders 'a few seconds ago' with current date",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                  "duration": 0.008,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ReadableDate renders 'an hour ago' with current date minus 60m",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                  "duration": 0.005,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ReadableDate renders proper tooltip without year for same year date",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                  "duration": 0.001,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ReadableDate renders proper tooltip with year for other year dates",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                  "duration": 0.002,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ReadableDate renders proper tooltip with TZ info for non-UTC dates",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                  "duration": 0.001,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ReadableDate renders proper tooltip as UTC for dates without TZ",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ResultItem",
                  "duration": 0.002,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ResultItem visible by default",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).ResultItem",
                  "duration": 0.001,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "ResultItem hidden by default",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                  "duration": 0.001,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "TimeDuration renders dash with no data",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                  "duration": 0.0,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "TimeDuration renders dash with invalid data",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                  "duration": 0.002,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "TimeDuration renders 'a few seconds' with 1ms",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                  "duration": 0.001,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "TimeDuration renders 'a few seconds' with 1ms as string",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                  "duration": 0.001,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "TimeDuration renders '3 hours' with 3.25h",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                  "duration": 0.001,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "TimeDuration renders a tooltip of '5m, 5s' when supplied value",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                  "duration": 0.001,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "TimeDuration renders a tooltip of '2h, 0m, 5s' when supplied value",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }, {
                  "testActions": [],
                  "age": 0,
                  "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                  "duration": 0.0,
                  "errorDetails": null,
                  "errorStackTrace": null,
                  "failedSince": 0,
                  "name": "TimeDuration renders a custom tooltip",
                  "skipped": false,
                  "skippedMessage": null,
                  "status": "PASSED",
                  "stderr": "",
                  "stdout": "\n    \n\n  "
              }],
              "duration": 0.151,
              "id": "0",
              "name": "PhantomJS 2.1.1 (Linux 0.0.0)",
              "stderr": "",
              "stdout": "\n    \n\n  ",
              "timestamp": "2016-07-14T19:56:28"
          }]
      }
      

          [JENKINS-36712] Test Results screen throws "unique keys" error

          Cliff Meyers created issue -
          Cliff Meyers made changes -
          Epic Link New: JENKINS-36296 [ 172305 ]
          Cliff Meyers made changes -
          Description Original: To repro:
          # Navigate to a pipeline that publishes test results (I used the JDL)
          # Choose a Run
          # Select the "Tests" tab

          Should be able to open and view test results, instead console error is thrown and results cannot be expanded.

          Each child in an array or iterator should have a unique "key" prop. Check the render method of `TestResult`. See https://fb.me/react-warning-keys for more information.

          JSON from endpoint:

          {code}

              "_class": "hudson.tasks.junit.TestResult",
              "testActions": [],
              "duration": 0.151,
              "empty": false,
              "failCount": 0,
              "passCount": 26,
              "skipCount": 0,
              "suites": [{
                  "cases": [{
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).CommitHash",
                      "duration": 0.049,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "CommitHash renders dash with no data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).CommitHash",
                      "duration": 0.003,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "CommitHash renders dash with invalid data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).CommitHash",
                      "duration": 0.006,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "CommitHash renders sha-1 char hash with proper length",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.006,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders dash with no data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.003,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders dash with invalid data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders 4 bytes",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.009,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders 1.5 MB",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders very large values reasonably",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.007,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders dash with no data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.017,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders dash with non-ISO-8601 date string",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.02,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders 'a few seconds ago' with current date",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.008,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders 'an hour ago' with current date minus 60m",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.005,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders proper tooltip without year for same year date",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders proper tooltip with year for other year dates",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders proper tooltip with TZ info for non-UTC dates",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders proper tooltip as UTC for dates without TZ",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ResultItem",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ResultItem visible by default",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ResultItem",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ResultItem hidden by default",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders dash with no data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.0,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders dash with invalid data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders 'a few seconds' with 1ms",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders 'a few seconds' with 1ms as string",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders '3 hours' with 3.25h",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders a tooltip of '5m, 5s' when supplied value",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders a tooltip of '2h, 0m, 5s' when supplied value",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.0,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders a custom tooltip",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }],
                  "duration": 0.151,
                  "id": "0",
                  "name": "PhantomJS 2.1.1 (Linux 0.0.0)",
                  "stderr": "",
                  "stdout": "\n \n\n ",
                  "timestamp": "2016-07-14T19:56:28"
              }]
          }
          {code}
          New: To repro:
          # Navigate to a pipeline that publishes test results (I used the JDL)
          # Choose a Run
          # Select the "Tests" tab

          Each child in an array or iterator should have a unique "key" prop. Check the render method of `TestResult`. See https://fb.me/react-warning-keys for more information.

          JSON from endpoint:

          {code}

              "_class": "hudson.tasks.junit.TestResult",
              "testActions": [],
              "duration": 0.151,
              "empty": false,
              "failCount": 0,
              "passCount": 26,
              "skipCount": 0,
              "suites": [{
                  "cases": [{
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).CommitHash",
                      "duration": 0.049,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "CommitHash renders dash with no data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).CommitHash",
                      "duration": 0.003,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "CommitHash renders dash with invalid data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).CommitHash",
                      "duration": 0.006,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "CommitHash renders sha-1 char hash with proper length",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.006,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders dash with no data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.003,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders dash with invalid data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders 4 bytes",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.009,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders 1.5 MB",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).FileSize",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "FileSize renders very large values reasonably",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.007,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders dash with no data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.017,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders dash with non-ISO-8601 date string",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.02,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders 'a few seconds ago' with current date",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.008,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders 'an hour ago' with current date minus 60m",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.005,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders proper tooltip without year for same year date",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders proper tooltip with year for other year dates",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders proper tooltip with TZ info for non-UTC dates",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ReadableDate",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ReadableDate renders proper tooltip as UTC for dates without TZ",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ResultItem",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ResultItem visible by default",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).ResultItem",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "ResultItem hidden by default",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders dash with no data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.0,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders dash with invalid data",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.002,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders 'a few seconds' with 1ms",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders 'a few seconds' with 1ms as string",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders '3 hours' with 3.25h",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders a tooltip of '5m, 5s' when supplied value",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.001,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders a tooltip of '2h, 0m, 5s' when supplied value",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }, {
                      "testActions": [],
                      "age": 0,
                      "className": "PhantomJS_2_1_1_(Linux_0_0_0).TimeDuration",
                      "duration": 0.0,
                      "errorDetails": null,
                      "errorStackTrace": null,
                      "failedSince": 0,
                      "name": "TimeDuration renders a custom tooltip",
                      "skipped": false,
                      "skippedMessage": null,
                      "status": "PASSED",
                      "stderr": "",
                      "stdout": "\n \n\n "
                  }],
                  "duration": 0.151,
                  "id": "0",
                  "name": "PhantomJS 2.1.1 (Linux 0.0.0)",
                  "stderr": "",
                  "stdout": "\n \n\n ",
                  "timestamp": "2016-07-14T19:56:28"
              }]
          }
          {code}
          James Dumay made changes -
          Assignee New: Keith Zantow [ kzantow ]
          James Dumay made changes -
          Sprint New: 1.0-m11 [ 71 ]
          James Dumay made changes -
          Rank New: Ranked lower
          James Dumay made changes -
          Sprint Original: 1.0-m11 [ 71 ] New: 1.0-m11, 1.0-m12 [ 71, 76 ]
          James Dumay made changes -
          Priority Original: Minor [ 4 ] New: Critical [ 2 ]
          James Dumay made changes -
          Rank New: Ranked higher
          Keith Zantow made changes -
          Priority Original: Critical [ 2 ] New: Minor [ 4 ]
          Keith Zantow made changes -
          Status Original: Open [ 1 ] New: In Progress [ 3 ]

            kzantow Keith Zantow
            cliffmeyers Cliff Meyers
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: