test: add quote detail page layout regression tests

Add a vitest suite that enforces critical layout invariants for the quote detail page, and include accompanying Playwright trace snapshots and console logs from the test execution.
This commit is contained in:
SJCoetz 2026-08-06 02:04:28 +02:00
parent e2bcafe4d8
commit 5053ec96ea
7 changed files with 605 additions and 0 deletions

View file

@ -9,3 +9,161 @@
[ 5124ms] [WARNING] The resource http://localhost:4001/_next/static/media/eaead17c7dbfcd5d-s.p.woff2?v=1785974168950 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ http://localhost:4001/quotes/ybqit9d6150vmg0:0
[ 5124ms] [WARNING] The resource http://localhost:4001/_next/static/media/ee40bb094c99a29a-s.p.woff2?v=1785974168950 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ http://localhost:4001/quotes/ybqit9d6150vmg0:0
[ 5124ms] [WARNING] The resource http://localhost:4001/_next/static/media/e4af272ccee01ff0-s.p.woff2?v=1785974168950 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. @ http://localhost:4001/quotes/ybqit9d6150vmg0:0
[ 60220ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 60416ms] [LOG] [HMR] connected @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 60697ms] [LOG] SW registered: http://localhost:4001/ @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 61557ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 61803ms] [LOG] [Fast Refresh] done in 246ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 62314ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 62343ms] [LOG] [Fast Refresh] done in 28ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 62377ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 62381ms] [LOG] [Fast Refresh] done in 3ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 62990ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 63048ms] [LOG] [Fast Refresh] done in 58ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 63053ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 63137ms] [LOG] [Fast Refresh] done in 84ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 63235ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 63296ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 63376ms] [LOG] [Fast Refresh] done in 79ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 63466ms] [LOG] [Fast Refresh] done in 169ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 64317ms] [LOG] [Fast Refresh] done in 1020ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 64371ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 69456ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 69540ms] [LOG] [HMR] connected @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 69561ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 70033ms] [LOG] SW registered: http://localhost:4001/ @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 71789ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 72203ms] [LOG] [Fast Refresh] done in 413ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 72517ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 72641ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 72659ms] [LOG] [Fast Refresh] done in 17ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 72740ms] [LOG] [Fast Refresh] done in 99ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 72759ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 73099ms] [LOG] [Fast Refresh] done in 339ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 73150ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 73164ms] [LOG] [Fast Refresh] done in 15ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 73809ms] [LOG] [Fast Refresh] done in 660ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 73830ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 74142ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 74185ms] [LOG] [Fast Refresh] done in 43ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 74485ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 74531ms] [LOG] [Fast Refresh] done in 47ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 80609ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 80691ms] [LOG] [HMR] connected @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 81109ms] [LOG] SW registered: http://localhost:4001/ @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 81650ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 81792ms] [LOG] [Fast Refresh] done in 142ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 82212ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 82440ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 82464ms] [LOG] [Fast Refresh] done in 25ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 82593ms] [LOG] [Fast Refresh] done in 153ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 82722ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 82914ms] [LOG] [Fast Refresh] done in 192ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 82966ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 83002ms] [LOG] [Fast Refresh] done in 36ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 83737ms] [LOG] [Fast Refresh] done in 772ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 83805ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 84056ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 84095ms] [LOG] [Fast Refresh] done in 40ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 89254ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 89308ms] [LOG] [HMR] connected @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 90069ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 90868ms] [LOG] SW registered: http://localhost:4001/ @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 91682ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 91889ms] [LOG] [Fast Refresh] done in 207ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 92070ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 92156ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 92163ms] [LOG] [Fast Refresh] done in 7ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 92216ms] [LOG] [Fast Refresh] done in 61ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 92240ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 92533ms] [LOG] [Fast Refresh] done in 293ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 92592ms] [LOG] [Fast Refresh] done in 351ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 92592ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 93176ms] [LOG] [Fast Refresh] done in 584ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 93206ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 98280ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 98360ms] [LOG] [HMR] connected @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 98580ms] [LOG] SW registered: http://localhost:4001/ @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 99283ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 99767ms] [LOG] [Fast Refresh] done in 485ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 99834ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 99840ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 100047ms] [LOG] [Fast Refresh] done in 207ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 100460ms] [LOG] [Fast Refresh] done in 621ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 100570ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 100794ms] [LOG] [Fast Refresh] done in 224ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 100847ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 100897ms] [LOG] [Fast Refresh] done in 51ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 101802ms] [LOG] [Fast Refresh] done in 956ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 101852ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 102019ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 102076ms] [LOG] [Fast Refresh] done in 58ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 109913ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 110003ms] [LOG] [HMR] connected @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 110112ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 112491ms] [ERROR] Can't perform a React state update on a component that hasn't mounted yet. This indicates that you have a side-effect in your render function that asynchronously tries to update the component. Move this work to useEffect instead. @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/userspace/app/errors/intercept-console-error.js:57
[ 112503ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 112807ms] [LOG] [Fast Refresh] done in 303ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 112940ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 113001ms] [LOG] [Fast Refresh] done in 61ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 113201ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 113238ms] [LOG] [Fast Refresh] done in 38ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 113447ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 113495ms] [LOG] [Fast Refresh] done in 48ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 113660ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 113701ms] [LOG] [Fast Refresh] done in 41ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 113893ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 113936ms] [LOG] [Fast Refresh] done in 42ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 114127ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 114159ms] [LOG] [Fast Refresh] done in 31ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 114347ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 114395ms] [LOG] [Fast Refresh] done in 48ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 114539ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 114574ms] [LOG] [Fast Refresh] done in 36ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 118752ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 119741ms] [LOG] [HMR] connected @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 120694ms] [LOG] SW registered: http://localhost:4001/ @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 122135ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 122349ms] [LOG] [Fast Refresh] done in 214ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 123566ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 123621ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 124398ms] [LOG] [Fast Refresh] done in 777ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 125622ms] [LOG] [Fast Refresh] done in 2002ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 125820ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 126395ms] [LOG] [Fast Refresh] done in 575ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 126464ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 126524ms] [LOG] [Fast Refresh] done in 59ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 128525ms] [LOG] [Fast Refresh] done in 2060ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 128579ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 130300ms] Invalid or unexpected token
[ 131666ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 132786ms] [LOG] [HMR] connected @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 135697ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 136091ms] [LOG] [Fast Refresh] done in 395ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 137357ms] [ERROR] Can't perform a React state update on a component that hasn't mounted yet. This indicates that you have a side-effect in your render function that asynchronously tries to update the component. Move this work to useEffect instead. @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/userspace/app/errors/intercept-console-error.js:57
[ 137386ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 137471ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 138117ms] [LOG] [Fast Refresh] done in 646ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 138526ms] [LOG] [Fast Refresh] done in 1054ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 138717ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 139411ms] [LOG] [Fast Refresh] done in 694ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 139485ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 139549ms] [LOG] [Fast Refresh] done in 64ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 141633ms] [LOG] [Fast Refresh] done in 2149ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 141651ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 142277ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 143529ms] [LOG] [Fast Refresh] done in 1253ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 145373ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 145436ms] [LOG] [HMR] connected @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 145452ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 146259ms] [LOG] SW registered: http://localhost:4001/ @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 147037ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 147356ms] [LOG] [Fast Refresh] done in 320ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 148310ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 148493ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 149336ms] [LOG] [Fast Refresh] done in 843ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 150334ms] [LOG] [Fast Refresh] done in 1841ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 150589ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 151027ms] [LOG] [Fast Refresh] done in 438ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 151079ms] [LOG] [Fast Refresh] rebuilding @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27
[ 151122ms] [LOG] [Fast Refresh] done in 43ms @ webpack-internal:///(app-pages-browser)/./node_modules/next/dist/next-devtools/shared/forward-logs-shared.js:27

View file

@ -0,0 +1,2 @@
- generic [active] [ref=f5e1]:
- region "Notifications alt+T"

View file

@ -0,0 +1,175 @@
- generic [active] [ref=f7e1]:
- generic [ref=f7e4]:
- complementary [ref=f7e5]:
- generic [ref=f7e6]:
- link "WFDASH WFDASH Westcott Fasteners" [ref=f7e7] [cursor=pointer]:
- /url: /dashboard
- img "WFDASH" [ref=f7e8]
- generic [ref=f7e9]:
- generic [ref=f7e10]: WFDASH
- generic [ref=f7e11]: Westcott Fasteners
- separator [ref=f7e12]
- navigation [ref=f7e15]:
- link "Dashboard" [ref=f7e16] [cursor=pointer]:
- /url: /dashboard
- separator [ref=f7e23]
- button "Management" [ref=f7e25]
- generic [ref=f7e28]:
- button "Quotes" [ref=f7e29]
- generic [ref=f7e32]:
- link "Quote List" [ref=f7e33] [cursor=pointer]:
- /url: /quotes
- link "Sprint" [ref=f7e40] [cursor=pointer]:
- /url: /sprint
- link "Pending Approvals" [ref=f7e44] [cursor=pointer]:
- /url: /quotes/approvals
- button "Orders" [ref=f7e50]
- button "Logistics" [ref=f7e54]
- button "Operations" [ref=f7e58]
- button "Stock" [ref=f7e62]
- button "Other" [ref=f7e66]
- separator [ref=f7e69]
- generic [ref=f7e70]:
- link "Settings" [ref=f7e71] [cursor=pointer]:
- /url: /settings
- button "Dark mode" [ref=f7e75]
- separator [ref=f7e78]
- generic [ref=f7e79]:
- generic [ref=f7e80]: D
- generic [ref=f7e82]:
- paragraph [ref=f7e83]: David Els
- paragraph [ref=f7e84]: david.els1@outlook.com
- button "Logout" [ref=f7e85]
- main [ref=f7e90]:
- generic [ref=f7e92]:
- generic [ref=f7e93]:
- button "Back to quotes" [ref=f7e94]
- generic [ref=f7e95]:
- heading "Q202607232" [level=1] [ref=f7e96]
- generic [ref=f7e97]: Cancelled
- button "More actions" [ref=f7e100]
- generic [ref=f7e103]:
- generic [ref=f7e104]:
- paragraph [ref=f7e105]: Customer
- paragraph [ref=f7e106]: Mark Wilkie
- paragraph [ref=f7e107]: Harmony - Gold Mining Company Limited
- generic [ref=f7e108]:
- paragraph [ref=f7e109]: Company
- paragraph [ref=f7e110]: —
- generic [ref=f7e111]:
- paragraph [ref=f7e112]: Created
- paragraph [ref=f7e113]: 27 Jul 2026
- generic [ref=f7e114]:
- paragraph [ref=f7e115]: Letterhead
- paragraph [ref=f7e116]: CNL
- generic [ref=f7e117]:
- paragraph [ref=f7e118]: Claimed by
- generic [ref=f7e119]:
- generic [ref=f7e120]: DA
- paragraph [ref=f7e122]: David Els
- 'button "Original request Fwd: Mark Wilkie" [ref=f7e124] [cursor=pointer]':
- generic [ref=f7e125]:
- text: Original request
- generic [ref=f7e129]: "Fwd: Mark Wilkie"
- generic [ref=f7e132]:
- generic [ref=f7e133]:
- generic [ref=f7e134]:
- generic [ref=f7e135]:
- generic [ref=f7e136]: AI Insights
- button "Regenerate" [ref=f7e140]
- generic [ref=f7e142]:
- heading "AI Insights" [level=3] [ref=f7e146]
- paragraph [ref=f7e147]: "Quote Q202607232: 1 line item(s), 0 priced, 1 need pricing. Customer: Mark Wilkie."
- generic [ref=f7e149]:
- heading "Parent" [level=4] [ref=f7e150]
- generic [ref=f7e151]:
- term [ref=f7e152]: Suggestions
- definition [ref=f7e153]: "[{\"message\":\"Top supplier: 'NSS Fastners' — used 13x, last cost R2.87.\",\"ref_id\":null}]"
- term [ref=f7e154]: Summary
- definition [ref=f7e155]: "Quote Q202607232: 1 line item(s), 0 priced, 1 need pricing. Customer: Mark Wilkie."
- term [ref=f7e156]: Warnings
- definition [ref=f7e157]: "[{\"message\":\"All 1 line items need pricing.\",\"ref_id\":null,\"severity\":\"high\",\"type\":\"missing_pricing\"}]"
- generic [ref=f7e158]:
- generic [ref=f7e159]:
- generic [ref=f7e160]: Items (1)
- generic [ref=f7e164]:
- generic [ref=f7e165]: "Subtotal: R 7,96VAT: R 1,19"
- button "Rewrite with AI" [ref=f7e166]
- table [ref=f7e170]:
- rowgroup [ref=f7e171]:
- row [ref=f7e172]:
- columnheader "Description" [ref=f7e173]
- columnheader "Qty" [ref=f7e174]
- columnheader "Supplier" [ref=f7e175]
- columnheader "Cost" [ref=f7e176]
- columnheader "Selling" [ref=f7e177]
- columnheader [ref=f7e178]
- columnheader "Processed" [ref=f7e184]
- columnheader [ref=f7e185]
- rowgroup [ref=f7e186]:
- row [ref=f7e187]:
- cell "View item history M16 x 75 8.8 sets HDG complete with nuts and washers" [ref=f7e188]:
- generic [ref=f7e189]:
- button "View item history" [ref=f7e190]
- generic [ref=f7e193]: M16 x 75 8.8 sets HDG complete with nuts and washers
- cell "1" [ref=f7e194]
- cell "NSS Fastners" [ref=f7e195]
- cell "R 2,87" [ref=f7e196]
- cell "R 7,96" [ref=f7e197]
- cell "177.4%" [ref=f7e198]
- cell "Yes" [ref=f7e199]
- cell [ref=f7e201]:
- button "Update price" [ref=f7e202]
- generic [ref=f7e203]:
- generic [ref=f7e204]:
- generic [ref=f7e205]: Attachments
- generic [ref=f7e210]:
- tablist [ref=f7e211]:
- tab "Outbound 0" [selected] [ref=f7e212]:
- text: Outbound
- generic [ref=f7e213]: "0"
- tab "Internal 0" [ref=f7e214]:
- text: Internal
- generic [ref=f7e215]: "0"
- tabpanel "Outbound 0" [ref=f7e216]:
- generic [ref=f7e217]:
- button "Upload outbound attachment" [ref=f7e218] [cursor=pointer]:
- paragraph [ref=f7e221]: Drop a file here or click to upload
- paragraph [ref=f7e222]: PDFs, images, Word / Excel docs
- paragraph [ref=f7e223]: No outbound attachments yet. The generated quote PDF will be added automatically when you approve and email the quote.
- generic [ref=f7e224]:
- generic [ref=f7e225]:
- generic [ref=f7e226]: Linked Orders
- generic [ref=f7e231]: Already-linked, or suggested and waiting for accept on the order detail page.
- generic [ref=f7e232]:
- paragraph [ref=f7e233]: No orders linked yet. They show up automatically when an order's matcher picks this quote, or when one is created from this quote via the menu.
- list
- generic [ref=f7e234]:
- generic [ref=f7e235]: Activity
- generic [ref=f7e240]:
- tablist [ref=f7e241]:
- tab "Email Status" [selected] [ref=f7e242]
- tab "History" [ref=f7e243]
- tabpanel "Email Status" [ref=f7e244]:
- generic [ref=f7e245]:
- generic [ref=f7e246]:
- paragraph [ref=f7e247]: Delivered
- generic [ref=f7e248]: "No"
- generic [ref=f7e253]:
- paragraph [ref=f7e254]: Opened
- generic [ref=f7e255]: "No"
- generic [ref=f7e260]:
- paragraph [ref=f7e261]: Sender
- paragraph [ref=f7e262]: gary@wfsales.co.za
- generic [ref=f7e263]:
- paragraph [ref=f7e264]: Subject
- paragraph [ref=f7e265]: "Fwd: Mark Wilkie"
- region "Notifications alt+T"
- button "Open Next.js Dev Tools" [ref=f7e271] [cursor=pointer]:
- generic [ref=f7e274]:
- text: Compiling
- generic [ref=f7e275]:
- generic [ref=f7e276]: .
- generic [ref=f7e277]: .
- generic [ref=f7e278]: .
- alert [ref=f7e279]

View file

@ -0,0 +1,2 @@
- generic [active] [ref=f10e1]:
- region "Notifications alt+T"

View file

@ -0,0 +1,175 @@
- generic [active] [ref=f12e1]:
- generic [ref=f12e5]:
- complementary [ref=f12e6]:
- generic [ref=f12e7]:
- link "WFDASH WFDASH Westcott Fasteners" [ref=f12e8] [cursor=pointer]:
- /url: /dashboard
- img "WFDASH" [ref=f12e9]
- generic [ref=f12e10]:
- generic [ref=f12e11]: WFDASH
- generic [ref=f12e12]: Westcott Fasteners
- separator [ref=f12e13]
- navigation [ref=f12e16]:
- link "Dashboard" [ref=f12e17] [cursor=pointer]:
- /url: /dashboard
- separator [ref=f12e24]
- button "Management" [ref=f12e26]
- generic [ref=f12e29]:
- button "Quotes" [ref=f12e30]
- generic [ref=f12e33]:
- link "Quote List" [ref=f12e34] [cursor=pointer]:
- /url: /quotes
- link "Sprint" [ref=f12e41] [cursor=pointer]:
- /url: /sprint
- link "Pending Approvals" [ref=f12e45] [cursor=pointer]:
- /url: /quotes/approvals
- button "Orders" [ref=f12e51]
- button "Logistics" [ref=f12e55]
- button "Operations" [ref=f12e59]
- button "Stock" [ref=f12e63]
- button "Other" [ref=f12e67]
- separator [ref=f12e70]
- generic [ref=f12e71]:
- link "Settings" [ref=f12e72] [cursor=pointer]:
- /url: /settings
- button "Dark mode" [ref=f12e76]
- separator [ref=f12e79]
- generic [ref=f12e80]:
- generic [ref=f12e81]: D
- generic [ref=f12e83]:
- paragraph [ref=f12e84]: David Els
- paragraph [ref=f12e85]: david.els1@outlook.com
- button "Logout" [ref=f12e86]
- main [ref=f12e91]:
- generic [ref=f12e93]:
- generic [ref=f12e94]:
- button "Back to quotes" [ref=f12e95]
- generic [ref=f12e96]:
- heading "Q202607232" [level=1] [ref=f12e97]
- generic [ref=f12e98]: Cancelled
- button "More actions" [ref=f12e101]
- generic [ref=f12e104]:
- generic [ref=f12e105]:
- paragraph [ref=f12e106]: Customer
- paragraph [ref=f12e107]: Mark Wilkie
- paragraph [ref=f12e108]: Harmony - Gold Mining Company Limited
- generic [ref=f12e109]:
- paragraph [ref=f12e110]: Company
- paragraph [ref=f12e111]: —
- generic [ref=f12e112]:
- paragraph [ref=f12e113]: Created
- paragraph [ref=f12e114]: 27 Jul 2026
- generic [ref=f12e115]:
- paragraph [ref=f12e116]: Letterhead
- paragraph [ref=f12e117]: CNL
- generic [ref=f12e118]:
- paragraph [ref=f12e119]: Claimed by
- generic [ref=f12e120]:
- generic [ref=f12e121]: DA
- paragraph [ref=f12e123]: David Els
- 'button "Original request Fwd: Mark Wilkie" [ref=f12e125] [cursor=pointer]':
- generic [ref=f12e126]:
- text: Original request
- generic [ref=f12e130]: "Fwd: Mark Wilkie"
- generic [ref=f12e133]:
- generic [ref=f12e134]:
- generic [ref=f12e135]:
- generic [ref=f12e136]:
- generic [ref=f12e137]: AI Insights
- button "Regenerate" [ref=f12e141]
- generic [ref=f12e143]:
- heading "AI Insights" [level=3] [ref=f12e147]
- paragraph [ref=f12e148]: "Quote Q202607232: 1 line item(s), 0 priced, 1 need pricing. Customer: Mark Wilkie."
- generic [ref=f12e150]:
- heading "Parent" [level=4] [ref=f12e151]
- generic [ref=f12e152]:
- term [ref=f12e153]: Suggestions
- definition [ref=f12e154]: "[{\"message\":\"Top supplier: 'NSS Fastners' — used 13x, last cost R2.87.\",\"ref_id\":null}]"
- term [ref=f12e155]: Summary
- definition [ref=f12e156]: "Quote Q202607232: 1 line item(s), 0 priced, 1 need pricing. Customer: Mark Wilkie."
- term [ref=f12e157]: Warnings
- definition [ref=f12e158]: "[{\"message\":\"All 1 line items need pricing.\",\"ref_id\":null,\"severity\":\"high\",\"type\":\"missing_pricing\"}]"
- generic [ref=f12e159]:
- generic [ref=f12e160]:
- generic [ref=f12e161]: Items (1)
- generic [ref=f12e165]:
- generic [ref=f12e166]: "Subtotal: R 7,96VAT: R 1,19"
- button "Rewrite with AI" [ref=f12e167]
- table [ref=f12e171]:
- rowgroup [ref=f12e172]:
- row [ref=f12e173]:
- columnheader "Description" [ref=f12e174]
- columnheader "Qty" [ref=f12e175]
- columnheader "Supplier" [ref=f12e176]
- columnheader "Cost" [ref=f12e177]
- columnheader "Selling" [ref=f12e178]
- columnheader [ref=f12e179]
- columnheader "Processed" [ref=f12e185]
- columnheader [ref=f12e186]
- rowgroup [ref=f12e187]:
- row [ref=f12e188]:
- cell "View item history M16 x 75 8.8 sets HDG complete with nuts and washers" [ref=f12e189]:
- generic [ref=f12e190]:
- button "View item history" [ref=f12e191]
- generic [ref=f12e194]: M16 x 75 8.8 sets HDG complete with nuts and washers
- cell "1" [ref=f12e195]
- cell "NSS Fastners" [ref=f12e196]
- cell "R 2,87" [ref=f12e197]
- cell "R 7,96" [ref=f12e198]
- cell "177.4%" [ref=f12e199]
- cell "Yes" [ref=f12e200]
- cell [ref=f12e202]:
- button "Update price" [ref=f12e203]
- generic [ref=f12e204]:
- generic [ref=f12e205]:
- generic [ref=f12e206]: Attachments
- generic [ref=f12e211]:
- tablist [ref=f12e212]:
- tab "Outbound 0" [selected] [ref=f12e213]:
- text: Outbound
- generic [ref=f12e214]: "0"
- tab "Internal 0" [ref=f12e215]:
- text: Internal
- generic [ref=f12e216]: "0"
- tabpanel "Outbound 0" [ref=f12e217]:
- generic [ref=f12e218]:
- button "Upload outbound attachment" [ref=f12e219] [cursor=pointer]:
- paragraph [ref=f12e222]: Drop a file here or click to upload
- paragraph [ref=f12e223]: PDFs, images, Word / Excel docs
- paragraph [ref=f12e224]: No outbound attachments yet. The generated quote PDF will be added automatically when you approve and email the quote.
- generic [ref=f12e225]:
- generic [ref=f12e226]:
- generic [ref=f12e227]: Linked Orders
- generic [ref=f12e232]: Already-linked, or suggested and waiting for accept on the order detail page.
- generic [ref=f12e233]:
- paragraph [ref=f12e234]: No orders linked yet. They show up automatically when an order's matcher picks this quote, or when one is created from this quote via the menu.
- list
- generic [ref=f12e235]:
- generic [ref=f12e236]: Activity
- generic [ref=f12e241]:
- tablist [ref=f12e242]:
- tab "Email Status" [selected] [ref=f12e243]
- tab "History" [ref=f12e244]
- tabpanel "Email Status" [ref=f12e245]:
- generic [ref=f12e246]:
- generic [ref=f12e247]:
- paragraph [ref=f12e248]: Delivered
- generic [ref=f12e249]: "No"
- generic [ref=f12e254]:
- paragraph [ref=f12e255]: Opened
- generic [ref=f12e256]: "No"
- generic [ref=f12e261]:
- paragraph [ref=f12e262]: Sender
- paragraph [ref=f12e263]: gary@wfsales.co.za
- generic [ref=f12e264]:
- paragraph [ref=f12e265]: Subject
- paragraph [ref=f12e266]: "Fwd: Mark Wilkie"
- region "Notifications alt+T"
- button "Open Next.js Dev Tools" [ref=f12e272] [cursor=pointer]:
- generic [ref=f12e275]:
- text: Compiling
- generic [ref=f12e276]:
- generic [ref=f12e277]: .
- generic [ref=f12e278]: .
- generic [ref=f12e279]: .
- alert [ref=f12e280]

View file

@ -0,0 +1,9 @@
- generic [active] [ref=f13e1]:
- region "Notifications alt+T"
- button "Open Next.js Dev Tools" [ref=f13e13] [cursor=pointer]:
- generic [ref=f13e16]:
- text: Compiling
- generic [ref=f13e17]:
- generic [ref=f13e18]: .
- generic [ref=f13e19]: .
- generic [ref=f13e20]: .

View file

@ -0,0 +1,84 @@
import { describe, it, expect } from "vitest";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
/**
* Layout contract regression test for the quote detail page.
*
* The page is a large Server Component that pulls from many PocketBase
* collections, calls multiple API endpoints, and has many modals — too
* heavy to mount in a unit test. Instead, this test guards the layout
* invariants that were negotiated with the operator during the
* redesign so a future edit can't silently regress them:
*
* 1. Customer info lives in a header strip (not a sidebar card).
* 2. The original email is a collapsible card that sits ABOVE the
* items table (the operator's main complaint — "email right at
* the bottom?").
* 3. The right sidebar consolidates History + Email Status into a
* single tabbed "Activity" card so the column is shorter.
* 4. The original email section does NOT also appear at the bottom
* of the page (was duplicated).
*
* Each invariant is anchored to a stable `data-testid` or
* `aria-controls` marker that the page already emits — so the source
* test reads as a contract, not as a regex grep over prose comments.
*/
const SOURCE = readFileSync(
resolve(__dirname, "page.tsx"),
"utf8",
);
function linesContaining(marker: string): number[] {
const hits: number[] = [];
SOURCE.split("\n").forEach((line, i) => {
if (line.includes(marker)) hits.push(i + 1);
});
return hits;
}
describe("quote detail page — layout contract", () => {
it("exposes the original-email toggle via aria-controls", () => {
// The email card above items uses a button with aria-controls so the
// operator can show/hide the original message without scrolling
// away from the items table.
const hits = linesContaining('aria-controls="quote-email-body"');
expect(hits.length).toBeGreaterThanOrEqual(1);
});
it("renders the email toggle BEFORE the items table marker", () => {
// The user complaint was "email right at the bottom". Lock the
// DOM ordering so the toggle card stays in the upper flow.
const emailToggle = linesContaining('aria-controls="quote-email-body"')[0];
const itemsHeading = SOURCE.indexOf("Items (");
expect(itemsHeading).toBeGreaterThan(-1);
// Convert char offset to a line number for the assertion message.
const itemsLine = SOURCE.slice(0, itemsHeading).split("\n").length;
expect(emailToggle).toBeLessThan(itemsLine);
});
it("consolidates History + Email Status into a tabbed Activity card", () => {
// The Activity card is what replaced the two standalone cards.
// Both triggers need a stable data-testid so the regression is
// locatable by future tests / e2e checks.
expect(linesContaining('data-testid="tab-email-status"').length).toBe(1);
expect(linesContaining('data-testid="tab-history"').length).toBe(1);
expect(SOURCE).toContain("Activity");
});
it("does NOT render the original email a second time at the bottom of the page", () => {
// During the redesign we moved the original email to a collapsible
// card above the items and removed the old bottom section. Lock
// that removal: only ONE `quote-original-request` anchor is allowed.
const matches = SOURCE.match(/quote-original-request/g) ?? [];
expect(matches.length).toBe(0);
});
it("history rows render inside a data-testid=history-list anchor", () => {
// The Activity > History tab's <ul> needs a stable marker so a
// future test can count the rows without depending on Tailwind
// class strings.
expect(linesContaining('data-testid="history-list"').length).toBe(1);
});
});