mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-06 07:29:42 +02:00
fix(git-status): address #537 review (docker workspaces, gone upstream, in-flight reset, docs)
- never inspect a repository at or inside a Docker case workspace (walk-up, scan, diff route): git would run its clean filters on the host - a branch whose upstream was deleted and pruned reports upstreamGone and falls back to commits on no remote, instead of green - turning the setting off during a poll releases the in-flight flag - log.showSignature=false; reword the docs: clean filters still run - CLAUDE.md frontend load order, changeset names git-diff - discovery reads a bounded, sorted directory listing; leading-dash paths allowed; diff 500 redacts credentials - keyboard focus survives the poll re-render; panel stays on screen on narrow viewports; aria-expanded visible on light skins Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JrzFKEdBLwVfu6ev2ZscJS
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
b2423c90ce
commit
0c4bb5169f
@@ -203,6 +203,23 @@ describe('Git status indicator in a real browser', () => {
|
||||
await page.click('#gitStatusBody button:has-text("Back")');
|
||||
});
|
||||
|
||||
it('keeps keyboard focus on the same file row across the 15 s re-render', async () => {
|
||||
await page.focus('.git-status-file:has-text("a.txt")');
|
||||
const key = () => page.evaluate(() => (document.activeElement as HTMLElement | null)?.dataset?.gitKey ?? null);
|
||||
expect(await key()).toBe('unstaged|a.txt');
|
||||
await refresh();
|
||||
await page.waitForFunction(() => document.activeElement?.getAttribute('data-git-key') === 'unstaged|a.txt');
|
||||
expect(await key()).toBe('unstaged|a.txt');
|
||||
});
|
||||
|
||||
it('the panel never starts off-screen, even on a 650px-wide viewport', async () => {
|
||||
const original = page.viewportSize()!;
|
||||
await page.setViewportSize({ width: 650, height: original.height });
|
||||
const left = await page.evaluate(() => document.getElementById('gitStatusPanel')!.getBoundingClientRect().left);
|
||||
await page.setViewportSize(original);
|
||||
expect(left).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
it('drags by the header', async () => {
|
||||
const before = await page.evaluate(() => document.getElementById('gitStatusPanel')!.getBoundingClientRect().left);
|
||||
const box = (await page.locator('.git-status-header').boundingBox())!;
|
||||
@@ -352,6 +369,33 @@ describe('Git status indicator in a real browser', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('turning the setting off while a read is in flight, then on again, does not leave polling dead', async () => {
|
||||
let slow = true;
|
||||
await page.route('**/api/sessions/*/git-status*', async (route) => {
|
||||
if (slow) await new Promise((r) => setTimeout(r, 1500));
|
||||
await route.continue();
|
||||
});
|
||||
page.setDefaultTimeout(6000);
|
||||
// A background poll may be mid-read: let it finish so OUR read is the one the slow route holds.
|
||||
await page.waitForFunction(() => (window as any).app._gitStatusInFlight === false);
|
||||
await page.evaluate(() => void (window as any).app.refreshGitStatus({ fresh: true }));
|
||||
await page.waitForFunction(() => (window as any).app._gitStatusInFlight === true);
|
||||
await setSetting(false);
|
||||
expect(await page.evaluate(() => (window as any).app._gitStatusInFlight)).toBe(false);
|
||||
slow = false;
|
||||
await setSetting(true);
|
||||
// Re-enabling starts its own read. With the flag stuck true that read is skipped for this session
|
||||
// and the indicator never comes back.
|
||||
await page.waitForFunction(() => !!(window as any).app._currentGitStatus());
|
||||
expect(await page.evaluate(() => (window as any).app._gitStatusInFlight)).toBe(false);
|
||||
page.setDefaultTimeout(30000);
|
||||
await page.unroute('**/api/sessions/*/git-status*');
|
||||
expect(await buttonVisible()).toBe(true);
|
||||
// Turning the setting off closed the panel; reopen it for the tests that follow.
|
||||
await page.click('#gitStatusBtn');
|
||||
await page.waitForSelector('#gitStatusPanel.visible');
|
||||
}, 30000);
|
||||
|
||||
it('closing the panel resets it; turning the setting off hides the button, closes the panel and stops polling', async () => {
|
||||
await page.click('.git-status-actions button[aria-label="Close git status"]');
|
||||
expect(await page.isVisible('#gitStatusPanel')).toBe(false);
|
||||
@@ -364,5 +408,5 @@ describe('Git status indicator in a real browser', () => {
|
||||
const before = gitStatusRequests.length;
|
||||
await page.waitForTimeout(3000);
|
||||
expect(gitStatusRequests.length).toBe(before);
|
||||
});
|
||||
}, 30000);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user