test(e2e): port authored_hints to Playwright (pages/components layout)#73200
Open
stephenliang wants to merge 5 commits into
Open
test(e2e): port authored_hints to Playwright (pages/components layout)#73200stephenliang wants to merge 5 commits into
stephenliang wants to merge 5 commits into
Conversation
stephenliang
commented
Jun 11, 2026
9a6e789 to
7ac68e4
Compare
Port 1 scenario from dashboard/test/ui/features/teacher_tools/authored_hints.feature. Green under the 5x/all-browser stress gate; original Cucumber feature tagged @playwright so the Cucumber suite skips it. Source: dashboard/test/ui/features/teacher_tools/authored_hints.feature
…layout Apply code-review findings to the authored_hints port (628cfc0): - Model authored hints as AuthoredHintsComponent composed into the LegacyBlocklyLab page object (lab.hints) instead of a POM subclass -- in the product they are a feature of the shared CSF instructions UI, not a page. Layout follows centralized pages/ + components/ + shared/ with kebab-case files; no Pom suffix. - Add labLevelUrl route builder (shared/routes.ts) with object params replacing the hardcoded level path; per-domain shared modules. - gotoLabLevelUrl rejects absolute URLs so a URL pasted from a Cucumber feature cannot bypass baseURL/TARGET_URL. - Dedupe selectors, pin waitForFunction timeout to expect.timeout, drop redundant waits/constructor, trim reviewer-directed comments. Green under the 5x/all-browser stress gate (15/15). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- gotoLabLevel(page, {lesson, level}) builds the URL itself; callers no
longer compose labLevelUrl by hand
- assertions on the instructions panel moved into the spec via the
exposed locator; assertInstructionsContainText wrapper removed
- lightbulb and Yes button use getByRole (live-verified accessible
names; exact: true on Yes since the lightbulb aria-label contains
"yes"); #hintCount stays CSS (no role or label)
- image-load wait uses native toHaveJSProperty instead of a custom
waitForFunction, inheriting expect.timeout
- assertNoYesPrompt renamed assertHintPromptAbsent
- labLevelUrl builds its query with URLSearchParams
Green under the 5x/all-browser stress gate (15/15).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7ac68e4 to
5e2b839
Compare
871ead7 to
fa20c43
Compare
Extract BasePage, which owns the global language dropdown — a labeled combobox located by role + accessible name. LegacyBlocklyLab now extends it instead of redeclaring its own page wiring, so every page object inherits the dropdown. No behavior change: the authored-hints spec is unchanged and stays green under the 5x/all-browser stress gate. Mirrors the page-object hierarchy from the region_select port — base-page.ts is byte-identical there, so it merges cleanly in either order; only legacy-blockly-lab.ts overlaps and is unioned at merge. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fa20c43 to
da348c2
Compare
Expose the hint locators (yesButton, hintImage) and remove all assertion methods (assertCount, assertImageVisible, assertNoneAvailable, assertHintPromptAbsent). The spec now asserts on the exposed locators directly, matching the page-objects-expose-locators / tests-assert convention; the component keeps only locators, interactions (viewNext, clickLightbulb), and the waitForImageLoad wait. No behavior change: same assertions, retry-safe via toHaveText. 15/15 green under the 5x/all-browser gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5a93bde to
8b0c6a3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports the first Cucumber UI test to Playwright —
teacher_tools/authored_hints.feature→frontend/packages/e2e-tests— and establishes the suite layout future ports will follow.What's new
The test.
authored-hints.spec.tscovers the full scenario: view three hints via the lightbulb and "Yes" prompt, count badge decrements then disappears, hint image loads, and clicking the exhausted lightbulb does nothing. The Cucumber original is tagged@playwright.The layout. Specs live in per-area directories; reusable code is centralized:
Composition over inheritance. Authored hints are a feature of the shared legacy CSF instructions UI (
apps/src/templates/instructions), not a page —AuthoredHintsComponentis composed into theLegacyBlocklyLabpage object, so specs read aslab.hints.viewNext()/lab.hints.assertCount(2).Net benefits vs the Cucumber implementation
#lightbulb,button:contains(Yes)); the port usesgetByRole('button', {name: 'lightbulb'})andgetByRole('button', {name: 'Yes', exact: true}), verified against the live DOM. The test now fails if these controls lose their button role or accessible name — a regression Cucumber couldn't see.$('.csf-top-instructions img').prop('complete')reads the first matching<img>, which can be the Immersive Reader icon rather than the hint content. The port scopes to the hint image and also checksnaturalWidth > 0(decoded, not merely complete-with-error).expectwith one consistent timeout profile (expect.timeout); noexecute_scriptpolling loops, and no dependency on the app's jQuery global from inside tests.--project.yarn typecheck+ eslint, vs regex-matched Ruby step definitions composing selector strings.Links
stephen/playwrightTesting story
yarn typecheck,yarn lint, and the pre-commit hook all pass.Deployment notes
The
@playwrighttag is not yet honored by the UI test runner — the scenario runs in both suites untilskip_tag('@playwright')is added todashboard/test/ui/runner.rb(intentional follow-up).🤖 Generated with Claude Code