Skip to content

Commit 4aa99da

Browse files
committed
refactor: reorganize tests by feature scope, remove Phase references
- Restructure tests into feature-specific describe blocks - Each feature (paste, blur, input, etc.) has its own top-level suite - Remove temporary 'Phase 1' terminology from tests and demo - Maintain same test coverage (66 tests, all passing)
1 parent b5c4f1e commit 4aa99da

2 files changed

Lines changed: 179 additions & 21 deletions

File tree

demo/index.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@
170170
}
171171
}
172172

173-
/* Phase 1 Feature Panel */
173+
/* Feature Panel */
174174
.feature-panel {
175175
background: rgba(255, 255, 255, 0.1);
176176
backdrop-filter: blur(10px);
@@ -281,7 +281,7 @@ <h1>🖥️ Ghostty Terminal</h1>
281281
</div>
282282

283283
<div class="feature-panel">
284-
<h3>🎯 Phase 1 Features - xterm.js API Parity</h3>
284+
<h3>🎯 xterm.js API Features</h3>
285285
<div class="button-grid">
286286
<button class="test-button" id="btn-paste">📋 Test paste()</button>
287287
<button class="test-button" id="btn-blur">👁️ Test blur()</button>
@@ -624,7 +624,7 @@ <h3>🎯 Phase 1 Features - xterm.js API Parity</h3>
624624
// - Ctrl+C / Cmd+C to copy (via browser context menu)
625625

626626
// =========================================================================
627-
// Phase 1 Features - Event Logging & Handlers
627+
// Event Logging & Handlers
628628
// =========================================================================
629629

630630
let customHandlerEnabled = false;
@@ -652,7 +652,7 @@ <h3>🎯 Phase 1 Features - xterm.js API Parity</h3>
652652
}
653653
}
654654

655-
function setupPhase1Events() {
655+
function setupEventHandlers() {
656656
// Event: onKey - fires on every keypress
657657
term.onKey((e) => {
658658
logEvent('onKey', `key="${e.key}" ctrl=${e.domEvent.ctrlKey} alt=${e.domEvent.altKey}`);
@@ -817,8 +817,8 @@ <h3>🎯 Phase 1 Features - xterm.js API Parity</h3>
817817
// Text selection is now built-in - no need to enable it!
818818
// You can use term.getSelection(), term.selectAll(), etc.
819819

820-
// Phase 1: Hook up new event listeners
821-
setupPhase1Events();
820+
// Hook up event listeners and test buttons
821+
setupEventHandlers();
822822

823823
// Connect to WebSocket server
824824
connect();

lib/terminal.test.ts

Lines changed: 173 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -449,11 +449,7 @@ describe('Terminal', () => {
449449
});
450450
});
451451

452-
// =============================================================================
453-
// Phase 1 Features Tests
454-
// =============================================================================
455-
456-
describe('Terminal > Phase 1 Features', () => {
452+
describe('Terminal > paste()', () => {
457453
let container: HTMLElement | null = null;
458454

459455
beforeEach(() => {
@@ -470,7 +466,7 @@ describe('Terminal > Phase 1 Features', () => {
470466
}
471467
});
472468

473-
describe('paste()', () => {
469+
describe('Basic functionality', () => {
474470
test('should fire onData event with pasted text', async () => {
475471
if (!container) return;
476472
const term = new Terminal({ cols: 80, rows: 24 });
@@ -511,8 +507,26 @@ describe('Terminal > Phase 1 Features', () => {
511507
term.dispose();
512508
});
513509
});
510+
});
511+
512+
describe('Terminal > blur()', () => {
513+
let container: HTMLElement | null = null;
514+
515+
beforeEach(() => {
516+
if (typeof document !== 'undefined') {
517+
container = document.createElement('div');
518+
document.body.appendChild(container);
519+
}
520+
});
521+
522+
afterEach(() => {
523+
if (container && container.parentNode) {
524+
container.parentNode.removeChild(container);
525+
container = null;
526+
}
527+
});
514528

515-
describe('blur()', () => {
529+
describe('Basic functionality', () => {
516530
test('should not throw when terminal is open', async () => {
517531
const term = new Terminal({ cols: 80, rows: 24 });
518532
// Using shared container from beforeEach
@@ -549,8 +563,26 @@ describe('Terminal > Phase 1 Features', () => {
549563
term.dispose();
550564
});
551565
});
566+
});
552567

553-
describe('input()', () => {
568+
describe('Terminal > input()', () => {
569+
let container: HTMLElement | null = null;
570+
571+
beforeEach(() => {
572+
if (typeof document !== 'undefined') {
573+
container = document.createElement('div');
574+
document.body.appendChild(container);
575+
}
576+
});
577+
578+
afterEach(() => {
579+
if (container && container.parentNode) {
580+
container.parentNode.removeChild(container);
581+
container = null;
582+
}
583+
});
584+
585+
describe('Basic functionality', () => {
554586
test('should write data to terminal', async () => {
555587
const term = new Terminal({ cols: 80, rows: 24 });
556588
// Using shared container from beforeEach
@@ -616,8 +648,26 @@ describe('Terminal > Phase 1 Features', () => {
616648
term.dispose();
617649
});
618650
});
651+
});
652+
653+
describe('Terminal > select()', () => {
654+
let container: HTMLElement | null = null;
619655

620-
describe('select()', () => {
656+
beforeEach(() => {
657+
if (typeof document !== 'undefined') {
658+
container = document.createElement('div');
659+
document.body.appendChild(container);
660+
}
661+
});
662+
663+
afterEach(() => {
664+
if (container && container.parentNode) {
665+
container.parentNode.removeChild(container);
666+
container = null;
667+
}
668+
});
669+
670+
describe('Basic functionality', () => {
621671
test('should create selection', async () => {
622672
const term = new Terminal({ cols: 80, rows: 24 });
623673
// Using shared container from beforeEach
@@ -663,8 +713,26 @@ describe('Terminal > Phase 1 Features', () => {
663713
term.dispose();
664714
});
665715
});
716+
});
717+
718+
describe('Terminal > selectLines()', () => {
719+
let container: HTMLElement | null = null;
720+
721+
beforeEach(() => {
722+
if (typeof document !== 'undefined') {
723+
container = document.createElement('div');
724+
document.body.appendChild(container);
725+
}
726+
});
666727

667-
describe('selectLines()', () => {
728+
afterEach(() => {
729+
if (container && container.parentNode) {
730+
container.parentNode.removeChild(container);
731+
container = null;
732+
}
733+
});
734+
735+
describe('Basic functionality', () => {
668736
test('should select entire lines', async () => {
669737
const term = new Terminal({ cols: 80, rows: 24 });
670738
// Using shared container from beforeEach
@@ -714,8 +782,26 @@ describe('Terminal > Phase 1 Features', () => {
714782
term.dispose();
715783
});
716784
});
785+
});
786+
787+
describe('Terminal > getSelectionPosition()', () => {
788+
let container: HTMLElement | null = null;
789+
790+
beforeEach(() => {
791+
if (typeof document !== 'undefined') {
792+
container = document.createElement('div');
793+
document.body.appendChild(container);
794+
}
795+
});
796+
797+
afterEach(() => {
798+
if (container && container.parentNode) {
799+
container.parentNode.removeChild(container);
800+
container = null;
801+
}
802+
});
717803

718-
describe('getSelectionPosition()', () => {
804+
describe('Basic functionality', () => {
719805
test('should return null when no selection', async () => {
720806
const term = new Terminal({ cols: 80, rows: 24 });
721807
// Using shared container from beforeEach
@@ -757,8 +843,26 @@ describe('Terminal > Phase 1 Features', () => {
757843
term.dispose();
758844
});
759845
});
846+
});
847+
848+
describe('Terminal > onKey event', () => {
849+
let container: HTMLElement | null = null;
850+
851+
beforeEach(() => {
852+
if (typeof document !== 'undefined') {
853+
container = document.createElement('div');
854+
document.body.appendChild(container);
855+
}
856+
});
760857

761-
describe('onKey event', () => {
858+
afterEach(() => {
859+
if (container && container.parentNode) {
860+
container.parentNode.removeChild(container);
861+
container = null;
862+
}
863+
});
864+
865+
describe('Basic functionality', () => {
762866
test('should exist', async () => {
763867
const term = new Terminal({ cols: 80, rows: 24 });
764868
// Using shared container from beforeEach
@@ -791,8 +895,26 @@ describe('Terminal > Phase 1 Features', () => {
791895
term.dispose();
792896
});
793897
});
898+
});
794899

795-
describe('onTitleChange event', () => {
900+
describe('Terminal > onTitleChange event', () => {
901+
let container: HTMLElement | null = null;
902+
903+
beforeEach(() => {
904+
if (typeof document !== 'undefined') {
905+
container = document.createElement('div');
906+
document.body.appendChild(container);
907+
}
908+
});
909+
910+
afterEach(() => {
911+
if (container && container.parentNode) {
912+
container.parentNode.removeChild(container);
913+
container = null;
914+
}
915+
});
916+
917+
describe('Basic functionality', () => {
796918
test('should exist', async () => {
797919
const term = new Terminal({ cols: 80, rows: 24 });
798920
// Using shared container from beforeEach
@@ -858,8 +980,26 @@ describe('Terminal > Phase 1 Features', () => {
858980
term.dispose();
859981
});
860982
});
983+
});
984+
985+
describe('Terminal > attachCustomKeyEventHandler()', () => {
986+
let container: HTMLElement | null = null;
987+
988+
beforeEach(() => {
989+
if (typeof document !== 'undefined') {
990+
container = document.createElement('div');
991+
document.body.appendChild(container);
992+
}
993+
});
994+
995+
afterEach(() => {
996+
if (container && container.parentNode) {
997+
container.parentNode.removeChild(container);
998+
container = null;
999+
}
1000+
});
8611001

862-
describe('attachCustomKeyEventHandler()', () => {
1002+
describe('Basic functionality', () => {
8631003
test('should accept a custom handler', async () => {
8641004
const term = new Terminal({ cols: 80, rows: 24 });
8651005
// Using shared container from beforeEach
@@ -883,8 +1023,26 @@ describe('Terminal > Phase 1 Features', () => {
8831023
term.dispose();
8841024
});
8851025
});
1026+
});
1027+
1028+
describe('Terminal > Options', () => {
1029+
let container: HTMLElement | null = null;
1030+
1031+
beforeEach(() => {
1032+
if (typeof document !== 'undefined') {
1033+
container = document.createElement('div');
1034+
document.body.appendChild(container);
1035+
}
1036+
});
1037+
1038+
afterEach(() => {
1039+
if (container && container.parentNode) {
1040+
container.parentNode.removeChild(container);
1041+
container = null;
1042+
}
1043+
});
8861044

887-
describe('Options', () => {
1045+
describe('convertEol and disableStdin', () => {
8881046
test('convertEol option should convert newlines', async () => {
8891047
const term = new Terminal({ cols: 80, rows: 24, convertEol: true });
8901048
// Using shared container from beforeEach

0 commit comments

Comments
 (0)