TestGenAI Report

AI-written tests can lie. TestGenAI makes every test prove itself.

Every acceptance criterion becomes either a Playwright assertion derived by a named rule, or an explicit test.fixme(). Planted bugs show whether the passing tests would actually fail on broken code.

Components
17
with user stories
Criteria
224
acceptance criteria
Asserted
201
90% · rest pending
Passing
201
0 failed
Bugs caught
41/47
planted, one at a time
Mutants killed
198/259
37 unproven · 6 suspect
+ Bob's tests
234/259
same mutants, either suite

Green is not the same as useful

Same components, same planted bugs, one at a time. A bug counts as caught only if at least one passing test fails on the broken build.

SuitePlanted bugs caught
v1 generator tests/e2e-baseline3 / 28
Current generator tests/e2e41 / 47

Held-out rounds

IBM Bob wrote each component and its story without reading the generator, with the rules frozen. These are the numbers before any fix.

RoundComponentCorrectPendingWrongWhat we learned
1Toggle3 / 1070Rules untouched before Bob's run. Gaps: text that flips with state, aria-checked, named classes. Now 10/10.
2Rating4 / 1271Frozen at heldout-freeze. Bob caught a test asserting the opposite of its criterion; fixed for every rule by a polarity safety net. Now 10/12.
3Alert1 / 1173Frozen at heldout-freeze-2; Bob used TestGenAI through MCP. 3 tests targeted an element only rendered under a prop. Fixed generically. Now 11/11.
4Counter0 / 1064Frozen before Bob's run. All 4 asserted tests passed but were wrong: a fixture chosen for 'is disabled' never reached the maximum. Bob flagged all 4. Fixed generically (preconditions are never guessed): now 0 wrong, the rest honestly pending. `testgen verify` on the unedited suite flags exactly the lying tests.
5CharTextarea0 / 1284Frozen before Bob's run. 3 wrong + 1 partial (clicking a textarea instead of typing; a precondition 'after clearing' ignored). Bob flagged all 4. Fixed generically: now 1 correct, 0 wrong, 11 pending.
6SearchBox1 / 1265Frozen at heldout-freeze-5. As recorded through Bob: 1 correct, 6 pending, 5 flawed, and all 5 FAILED rather than passing (typing done as a click, Enter never pressed, the input clicked instead of the Search button, two fixtures in which the clear button never renders). Found afterwards: Bob's MCP server had been running since before the freeze and served older rules; regenerated with the frozen rules the result is 2 correct, 6 pending, 4 flawed (all failing). The MCP server now reloads the rules on every call and reports the commit they come from. Fixed generically (text fields without a length limit, elements revealed by typing, Enter key, callback arguments from the text state, exact quoted labels): now 11/12, 1 honestly pending.

Prove it: testgen verify

No hand-planted bugs here. verify derives mutants from each component's source (callback not called, condition inverted, guard removed, off by one…), re-runs the suite against each one, and reports tests that never fail (unproven) and tests whose title names something a surviving mutant deleted (🚩 suspect). A surviving mutant can be equivalent, so a low score is a prompt to look, not a verdict.

SuiteMutants killed+ Bob's testsUnproven testsSuspects
Accordion
tests/e2e/Accordion.spec.ts
6 / 99 / 930
Alert
tests/e2e/Alert.spec.ts
9 / 9–10
Button
tests/e2e/Button.spec.ts
5 / 5–00
CharTextarea
tests/e2e/CharTextarea.spec.ts
13 / 2014 / 201🚩 1
🚩 “When the text length reaches the maximum, the counter receives a visual indicator class that it is at the limit” says limit, yet still passes with atLimit removed (class dropped, line 56)
Counter
tests/r4/Counter.spec.ts
3 / 24–0🚩 2
🚩 “The increment button is disabled when the value reaches the maximum” says maximum, yet still passes with max removed (guard removed, line 41)
🚩 “The decrement button is disabled when the value reaches the minimum” says minimum, yet still passes with min removed (guard removed, line 36)
Counter
tests/e2e/Counter.spec.ts
11 / 2012 / 201🚩 1
🚩 “The counter never displays a value below the minimum or above the maximum” says minimum, yet still passes with min removed (guard removed, line 36)
DataTable
tests/e2e/DataTable.spec.ts
17 / 2020 / 202🚩 1
🚩 “Displays columns: select checkbox, name, email, status, created date, actions” says name, yet still passes with name removed (rendered value dropped, line 115)
Dropdown
tests/e2e/Dropdown.spec.ts
14 / 1817 / 182🚩 1
🚩 “Search input filters options by label” says label, yet still passes with label removed (rendered value dropped, line 91)
FileUpload
tests/e2e/FileUpload.spec.ts
16 / 2020 / 2020
LoginForm
tests/e2e/LoginForm.spec.ts
15 / 1616 / 1610
Modal
tests/e2e/Modal.spec.ts
13 / 13–20
Pagination
tests/e2e/Pagination.spec.ts
12 / 2018 / 2050
Rating
tests/e2e/Rating.spec.ts
11 / 2015 / 202🚩 1
🚩 “The star buttons have descriptive aria-label attributes (e.g. "3 stars")” says label, yet still passes with label removed (rendered value dropped, line 56)
SearchBox
tests/e2e/SearchBox.spec.ts
19 / 2020 / 2020
Stepper
tests/e2e/Stepper.spec.ts
14 / 2018 / 2050
Tabs
tests/e2e/Tabs.spec.ts
8 / 1010 / 108🚩 1
🚩 “Tab buttons have proper ARIA roles (tablist, tab)” says tablist, yet still passes with tabId removed (callback argument wrong, line 27)
Toggle
tests/e2e/Toggle.spec.ts
6 / 87 / 800
Tooltip
tests/e2e/Tooltip.spec.ts
9 / 1111 / 1100

IBM Bob fills the gaps

TestGenAI left Pagination's layout criteria as honest test.fixme(). These bugs were planted before Bob wrote tests for those criteria. Generated: 3/6. Bob: 4/6. Together: 6/6.

Planted bug in PaginationGenerated testsBob's tests
Next skips a pagecaughtmissed
Previous enabled on the first pagecaughtmissed
leading ellipsis never shown when pages are skippedmissedcaught
last page button missing when the window ends earlymissedcaught
window shows 7 page numbers instead of 5missedcaught
window starts at the current page instead of centring on itcaughtcaught

Components

Accordion 16/18 asserted · 16 passed · 3/3 bugs caught
Acceptance criterionRuleResult
Renders accordion with multiple items from propscollection✓ passed
Displays each item with a title and toggle buttoncollection✓ passed
Shows content when item is expandeddisclosure✓ passed
Hides content when item is collapseddisclosure✓ passed
Clicking button toggles item expanded statedisclosure✓ passed
Displays expand/collapse icon that rotatespending– pending
Single item mode: expanding one item collapses othersdisclosure✓ passed
Multiple item mode (allowMultiple=true): multiple items can be expandeddisclosure✓ passed
Calls onItemToggle callback when item is toggledcallback✓ passed
Supports keyboard navigation (Enter/Space to toggle)keyboard-toggle✓ passed
Assigns unique data-testid to each itemunique-testids✓ passed
Uses aria-expanded attribute for accessibilityaria✓ passed
Uses aria-controls for semantic associationsaria✓ passed
Returns to collapsed state by defaultdisclosure✓ passed
Handles empty items array gracefullydegenerate-data✓ passed
All content is hidden when not expandeddisclosure✓ passed
Button text displays item title clearlycollection✓ passed
Visual icon indicates expansion statepending– pending

Planted bugs

  • caught allowMultiple ignored (always single mode)
    by “Multiple item mode (allowMultiple=true): multiple items can be expanded”
  • caught onItemToggle never called
    by “Calls onItemToggle callback when item is toggled”
  • caught aria-expanded stuck at false
    by “Clicking button toggles item expanded state”
Alert 11/11 asserted · 11 passed · 6/6 bugs caught
Acceptance criterionRuleResult
The alert displays the message text passed to itrenders-prop✓ passed
When a title is provided, the title appears above the messageorder✓ passed
When no title is provided, the title area is not renderedabsent-when-prop✓ passed
The alert reflects the correct severity: info, success, warning, and error variants are all supportedclass-from-prop✓ passed
A dismissible alert shows a dismiss buttonpresent✓ passed
A non-dismissible alert does not show a dismiss buttonabsent-when-prop✓ passed
Clicking the dismiss button removes the alert from the pageremoves-self✓ passed
Clicking the dismiss button calls the onDismiss callbackcallback✓ passed
After dismissal the alert is no longer visibleremoves-self✓ passed
The dismiss button has an accessible label so screen-reader users know its purposearia✓ passed
The alert container has the ARIA role "alert" so assistive technology announces it automaticallyaria✓ passed

Planted bugs

  • caught dismiss does not remove the alert
    by “Clicking the dismiss button removes the alert from the page”
  • caught onDismiss never called
    by “Clicking the dismiss button calls the onDismiss callback”
  • caught dismiss button shown even when not dismissible
    by “A non-dismissible alert does not show a dismiss button”
  • caught empty title element rendered when no title
    by “When no title is provided, the title area is not rendered”
  • caught severity class hard-coded to info
    by “The alert reflects the correct severity: info, success, warning, and error variants are all supported”
  • caught dismiss button loses its accessible label
    by “The dismiss button has an accessible label so screen-reader users know its purpose”
Button 6/7 asserted · 6 passed · 2/2 bugs caught
Acceptance criterionRuleResult
Button renders with provided label textrenders-prop✓ passed
Button is clickable and triggers onClick handlercallback✓ passed
Button displays disabled state when disabled prop is trueis-disabled✓ passed
Button supports primary and secondary variantsclass-from-prop✓ passed
Button supports small, medium, and large sizesclass-from-prop✓ passed
Button prevents click handler when disabledprevent-when-disabled✓ passed
Button has proper accessibility attributespending– pending

Planted bugs

  • caught disabled prop not forwarded
    by “Button displays disabled state when disabled prop is true”
  • caught variant class hard-coded
    by “Button supports primary and secondary variants”
CharTextarea 11/12 asserted · 11 passed
Acceptance criterionRuleResult
The textarea renders with the provided placeholder text when the value is emptytext-placeholder✓ passed
The character counter displays the remaining characters out of the maximum in the format "remaining/max"text-counter✓ passed
Typing in the textarea updates the displayed value and decreases the remaining character counttext-typing✓ passed
When the text length reaches the maximum, no additional characters can be enteredtext-limit✓ passed
When the text length reaches the maximum, the counter receives a visual indicator class that it is at the limittext-limit-class✓ passed
The Clear button is disabled when the textarea is emptytext-clear-disabled✓ passed
Clicking the Clear button removes all text and resets the character counter to the full maximumtext-clear✓ passed
After clearing, the Clear button becomes disabled againtext-clear-after✓ passed
When the disabled prop is true, the textarea cannot be editedtext-readonly-when-disabled✓ passed
When the disabled prop is true, the Clear button is disabled even when there is existing textpending– pending
Typing fires the onChange callback with the current value on every keystrokecallback✓ passed
Clicking Clear fires the onChange callback with an empty stringtext-clear-callback✓ passed
Counter 10/10 asserted · 10 passed
Acceptance criterionRuleResult
The counter displays its initial value when first renderednumeric-initial✓ passed
Clicking the increment button increases the displayed value by one stepnumeric-step✓ passed
Clicking the decrement button decreases the displayed value by one stepnumeric-step✓ passed
The increment button is disabled when the value reaches the maximumnumeric-boundary✓ passed
The decrement button is disabled when the value reaches the minimumnumeric-boundary✓ passed
Clicking the Reset button returns the value to the initial valuenumeric-reset✓ passed
Incrementing calls the onChange callback with the new valuenumeric-callback✓ passed
Decrementing calls the onChange callback with the new valuenumeric-callback✓ passed
When the counter is disabled, none of the buttons can be clicked and no value changes occurnumeric-frozen✓ passed
The counter never displays a value below the minimum or above the maximumnumeric-clamp✓ passed
DataTable 13/15 asserted · 13 passed · 4/4 bugs caught
Acceptance criterionRuleResult
Renders table with data rows from propscollection✓ passed
Displays columns: select checkbox, name, email, status, created date, actionscolumns✓ passed
Allows clicking row to trigger onRowClick callback with row datacallback✓ passed
Allows sorting data by name, email, or status proppending– pending
Allows filtering by status prop (active, inactive, pending, all)filter-by-prop✓ passed
Supports multi-select with individual row checkboxesmulti-select✓ passed
Select all checkbox selects/deselects all visible rowsselect-all✓ passed
Delete button on each row triggers onDelete callback with row idcallback✓ passed
Delete Selected button bulk deletes all selected rowsbulk-action✓ passed
Delete Selected button is disabled when no rows are selectedis-disabled✓ passed
Shows "No data available" message when data array is emptyquoted-text✓ passed
Handles empty data array gracefully without errorsdegenerate-data✓ passed
Clicking on a row selects it visually without triggering onRowClick during checkbox interactionwithout-triggering✓ passed
Status column displays status with appropriate stylingclass-from-item✓ passed
Date formatting displays in locale-appropriate formatpending– pending

Planted bugs

  • caught bulk delete removes every row, not just selected
    by “Delete Selected button bulk deletes all selected rows”
  • caught row checkbox click also triggers onRowClick
    by “Clicking on a row selects it visually without triggering onRowClick during checkbox interaction”
  • caught status filter ignored
    by “Allows filtering by status prop (active, inactive, pending, all)”
  • caught onDelete receives the row index instead of its id
    by “Delete button on each row triggers onDelete callback with row id”
Dropdown 16/19 asserted · 16 passed · 3/3 bugs caught
Acceptance criterionRuleResult
Renders dropdown button with selected value or placeholderselected-value✓ passed
Clicking button opens dropdown menudisclosure✓ passed
Menu displays all available options from propscollection✓ passed
Clicking option selects it and closes menuclose-action✓ passed
Selected option is highlighted visuallyconditional-class✓ passed
Search input filters options by labelsearch-filter✓ passed
Shows "No options found" when no matchessearch-filter✓ passed
Handles disabled state (button disabled, menu closed)is-disabled✓ passed
Calls onSelect callback with selected optioncallback✓ passed
Closes menu when clicking outside dropdownclose-action✓ passed
Closes menu when option is selectedclose-action✓ passed
Displays selected option value in buttonselected-value✓ passed
Arrow icon rotates when menu is openpending– pending
Supports aria-expanded and aria-haspopup for accessibilityaria✓ passed
Each option has unique data-testidunique-testids✓ passed
Option click event works correctlypending– pending
Search input updates filter in real-timesearch-filter✓ passed
Empty options array handled gracefullydegenerate-data✓ passed
Multiple rapid selections work correctlypending– pending

Planted bugs

  • caught menu stays open after selecting an option
    by “Clicking option selects it and closes menu”
  • caught search box does not filter
    by “Search input filters options by label”
  • caught click outside no longer closes the menu
    by “Closes menu when clicking outside dropdown”
FileUpload 15/15 asserted · 15 passed · 3/3 bugs caught
Acceptance criterionRuleResult
Drop zone accepts dragged filesfile-upload✓ passed
Drop zone shows visual feedback when dragging overfile-upload✓ passed
Clicking drop zone opens file pickerfile-upload✓ passed
File input accepts files and triggers onUploadfile-upload✓ passed
Selected files display in a listfile-upload✓ passed
Each file shows name and remove buttonfile-upload✓ passed
Remove button deletes file from selectionfile-upload✓ passed
Multiple file support controlled by multiple propfile-upload✓ passed
Validates against maxSize propfile-upload✓ passed
Shows error message when file too largefile-upload✓ passed
Shows error message when multiple files not allowedfile-upload✓ passed
onError callback fires when validation failsfile-upload✓ passed
Accept attribute filters file typesfile-upload✓ passed
Error message clears when valid files selectedfile-upload✓ passed
Handles empty file selection gracefullyfile-upload✓ passed

Planted bugs

  • caught maxSize off by one (rejects a file of exactly maxSize)
    by “Validates against maxSize prop”
  • caught remove button does not remove the file
    by “Remove button deletes file from selection”
  • caught error not cleared after a valid selection
    by “Error message clears when valid files selected”
LoginForm 8/8 asserted · 8 passed · 3/3 bugs caught
Acceptance criterionRuleResult
Form renders with email and password inputspresent✓ passed
Form validates email formatform✓ passed
Form requires both email and passwordform✓ passed
Form displays error messagesform✓ passed
Form is disabled during submissionform✓ passed
Form calls onSubmit with correct credentialsform✓ passed
Form clears errors on new attemptform✓ passed
Submit button shows loading stateform✓ passed

Planted bugs

  • caught required-field validation removed
    by “Form requires both email and password”
  • caught onSubmit arguments swapped
    by “Form calls onSubmit with correct credentials”
  • caught inputs stay enabled while loading
    by “Form is disabled during submission”
Modal 13/14 asserted · 13 passed · 3/3 bugs caught
Acceptance criterionRuleResult
Modal is hidden when isOpen prop is falserender-when-prop✓ passed
Modal is visible when isOpen prop is truerender-when-prop✓ passed
Displays modal title from title proprenders-prop✓ passed
Displays modal content from children proprenders-prop✓ passed
Close button (×) closes modal by calling onClose callbackclose-action✓ passed
Clicking overlay background closes modalclose-action✓ passed
Cancel button closes modal without confirmingclose-action✓ passed
Confirm button calls onConfirm callback when presentcallback✓ passed
Confirm button text customizable via confirmText proprenders-prop✓ passed
Cancel button text customizable via cancelText proprenders-prop✓ passed
Danger modal variant shows red confirm button when isDangerous is trueconditional-class✓ passed
Clicking inside modal content doesn't close modalclose-action✓ passed
Modal handles both confirmation and info-only modespending– pending
Accessibility: Close button has aria-labelaria✓ passed

Planted bugs

  • caught overlay click no longer closes
    by “Clicking overlay background closes modal”
  • caught clicks inside the dialog bubble to the overlay and close it
    by “Clicking inside modal content doesn't close modal”
  • caught cancel button confirms instead of closing
    by “Cancel button closes modal without confirming”
Pagination 11/15 asserted · 11 passed · 3/6 bugs caught
Acceptance criterionRuleResult
Displays current page and total pagesrenders-prop✓ passed
Previous button is disabled when on first pageis-disabled✓ passed
Next button is disabled when on last pageis-disabled✓ passed
Previous button navigates to previous page when enablednavigation✓ passed
Next button navigates to next page when enablednavigation✓ passed
Shows page number buttons for navigationpresent✓ passed
Current page button is highlighted/activeconditional-class✓ passed
Clicking page number navigates to that pagenavigation✓ passed
Shows ellipsis (...) when pages are skippedpending– pending
Always shows first and last page numberspending– pending
Shows maximum of 5 page numbers plus ellipsispending– pending
Page numbers centered around current pagepending– pending
Displays "Page X of Y" textquoted-text✓ passed
Accessible: Previous/Next buttons have aria-labelsaria✓ passed
Accessible: Current page has aria-current="page"aria✓ passed

Planted bugs

  • caught Next skips a page
    by “Next button navigates to next page when enabled”
  • caught Previous enabled on the first page
    by “Previous button is disabled when on first page”
  • missed leading ellipsis never shown when pages are skipped
  • missed last page button missing when the window ends early
  • missed window shows 7 page numbers instead of 5
  • caught window starts at the current page instead of centring on it
    by “Previous button navigates to previous page when enabled”
Rating 10/12 asserted · 10 passed · 3/5 bugs caught
Acceptance criterionRuleResult
Renders the correct number of star buttons (default 5)item-count✓ passed
Displays "Not rated" when no value has been selectedstate-text✓ passed
Displays the selected value as "<n> / <max>" after a star is clickedtemplate-text✓ passed
Clicking a star selects that rating and calls the onChange callback with the numeric valuecallback✓ passed
The clicked star and all stars before it receive the filled style (rating-star-filled class)cumulative-class✓ passed
Stars after the selected star are rendered as unfilledcumulative-class✓ passed
Hovering over a star highlights that star and all stars before it without changing the committed valuehover-preview✓ passed
Moving the mouse away from the stars reverts the highlight to the committed valuehover-preview✓ passed
A disabled Rating cannot be clicked and does not fire onChangeprevent-when-disabled✓ passed
A read-only Rating cannot be clicked and does not fire onChangepending– pending
The star buttons have descriptive aria-label attributes (e.g. "3 stars")aria✓ passed
The component renders a visible label text identifying the rating grouppending– pending

Planted bugs

  • caught fill is off by one (clicked star not filled)
    by “The clicked star and all stars before it receive the filled style (rating-star-filled class)”
  • caught hover highlight not cleared on mouse leave
    by “Moving the mouse away from the stars reverts the highlight to the committed value”
  • caught empty-state text changed
    by “Displays "Not rated" when no value has been selected”
  • missed onChange receives a 0-based index instead of the star value
  • missed read-only is ignored on click
SearchBox 11/12 asserted · 11 passed
Acceptance criterionRuleResult
The search input renders with the provided placeholder text when no value is enteredtext-placeholder✓ passed
Typing into the search input updates the displayed value and calls the onChange callback with the new textcallback✓ passed
The clear button is not visible when the input is emptytext-gated-visibility✓ passed
The clear button appears once the user has typed at least one charactertext-gated-visibility✓ passed
Clicking the clear button empties the input and calls the onClear callbacktext-clear✓ passed
Clicking the clear button also calls the onChange callback with an empty stringtext-clear-callback✓ passed
Pressing Enter while the input is focused calls the onSearch callback with the current input valuekey-callback✓ passed
Clicking the Search button calls the onSearch callback with the current input valuecallback✓ passed
When the disabled prop is true, the input cannot be typed in and the Search button is disabledtext-readonly-when-disabled✓ passed
When the disabled prop is true, the clear button is disabled when it is visiblepending– pending
The search input has an accessible label "Search"aria✓ passed
The clear button has an accessible label "Clear search"aria✓ passed
Stepper 16/19 asserted · 16 passed · 2/2 bugs caught
Acceptance criterionRuleResult
Renders all steps from props with labelscollection✓ passed
Displays current step as active/highlightedconditional-class✓ passed
Previous steps marked as completed with checkmarknavigation✓ passed
Clicking completed step navigates back to itnavigation✓ passed
Clicking current step is disablednavigation✓ passed
Clicking future steps is disabled (except next step)navigation✓ passed
Next button advances to next stepnavigation✓ passed
Previous button goes back to previous stepnavigation✓ passed
First step has Previous button disabledis-disabled✓ passed
Last step has Next button disabledis-disabled✓ passed
Step indicator shows current position (e.g. "Step 2 of 5")quoted-text✓ passed
Connector lines show progress between stepspending– pending
Connector lines highlight for completed stepspending– pending
Calls onStepChange callback when step changescallback✓ passed
Supports disableNavigation prop to prevent clickingnavigation✓ passed
Each step has unique data-testidunique-testids✓ passed
Handles single step gracefullydegenerate-data✓ passed
Handles empty steps array gracefullydegenerate-data✓ passed
Step status prop reflects in stylingpending– pending

Planted bugs

  • caught Previous not disabled on the first step
    by “First step has Previous button disabled”
  • caught current step also marked completed
    by “Previous steps marked as completed with checkmark”
Tabs 13/15 asserted · 13 passed · 0/1 bugs caught
Acceptance criterionRuleResult
Displays all tabs from tabs propcollection✓ passed
First tab is active by defaultnavigation✓ passed
Can set default active tab via defaultTabId propnavigation✓ passed
Clicking tab button activates that tabnavigation✓ passed
Active tab button shows active stylingconditional-class✓ passed
Displays content of active tabnavigation✓ passed
Active tab button has aria-selected="true"aria✓ passed
Inactive tab buttons have aria-selected="false"aria✓ passed
Disabled tabs cannot be clickednavigation✓ passed
Disabled tabs show disabled stylingconditional-class✓ passed
Tab buttons have proper ARIA roles (tablist, tab)aria✓ passed
Tab panel has proper ARIA controlsaria✓ passed
Tab content updates when tab changespending– pending
onTabChange callback fires when tab is clickedcallback✓ passed
Each tab can have different content typespending– pending

Planted bugs

  • missed disabled tabs can be activated
Toggle 10/10 asserted · 10 passed · 4/4 bugs caught
Acceptance criterionRuleResult
Toggle renders with the provided label text visiblerenders-prop✓ passed
Toggle renders with `data-testid="toggle-state"` showing "Off" by defaultstate-text✓ passed
Toggle renders with `data-testid="toggle-state"` showing "On" when the `checked` prop is truestate-text✓ passed
Clicking the toggle switch flips the state from "Off" to "On"state-text✓ passed
Clicking the toggle switch again flips the state back from "On" to "Off"state-text✓ passed
Clicking the toggle calls the `onChange` callback with the new boolean valuecallback✓ passed
The switch button has `aria-checked` set to `false` when off and `true` when onaria✓ passed
The switch button has the class `toggle-on` when checked and no such class when uncheckednamed-class✓ passed
The toggle switch is disabled and cannot be clicked when the `disabled` prop is trueis-disabled✓ passed
A disabled toggle does not call `onChange` when interacted withprevent-when-disabled✓ passed

Planted bugs

  • caught onChange never called
    by “Clicking the toggle calls the `onChange` callback with the new boolean value”
  • caught state text inverted (shows On when off)
    by “Toggle renders with `data-testid="toggle-state"` showing "Off" by default”
  • caught aria-checked stuck at false
    by “The switch button has `aria-checked` set to `false` when off and `true` when on”
  • caught toggle-on class never applied
    by “The switch button has the class `toggle-on` when checked and no such class when unchecked”
Tooltip 11/12 asserted · 11 passed · 2/2 bugs caught
Acceptance criterionRuleResult
Tooltip is hidden by defaultdisclosure✓ passed
Tooltip appears on mouse enter after delaydisclosure✓ passed
Tooltip disappears on mouse leavedisclosure✓ passed
Tooltip displays content from content proprenders-prop✓ passed
Tooltip position can be set to top, bottom, left, or rightclass-from-prop✓ passed
Tooltip position defaults to topclass-from-prop✓ passed
Delay can be customized via delay propdisclosure✓ passed
Delay defaults to 200mspending– pending
Tooltip has role="tooltip" for accessibilityaria✓ passed
Multiple hover events handled correctlydisclosure✓ passed
Clicking trigger doesn't hide tooltipdisclosure✓ passed
Tooltip position styling applied correctlyclass-from-prop✓ passed

Planted bugs

  • caught delay prop ignored (always 200ms)
    by “Tooltip appears on mouse enter after delay”
  • caught tooltip does not hide on mouse leave
    by “Tooltip disappears on mouse leave”