JSFiddle - React, Tailwind, and code Playground

HTML

<h2>Results</h2>
    <div id="selfTestPanel">
        <h3>Try it yourself</h3>
        <table>
            <tr><td>Left</td><td colspan="2">right</td></tr>
            <tr>
                <td><input type="text" id="testLeft" /></td>
                <td><input type="text" id="testRight" /></td>
                <td><button id="selfTryButton">Try</button></td>
            </tr>
        
        </table>
    </div>
    <br />
    <div id="tablePanel" >
        <h3>Positive Tests</h3>
        <table class="resultsTable" id="positiveOutput">
            <thead>
                <tr><th>left</th><th>right</th><th>Result</th><th>Comment</th></tr>
            </thead>
            <tbody />
        </table>
        <br />
        <h3>Negative Tests</h3>
        <table class="resultsTable" id="negativeOutput">
            <thead>
                <tr><th>left</th><th>right</th><th>Result</th><th>Comment</th></tr>
            </thead>
            <tbody />
        </table>
    </div>
    <div id="logPanel">
        <h3>Tokens</h3>
        <table id="logHead">
        <tr><td>Left:</td><td id="logLeft" ></td></tr>
        <tr><td>Right:</td><td id="logRight" ></td></tr>
        <tr><td>Result:</td><td id="logResult" ></td></tr>
        <tr><td>Comment:</td><td id="logComment" ></td></tr>
        </table>
        <table id="logOutput">
            <thead>
                <tr><th>left</th><th>right</th></tr>
            </thead>
            <tbody />
        </table>
    </div>

CSS

body {
            font-family: verdana;
        }
        th {
            text-align: left;
            text-transform: uppercase;
        }
        table {
            border-collapse:collapse;
        }
        td {
            text-align: left;
            padding: 4px 20px 4px 0px;
        }
        tr
        {
            cursor: pointer;
        }
        h3
        {
            margin: 0 0 5px 0;
            border-bottom: 1px solid #ddd;
        }
        .resultsTable tbody tr:nth-child(2n+1) {
           background:#f8f8f8;   
        }
            .resultsTable tbody tr:hover
            {
                background: #f0f0f0;
            }

        #logOutput tbody tr:nth-child(2n+1)
        {
            background: #f8f8e8;
        }

        #logOutput, .resultsTable
        {
            width: 100%;
        }

        #positiveOutput .bad, #negativeOutput .good {
            color: red;
        }

        #logPanel
        {
            position:absolute;
            top: 10px;
            left: 20px;
            border: 1px #e8e8ee solid;
            border-radius: 3px;
            padding: 5px;
            background: #fffff0;
            width: 400px;
            max-height: 300px;
            overflow-y: scroll;
        }
        .nulltoken
        {
            color: red;
        }

JavaScript

var trueInput = [
    { left: '[abcd]d', right: '*d', comment: 'Recursive Backtracking', expects: true },
    { left: 'abc', right: 'abc', comment: 'literal', expects: true },
    { left: '*', right: 'abc', comment: 'base *', expects: true },
    { left: '?', right: 'a', comment: 'base ?', expects: true },
    { left: '[abc]', right: 'a', comment: 'base set', expects: true },
    { left: 'prefix*', right: 'prefix:extended*', comment: 'from question', expects: true },
    { left: '*suffix', right: '*:extended:suffix', comment: 'from question', expects: true },
    { left: 'left*right', right: 'left*middle*right', comment: 'from question', expects: true },
    { left: 'a*b*c', right: 'a*b*d*b*c', comment: 'from question', expects: true },
    { left: 'hello*', right: '*ok', comment: 'from question', expects: true },
    { left: 'pre[ab]fix*', right: 'pre[bc]fix*', comment: 'from question', expects: true },
    { left: '***', right: '***', comment: 'mirror *', expects: true },
    { left: '???', right: '???', comment: 'mirror ?', expects: true },
    { left: 'abc?efg?ijk?n?p', right: 'abcdefg[hijk]ijk*mnop', comment: '? vs all', expects: true },
    { left: 'abc[def]efg[hij]ijk[lmn]mno[pqr]q', right: 'abcdefg[hij]ijk*lmno?q', comment: 'set vs all', expects: true },
    { left: 'abc*fgh*ijklmn*pqr*tu', right: 'abcdefgh[ijk]jklmn?qr*u', comment: 'any vs all', expects: true },
    { left: '[abc][cde][efg]', right: '[abc][cde][efg]', comment: 'mirror set', expects: true },
    { left: '[abc]*[def]*[abc]', right: 'cda', comment: 'zero length *', expects: true },
    { left: 'ab*?*de', right: 'abcde', comment: 'zero length *', expects: true },
    { left: '[abc]*[cde]*[efg]', right: 'abcde', comment: '1 length *', expects: true },
    { left: 'ab*?*de', right: 'abcde', comment: '1 length *', expects: true },
    { left: 'abc*def*hij', right: 'abc*def*hij', comment: 'recursive *', expects: true },
    { left: 'abc[def]hij', right: 'a*j', comment: 'set in any', expects:...