Path: blob/main/test/smoke/src/areas/terminal/terminal-stickyScroll.test.ts
3520 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Application, Terminal, SettingsEditor, TerminalCommandIdWithValue } from '../../../../automation';6import { setTerminalTestSettings } from './terminal-helpers';78export function setup(options?: { skipSuite: boolean }) {9(options?.skipSuite ? describe.skip : describe)('Terminal stickyScroll', () => {10// Acquire automation API11let app: Application;12let terminal: Terminal;13let settingsEditor: SettingsEditor;14before(async function () {15app = this.app as Application;16terminal = app.workbench.terminal;17settingsEditor = app.workbench.settingsEditor;18await setTerminalTestSettings(app, [19['terminal.integrated.stickyScroll.enabled', 'true']20]);21});2223after(async function () {24await settingsEditor.clearUserSettings();25});2627// A polling approach is used to avoid test flakiness. While it's not ideal that this28// occurs, the main purpose of the tests is to verify sticky scroll shows and updates,29// not edge case race conditions on terminal start up30async function checkCommandAndOutput(31command: string,32exitCode: number,33prompt: string = 'Prompt> ',34expectedLineCount: number = 135): Promise<void> {36const data = generateCommandAndOutput(prompt, command, exitCode);37await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, data);38// Verify line count39await app.code.waitForElements('.terminal-sticky-scroll .xterm-rows > *', true, e => e.length === expectedLineCount);40// Verify content41const element = await app.code.getElement('.terminal-sticky-scroll .xterm-rows');42if (43element &&44// New lines don't come through in textContent45element.textContent.indexOf(`${prompt.replace(/\\r\\n/g, '')}${command}`) >= 046) {47return;48}49throw new Error(`Failed for command ${command}, exitcode ${exitCode}, text content ${element?.textContent}`);50}5152// Don't use beforeEach as that ignores the retry count, createEmptyTerminal has been53// flaky in the past54async function beforeEachSetup() {55// Create the simplest system profile to get as little process interaction as possible56await terminal.createEmptyTerminal();57}5859it('should show sticky scroll when appropriate', async () => {60await beforeEachSetup();6162// Write prompt, fill viewport, finish command, print new prompt, verify sticky scroll63await checkCommandAndOutput('sticky scroll 1', 0);6465// And again with a failed command66await checkCommandAndOutput('sticky scroll 2', 1);67});6869it('should support multi-line prompt', async () => {70await beforeEachSetup();7172// Standard multi-line prompt73await checkCommandAndOutput('sticky scroll 1', 0, "Multi-line\\r\\nPrompt> ", 2);7475// New line before prompt76await checkCommandAndOutput('sticky scroll 2', 0, "\\r\\nMulti-line Prompt> ", 1);7778// New line before multi-line prompt79await checkCommandAndOutput('sticky scroll 3', 0, "\\r\\nMulti-line\\r\\nPrompt> ", 2);80});81});82}8384function generateCommandAndOutput(prompt: string, command: string, exitCode: number): string {85return [86`${vsc('A')}${prompt}${vsc('B')}${command}`,87`\\r\\n${vsc('C')}`,88`\\r\\ndata`.repeat(50),89`\\r\\n${vsc(`D;${exitCode}`)}`,90].join('');91}9293function vsc(data: string) {94return setTextParams(`633;${data}`);95}9697function setTextParams(data: string) {98return osc(`${data}\\x07`);99}100101function osc(data: string) {102return `\\x1b]${data}`;103}104105106