Resolve tech debt: migrate to React hooks, fix memory leaks, expand test coverage #111
Resolve tech debt: migrate to React hooks, fix memory leaks, expand test coverage #111QilongTang wants to merge 7 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR modernizes the splash screen codebase by converting key React components from class-based implementations to function components with hooks, and expands automated test coverage to support the refactor.
Changes:
- Refactor
App,Static,Dynamic, andToastto functional components using React hooks and window-API registration viauseEffect. - Add new unit tests for
App,Static, andDynamic, and fix Playwright assertions in the E2E test. - Update tooling/config: dependency changes (removing CRA bits, adding Babel/Webpack tooling), tighten CI install behavior (
npm ciwithout--force), and adjust ESLint globals/rules.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Static.test.js | Adds unit tests for Static behaviors and window APIs. |
| tests/Dynamic.test.js | Adds unit tests for Dynamic window API and rendering. |
| tests/App.test.js | Expands App tests around Dynamic/Static switching and window APIs. |
| tests/e2e.test.js | Fixes Playwright matcher calls (toBeVisible()). |
| src/Toast.js | Refactors Toast to hooks and keeps global show/hide APIs. |
| src/Static.js | Refactors Static to hooks, ref-based checkbox state, and window APIs. |
| src/Dynamic.js | Refactors Dynamic to hooks and window API registration. |
| src/Dynamic.css | Minor styling/formatting adjustments. |
| src/App.js | Refactors App to hooks and adjusts background image handling and debug mode. |
| package.json | Updates dependencies/scripts for non-CRA build/test setup. |
| .github/workflows/npm-publish.yml | Removes --force from npm ci steps. |
| .eslintrc.json | Adds chrome global and updates lint rules/env. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| </Row> | ||
| </Col> | ||
| <Col className='p-0'> | ||
| {loadingDone && <span className='close' />} |
There was a problem hiding this comment.
The close control is rendered as a plain with no click handler, and there’s no close styling in src/App.css. This looks like a functional regression from the previous close button behavior; either reintroduce the close handler (e.g., calling the WebView host close API) and associated styling, or remove the element entirely if closing is no longer supported.
| {loadingDone && <span className='close' />} |
| {loadingDone | ||
| ? <Static | ||
| signInStatus={signInStatus} | ||
| labels={labels} | ||
| onCheckedChange={() => {}} | ||
| /> |
There was a problem hiding this comment.
Static requires onCheckedChange, but App now passes a no-op (() => {}). If the parent no longer needs this callback, consider making onCheckedChange optional (and/or removing the prop) to avoid a misleading required API; otherwise wire it to real state/behavior so the checkbox change is observable by the rest of the app.
src/Static.js
Outdated
| useEffect(() => { | ||
| window.setImportStatus = (status) => { | ||
| setImportStatus(status.status); | ||
| setErrorDescription(status.errorDescription || ''); |
There was a problem hiding this comment.
window.setImportStatus currently overwrites the existing errorDescription with an empty string when status.errorDescription is falsy. This can result in a blank tooltip on error and also discards the default fallback message. Consider only updating errorDescription when a non-empty value is provided (or only when status.status === importStatusEnum.error), and otherwise keep the current/default message.
| setErrorDescription(status.errorDescription || ''); | |
| if (status.status === importStatusEnum.error) { | |
| const defaultErrorDescription = | |
| 'Something went wrong when importing your custom setting file. Please try again or proceed with default settings.'; | |
| const hasCustomDescription = | |
| typeof status.errorDescription === 'string' && status.errorDescription.trim().length > 0; | |
| setErrorDescription(hasCustomDescription ? status.errorDescription : defaultErrorDescription); | |
| } |
| @@ -33,15 +33,7 @@ | |||
| "lic_direct": "npx @adsk/adsk-npm-license-puller --path . --app-name 'splash-screen' --verbose --about-box ./license_output/about-box_direct.html --about-box-type desktop --year $(date \"+%Y\") --paos ./license_output/paos_direct.csv", | |||
| "lic_transitive": "npx @adsk/adsk-npm-license-puller --path . --app-name 'splash-screen' --verbose --about-box ./license_output/about-box_transitive.html --about-box-type desktop --transitive --year $(date \"+%Y\") --paos ./license_output/paos_transitive.csv", | |||
| "generate_license": "npm run lic_direct && npm run lic_transitive", | |||
| "test:unit": "NODE_ENV=test jest tests/App.test.js tests/Toast.test.js", | |||
| "test:e2e": "playwright test tests/e2e.test.js", | |||
| "eject": "react-scripts eject" | |||
| }, | |||
| "eslintConfig": { | |||
| "extends": [ | |||
| "react-app", | |||
| "react-app/jest" | |||
| ] | |||
| "test:unit": "NODE_ENV=test jest tests/App.test.js tests/Toast.test.js tests/Dynamic.test.js tests/Static.test.js" | |||
| }, | |||
There was a problem hiding this comment.
package.json removes react-scripts (which previously provided Jest) but the repo still relies on the jest binary in test:unit, and webpack serve typically requires a direct webpack-dev-server dependency. As-is, a clean install/CI run is likely to fail; add the missing direct devDependencies (Jest + required jsdom/babel-jest tooling, and webpack-dev-server if applicable) and regenerate/commit an updated package-lock.json so npm ci remains reliable.
|
@copilot Help me fix this PR so that build pass, tests pass and PR comments with confidence are addressed |
Agent-Logs-Url: https://github.com/DynamoDS/SplashScreen/sessions/aa38d1dc-3c38-4abb-bca5-da15e953d097 Co-authored-by: QilongTang <3942418+QilongTang@users.noreply.github.com>
…x setImportStatus and onCheckedChange prop Agent-Logs-Url: https://github.com/DynamoDS/SplashScreen/sessions/aa38d1dc-3c38-4abb-bca5-da15e953d097 Co-authored-by: QilongTang <3942418+QilongTang@users.noreply.github.com>
Fixed in commit
|
|
@copilot Address the merge conflict and the build is still failing, try fixing it another time. |
…k-dev-server@5 Agent-Logs-Url: https://github.com/DynamoDS/SplashScreen/sessions/3763e823-c5fe-4305-95f4-9fca9414dfd7 Co-authored-by: QilongTang <3942418+QilongTang@users.noreply.github.com>
Fixed in commit |
Merges three Dependabot PRs from master: - Bump brace-expansion (#110) - Bump node-forge from 1.3.2 to 1.4.0 (#107) - Bump path-to-regexp from 0.1.12 to 0.1.13 (#108) package-lock.json conflict resolved by taking TechDebts (fully regenerated lock), which subsumes master's transitive changes. Run `npm install` to produce a final lock that incorporates all new direct deps alongside these security bumps. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@copilot The e2e tests keeps failing, figure out if fix or re-write is required |
…t width:0%) Agent-Logs-Url: https://github.com/DynamoDS/SplashScreen/sessions/81975e31-ed56-48d5-beaf-a16a3a0b841b Co-authored-by: QilongTang <3942418+QilongTang@users.noreply.github.com>
Fixed in commit |
Summary
This PR addresses a backlog of tech debt identified through a full codebase
audit. The changes span component architecture, test coverage, CI reliability,
and tooling configuration.
Component migration — class → function components
All four components (App, Dynamic, Static, Toast) have been rewritten as
function components using React hooks. This aligns with current React best
practices and makes the codebase easier to onboard contributors into.
Memory leak fixes
Every window.* method assignment (e.g. window.setBarProperties,
window.setLoadingDone, window.showToast) is now registered inside a useEffect
with a cleanup function that deletes the method on unmount. Previously, none
of these were ever cleaned up.
Bug fixes
— the old code persisted checkbox state across component unmounts
refs, removing fragile DOM queries with no null guards
logic rewritten as a pure expression
typed; onCheckedChange marked .isRequired
were passing vacuously
Test coverage
switching, setLabels, mount/unmount cleanup)
updates, loading time, and unmount cleanup
loading time, import success/reset, button enable/disable, and unmount
cleanup
CI / tooling
bypassing peer-dependency validation
step)
browser extension; the flag was polluting globals with extension APIs
correctly
only use was the dead eject script, which has also been removed)
@babel/preset-react, babel-loader, css-loader, style-loader,
terser-webpack-plugin
Agent-friendliness
pattern, window API, conventions, and release workflow for AI-assisted
development
Test plan
automatically (debug mode), all buttons render correctly