Repository navigation
Conversation
Rewrite both specs to drive the real KSelect the way a user does instead of reading component internals. Add cases for the selected option label and for keeping saved answers when another field changes.
|
👋 Hi @rishiraj38, thanks for contributing! For the review process to begin, please verify that the following is satisfied:
📢✨ Before we assign a reviewer:
Also check that issue requirements are satisfied & you ran Pull requests that don't follow the guidelines will be closed. Reviewer assignment can take up to 2 weeks. |
🟡 Waiting for changesLast updated: 2026-10-05 04:10 UTC |
Build Artifacts
Smoke test screenshot |
rtibblesbot
left a comment
There was a problem hiding this comment.
PR #15466 is a clean, in-scope migration. Both specs now drive the real KSelect. They assert on labels and emitted values, with no wrapper.vm reads. I didn't run Jest locally; the worktree has no node_modules.
- CI:
Build WHLfailed at "Build Kolibri" (exit 2).WHL smoke testsfailed only because it depends on that job. This diff touches only two spec files, so it can't cause the failure. I couldn't read the logs from the sandbox. Please re-run the job. If it fails again, check develop. - One nitpick inline.
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Ran a core review pass only:
- Classified the diff and reviewed the whole PR for correctness, design, testing, and completeness
- Specialized frontend/backend lenses and manual QA run when a review is explicitly requested by a maintainer
- Checked CI status and chose the verdict from the findings, CI status, and available evidence
The two description tests only clicked the description text. They now tab to the select and assert the description is visible inside the focused control, then open it.
npm Package VersionsMerging this PR will publish the following packages to npm:
Warning The following packages have changed files but no version bump:
If these changes affect published code, consider bumping the version. |
rtibblesbot
left a comment
There was a problem hiding this comment.
PR #15466: no new findings. The 1 prior finding is resolved. CI is still pending.
Prior-finding status
RESOLVED — packages/kolibri-common/components/ExtraDemographics/tests/ExtraDemographicField.spec.js:56 — test never asserts the description is shown
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:
- Retrieved prior bot reviews via the GitHub API
- Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
- Only raised NEW findings for newly introduced code
- Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
- Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence
rtibbles
left a comment
There was a problem hiding this comment.
Possible for some of these assertions to be more specific, I think.
| renderComponent({ field: translatedField }); | ||
|
|
||
| const select = await tabToSelect(); | ||
| expect(within(select).getByText(TRANSLATED_DESCRIPTION)).toBeVisible(); |
There was a problem hiding this comment.
getByText along with toBeVisible, or toBeInDocument are very weak assertions, and lots could be changed about the component while still passing these tests. See here for more details: https://testing-library.com/docs/queries/about/#priority
There was a problem hiding this comment.
KSelect's control has no role or accessible name, so only getByText matches here. The test now finds the description inside the focused control and clicks it to open the list, then asserts the options in order. Do you want a KDS follow-up that adds a combobox role and a label association?
There was a problem hiding this comment.
Went through the priority list. getByRole, getByLabelText and getByPlaceholderText return nothing for KSelect, so getByText is the highest query available here. If you prefer, I'll add a data-testid on the select and assert toHaveTextContent on it, as in #14376.
There was a problem hiding this comment.
Thanks for working through the query priorities. No KDS follow-up needed from you: I've filed learningequality/kolibri-design-system#1348 to make KSelect a combobox with a labelled listbox. A data-testid would land on KSelect's root, which also contains the option labels, so it wouldn't be any stronger. Keep the current test for now; once #1348 lands this can become getByRole('combobox', { name: description }).
| it('shows the label of the selected option', () => { | ||
| renderComponent({ field, value: SIX_TO_TEN.value }); | ||
|
|
||
| expect(screen.getByText(SIX_TO_TEN.defaultLabel)).toBeInTheDocument(); |
There was a problem hiding this comment.
This now reads the value from the focused control, outside the hidden option list, then opens with Enter and confirms with Enter, which has to emit the preselected value. The selected item carries only a class, so there is no aria-selected to query.
The description tests now open the select by clicking the description inside the focused control, so the text has to be the select's label. The selected option test finds the displayed value outside the hidden option list, then opens the list and confirms with Enter, which has to emit the preselected option.
rtibblesbot
left a comment
There was a problem hiding this comment.
PR #15466: the one prior finding is resolved; no new findings.
Prior-finding status
RESOLVED — packages/kolibri-common/components/ExtraDemographics/tests/ExtraDemographicField.spec.js:65 — description test never asserts the description is shown
Written by rtibblesbot, an LLM-based coding agent.
rtibbles
left a comment
There was a problem hiding this comment.
Thanks for sticking with this one, @rishiraj38. The tests now check real behaviour, and digging into KSelect's markup turned up the gap we're fixing in learningequality/kolibri-design-system#1348.
|
Thanks @rtibbles for the reviews. |
Summary
Migrates
ExtraDemographicField.spec.jsandExtraDemographics.spec.jsfrom@vue/test-utilsto Vue Testing Library. The old tests readwrapper.vm.description,wrapper.vm.optionsandwrapper.vm.customSchemaand firedselectby hand on the child component. The new ones render the realKSelect, open it, and assert on the labels, options and emitted values a user produces.Only the two spec files change.
Acceptance criteria from #14270:
@testing-library/vue: both specs userenderandscreen.@vue/test-utilsimports: none left in either file.getAllByRole('listitem').KSelectgives its control no role or accessible name and its label is a plaindiv, and its selected option is marked only by a class. The description tests tab to the control, find the description inside it and click it to open this select's options. The selected option test finds the displayed label outside the option list, then confirms the preselected option with Enter and checks the emitted value.renderComponentandemitted()as inCoreMenuOption.spec.js,selectKSelectOptionfromtestUtilsas in the coachLessonsRootPage,ExamsRootPageandLearnersRootPagespecs,userEventfor the direct clicks.pnpm run test-jest -- --testPathPattern ExtraDemographicspasses: 2 suites, 6 tests.References
Fixes #14270
Reviewer guidance
Commands and results:
pnpm run test-jest -- --testPathPattern ExtraDemographics: 2 suites, 6 tests pass.pnpm test-jest packages/kolibri-common: 63 suites, 1115 tests pass.prek run --from-ref origin/develop --to-ref HEAD: all hooks pass, nothing rewritten.Old to new,
ExtraDemographicField.spec.js(5 tests to 4):shows the description and the default option labels of a field without translations. Tabs to the select, asserts the description is visible inside the focused control and clicks it to open the list.emits the value of the option the user picks.shows the description and the option labels translated into the current language. Same steps with the translated description.emits the value of the option the user picks, with a real click on the option instead of$emiton the child.shows the selected option as the value and keeps it selected when the list opensOld to new,
ExtraDemographics.spec.js(3 tests to 2):emits the picked answer when no answers are saved yet, samevalue: nullinput, with a real click.wrapper.vm.customSchemato the prop it is read from. Its visible effect, one select per entry indemographic_fields, is covered by the two tests.keeps the saved answers when another field is answeredWhat each test pins. I broke the components one line at a time (18 changes) and ran both specs after each one. Every change failed at least one test. The changes that fail only one test:
shows the description and the option labels translated into the current language: droppinggetTranslatedString(this.field)fromdescription, orgetTranslatedString(option)fromoptions.shows the selected option as the value and keeps it selected when the list opens: removing:value="optionValue", or thefindinoptionValue.emits the picked answer when no answers are saved yet: removing the(value || {})guard in theindex.vuetemplate.keeps the saved answers when another field is answered: removing...this.valuefromsetInput, or rendering only the first field.The other two tests share their lines with the parent spec, which renders the same field component. Within
ExtraDemographicField.spec.js,shows the description and the default option labels of a field without translationsfails when the|| this.field.descriptionor|| option.defaultLabelfallback is removed, andemits the value of the option the user picksfails when@select="emitSelectEvent"is removed oremitSelectEventemits the option object instead of its value.Picking an option goes through
selectKSelectOption, which usesfireEventandKSelect's class names internally. I used it because it is the shared helper for this; the specs themselves have no class selectors.Not checked:
disabledprop is a plain pass-through toKSelectin both components. The old specs did not cover it and I left it that way.packages/kolibri-commonsuite, not the whole repo's Jest suite.The two added tests go slightly beyond a straight port. I added them because they are the two pieces of logic the old suite skipped (
optionValueand the merge insetInput). I can drop them if you prefer a strict one-to-one migration.AI usage
I used Claude Code to migrate both specs, prompting it to follow
CoreMenuOption.spec.js, theselectKSelectOptionhelper the coach specs use, and the review feedback on the earlier migrations in #14563, #14656 and #14883. I had it break each component one line at a time to confirm a test fails for every change, and run the ExtraDemographics specs, thekolibri-commonsuite and prek. I reviewed the new tests against the old ones for parity, which is the list above: the four label and option tests became two, the two parent tests that counted child components or readcustomSchemawere removed, and two tests were added. I also used it to check what KSelect renders in each state and to tighten the description and selected-option assertions after review. I reviewed those changes and ran the specs, thekolibri-commonsuite and prek.