Skip to content

TestResultTable

<caos-test-result-table>

per-method test results, with the message and stack trace opened in place

May be placed on a page inside an app.

Name Attribute Description Type Default Required
results property only What each test did: { className, method, outcome?, durationMs?, message?, stack? }[]. outcome ABSENT means NOT RUN — aborted, or still going — and is never counted as a pass. Setting this closes any open stack traces, because they belonged to the previous run. json empty list Optional
sortKey sort-key, markup only Which column orders the rows. Unset means failures first, then not-run, then skipped, then passes — the order a run is actually read in. text — one of outcome, className, method, durationMs outcome Optional
sortDirection sort-direction, markup only Which way. A test with no duration sorts last in BOTH directions rather than reading as the fastest test in the run. text — one of asc, desc asc Optional
emptyText empty-text, markup only What to say before anything has run. text No results yet. Optional

Not documented yet — this piece has not said.

Not documented yet — this piece has not said.

Not documented yet — this piece has not said.

Not documented yet — this piece has not said.

Name Type What it tells you
tally { pass, fail, skip, notRun } How many of each. notRun is its own number and is never added to any of the others — read it to gate anything that depends on a run having actually completed.
failures CaosTestResult[] The failures, in the order shown. Read it to build a re-run list without re-deciding what failed.
ordered CaosTestResult[] The results in the order they are drawn.
Part Which piece of it When it is there
::part(results) The outer column. Always
::part(summary) The counts line. Always
::part(table) The composed data table. Always
::part(outcome) The result pill in a row. Always
::part(detail) The detail cell. Always
::part(message) The failure message. The result carries a message or a stack.
::part(expand) The show/hide stack-trace control. The result carries a stack trace.
::part(stack) The stack trace itself. It is open.

After a run, when the question is what it did — and almost always, specifically, what failed.

  • TestRunGrid — somebody is choosing what to run rather than reading what ran.
  • CoverageList — the question is coverage rather than pass or fail.
  • DataTable — the rows are not test results. This one knows what a failure is, and orders and counts on that basis.

Every outcome is a WORD in its own pill — “failed”, “passed”, “skipped”, “not run” — so colour repeats the result and never carries it. The counts line is a role="status" live region, so a finished run announces what it found rather than only redrawing. The stack-trace control is a real button with aria-expanded and an accessible name naming the test it belongs to, which matters on a screen holding forty identical-looking toggles.

The two failures lead, whatever order they arrived in, with the message beside each and the stack trace one press away in the row itself.

{
"id": "example",
"section": "A run with failures",
"columns": 1,
"items": [
{
"id": "test_result_table_1",
"type": "component",
"key": "test_result_table",
"inputs": {
"results": [
{
"className": "BillingServiceTest",
"method": "chargesTax",
"outcome": "pass",
"durationMs": 84
},
{
"className": "BillingServiceTest",
"method": "roundsHalfUp",
"outcome": "fail",
"durationMs": 91,
"message": "expected 4.25 but got 4.24",
"stack": "BillingService.round line 48\nBillingServiceTest.roundsHalfUp line 12"
},
{
"className": "AccountTriggerTest",
"method": "insertsHandler",
"outcome": "pass",
"durationMs": 1220
},
{
"className": "QuoteCalculatorTest",
"method": "clampsToFloor",
"outcome": "fail",
"durationMs": 12,
"message": "the floor was not applied",
"stack": "QuoteCalculator.apply line 96"
},
{
"className": "QuoteCalculatorTest",
"method": "appliesDiscount",
"outcome": "skip"
}
]
}
}
]
}
<caos-test-result-table id="testResultTable1"></caos-test-result-table>
// What an attribute cannot hold, set as a property — the same values the preview is drawn with.
const testResultTable1 = document.getElementById('testResultTable1');
testResultTable1.results = [
{
"className": "BillingServiceTest",
"method": "chargesTax",
"outcome": "pass",
"durationMs": 84
},
{
"className": "BillingServiceTest",
"method": "roundsHalfUp",
"outcome": "fail",
"durationMs": 91,
"message": "expected 4.25 but got 4.24",
"stack": "BillingService.round line 48\nBillingServiceTest.roundsHalfUp line 12"
},
{
"className": "AccountTriggerTest",
"method": "insertsHandler",
"outcome": "pass",
"durationMs": 1220
},
{
"className": "QuoteCalculatorTest",
"method": "clampsToFloor",
"outcome": "fail",
"durationMs": 12,
"message": "the floor was not applied",
"stack": "QuoteCalculator.apply line 96"
},
{
"className": "QuoteCalculatorTest",
"method": "appliesDiscount",
"outcome": "skip"
}
];

The tests that never executed read “not run” and are counted on their own. Folding them into the passes would report a suite as green when a third of it never ran.

{
"id": "example",
"section": "A run that was stopped part way",
"columns": 1,
"items": [
{
"id": "test_result_table_1",
"type": "component",
"key": "test_result_table",
"inputs": {
"results": [
{
"className": "BillingServiceTest",
"method": "chargesTax",
"outcome": "pass",
"durationMs": 84
},
{
"className": "BillingServiceTest",
"method": "roundsHalfUp"
},
{
"className": "BillingServiceTest",
"method": "splitsByLine"
},
{
"className": "AccountTriggerTest",
"method": "insertsHandler"
}
]
}
}
]
}
<caos-test-result-table id="testResultTable1"></caos-test-result-table>
// What an attribute cannot hold, set as a property — the same values the preview is drawn with.
const testResultTable1 = document.getElementById('testResultTable1');
testResultTable1.results = [
{
"className": "BillingServiceTest",
"method": "chargesTax",
"outcome": "pass",
"durationMs": 84
},
{
"className": "BillingServiceTest",
"method": "roundsHalfUp"
},
{
"className": "BillingServiceTest",
"method": "splitsByLine"
},
{
"className": "AccountTriggerTest",
"method": "insertsHandler"
}
];

The other question this table answers. A test that was never timed sorts to the END in both directions rather than reading as the fastest in the run.

{
"id": "example",
"section": "Ordered by what is slow",
"columns": 1,
"items": [
{
"id": "test_result_table_1",
"type": "component",
"key": "test_result_table",
"inputs": {
"sort_key": "durationMs",
"sort_direction": "desc",
"results": [
{
"className": "AccountTriggerTest",
"method": "insertsHandler",
"outcome": "pass",
"durationMs": 1220
},
{
"className": "BillingServiceTest",
"method": "chargesTax",
"outcome": "pass",
"durationMs": 84
},
{
"className": "QuoteCalculatorTest",
"method": "clampsToFloor",
"outcome": "pass",
"durationMs": 12
},
{
"className": "QuoteCalculatorTest",
"method": "appliesDiscount",
"outcome": "skip"
}
]
}
}
]
}
<caos-test-result-table id="testResultTable1" sort-key="durationMs" sort-direction="desc"></caos-test-result-table>
// What an attribute cannot hold, set as a property — the same values the preview is drawn with.
const testResultTable1 = document.getElementById('testResultTable1');
testResultTable1.results = [
{
"className": "AccountTriggerTest",
"method": "insertsHandler",
"outcome": "pass",
"durationMs": 1220
},
{
"className": "BillingServiceTest",
"method": "chargesTax",
"outcome": "pass",
"durationMs": 84
},
{
"className": "QuoteCalculatorTest",
"method": "clampsToFloor",
"outcome": "pass",
"durationMs": 12
},
{
"className": "QuoteCalculatorTest",
"method": "appliesDiscount",
"outcome": "skip"
}
];