diff --git a/src/web/public/styles.css b/src/web/public/styles.css index 19631492..9cb4a7d7 100644 --- a/src/web/public/styles.css +++ b/src/web/public/styles.css @@ -15977,8 +15977,10 @@ body.touch-device.cjk-input-visible .main { white-space: nowrap; } +/* An ordinary status fits one line; a refusal may not, and it must be readable whole. */ .path-picker-status.error { color: var(--danger, #ef4444); + white-space: normal; } .path-picker-list { diff --git a/test/path-picker-new-folder.test.ts b/test/path-picker-new-folder.test.ts index 3f13f3bf..03436d0d 100644 --- a/test/path-picker-new-folder.test.ts +++ b/test/path-picker-new-folder.test.ts @@ -14,6 +14,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; const PUBLIC = resolve(import.meta.dirname, '../src/web/public'); const accessoryJs = readFileSync(resolve(PUBLIC, 'keyboard-accessory.js'), 'utf8'); const sessionUiJs = readFileSync(resolve(PUBLIC, 'session-ui.js'), 'utf8'); +const stylesCss = readFileSync(resolve(PUBLIC, 'styles.css'), 'utf8'); const dom = new JSDOM('', { url: 'https://localhost/' }); const jsdomWindow = dom.window as unknown as Window & typeof globalThis; @@ -166,22 +167,31 @@ describe('PathPicker New folder', () => { expect(doc.querySelector('.path-picker-overlay')).not.toBeNull(); }); + // A picker's whole options object: a fixed window stops short of the container picker's long one. + const pickerOptions = (name: string) => { + const start = sessionUiJs.indexOf(`${name}() {`); + expect(start, name).toBeGreaterThan(-1); + const open = sessionUiJs.indexOf('PathPicker.open', start); + expect(open, name).toBeGreaterThan(start); + const end = sessionUiJs.indexOf('\n });', open); + expect(end, name).toBeGreaterThan(open); + return sessionUiJs.slice(open, end); + }; + it("is on for Create New's custom folder picker too", () => { - const start = sessionUiJs.indexOf('openNewCasePathPicker() {'); - expect(sessionUiJs.slice(start, sessionUiJs.indexOf('PathPicker.open', start) + 400)).toContain( - 'allowNewFolder: true' - ); + expect(pickerOptions('openNewCasePathPicker')).toContain('allowNewFolder: true'); }); - it('is on for Link Existing and off for the other session-ui pickers', () => { - const block = (name: string) => { - const start = sessionUiJs.indexOf(`${name}() {`); - expect(start, name).toBeGreaterThan(-1); - return sessionUiJs.slice(start, sessionUiJs.indexOf('PathPicker.open', start) + 400); - }; - expect(block('openLinkCasePathPicker')).toContain('allowNewFolder: true'); + it('is on for Link Existing and off for the Clone and Docker pickers', () => { + expect(pickerOptions('openLinkCasePathPicker')).toContain('allowNewFolder: true'); for (const other of ['openDockerWorkspacePathPicker', 'openDockerWorkdirPicker', 'openCloneCasePathPicker']) { - expect(block(other), other).not.toContain('allowNewFolder'); + expect(pickerOptions(other), other).not.toContain('allowNewFolder'); } }); + + it('lets an error wrap: the status line has no other way to show the rest of a long refusal', () => { + const start = stylesCss.indexOf('.path-picker-status.error {'); + expect(start).toBeGreaterThan(-1); + expect(stylesCss.slice(start, stylesCss.indexOf('}', start))).toContain('white-space: normal'); + }); });