fix(e2e): align Astryx-migrated selectors in four specs - #1752

Merged
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors
Aug 1, 2026
Merged

fix(e2e): align Astryx-migrated selectors in four specs#1752
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

#1728 moved the conversation surface onto Astryx primitives but left four E2E specs pointing at removed DOM, failing the CI e2e job with the same 8 tests across runs (scroll-geometry ×4, permission-mode-surface ×2, disclosure-output, session-health-notice). The product contracts those tests lock are all still live; only the selectors went stale.

  • permission-mode-surface: the permission picker moved from the footer's .maka-composer-left-controls to the Astryx header context (.maka-composer-header-context); the Selector trigger is still a combobox, so only the container selector changed.
  • scroll-geometry / session-health-notice: the composer card anchor .maka-composer-inner is gone; .maka-composer-astryx now carries the centered measure (width: min(var(--maka-chat-measure), 100%)).
  • disclosure-output: live tools now render through Astryx ChatToolCalls; a single running tool is one collapsed CallRow (role=button) whose detail mounts on demand, replacing the [data-processing=block] wrapper and its fixture readiness selector.

Two assertions tracked deliberate Astryx changes instead of product regressions: the turn gap is now 16px (ChatMessageList density=compact gap={4}), and a fully pinned scroller can read a 1px distance because Chromium keeps sub-pixel scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.

Verification

  • npx playwright test (apps/desktop): 93 passed — full suite green, including the 8 previously failing tests.
  • npm run format:check and npm run lint: clean (specs live under the formatter-excluded apps/desktop/**).

#1728 moved the conversation surface onto Astryx primitives but left four
E2E specs pointing at the removed DOM:
- permission-mode-surface: the permission picker moved from the footer's
.maka-composer-left-controls to the Astryx header context
(.maka-composer-header-context); the Selector trigger is still a
combobox, so only the container selector changed.
- scroll-geometry / session-health-notice: the composer card anchor
.maka-composer-inner is gone; .maka-composer-astryx now carries the
centered measure (width: min(var(--maka-chat-measure), 100%)).
- disclosure-output: live tools now render through Astryx ChatToolCalls;
a single running tool is one collapsed CallRow (role=button) whose
detail mounts on demand, replacing the [data-processing=block] wrapper
and its fixture readiness selector.
Two assertions also tracked deliberate Astryx changes: the turn gap is
16px (ChatMessageList density=compact gap=4) instead of 12px, and a fully
pinned scroller can read a 1px distance because Chromium keeps sub-pixel
scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.
Full suite: 93 passed.
@Astro-Han
Astro-Han merged commit 50ef904 into mainAug 1, 2026
5 of 6 checks passed
Astro-Han added a commit that referenced this pull request Aug 1, 2026
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
Astryx 0.2.0 ResizeHandle hitAreaOffsetX applies translateY(-50%) without
top:50%, so only the top half of the handle receives pointer events. A
center drag (where the pill sits, and where e2e aims) hits the handle
root with no pointerdown and never collapses — the sole remaining main
e2e failure after #1752. Neutralize the transform on the official
SideNav handle; remove once Astryx fixes hitAreaOffsetX.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
… the long-failing sidebar spec (#1756)
* test(e2e): move Electron teardown coverage to node --test
closeElectronApplication drives a fake process handle and never launches
Electron, so it was the one spec in the Playwright suite paying a real
Electron slot for assertions that need none. It tests the launch harness
itself, not product behavior.
Move both cases to scripts/electron-lifecycle.test.mjs, beside the sibling
harness tests (fixture-env, fixture-window), and register them in
test:scripts. No coverage changes.
* test(e2e): drop the retired screenshot capture paths
MAKA_MCP_E2E_SCREENSHOT and MAKA_DISCLOSURE_E2E_SCREENSHOT are set by
nothing in the repo — no script, no workflow, no docs — so both branches
were dead in every run. AGENTS.md already records that the screenshot
capture harness was retired because its baselines rot and never ran in CI.
The mcp block cost more than dead code: capturing variants meant flipping
to dark theme and resizing to 760px mid-journey, so a spec about add /
discover / disable / import / delete also carried theme and viewport
churn unrelated to any of it.
The session-workbar half is folded into the following commit, which
rewrites the surrounding disclosure assertions.
* test(e2e): assert disclosure and locale behavior instead of design tokens
These assertions pinned numbers, not outcomes: they go red when Astryx
retunes a size, and stay green through anything a user would notice.
- session-workbar: the collapsed Collapsible was measured for trigger vs
root width and label/chevron centering — upstream component internals.
What the journey is about is that a collapsed section hides its rows and
Enter reveals them, which reads directly off the row. Drops the dead
screenshot branch in the same rewrite.
- sidebar-navigation: a 13px font-size pair, and a whole test whose only
assertion was menu width < 128. The heading test keeps its real
contract (one 会话 heading, no redundant group label).
- scroll-geometry: turn separation must equal exactly 16px.
- bot-onboarding: a 284px QR frame and a 522px dialog cap. Replaced by the
contract that matters for scanning a code — the dialog stays inside the
window and the QR is in the viewport.
- locale-renderer: screenshot.byteLength > 10_000 cannot disagree with the
implementation; a blank frame clears it too. The rendered translated
control is the evidence, and it was already being asserted.
* test(e2e): consolidate window-floor sweeps and step the provider journey
Five settings tests each launched their own Electron window to do the same
thing: shrink to the 480px floor and walk pages. They now share one window
and one sweep, split into named steps. Every page-specific assertion is
carried over unchanged — health tiles, usage tabs, the web-search hint,
memory's preview header and status Item, palette wrapping, the data
strategy field and workspace path, about, daily review. The three wide
track-count checks collapse the same way. Pages needing their own seeded
fixture (permissions, usage logs, search results) stay separate: their
state is what makes the contract reachable.
The provider add journey ran ~150 lines and ten behaviors under one name,
so any failure meant reading all of it to learn what broke. Splitting it
into separate tests would buy isolation at four more cold starts;
test.step gives the trace the same answer for free.
Also drops two more token assertions found in that journey (dialog width
cap, 24px brand plate) and the settings switch's 40x24 geometry test.
Net: 20 settings tests to 14, and the E2E suite from 94 to 86.
* test(e2e): record the suite's new size in the config note
* test(e2e): restore the QR rendering contract dropped in the token sweep
The token sweep replaced the QR geometry block with `toBeInViewport()`, which
was too weak for what the comment claimed. Playwright's default `ratio: 0`
passes on any positive intersection, so a QR with one corner on screen — or
one shrunk to a dot inside its frame — cleared the assertion while being
unscannable.
The 284px frame and 522px dialog cap really were tokens. But `qrBox.width ===
qrFrameBox.width - 2` was not: it is the relationship "the image fills its
frame", and nothing else in the suite covers rendered QR geometry. Restored as
relationships rather than constants: fills its frame, square, at least 160px,
centred in its dialog, wholly in the viewport via `ratio: 1`.
Both halves proved by negative control — shrinking the QR to 1px and shifting
it so only a corner shows each turn the test red.
* test(e2e): stop recording a test count that rots
The note said 94 tests; it had been stale for a while, and my own edit made it
worse by writing 86 from a passed-count that excluded a failing test. Actual
discovery is 87 on this branch and 98 on main.
A number that has now been wrong twice, in the same comment, is not worth
maintaining: `playwright test --list` is authoritative and free. Keeps the
timing measurement, which is what the note exists for.
* fix(e2e): drive sidebar collapse through a path that still works
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(e2e): align Astryx-migrated selectors in four specs - #1752

Merged
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors
Aug 1, 2026
Merged

fix(e2e): align Astryx-migrated selectors in four specs#1752
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

#1728 moved the conversation surface onto Astryx primitives but left four E2E specs pointing at removed DOM, failing the CI e2e job with the same 8 tests across runs (scroll-geometry ×4, permission-mode-surface ×2, disclosure-output, session-health-notice). The product contracts those tests lock are all still live; only the selectors went stale.

  • permission-mode-surface: the permission picker moved from the footer's .maka-composer-left-controls to the Astryx header context (.maka-composer-header-context); the Selector trigger is still a combobox, so only the container selector changed.
  • scroll-geometry / session-health-notice: the composer card anchor .maka-composer-inner is gone; .maka-composer-astryx now carries the centered measure (width: min(var(--maka-chat-measure), 100%)).
  • disclosure-output: live tools now render through Astryx ChatToolCalls; a single running tool is one collapsed CallRow (role=button) whose detail mounts on demand, replacing the [data-processing=block] wrapper and its fixture readiness selector.

Two assertions tracked deliberate Astryx changes instead of product regressions: the turn gap is now 16px (ChatMessageList density=compact gap={4}), and a fully pinned scroller can read a 1px distance because Chromium keeps sub-pixel scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.

Verification

  • npx playwright test (apps/desktop): 93 passed — full suite green, including the 8 previously failing tests.
  • npm run format:check and npm run lint: clean (specs live under the formatter-excluded apps/desktop/**).

#1728 moved the conversation surface onto Astryx primitives but left four
E2E specs pointing at the removed DOM:
- permission-mode-surface: the permission picker moved from the footer's
.maka-composer-left-controls to the Astryx header context
(.maka-composer-header-context); the Selector trigger is still a
combobox, so only the container selector changed.
- scroll-geometry / session-health-notice: the composer card anchor
.maka-composer-inner is gone; .maka-composer-astryx now carries the
centered measure (width: min(var(--maka-chat-measure), 100%)).
- disclosure-output: live tools now render through Astryx ChatToolCalls;
a single running tool is one collapsed CallRow (role=button) whose
detail mounts on demand, replacing the [data-processing=block] wrapper
and its fixture readiness selector.
Two assertions also tracked deliberate Astryx changes: the turn gap is
16px (ChatMessageList density=compact gap=4) instead of 12px, and a fully
pinned scroller can read a 1px distance because Chromium keeps sub-pixel
scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.
Full suite: 93 passed.
@Astro-Han
Astro-Han merged commit 50ef904 into mainAug 1, 2026
5 of 6 checks passed
Astro-Han added a commit that referenced this pull request Aug 1, 2026
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
Astryx 0.2.0 ResizeHandle hitAreaOffsetX applies translateY(-50%) without
top:50%, so only the top half of the handle receives pointer events. A
center drag (where the pill sits, and where e2e aims) hits the handle
root with no pointerdown and never collapses — the sole remaining main
e2e failure after #1752. Neutralize the transform on the official
SideNav handle; remove once Astryx fixes hitAreaOffsetX.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
… the long-failing sidebar spec (#1756)
* test(e2e): move Electron teardown coverage to node --test
closeElectronApplication drives a fake process handle and never launches
Electron, so it was the one spec in the Playwright suite paying a real
Electron slot for assertions that need none. It tests the launch harness
itself, not product behavior.
Move both cases to scripts/electron-lifecycle.test.mjs, beside the sibling
harness tests (fixture-env, fixture-window), and register them in
test:scripts. No coverage changes.
* test(e2e): drop the retired screenshot capture paths
MAKA_MCP_E2E_SCREENSHOT and MAKA_DISCLOSURE_E2E_SCREENSHOT are set by
nothing in the repo — no script, no workflow, no docs — so both branches
were dead in every run. AGENTS.md already records that the screenshot
capture harness was retired because its baselines rot and never ran in CI.
The mcp block cost more than dead code: capturing variants meant flipping
to dark theme and resizing to 760px mid-journey, so a spec about add /
discover / disable / import / delete also carried theme and viewport
churn unrelated to any of it.
The session-workbar half is folded into the following commit, which
rewrites the surrounding disclosure assertions.
* test(e2e): assert disclosure and locale behavior instead of design tokens
These assertions pinned numbers, not outcomes: they go red when Astryx
retunes a size, and stay green through anything a user would notice.
- session-workbar: the collapsed Collapsible was measured for trigger vs
root width and label/chevron centering — upstream component internals.
What the journey is about is that a collapsed section hides its rows and
Enter reveals them, which reads directly off the row. Drops the dead
screenshot branch in the same rewrite.
- sidebar-navigation: a 13px font-size pair, and a whole test whose only
assertion was menu width < 128. The heading test keeps its real
contract (one 会话 heading, no redundant group label).
- scroll-geometry: turn separation must equal exactly 16px.
- bot-onboarding: a 284px QR frame and a 522px dialog cap. Replaced by the
contract that matters for scanning a code — the dialog stays inside the
window and the QR is in the viewport.
- locale-renderer: screenshot.byteLength > 10_000 cannot disagree with the
implementation; a blank frame clears it too. The rendered translated
control is the evidence, and it was already being asserted.
* test(e2e): consolidate window-floor sweeps and step the provider journey
Five settings tests each launched their own Electron window to do the same
thing: shrink to the 480px floor and walk pages. They now share one window
and one sweep, split into named steps. Every page-specific assertion is
carried over unchanged — health tiles, usage tabs, the web-search hint,
memory's preview header and status Item, palette wrapping, the data
strategy field and workspace path, about, daily review. The three wide
track-count checks collapse the same way. Pages needing their own seeded
fixture (permissions, usage logs, search results) stay separate: their
state is what makes the contract reachable.
The provider add journey ran ~150 lines and ten behaviors under one name,
so any failure meant reading all of it to learn what broke. Splitting it
into separate tests would buy isolation at four more cold starts;
test.step gives the trace the same answer for free.
Also drops two more token assertions found in that journey (dialog width
cap, 24px brand plate) and the settings switch's 40x24 geometry test.
Net: 20 settings tests to 14, and the E2E suite from 94 to 86.
* test(e2e): record the suite's new size in the config note
* test(e2e): restore the QR rendering contract dropped in the token sweep
The token sweep replaced the QR geometry block with `toBeInViewport()`, which
was too weak for what the comment claimed. Playwright's default `ratio: 0`
passes on any positive intersection, so a QR with one corner on screen — or
one shrunk to a dot inside its frame — cleared the assertion while being
unscannable.
The 284px frame and 522px dialog cap really were tokens. But `qrBox.width ===
qrFrameBox.width - 2` was not: it is the relationship "the image fills its
frame", and nothing else in the suite covers rendered QR geometry. Restored as
relationships rather than constants: fills its frame, square, at least 160px,
centred in its dialog, wholly in the viewport via `ratio: 1`.
Both halves proved by negative control — shrinking the QR to 1px and shifting
it so only a corner shows each turn the test red.
* test(e2e): stop recording a test count that rots
The note said 94 tests; it had been stale for a while, and my own edit made it
worse by writing 86 from a passed-count that excluded a failing test. Actual
discovery is 87 on this branch and 98 on main.
A number that has now been wrong twice, in the same comment, is not worth
maintaining: `playwright test --list` is authoritative and free. Keeps the
timing measurement, which is what the note exists for.
* fix(e2e): drive sidebar collapse through a path that still works
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(e2e): align Astryx-migrated selectors in four specs - #1752

Merged
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors
Aug 1, 2026
Merged

fix(e2e): align Astryx-migrated selectors in four specs#1752
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

#1728 moved the conversation surface onto Astryx primitives but left four E2E specs pointing at removed DOM, failing the CI e2e job with the same 8 tests across runs (scroll-geometry ×4, permission-mode-surface ×2, disclosure-output, session-health-notice). The product contracts those tests lock are all still live; only the selectors went stale.

  • permission-mode-surface: the permission picker moved from the footer's .maka-composer-left-controls to the Astryx header context (.maka-composer-header-context); the Selector trigger is still a combobox, so only the container selector changed.
  • scroll-geometry / session-health-notice: the composer card anchor .maka-composer-inner is gone; .maka-composer-astryx now carries the centered measure (width: min(var(--maka-chat-measure), 100%)).
  • disclosure-output: live tools now render through Astryx ChatToolCalls; a single running tool is one collapsed CallRow (role=button) whose detail mounts on demand, replacing the [data-processing=block] wrapper and its fixture readiness selector.

Two assertions tracked deliberate Astryx changes instead of product regressions: the turn gap is now 16px (ChatMessageList density=compact gap={4}), and a fully pinned scroller can read a 1px distance because Chromium keeps sub-pixel scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.

Verification

  • npx playwright test (apps/desktop): 93 passed — full suite green, including the 8 previously failing tests.
  • npm run format:check and npm run lint: clean (specs live under the formatter-excluded apps/desktop/**).

#1728 moved the conversation surface onto Astryx primitives but left four
E2E specs pointing at the removed DOM:
- permission-mode-surface: the permission picker moved from the footer's
.maka-composer-left-controls to the Astryx header context
(.maka-composer-header-context); the Selector trigger is still a
combobox, so only the container selector changed.
- scroll-geometry / session-health-notice: the composer card anchor
.maka-composer-inner is gone; .maka-composer-astryx now carries the
centered measure (width: min(var(--maka-chat-measure), 100%)).
- disclosure-output: live tools now render through Astryx ChatToolCalls;
a single running tool is one collapsed CallRow (role=button) whose
detail mounts on demand, replacing the [data-processing=block] wrapper
and its fixture readiness selector.
Two assertions also tracked deliberate Astryx changes: the turn gap is
16px (ChatMessageList density=compact gap=4) instead of 12px, and a fully
pinned scroller can read a 1px distance because Chromium keeps sub-pixel
scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.
Full suite: 93 passed.
@Astro-Han
Astro-Han merged commit 50ef904 into mainAug 1, 2026
5 of 6 checks passed
Astro-Han added a commit that referenced this pull request Aug 1, 2026
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
Astryx 0.2.0 ResizeHandle hitAreaOffsetX applies translateY(-50%) without
top:50%, so only the top half of the handle receives pointer events. A
center drag (where the pill sits, and where e2e aims) hits the handle
root with no pointerdown and never collapses — the sole remaining main
e2e failure after #1752. Neutralize the transform on the official
SideNav handle; remove once Astryx fixes hitAreaOffsetX.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
… the long-failing sidebar spec (#1756)
* test(e2e): move Electron teardown coverage to node --test
closeElectronApplication drives a fake process handle and never launches
Electron, so it was the one spec in the Playwright suite paying a real
Electron slot for assertions that need none. It tests the launch harness
itself, not product behavior.
Move both cases to scripts/electron-lifecycle.test.mjs, beside the sibling
harness tests (fixture-env, fixture-window), and register them in
test:scripts. No coverage changes.
* test(e2e): drop the retired screenshot capture paths
MAKA_MCP_E2E_SCREENSHOT and MAKA_DISCLOSURE_E2E_SCREENSHOT are set by
nothing in the repo — no script, no workflow, no docs — so both branches
were dead in every run. AGENTS.md already records that the screenshot
capture harness was retired because its baselines rot and never ran in CI.
The mcp block cost more than dead code: capturing variants meant flipping
to dark theme and resizing to 760px mid-journey, so a spec about add /
discover / disable / import / delete also carried theme and viewport
churn unrelated to any of it.
The session-workbar half is folded into the following commit, which
rewrites the surrounding disclosure assertions.
* test(e2e): assert disclosure and locale behavior instead of design tokens
These assertions pinned numbers, not outcomes: they go red when Astryx
retunes a size, and stay green through anything a user would notice.
- session-workbar: the collapsed Collapsible was measured for trigger vs
root width and label/chevron centering — upstream component internals.
What the journey is about is that a collapsed section hides its rows and
Enter reveals them, which reads directly off the row. Drops the dead
screenshot branch in the same rewrite.
- sidebar-navigation: a 13px font-size pair, and a whole test whose only
assertion was menu width < 128. The heading test keeps its real
contract (one 会话 heading, no redundant group label).
- scroll-geometry: turn separation must equal exactly 16px.
- bot-onboarding: a 284px QR frame and a 522px dialog cap. Replaced by the
contract that matters for scanning a code — the dialog stays inside the
window and the QR is in the viewport.
- locale-renderer: screenshot.byteLength > 10_000 cannot disagree with the
implementation; a blank frame clears it too. The rendered translated
control is the evidence, and it was already being asserted.
* test(e2e): consolidate window-floor sweeps and step the provider journey
Five settings tests each launched their own Electron window to do the same
thing: shrink to the 480px floor and walk pages. They now share one window
and one sweep, split into named steps. Every page-specific assertion is
carried over unchanged — health tiles, usage tabs, the web-search hint,
memory's preview header and status Item, palette wrapping, the data
strategy field and workspace path, about, daily review. The three wide
track-count checks collapse the same way. Pages needing their own seeded
fixture (permissions, usage logs, search results) stay separate: their
state is what makes the contract reachable.
The provider add journey ran ~150 lines and ten behaviors under one name,
so any failure meant reading all of it to learn what broke. Splitting it
into separate tests would buy isolation at four more cold starts;
test.step gives the trace the same answer for free.
Also drops two more token assertions found in that journey (dialog width
cap, 24px brand plate) and the settings switch's 40x24 geometry test.
Net: 20 settings tests to 14, and the E2E suite from 94 to 86.
* test(e2e): record the suite's new size in the config note
* test(e2e): restore the QR rendering contract dropped in the token sweep
The token sweep replaced the QR geometry block with `toBeInViewport()`, which
was too weak for what the comment claimed. Playwright's default `ratio: 0`
passes on any positive intersection, so a QR with one corner on screen — or
one shrunk to a dot inside its frame — cleared the assertion while being
unscannable.
The 284px frame and 522px dialog cap really were tokens. But `qrBox.width ===
qrFrameBox.width - 2` was not: it is the relationship "the image fills its
frame", and nothing else in the suite covers rendered QR geometry. Restored as
relationships rather than constants: fills its frame, square, at least 160px,
centred in its dialog, wholly in the viewport via `ratio: 1`.
Both halves proved by negative control — shrinking the QR to 1px and shifting
it so only a corner shows each turn the test red.
* test(e2e): stop recording a test count that rots
The note said 94 tests; it had been stale for a while, and my own edit made it
worse by writing 86 from a passed-count that excluded a failing test. Actual
discovery is 87 on this branch and 98 on main.
A number that has now been wrong twice, in the same comment, is not worth
maintaining: `playwright test --list` is authoritative and free. Keeps the
timing measurement, which is what the note exists for.
* fix(e2e): drive sidebar collapse through a path that still works
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(e2e): align Astryx-migrated selectors in four specs - #1752

Merged
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors
Aug 1, 2026
Merged

fix(e2e): align Astryx-migrated selectors in four specs#1752
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

#1728 moved the conversation surface onto Astryx primitives but left four E2E specs pointing at removed DOM, failing the CI e2e job with the same 8 tests across runs (scroll-geometry ×4, permission-mode-surface ×2, disclosure-output, session-health-notice). The product contracts those tests lock are all still live; only the selectors went stale.

  • permission-mode-surface: the permission picker moved from the footer's .maka-composer-left-controls to the Astryx header context (.maka-composer-header-context); the Selector trigger is still a combobox, so only the container selector changed.
  • scroll-geometry / session-health-notice: the composer card anchor .maka-composer-inner is gone; .maka-composer-astryx now carries the centered measure (width: min(var(--maka-chat-measure), 100%)).
  • disclosure-output: live tools now render through Astryx ChatToolCalls; a single running tool is one collapsed CallRow (role=button) whose detail mounts on demand, replacing the [data-processing=block] wrapper and its fixture readiness selector.

Two assertions tracked deliberate Astryx changes instead of product regressions: the turn gap is now 16px (ChatMessageList density=compact gap={4}), and a fully pinned scroller can read a 1px distance because Chromium keeps sub-pixel scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.

Verification

  • npx playwright test (apps/desktop): 93 passed — full suite green, including the 8 previously failing tests.
  • npm run format:check and npm run lint: clean (specs live under the formatter-excluded apps/desktop/**).

#1728 moved the conversation surface onto Astryx primitives but left four
E2E specs pointing at the removed DOM:
- permission-mode-surface: the permission picker moved from the footer's
.maka-composer-left-controls to the Astryx header context
(.maka-composer-header-context); the Selector trigger is still a
combobox, so only the container selector changed.
- scroll-geometry / session-health-notice: the composer card anchor
.maka-composer-inner is gone; .maka-composer-astryx now carries the
centered measure (width: min(var(--maka-chat-measure), 100%)).
- disclosure-output: live tools now render through Astryx ChatToolCalls;
a single running tool is one collapsed CallRow (role=button) whose
detail mounts on demand, replacing the [data-processing=block] wrapper
and its fixture readiness selector.
Two assertions also tracked deliberate Astryx changes: the turn gap is
16px (ChatMessageList density=compact gap=4) instead of 12px, and a fully
pinned scroller can read a 1px distance because Chromium keeps sub-pixel
scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.
Full suite: 93 passed.
@Astro-Han
Astro-Han merged commit 50ef904 into mainAug 1, 2026
5 of 6 checks passed
Astro-Han added a commit that referenced this pull request Aug 1, 2026
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
Astryx 0.2.0 ResizeHandle hitAreaOffsetX applies translateY(-50%) without
top:50%, so only the top half of the handle receives pointer events. A
center drag (where the pill sits, and where e2e aims) hits the handle
root with no pointerdown and never collapses — the sole remaining main
e2e failure after #1752. Neutralize the transform on the official
SideNav handle; remove once Astryx fixes hitAreaOffsetX.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
… the long-failing sidebar spec (#1756)
* test(e2e): move Electron teardown coverage to node --test
closeElectronApplication drives a fake process handle and never launches
Electron, so it was the one spec in the Playwright suite paying a real
Electron slot for assertions that need none. It tests the launch harness
itself, not product behavior.
Move both cases to scripts/electron-lifecycle.test.mjs, beside the sibling
harness tests (fixture-env, fixture-window), and register them in
test:scripts. No coverage changes.
* test(e2e): drop the retired screenshot capture paths
MAKA_MCP_E2E_SCREENSHOT and MAKA_DISCLOSURE_E2E_SCREENSHOT are set by
nothing in the repo — no script, no workflow, no docs — so both branches
were dead in every run. AGENTS.md already records that the screenshot
capture harness was retired because its baselines rot and never ran in CI.
The mcp block cost more than dead code: capturing variants meant flipping
to dark theme and resizing to 760px mid-journey, so a spec about add /
discover / disable / import / delete also carried theme and viewport
churn unrelated to any of it.
The session-workbar half is folded into the following commit, which
rewrites the surrounding disclosure assertions.
* test(e2e): assert disclosure and locale behavior instead of design tokens
These assertions pinned numbers, not outcomes: they go red when Astryx
retunes a size, and stay green through anything a user would notice.
- session-workbar: the collapsed Collapsible was measured for trigger vs
root width and label/chevron centering — upstream component internals.
What the journey is about is that a collapsed section hides its rows and
Enter reveals them, which reads directly off the row. Drops the dead
screenshot branch in the same rewrite.
- sidebar-navigation: a 13px font-size pair, and a whole test whose only
assertion was menu width < 128. The heading test keeps its real
contract (one 会话 heading, no redundant group label).
- scroll-geometry: turn separation must equal exactly 16px.
- bot-onboarding: a 284px QR frame and a 522px dialog cap. Replaced by the
contract that matters for scanning a code — the dialog stays inside the
window and the QR is in the viewport.
- locale-renderer: screenshot.byteLength > 10_000 cannot disagree with the
implementation; a blank frame clears it too. The rendered translated
control is the evidence, and it was already being asserted.
* test(e2e): consolidate window-floor sweeps and step the provider journey
Five settings tests each launched their own Electron window to do the same
thing: shrink to the 480px floor and walk pages. They now share one window
and one sweep, split into named steps. Every page-specific assertion is
carried over unchanged — health tiles, usage tabs, the web-search hint,
memory's preview header and status Item, palette wrapping, the data
strategy field and workspace path, about, daily review. The three wide
track-count checks collapse the same way. Pages needing their own seeded
fixture (permissions, usage logs, search results) stay separate: their
state is what makes the contract reachable.
The provider add journey ran ~150 lines and ten behaviors under one name,
so any failure meant reading all of it to learn what broke. Splitting it
into separate tests would buy isolation at four more cold starts;
test.step gives the trace the same answer for free.
Also drops two more token assertions found in that journey (dialog width
cap, 24px brand plate) and the settings switch's 40x24 geometry test.
Net: 20 settings tests to 14, and the E2E suite from 94 to 86.
* test(e2e): record the suite's new size in the config note
* test(e2e): restore the QR rendering contract dropped in the token sweep
The token sweep replaced the QR geometry block with `toBeInViewport()`, which
was too weak for what the comment claimed. Playwright's default `ratio: 0`
passes on any positive intersection, so a QR with one corner on screen — or
one shrunk to a dot inside its frame — cleared the assertion while being
unscannable.
The 284px frame and 522px dialog cap really were tokens. But `qrBox.width ===
qrFrameBox.width - 2` was not: it is the relationship "the image fills its
frame", and nothing else in the suite covers rendered QR geometry. Restored as
relationships rather than constants: fills its frame, square, at least 160px,
centred in its dialog, wholly in the viewport via `ratio: 1`.
Both halves proved by negative control — shrinking the QR to 1px and shifting
it so only a corner shows each turn the test red.
* test(e2e): stop recording a test count that rots
The note said 94 tests; it had been stale for a while, and my own edit made it
worse by writing 86 from a passed-count that excluded a failing test. Actual
discovery is 87 on this branch and 98 on main.
A number that has now been wrong twice, in the same comment, is not worth
maintaining: `playwright test --list` is authoritative and free. Keeps the
timing measurement, which is what the note exists for.
* fix(e2e): drive sidebar collapse through a path that still works
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(e2e): align Astryx-migrated selectors in four specs - #1752

Merged
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors
Aug 1, 2026
Merged

fix(e2e): align Astryx-migrated selectors in four specs#1752
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

#1728 moved the conversation surface onto Astryx primitives but left four E2E specs pointing at removed DOM, failing the CI e2e job with the same 8 tests across runs (scroll-geometry ×4, permission-mode-surface ×2, disclosure-output, session-health-notice). The product contracts those tests lock are all still live; only the selectors went stale.

  • permission-mode-surface: the permission picker moved from the footer's .maka-composer-left-controls to the Astryx header context (.maka-composer-header-context); the Selector trigger is still a combobox, so only the container selector changed.
  • scroll-geometry / session-health-notice: the composer card anchor .maka-composer-inner is gone; .maka-composer-astryx now carries the centered measure (width: min(var(--maka-chat-measure), 100%)).
  • disclosure-output: live tools now render through Astryx ChatToolCalls; a single running tool is one collapsed CallRow (role=button) whose detail mounts on demand, replacing the [data-processing=block] wrapper and its fixture readiness selector.

Two assertions tracked deliberate Astryx changes instead of product regressions: the turn gap is now 16px (ChatMessageList density=compact gap={4}), and a fully pinned scroller can read a 1px distance because Chromium keeps sub-pixel scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.

Verification

  • npx playwright test (apps/desktop): 93 passed — full suite green, including the 8 previously failing tests.
  • npm run format:check and npm run lint: clean (specs live under the formatter-excluded apps/desktop/**).

#1728 moved the conversation surface onto Astryx primitives but left four
E2E specs pointing at the removed DOM:
- permission-mode-surface: the permission picker moved from the footer's
.maka-composer-left-controls to the Astryx header context
(.maka-composer-header-context); the Selector trigger is still a
combobox, so only the container selector changed.
- scroll-geometry / session-health-notice: the composer card anchor
.maka-composer-inner is gone; .maka-composer-astryx now carries the
centered measure (width: min(var(--maka-chat-measure), 100%)).
- disclosure-output: live tools now render through Astryx ChatToolCalls;
a single running tool is one collapsed CallRow (role=button) whose
detail mounts on demand, replacing the [data-processing=block] wrapper
and its fixture readiness selector.
Two assertions also tracked deliberate Astryx changes: the turn gap is
16px (ChatMessageList density=compact gap=4) instead of 12px, and a fully
pinned scroller can read a 1px distance because Chromium keeps sub-pixel
scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.
Full suite: 93 passed.
@Astro-Han
Astro-Han merged commit 50ef904 into mainAug 1, 2026
5 of 6 checks passed
Astro-Han added a commit that referenced this pull request Aug 1, 2026
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
Astryx 0.2.0 ResizeHandle hitAreaOffsetX applies translateY(-50%) without
top:50%, so only the top half of the handle receives pointer events. A
center drag (where the pill sits, and where e2e aims) hits the handle
root with no pointerdown and never collapses — the sole remaining main
e2e failure after #1752. Neutralize the transform on the official
SideNav handle; remove once Astryx fixes hitAreaOffsetX.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
… the long-failing sidebar spec (#1756)
* test(e2e): move Electron teardown coverage to node --test
closeElectronApplication drives a fake process handle and never launches
Electron, so it was the one spec in the Playwright suite paying a real
Electron slot for assertions that need none. It tests the launch harness
itself, not product behavior.
Move both cases to scripts/electron-lifecycle.test.mjs, beside the sibling
harness tests (fixture-env, fixture-window), and register them in
test:scripts. No coverage changes.
* test(e2e): drop the retired screenshot capture paths
MAKA_MCP_E2E_SCREENSHOT and MAKA_DISCLOSURE_E2E_SCREENSHOT are set by
nothing in the repo — no script, no workflow, no docs — so both branches
were dead in every run. AGENTS.md already records that the screenshot
capture harness was retired because its baselines rot and never ran in CI.
The mcp block cost more than dead code: capturing variants meant flipping
to dark theme and resizing to 760px mid-journey, so a spec about add /
discover / disable / import / delete also carried theme and viewport
churn unrelated to any of it.
The session-workbar half is folded into the following commit, which
rewrites the surrounding disclosure assertions.
* test(e2e): assert disclosure and locale behavior instead of design tokens
These assertions pinned numbers, not outcomes: they go red when Astryx
retunes a size, and stay green through anything a user would notice.
- session-workbar: the collapsed Collapsible was measured for trigger vs
root width and label/chevron centering — upstream component internals.
What the journey is about is that a collapsed section hides its rows and
Enter reveals them, which reads directly off the row. Drops the dead
screenshot branch in the same rewrite.
- sidebar-navigation: a 13px font-size pair, and a whole test whose only
assertion was menu width < 128. The heading test keeps its real
contract (one 会话 heading, no redundant group label).
- scroll-geometry: turn separation must equal exactly 16px.
- bot-onboarding: a 284px QR frame and a 522px dialog cap. Replaced by the
contract that matters for scanning a code — the dialog stays inside the
window and the QR is in the viewport.
- locale-renderer: screenshot.byteLength > 10_000 cannot disagree with the
implementation; a blank frame clears it too. The rendered translated
control is the evidence, and it was already being asserted.
* test(e2e): consolidate window-floor sweeps and step the provider journey
Five settings tests each launched their own Electron window to do the same
thing: shrink to the 480px floor and walk pages. They now share one window
and one sweep, split into named steps. Every page-specific assertion is
carried over unchanged — health tiles, usage tabs, the web-search hint,
memory's preview header and status Item, palette wrapping, the data
strategy field and workspace path, about, daily review. The three wide
track-count checks collapse the same way. Pages needing their own seeded
fixture (permissions, usage logs, search results) stay separate: their
state is what makes the contract reachable.
The provider add journey ran ~150 lines and ten behaviors under one name,
so any failure meant reading all of it to learn what broke. Splitting it
into separate tests would buy isolation at four more cold starts;
test.step gives the trace the same answer for free.
Also drops two more token assertions found in that journey (dialog width
cap, 24px brand plate) and the settings switch's 40x24 geometry test.
Net: 20 settings tests to 14, and the E2E suite from 94 to 86.
* test(e2e): record the suite's new size in the config note
* test(e2e): restore the QR rendering contract dropped in the token sweep
The token sweep replaced the QR geometry block with `toBeInViewport()`, which
was too weak for what the comment claimed. Playwright's default `ratio: 0`
passes on any positive intersection, so a QR with one corner on screen — or
one shrunk to a dot inside its frame — cleared the assertion while being
unscannable.
The 284px frame and 522px dialog cap really were tokens. But `qrBox.width ===
qrFrameBox.width - 2` was not: it is the relationship "the image fills its
frame", and nothing else in the suite covers rendered QR geometry. Restored as
relationships rather than constants: fills its frame, square, at least 160px,
centred in its dialog, wholly in the viewport via `ratio: 1`.
Both halves proved by negative control — shrinking the QR to 1px and shifting
it so only a corner shows each turn the test red.
* test(e2e): stop recording a test count that rots
The note said 94 tests; it had been stale for a while, and my own edit made it
worse by writing 86 from a passed-count that excluded a failing test. Actual
discovery is 87 on this branch and 98 on main.
A number that has now been wrong twice, in the same comment, is not worth
maintaining: `playwright test --list` is authoritative and free. Keeps the
timing measurement, which is what the note exists for.
* fix(e2e): drive sidebar collapse through a path that still works
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(e2e): align Astryx-migrated selectors in four specs - #1752

Merged
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors
Aug 1, 2026
Merged

fix(e2e): align Astryx-migrated selectors in four specs#1752
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

#1728 moved the conversation surface onto Astryx primitives but left four E2E specs pointing at removed DOM, failing the CI e2e job with the same 8 tests across runs (scroll-geometry ×4, permission-mode-surface ×2, disclosure-output, session-health-notice). The product contracts those tests lock are all still live; only the selectors went stale.

  • permission-mode-surface: the permission picker moved from the footer's .maka-composer-left-controls to the Astryx header context (.maka-composer-header-context); the Selector trigger is still a combobox, so only the container selector changed.
  • scroll-geometry / session-health-notice: the composer card anchor .maka-composer-inner is gone; .maka-composer-astryx now carries the centered measure (width: min(var(--maka-chat-measure), 100%)).
  • disclosure-output: live tools now render through Astryx ChatToolCalls; a single running tool is one collapsed CallRow (role=button) whose detail mounts on demand, replacing the [data-processing=block] wrapper and its fixture readiness selector.

Two assertions tracked deliberate Astryx changes instead of product regressions: the turn gap is now 16px (ChatMessageList density=compact gap={4}), and a fully pinned scroller can read a 1px distance because Chromium keeps sub-pixel scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.

Verification

  • npx playwright test (apps/desktop): 93 passed — full suite green, including the 8 previously failing tests.
  • npm run format:check and npm run lint: clean (specs live under the formatter-excluded apps/desktop/**).

#1728 moved the conversation surface onto Astryx primitives but left four
E2E specs pointing at the removed DOM:
- permission-mode-surface: the permission picker moved from the footer's
.maka-composer-left-controls to the Astryx header context
(.maka-composer-header-context); the Selector trigger is still a
combobox, so only the container selector changed.
- scroll-geometry / session-health-notice: the composer card anchor
.maka-composer-inner is gone; .maka-composer-astryx now carries the
centered measure (width: min(var(--maka-chat-measure), 100%)).
- disclosure-output: live tools now render through Astryx ChatToolCalls;
a single running tool is one collapsed CallRow (role=button) whose
detail mounts on demand, replacing the [data-processing=block] wrapper
and its fixture readiness selector.
Two assertions also tracked deliberate Astryx changes: the turn gap is
16px (ChatMessageList density=compact gap=4) instead of 12px, and a fully
pinned scroller can read a 1px distance because Chromium keeps sub-pixel
scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.
Full suite: 93 passed.
@Astro-Han
Astro-Han merged commit 50ef904 into mainAug 1, 2026
5 of 6 checks passed
Astro-Han added a commit that referenced this pull request Aug 1, 2026
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
Astryx 0.2.0 ResizeHandle hitAreaOffsetX applies translateY(-50%) without
top:50%, so only the top half of the handle receives pointer events. A
center drag (where the pill sits, and where e2e aims) hits the handle
root with no pointerdown and never collapses — the sole remaining main
e2e failure after #1752. Neutralize the transform on the official
SideNav handle; remove once Astryx fixes hitAreaOffsetX.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
… the long-failing sidebar spec (#1756)
* test(e2e): move Electron teardown coverage to node --test
closeElectronApplication drives a fake process handle and never launches
Electron, so it was the one spec in the Playwright suite paying a real
Electron slot for assertions that need none. It tests the launch harness
itself, not product behavior.
Move both cases to scripts/electron-lifecycle.test.mjs, beside the sibling
harness tests (fixture-env, fixture-window), and register them in
test:scripts. No coverage changes.
* test(e2e): drop the retired screenshot capture paths
MAKA_MCP_E2E_SCREENSHOT and MAKA_DISCLOSURE_E2E_SCREENSHOT are set by
nothing in the repo — no script, no workflow, no docs — so both branches
were dead in every run. AGENTS.md already records that the screenshot
capture harness was retired because its baselines rot and never ran in CI.
The mcp block cost more than dead code: capturing variants meant flipping
to dark theme and resizing to 760px mid-journey, so a spec about add /
discover / disable / import / delete also carried theme and viewport
churn unrelated to any of it.
The session-workbar half is folded into the following commit, which
rewrites the surrounding disclosure assertions.
* test(e2e): assert disclosure and locale behavior instead of design tokens
These assertions pinned numbers, not outcomes: they go red when Astryx
retunes a size, and stay green through anything a user would notice.
- session-workbar: the collapsed Collapsible was measured for trigger vs
root width and label/chevron centering — upstream component internals.
What the journey is about is that a collapsed section hides its rows and
Enter reveals them, which reads directly off the row. Drops the dead
screenshot branch in the same rewrite.
- sidebar-navigation: a 13px font-size pair, and a whole test whose only
assertion was menu width < 128. The heading test keeps its real
contract (one 会话 heading, no redundant group label).
- scroll-geometry: turn separation must equal exactly 16px.
- bot-onboarding: a 284px QR frame and a 522px dialog cap. Replaced by the
contract that matters for scanning a code — the dialog stays inside the
window and the QR is in the viewport.
- locale-renderer: screenshot.byteLength > 10_000 cannot disagree with the
implementation; a blank frame clears it too. The rendered translated
control is the evidence, and it was already being asserted.
* test(e2e): consolidate window-floor sweeps and step the provider journey
Five settings tests each launched their own Electron window to do the same
thing: shrink to the 480px floor and walk pages. They now share one window
and one sweep, split into named steps. Every page-specific assertion is
carried over unchanged — health tiles, usage tabs, the web-search hint,
memory's preview header and status Item, palette wrapping, the data
strategy field and workspace path, about, daily review. The three wide
track-count checks collapse the same way. Pages needing their own seeded
fixture (permissions, usage logs, search results) stay separate: their
state is what makes the contract reachable.
The provider add journey ran ~150 lines and ten behaviors under one name,
so any failure meant reading all of it to learn what broke. Splitting it
into separate tests would buy isolation at four more cold starts;
test.step gives the trace the same answer for free.
Also drops two more token assertions found in that journey (dialog width
cap, 24px brand plate) and the settings switch's 40x24 geometry test.
Net: 20 settings tests to 14, and the E2E suite from 94 to 86.
* test(e2e): record the suite's new size in the config note
* test(e2e): restore the QR rendering contract dropped in the token sweep
The token sweep replaced the QR geometry block with `toBeInViewport()`, which
was too weak for what the comment claimed. Playwright's default `ratio: 0`
passes on any positive intersection, so a QR with one corner on screen — or
one shrunk to a dot inside its frame — cleared the assertion while being
unscannable.
The 284px frame and 522px dialog cap really were tokens. But `qrBox.width ===
qrFrameBox.width - 2` was not: it is the relationship "the image fills its
frame", and nothing else in the suite covers rendered QR geometry. Restored as
relationships rather than constants: fills its frame, square, at least 160px,
centred in its dialog, wholly in the viewport via `ratio: 1`.
Both halves proved by negative control — shrinking the QR to 1px and shifting
it so only a corner shows each turn the test red.
* test(e2e): stop recording a test count that rots
The note said 94 tests; it had been stale for a while, and my own edit made it
worse by writing 86 from a passed-count that excluded a failing test. Actual
discovery is 87 on this branch and 98 on main.
A number that has now been wrong twice, in the same comment, is not worth
maintaining: `playwright test --list` is authoritative and free. Keeps the
timing measurement, which is what the note exists for.
* fix(e2e): drive sidebar collapse through a path that still works
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(e2e): align Astryx-migrated selectors in four specs - #1752

Merged
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors
Aug 1, 2026
Merged

fix(e2e): align Astryx-migrated selectors in four specs#1752
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

#1728 moved the conversation surface onto Astryx primitives but left four E2E specs pointing at removed DOM, failing the CI e2e job with the same 8 tests across runs (scroll-geometry ×4, permission-mode-surface ×2, disclosure-output, session-health-notice). The product contracts those tests lock are all still live; only the selectors went stale.

  • permission-mode-surface: the permission picker moved from the footer's .maka-composer-left-controls to the Astryx header context (.maka-composer-header-context); the Selector trigger is still a combobox, so only the container selector changed.
  • scroll-geometry / session-health-notice: the composer card anchor .maka-composer-inner is gone; .maka-composer-astryx now carries the centered measure (width: min(var(--maka-chat-measure), 100%)).
  • disclosure-output: live tools now render through Astryx ChatToolCalls; a single running tool is one collapsed CallRow (role=button) whose detail mounts on demand, replacing the [data-processing=block] wrapper and its fixture readiness selector.

Two assertions tracked deliberate Astryx changes instead of product regressions: the turn gap is now 16px (ChatMessageList density=compact gap={4}), and a fully pinned scroller can read a 1px distance because Chromium keeps sub-pixel scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.

Verification

  • npx playwright test (apps/desktop): 93 passed — full suite green, including the 8 previously failing tests.
  • npm run format:check and npm run lint: clean (specs live under the formatter-excluded apps/desktop/**).

#1728 moved the conversation surface onto Astryx primitives but left four
E2E specs pointing at the removed DOM:
- permission-mode-surface: the permission picker moved from the footer's
.maka-composer-left-controls to the Astryx header context
(.maka-composer-header-context); the Selector trigger is still a
combobox, so only the container selector changed.
- scroll-geometry / session-health-notice: the composer card anchor
.maka-composer-inner is gone; .maka-composer-astryx now carries the
centered measure (width: min(var(--maka-chat-measure), 100%)).
- disclosure-output: live tools now render through Astryx ChatToolCalls;
a single running tool is one collapsed CallRow (role=button) whose
detail mounts on demand, replacing the [data-processing=block] wrapper
and its fixture readiness selector.
Two assertions also tracked deliberate Astryx changes: the turn gap is
16px (ChatMessageList density=compact gap=4) instead of 12px, and a fully
pinned scroller can read a 1px distance because Chromium keeps sub-pixel
scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.
Full suite: 93 passed.
@Astro-Han
Astro-Han merged commit 50ef904 into mainAug 1, 2026
5 of 6 checks passed
Astro-Han added a commit that referenced this pull request Aug 1, 2026
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
Astryx 0.2.0 ResizeHandle hitAreaOffsetX applies translateY(-50%) without
top:50%, so only the top half of the handle receives pointer events. A
center drag (where the pill sits, and where e2e aims) hits the handle
root with no pointerdown and never collapses — the sole remaining main
e2e failure after #1752. Neutralize the transform on the official
SideNav handle; remove once Astryx fixes hitAreaOffsetX.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
… the long-failing sidebar spec (#1756)
* test(e2e): move Electron teardown coverage to node --test
closeElectronApplication drives a fake process handle and never launches
Electron, so it was the one spec in the Playwright suite paying a real
Electron slot for assertions that need none. It tests the launch harness
itself, not product behavior.
Move both cases to scripts/electron-lifecycle.test.mjs, beside the sibling
harness tests (fixture-env, fixture-window), and register them in
test:scripts. No coverage changes.
* test(e2e): drop the retired screenshot capture paths
MAKA_MCP_E2E_SCREENSHOT and MAKA_DISCLOSURE_E2E_SCREENSHOT are set by
nothing in the repo — no script, no workflow, no docs — so both branches
were dead in every run. AGENTS.md already records that the screenshot
capture harness was retired because its baselines rot and never ran in CI.
The mcp block cost more than dead code: capturing variants meant flipping
to dark theme and resizing to 760px mid-journey, so a spec about add /
discover / disable / import / delete also carried theme and viewport
churn unrelated to any of it.
The session-workbar half is folded into the following commit, which
rewrites the surrounding disclosure assertions.
* test(e2e): assert disclosure and locale behavior instead of design tokens
These assertions pinned numbers, not outcomes: they go red when Astryx
retunes a size, and stay green through anything a user would notice.
- session-workbar: the collapsed Collapsible was measured for trigger vs
root width and label/chevron centering — upstream component internals.
What the journey is about is that a collapsed section hides its rows and
Enter reveals them, which reads directly off the row. Drops the dead
screenshot branch in the same rewrite.
- sidebar-navigation: a 13px font-size pair, and a whole test whose only
assertion was menu width < 128. The heading test keeps its real
contract (one 会话 heading, no redundant group label).
- scroll-geometry: turn separation must equal exactly 16px.
- bot-onboarding: a 284px QR frame and a 522px dialog cap. Replaced by the
contract that matters for scanning a code — the dialog stays inside the
window and the QR is in the viewport.
- locale-renderer: screenshot.byteLength > 10_000 cannot disagree with the
implementation; a blank frame clears it too. The rendered translated
control is the evidence, and it was already being asserted.
* test(e2e): consolidate window-floor sweeps and step the provider journey
Five settings tests each launched their own Electron window to do the same
thing: shrink to the 480px floor and walk pages. They now share one window
and one sweep, split into named steps. Every page-specific assertion is
carried over unchanged — health tiles, usage tabs, the web-search hint,
memory's preview header and status Item, palette wrapping, the data
strategy field and workspace path, about, daily review. The three wide
track-count checks collapse the same way. Pages needing their own seeded
fixture (permissions, usage logs, search results) stay separate: their
state is what makes the contract reachable.
The provider add journey ran ~150 lines and ten behaviors under one name,
so any failure meant reading all of it to learn what broke. Splitting it
into separate tests would buy isolation at four more cold starts;
test.step gives the trace the same answer for free.
Also drops two more token assertions found in that journey (dialog width
cap, 24px brand plate) and the settings switch's 40x24 geometry test.
Net: 20 settings tests to 14, and the E2E suite from 94 to 86.
* test(e2e): record the suite's new size in the config note
* test(e2e): restore the QR rendering contract dropped in the token sweep
The token sweep replaced the QR geometry block with `toBeInViewport()`, which
was too weak for what the comment claimed. Playwright's default `ratio: 0`
passes on any positive intersection, so a QR with one corner on screen — or
one shrunk to a dot inside its frame — cleared the assertion while being
unscannable.
The 284px frame and 522px dialog cap really were tokens. But `qrBox.width ===
qrFrameBox.width - 2` was not: it is the relationship "the image fills its
frame", and nothing else in the suite covers rendered QR geometry. Restored as
relationships rather than constants: fills its frame, square, at least 160px,
centred in its dialog, wholly in the viewport via `ratio: 1`.
Both halves proved by negative control — shrinking the QR to 1px and shifting
it so only a corner shows each turn the test red.
* test(e2e): stop recording a test count that rots
The note said 94 tests; it had been stale for a while, and my own edit made it
worse by writing 86 from a passed-count that excluded a failing test. Actual
discovery is 87 on this branch and 98 on main.
A number that has now been wrong twice, in the same comment, is not worth
maintaining: `playwright test --list` is authoritative and free. Keeps the
timing measurement, which is what the note exists for.
* fix(e2e): drive sidebar collapse through a path that still works
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(e2e): align Astryx-migrated selectors in four specs - #1752

Merged
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors
Aug 1, 2026
Merged

fix(e2e): align Astryx-migrated selectors in four specs#1752
Astro-Han merged 1 commit into
mainfrom
fix/e2e-astryx-selectors

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

#1728 moved the conversation surface onto Astryx primitives but left four E2E specs pointing at removed DOM, failing the CI e2e job with the same 8 tests across runs (scroll-geometry ×4, permission-mode-surface ×2, disclosure-output, session-health-notice). The product contracts those tests lock are all still live; only the selectors went stale.

  • permission-mode-surface: the permission picker moved from the footer's .maka-composer-left-controls to the Astryx header context (.maka-composer-header-context); the Selector trigger is still a combobox, so only the container selector changed.
  • scroll-geometry / session-health-notice: the composer card anchor .maka-composer-inner is gone; .maka-composer-astryx now carries the centered measure (width: min(var(--maka-chat-measure), 100%)).
  • disclosure-output: live tools now render through Astryx ChatToolCalls; a single running tool is one collapsed CallRow (role=button) whose detail mounts on demand, replacing the [data-processing=block] wrapper and its fixture readiness selector.

Two assertions tracked deliberate Astryx changes instead of product regressions: the turn gap is now 16px (ChatMessageList density=compact gap={4}), and a fully pinned scroller can read a 1px distance because Chromium keeps sub-pixel scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.

Verification

  • npx playwright test (apps/desktop): 93 passed — full suite green, including the 8 previously failing tests.
  • npm run format:check and npm run lint: clean (specs live under the formatter-excluded apps/desktop/**).

#1728 moved the conversation surface onto Astryx primitives but left four
E2E specs pointing at the removed DOM:
- permission-mode-surface: the permission picker moved from the footer's
.maka-composer-left-controls to the Astryx header context
(.maka-composer-header-context); the Selector trigger is still a
combobox, so only the container selector changed.
- scroll-geometry / session-health-notice: the composer card anchor
.maka-composer-inner is gone; .maka-composer-astryx now carries the
centered measure (width: min(var(--maka-chat-measure), 100%)).
- disclosure-output: live tools now render through Astryx ChatToolCalls;
a single running tool is one collapsed CallRow (role=button) whose
detail mounts on demand, replacing the [data-processing=block] wrapper
and its fixture readiness selector.
Two assertions also tracked deliberate Astryx changes: the turn gap is
16px (ChatMessageList density=compact gap=4) instead of 12px, and a fully
pinned scroller can read a 1px distance because Chromium keeps sub-pixel
scrollTop values (observed 30106.5), so the pin contract accepts <= 1px.
Full suite: 93 passed.
@Astro-Han
Astro-Han merged commit 50ef904 into mainAug 1, 2026
5 of 6 checks passed
Astro-Han added a commit that referenced this pull request Aug 1, 2026
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
Astryx 0.2.0 ResizeHandle hitAreaOffsetX applies translateY(-50%) without
top:50%, so only the top half of the handle receives pointer events. A
center drag (where the pill sits, and where e2e aims) hits the handle
root with no pointerdown and never collapses — the sole remaining main
e2e failure after #1752. Neutralize the transform on the official
SideNav handle; remove once Astryx fixes hitAreaOffsetX.
Astro-Han added a commit that referenced this pull request Aug 1, 2026
… the long-failing sidebar spec (#1756)
* test(e2e): move Electron teardown coverage to node --test
closeElectronApplication drives a fake process handle and never launches
Electron, so it was the one spec in the Playwright suite paying a real
Electron slot for assertions that need none. It tests the launch harness
itself, not product behavior.
Move both cases to scripts/electron-lifecycle.test.mjs, beside the sibling
harness tests (fixture-env, fixture-window), and register them in
test:scripts. No coverage changes.
* test(e2e): drop the retired screenshot capture paths
MAKA_MCP_E2E_SCREENSHOT and MAKA_DISCLOSURE_E2E_SCREENSHOT are set by
nothing in the repo — no script, no workflow, no docs — so both branches
were dead in every run. AGENTS.md already records that the screenshot
capture harness was retired because its baselines rot and never ran in CI.
The mcp block cost more than dead code: capturing variants meant flipping
to dark theme and resizing to 760px mid-journey, so a spec about add /
discover / disable / import / delete also carried theme and viewport
churn unrelated to any of it.
The session-workbar half is folded into the following commit, which
rewrites the surrounding disclosure assertions.
* test(e2e): assert disclosure and locale behavior instead of design tokens
These assertions pinned numbers, not outcomes: they go red when Astryx
retunes a size, and stay green through anything a user would notice.
- session-workbar: the collapsed Collapsible was measured for trigger vs
root width and label/chevron centering — upstream component internals.
What the journey is about is that a collapsed section hides its rows and
Enter reveals them, which reads directly off the row. Drops the dead
screenshot branch in the same rewrite.
- sidebar-navigation: a 13px font-size pair, and a whole test whose only
assertion was menu width < 128. The heading test keeps its real
contract (one 会话 heading, no redundant group label).
- scroll-geometry: turn separation must equal exactly 16px.
- bot-onboarding: a 284px QR frame and a 522px dialog cap. Replaced by the
contract that matters for scanning a code — the dialog stays inside the
window and the QR is in the viewport.
- locale-renderer: screenshot.byteLength > 10_000 cannot disagree with the
implementation; a blank frame clears it too. The rendered translated
control is the evidence, and it was already being asserted.
* test(e2e): consolidate window-floor sweeps and step the provider journey
Five settings tests each launched their own Electron window to do the same
thing: shrink to the 480px floor and walk pages. They now share one window
and one sweep, split into named steps. Every page-specific assertion is
carried over unchanged — health tiles, usage tabs, the web-search hint,
memory's preview header and status Item, palette wrapping, the data
strategy field and workspace path, about, daily review. The three wide
track-count checks collapse the same way. Pages needing their own seeded
fixture (permissions, usage logs, search results) stay separate: their
state is what makes the contract reachable.
The provider add journey ran ~150 lines and ten behaviors under one name,
so any failure meant reading all of it to learn what broke. Splitting it
into separate tests would buy isolation at four more cold starts;
test.step gives the trace the same answer for free.
Also drops two more token assertions found in that journey (dialog width
cap, 24px brand plate) and the settings switch's 40x24 geometry test.
Net: 20 settings tests to 14, and the E2E suite from 94 to 86.
* test(e2e): record the suite's new size in the config note
* test(e2e): restore the QR rendering contract dropped in the token sweep
The token sweep replaced the QR geometry block with `toBeInViewport()`, which
was too weak for what the comment claimed. Playwright's default `ratio: 0`
passes on any positive intersection, so a QR with one corner on screen — or
one shrunk to a dot inside its frame — cleared the assertion while being
unscannable.
The 284px frame and 522px dialog cap really were tokens. But `qrBox.width ===
qrFrameBox.width - 2` was not: it is the relationship "the image fills its
frame", and nothing else in the suite covers rendered QR geometry. Restored as
relationships rather than constants: fills its frame, square, at least 160px,
centred in its dialog, wholly in the viewport via `ratio: 1`.
Both halves proved by negative control — shrinking the QR to 1px and shifting
it so only a corner shows each turn the test red.
* test(e2e): stop recording a test count that rots
The note said 94 tests; it had been stale for a while, and my own edit made it
worse by writing 86 from a passed-count that excluded a failing test. Actual
discovery is 87 on this branch and 98 on main.
A number that has now been wrong twice, in the same comment, is not worth
maintaining: `playwright test --list` is authoritative and free. Keeps the
timing measurement, which is what the note exists for.
* fix(e2e): drive sidebar collapse through a path that still works
`titlebar restores the official SideNav width after pointer collapse` has
failed on every CI run since #1750 upgraded Astryx to 0.2.0. It was green when
introduced in #1751 and appeared in the failure list for the first time in the
#1750 run; #1752 fixed the other Astryx-migration failures but not this one.
Cause: the resize handle no longer responds to synthesised pointer input.
Measured — after `mouse.down()` on the handle and a drag across the panel,
`aria-valuenow` and the rendered width both stay at 260, and a hand-built
`PointerEvent` sequence with the right `pointerId`, `buttons`, and `isPrimary`,
dispatched to both the handle and `window`, moves neither. Keyboard resize
still works, so this is specific to pointer drag. The test went on asserting
`collapsed` after a drag that collapsed nothing.
Collapse through the titlebar control instead: same round trip, by the path a
user has, and drivable. Strengthened while here — it now picks a non-default
width first, so restoring proves the chosen width came back rather than the
260px default.
The `app-shell.tsx` guard that refuses to persist a sub-minimum width is left
explicitly uncovered and documented as such: only pointer drag produces an
under-minimum width, and there is no renderer-side seam for it today. Better
named as a gap than papered over by a test that cannot reach it.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Astro-Han